Compare commits

..
Author SHA1 Message Date
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
170b020e17 Version Packages (#7682)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-23 19:25:46 -07:00
Joaquim VergesandGitHub 8260af3a92 [Dashboard] Replace modular contracts with Arbitrum Stylus contracts in explore page (#7685) 2025-07-22 19:15:42 -07:00
Joaquim VergesandGitHub b9154cc9e7 [API] Init API wrapper package (#7684) 2025-07-22 18:46:02 -07:00
Joaquim VergesandGitHub 08955f1588 [SDK] Expose getAuthToken from inApp and ecosystem wallets (#7683) 2025-07-22 18:26:46 -07:00
gregandGitHub 756295241a [SDK] Feature: Adds optional transactionId parameter to Bridge.status (#7681) 2025-07-22 15:11:04 -07:00
Joaquim VergesandGitHub 249679481e [Docs] Update redirects for wallets and payments paths (#7680) 2025-07-22 15:09:00 -07:00
Joaquim VergesandGitHub a491de4d7c [Docs] Refactor Contract and Tokens docs (#7676) 2025-07-22 17:20:00 +12:00
gregandGitHub 898efc56a9 [Portal] Fix: Test Jam Feedback (#7677) 2025-07-21 21:32:26 -07:00
c0e7ae95de Add external wallet filter and display (#7669)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-21 20:39:26 -07:00
Joaquim VergesandGitHub 1e8190a1f9 [Docs] Add frontend/backend tabs for transaction sending examples (#7670) 2025-07-21 19:36:18 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
aac187a76c Version Packages (#7662)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-21 16:35:51 -07:00
Manan TankandGitHub 03390c1e25 Portal: homepage UI improvements (#7667) 2025-07-21 16:35:29 -07:00
8d3b9c6a33 [Portal] Fix: update sidebar overflow behavior in DocLayout component (#7653)
Co-authored-by: Joaquim Verges <[email protected]>
2025-07-21 14:47:24 -07:00
MananTank ddef88866f [PRO-249] Portal: Update OG images (#7664)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the metadata and image attributes across various pages in the `thirdweb` portal, particularly in the payments and vault sections. It modifies titles, icons, and descriptions to enhance clarity and consistency.

### Detailed summary
- Changed `metadata` for payments to use "payments" icon and updated titles.
- Updated vault metadata to include a new image with the "vault" icon.
- Modified various page descriptions for clarity and consistency.
- Added a new script for formatting in `package.json`.
- Removed unused code in `api/og/route.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added and updated metadata images and titles across several pages, including "Contracts", "Vault", and various "Payments" pages for improved visual representation.
  * Introduced support for a new "vault" icon in metadata image options.

* **Style**
  * Improved formatting and removed extraneous blank lines in code examples and UI components for better readability.
  * Cleaned up whitespace in multiple example code snippets.

* **Chores**
  * Added a new formatting script for consistent code style across the project.

* **Refactor**
  * Simplified Open Graph image layouts by removing certain UI elements.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-21 20:42:32 +00:00
Manan TankandGitHub 8133fab9e4 [TOOL-5083] Portal: Fix header on mobile viewport (#7661) 2025-07-21 13:41:30 -07:00
Joaquim VergesandGitHub 37414eb54a [SDK] Fix native token fallback when insight query fails (#7666) 2025-07-21 13:39:29 -07:00
MananTank 22bf68a6f0 [TOOL-5075] SDK: Fix various alignment issues in components (#7657)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on fixing various alignment issues in React components within the `thirdweb` package, enhancing hover states and visual consistency across different UI elements.

### Detailed summary
- Updated hover styles in several components to improve visual feedback.
- Adjusted `all` property to "unset" for better styling control.
- Modified colors and borders in `OTPLoginUI.tsx`, `ReceiveFunds.tsx`, `DepositScreen.tsx`, and others for consistency.
- Enhanced button styles in `MenuButton.tsx`, `WalletEntryButton.tsx`, and `NetworkSelector.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Bug Fixes**
  * Resolved various alignment issues in React components to improve visual consistency across the interface.

* **Chores**
  * Updated internal documentation to reflect the latest patch addressing alignment fixes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-21 17:58:07 +00:00
EimanandGitHub 68dd4dc17e fixed playground import (#7660) 2025-07-21 10:46:58 -07:00
saminacodes ecf6dbf2aa Update portal label to TypeScript SDK (#7658)
```
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

[Portal] Fix: Update SDK title for TypeScript reference pages

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Updates the SDK title displayed on TypeScript reference pages from "Connect SDK" to "TypeScript SDK" for improved clarity and accuracy.

## How to test

Navigate to any `/references/typescript/v*/` page (e.g., `/references/typescript/v5/`). Verify the header displays "TypeScript SDK".

-->
```

---

**Open Background Agent:**
[Web](https://www.cursor.com/agents?id=bc-2dec36af-4b62-431c-b277-891c1b46bb48) · [Cursor](https://cursor.com/background-agent?bcId=bc-2dec36af-4b62-431c-b277-891c1b46bb48)

[Slack Thread](https://thirdwebdev.slack.com/archives/C04DYC3G5NZ/p1753110978408999?thread_ts=1753110978.408999&cid=C04DYC3G5NZ)

Learn more about [Background Agents](https://docs.cursor.com/background-agents)

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on renaming references from `Connect SDK` to `TypeScript SDK` and `thirdweb SDK` across multiple files in the project, enhancing clarity and consistency in the documentation and codebase.

### Detailed summary
- Updated `label` from `Connect SDKs` to `thirdweb SDKs`.
- Changed `name` from `Connect SDK` to `TypeScript SDK`.
- Modified `sdkTitle` from `Connect SDK` to `TypeScript SDK`.
- Adjusted example descriptions and titles to reflect `TypeScript SDK`.
- Updated installation instructions to refer to `TypeScript SDK`.
- Revised descriptions related to wallet support to mention `thirdweb SDKs`.
- Changed references in guides and documentation from `Connect SDK` to `TypeScript SDK`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Updated SDK naming from "Connect SDK" to "TypeScript SDK" and "thirdweb SDK" across documentation, guides, UI labels, and sidebar links for improved clarity and consistency.

* **Chores**
  * Removed the "Engine" API link from the main navigation header.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-21 16:52:47 +00:00
Phillip HoandGitHub 01daaceb21 only one file (#7659) 2025-07-21 23:23:18 +08:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
a5345808ec Version Packages (#7640)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-21 02:22:54 -07:00
Joaquim VergesandGitHub bfa0a42219 [SDK] Fix TransactionWidget when wallet has enough currency (#7656) 2025-07-21 02:13:17 -07:00
426bb8bbb2 [SDK] Fix: fixes auto-connect on native <ConnectEmbed /> component (#7650)
Co-authored-by: Joaquim Verges <[email protected]>
2025-07-20 18:09:51 -07:00
823af013ae [SDK] Fix: update hooks to use core transaction types (#7647)
Co-authored-by: Joaquim Verges <[email protected]>
2025-07-20 18:02:09 -07:00
gregandGitHub 98aea1e0b9 [Portal] Payments Docs (#7651) 2025-07-20 17:46:20 -07:00
Joaquim VergesandGitHub 620e294f8c [Engine] Update server wallet config types for EOA and EIP-7702 execution (#7652) 2025-07-20 17:43:13 -07:00
Joaquim VergesandGitHub 84eaded152 [Dashboard] Show EOA server wallets by default (#7645) 2025-07-20 16:26:55 -07:00
MananTank 31d7173432 Dashboard: Show upsell card on support page for free plan (#7648)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the support functionality within the dashboard, particularly for teams on a free billing plan. It adds checks for the billing plan, modifies the `SupportHeader`, and integrates upsell content to encourage users to upgrade their plans.

### Detailed summary
- `SupportHeader` now accepts `isFreePlan` prop to conditionally render buttons.
- Redirects free plan users from creating support cases.
- Displays upsell content for free plan users in the support page.
- Added functionality to show/hide support forms based on billing plan.
- Updated `CreateSupportCase` component to handle dialog state for support case creation.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Free plan users now see an upsell prompt encouraging upgrade to access the Support Center, with a clear list of benefits.
  * The Support Center title has been updated for improved clarity.
  * Support case creation is disabled for free plan users, showing an informative message with a billing link instead.
  * Conditional support action buttons are shown only for paid plans, adapting to the user's context.

* **Improvements**
  * Enhanced visual styling and layout for benefit descriptions in upsell prompts.
  * Error messages in the Support Center now display detailed information for easier troubleshooting.
  * Dialogs for creating support cases now open and close with explicit user control for better interaction.
  * The chat button is hidden on the Support Center page to reduce UI clutter.

* **Bug Fixes**
  * Free plan users are prevented from accessing the support case creation page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-18 21:17:54 +00:00
Yash094 a48329b697 [dashboard] - support in dashboard (#7608)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on restructuring the support ticketing system by moving components and modifying links to streamline support interactions within the application.

### Detailed summary
- Deleted multiple support-related files and components.
- Changed `getTeamById` function to remove the `export` keyword.
- Updated support links to point to `/team/~/~/support`.
- Added new support ticket types and forms.
- Introduced new components for handling support tickets.
- Implemented ticket status handling and filtering.
- Enhanced the support case list display with filtering options.
- Created API endpoints for support ticket management.
- Integrated dynamic imports for various support forms.

> The following files were skipped due to too many changes: `apps/dashboard/src/@/components/chat/CustomChatContent.tsx`, `apps/dashboard/src/@/components/chat/CustomChats.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/_components/SupportCaseDetails.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/support/_components/CreateSupportCase.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Unified support ticket system integrated into team dashboards with AI chat assistant and dynamic product-specific support forms.
  * Support ticket listing with status filtering, search, detailed conversation views, and reply functionality.
  * Added "Support" link in team sidebar footer; updated support headers, layouts, and navigation flows.
  * Introduced monochrome mode for mini logo and refined chat UI elements.

* **Bug Fixes / Improvements**
  * Enhanced chat component styling and user experience.
  * Removed obsolete "Support" links from navigation menus and headers.
  * Updated button labels, including changing "Ask AI Assistant" to "Get Help".

* **Chores**
  * Removed legacy support ticket creation pages, components, and client/server logic to consolidate support workflows.
  * Cleaned deprecated components, imports, redirects, and updated error messages to point to the new support section.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-18 19:09:16 +00:00
Joaquim VergesandGitHub 6e62a3aa5c [Docs] Add Ecosystem Wallet to sidebar and update documentation (#7643) 2025-07-18 16:47:56 +12:00
Jonas DanielsandGitHub 746b0c9d8b Add mcp to team capabilities (#7636) 2025-07-17 17:46:55 -07:00
gregandGitHub 0f38a1287a [SDK] Feature: Hide the TransactionWidget contract label if unknown (#7642) 2025-07-17 16:32:05 -07:00
gregandGitHub 61bfebf5d8 Chore: Use /search route for routes page (#7639) 2025-07-17 13:40:29 -07:00
170c377445 Handle token balance retrieval failures (#7600)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-17 13:40:15 -07:00
Yash094 4cbf67181d Add etherlink chain (#7634)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces new blockchain definitions for the Etherlink mainnet and testnet, enhancing the `thirdweb` package with additional chain support.

### Detailed summary
- Added `etherlink` mainnet definition in `packages/thirdweb/src/chains/chain-definitions/etherlink.ts`.
- Added `etherlinkTestnet` definition in `packages/thirdweb/src/chains/chain-definitions/etherlink-testnet.ts`.
- Exported `etherlink` and `etherlinkTestnet` in `packages/thirdweb/src/exports/chains.ts`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added support for the Etherlink mainnet and Etherlink testnet blockchain networks.
  * Users can now interact with these new chains within the platform.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-17 19:24:21 +00:00
arcoraven 6bf6108beb chore: webhooks docs (#7604)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new `Webhooks` section in the application, providing a sidebar navigation item, a dedicated layout, and detailed documentation on webhooks, including their configuration, management, and security practices.

### Detailed summary
- Added `sidebar` configuration for `Webhooks` in `sidebar.tsx`.
- Introduced `SDKCard` for `Webhooks` in `page.tsx`.
- Renamed `BAST_URL` to `BASE_URL` in `metadata.ts`.
- Created a new `Layout` component for `Webhooks` in `layout.tsx`.
- Defined metadata for `Webhooks` in `layout.tsx`.
- Added comprehensive documentation for webhooks in `page.mdx`, covering setup, management, event handling, and security.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a new "Webhooks" section in the backend APIs grid, accessible from the main portal.
  * Added comprehensive documentation for thirdweb Webhooks, including setup, management, security, and troubleshooting guides.
  * Implemented a dedicated sidebar and layout for the Webhooks documentation page for easier navigation.

* **Documentation**
  * Provided detailed instructions and code examples for implementing and verifying webhook integrations.

* **Bug Fixes**
  * Corrected a typo in the base URL constant used for metadata generation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-17 19:12:38 +00:00
Phillip HoandGitHub ce85be3346 chore: accordion, rename insight topic, test webhook endpoint (#7635) 2025-07-17 20:57:22 +08:00
MananTank e125e743a3 Dashboard: Temporarily remove gas sponsorship option in token creation (#7631)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on temporarily disabling the gasless feature in two components: `launch-token.tsx` and `launch-nft.tsx`. The condition for enabling gasless functionality has been commented out and replaced with a static `false` value.

### Detailed summary
- In `launch-token.tsx`:
  - `canEnableGasless` is set to `false` with a comment about enabling it later.
  - `showGaslessSection` is set to `false`.

- In `launch-nft.tsx`:
  - `canEnableGasless` is set to `false` with a comment about enabling it later.
  - `showGaslessSection` is set to `false`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * The gasless transaction feature and related UI have been temporarily disabled for both NFT and token launch flows.

* **Chores**
  * Updated internal logic to prevent access to the gasless sponsorship section until further notice.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-16 17:35:01 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
05da842b7a Version Packages (#7616)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-16 10:14:03 -07:00
MananTank 216b70475e Dashboard, Portal, Playground: Rename leftover usage of 'Universal Bridge' to 'Payments' in UI (#7611)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on renaming references from `Universal Bridge` to `Payments` across various files in the codebase, reflecting a rebranding initiative.

### Detailed summary
- Changed `name` and `title` from `Universal Bridge` to `Payments` in multiple files.
- Updated labels and descriptions in UI components to reflect the new branding.
- Modified sidebar links and metadata to align with the new `Payments` terminology.
- Adjusted documentation references to `Payments` from `Universal Bridge`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Style**
  * Updated all user-facing references of "Universal Bridge" to "Payments" across banners, page titles, headings, navigation links, sidebars, and documentation content for a consistent branding experience.

* **Documentation**
  * Revised documentation text, metadata, and quickstart guides to reflect the new "Payments" terminology and branding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-16 16:20:48 +00:00
iuwqyir 9d259d0836 add insight filter selection to webhook creation and update (#7598)
<!-- start pr-codex -->

## PR-Codex overview
This PR focuses on enhancing the webhook configuration components by introducing optional support for `ThirdwebClient` and `supportedChainIds`. It improves error handling and validation, particularly in the context of filtering for event and transaction webhooks.

### Detailed summary
- Made `thirdwebClient` optional in `useAbiProcessing` hook.
- Updated `CreateWebhookConfigModal`, `EditWebhookConfigModal`, `WebhooksOverview` to accept `client` and `supportedChainIds`.
- Enhanced error handling in `useQuery` for missing `thirdwebClient`.
- Introduced separate forms for event and transaction filters in `TopicSelectorModal`.
- Improved validation and fetching of ABIs in the filter forms.
- Added support for displaying ABI fetch status and results.
- Enhanced UI elements to accommodate new filter configurations.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Enhanced webhook topic selection with advanced, form-driven filtering for contract webhook topics, including multi-network and ABI-based options.
  * Added support for passing client and supported chain information throughout the webhooks dashboard for improved filtering and configuration.

* **Improvements**
  * Increased dialog width for filter configuration to improve usability.
  * Streamlined handling of webhook topic filters for consistency and flexibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-16 13:17:01 +00:00
Phillip HoandGitHub ca52cdd3bf chore: /token and /vault landing pages (#7633) 2025-07-16 20:26:13 +08:00
Joaquim VergesandGitHub cf68002922 [Docs] Update page.mdx (#7632)
Signed-off-by: Joaquim Verges <[email protected]>
2025-07-16 02:08:40 -07:00
MananTank 495c7f925d [TOOL-5047] Dashboard: Fix client object missing teamId on contract publish page (#7628)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `PublishContractPage` component to utilize the `getUserThirdwebClient` function for client initialization, enhancing user authentication handling during contract publishing.

### Detailed summary
- Added import for `getUserThirdwebClient` from `@/api/auth-token`.
- Removed import for `getClientThirdwebClient` from `@/constants/thirdweb-client.client`.
- Replaced the client initialization in `ContractPublishForm` with `userThirdwebClient` from `getUserThirdwebClient`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Refactor**
  * Updated the way the client is obtained for the contract publish form, improving consistency in client retrieval. No visible changes to user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 20:09:58 +00:00
iuwqyir 32add5f602 Display webhook secret in dashboard (#7610)
```
<!--

## title your PR with this format: "[Dashboard] Feature: Display and Mask Webhook Secret in Contracts Webhooks List"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):
INFRA-1524

## Notes for the reviewer

This PR introduces a new column to the Contracts Webhooks table to display the `webhook_secret`.

Key points:
- The secret is masked for security, showing `**********` followed by the last 3 characters (e.g., `**********xyz`).
- The full secret can be copied to the clipboard using the adjacent copy button.
- No backend changes were required as the `webhook_secret` is already available in the `WebhookResponse`.

## How to test

1. Navigate to a project's webhooks page on the dashboard (`/dashboard/[team_slug]/[project_slug]/webhooks`).
2. Observe the new "Webhook Secret" column in the table.
3. Verify that the secrets are displayed in the masked format (`**********xyz`).
4. Click the copy icon next to a masked secret and confirm that the full secret is copied to your clipboard.

-->
```

---

[Slack Thread](https://thirdwebdev.slack.com/archives/C085X0VQCF3/p1752487882125419?thread_ts=1752487882.125419&cid=C085X0VQCF3)

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new function to mask webhook secrets for improved security and updates the `WebhooksTable` component to display the masked secret while allowing users to copy the original secret.

### Detailed summary
- Added `maskWebhookSecret` function to mask webhook secrets.
- Updated `WebhooksTable` to include a new column for "Webhook Secret."
- Displayed masked secret in the table with an option to copy the original secret.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added a new "Webhook Secret" column to the webhooks table, displaying masked webhook secrets for improved privacy.
  * Included a copy button to easily copy the full unmasked webhook secret to the clipboard.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 19:59:09 +00:00
gregandGitHub 5f74b3ca3e Chore: Update UB jsdocs to include types (#7629) 2025-07-15 11:50:42 -07:00
GiselleNessi 761cde6a32 [portal] add new support article (#7595)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `knowledge-base` section by adding new assets and a comprehensive guide for bulk updating NFT metadata, specifically for ERC-721A contracts.

### Detailed summary
- Added multiple image assets to the `knowledge-base`.
- Introduced a new guide in `page.mdx` for bulk updating NFT metadata.
- Explained concepts of batch and base URI in the context of NFTs.
- Provided step-by-step instructions for updating NFT metadata efficiently.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added a new sidebar entry for "Bulk update NFT metadata" under the "Contracts" section in the Troubleshoot category.
  * Introduced a comprehensive step-by-step guide on how to update metadata for multiple NFTs in bulk, including instructions, images, and helpful resources.

* **Documentation**
  * Expanded the knowledge base with detailed troubleshooting documentation for bulk updating NFT metadata.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 16:55:09 +00:00
Joaquim VergesandGitHub 9546b927d9 [Docs] Redesign sidebar and update wallet documentation (#7602) 2025-07-15 01:26:32 -07:00
jnsdls f82f885dad Update nebula rateLimit type to include perSecond and perMinute (#7614)
# Update Nebula Rate Limit Type

This PR updates the Nebula rate limit type to provide more granular control by replacing the single `rateLimit` number with an object containing `perSecond` and `perMinute` properties. The change affects:

- The `TeamCapabilities` type in the service-utils package
- Corresponding mock data and stubs in the dashboard app
- Added a changeset to document this patch update
2025-07-15 00:12:41 +00:00
jnsdls 34d2fddf49 Update error response URL for project settings (#7613)
# Update error response URL in service-utils

This PR updates the error response URLs in the service-utils package to point to the project-specific settings page instead of the generic API key creation page. The new URLs follow the format `https://thirdweb.com/${team.slug}/${project.slug}/settings`, providing users with a direct link to manage restrictions for their specific project.

The changes affect error messages for:
- Unauthorized domains
- Unauthorized bundle IDs
- Unauthorized services
- Unauthorized service actions

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Bug Fixes**
  * Updated error messages for unauthorized access to provide project-specific URLs, directing users to the relevant project settings page for more accurate guidance.

* **Chores**
  * Added documentation to track the patch update related to error response URLs.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-15 00:12:41 +00:00
a7544f75ce [Portal] Add next button to inner page footers (#7605)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-14 15:46:21 -07:00
gregandGitHub bd3d645be6 [SDK] Fix: Adds BuyWidget fallback when native isn't supported (#7601) 2025-07-14 12:06:18 -07:00
MananTank 5fedc2c040 [TOOL-5037] Dashboard: Remove autoConnect on /login page (#7609)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on refactoring import paths for better organization and consistency across the codebase, as well as enhancing the login and onboarding components, including UI adjustments and functionality updates.

### Detailed summary
- Updated import paths to use absolute imports instead of relative paths.
- Modified the `DashboardLayout` to enable auto-connect.
- Enhanced the `LoginPage` with a new footer message regarding phone login support.
- Adjusted the `Toaster` component to simplify its usage.
- Improved onboarding UI components for better user experience.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added an option to enable automatic wallet connection in the app layout.

* **Refactor**
  * Standardized import paths across the dashboard for improved maintainability and clarity.
  * Updated usage of the notification component to a local version with simplified theming.
  * Improved layout and messaging on the login page, moving phone login deprecation notice to a dedicated footer and refining spacing.

* **Documentation**
  * Enhanced SEO and social sharing metadata on the login page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-14 18:36:51 +00:00
Yash094 6c8a7cf2ba fix playground payments widget (#7607)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `CodeGen` component in the `playground-web` application by renaming a prop for consistency and clarity.

### Detailed summary
- Changed the prop name from `token` to `tokenAddress` in the `CodeGen` component.
- Maintained existing conditional rendering for other props such as `seller`, `title`, `image`, `description`, `paymentMethods`, and `currency`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Refactor**
  * Updated the generated code output to use the prop name `tokenAddress` instead of `token` when displaying the token address in the code example. This change does not affect any other visible functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-14 18:01:58 +00:00
Phillip HoandGitHub 4f02f6eeb7 chore: add webhook secret to table, fix api error (#7606) 2025-07-14 15:55:21 +08:00
72f75ea40b Update converter SDK reference (#7603)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-14 12:53:52 +08:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8b6a953933 Version Packages (#7594)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-13 10:27:06 +12:00
Joaquim VergesandGitHub 33b0b6dcb4 [Dashboard] Add server-wallet signAuthorization capability to wallet access token (#7530) 2025-07-12 02:53:53 -07:00
MananTank cdc7d95db2 [TOOL-4959] Dashboard: Asset page UI improvements (#7599)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refining the UI components and enhancing the functionality of the `ERC20` public page. It includes improvements in layout, styling, and the introduction of new features related to token price data and analytics.

### Detailed summary
- Deleted unused files: `useTokenPriceData.ts` and `ContractCreatorBadge.tsx`.
- Updated `PageHeader` to change border style.
- Added `tooltip` prop in `CopyAddressButton`.
- Changed API key usage in `fetchTokenInfoFromBridge`.
- Enhanced `ThirdwebAreaChart` with better props handling.
- Introduced `GridPattern` component for background.
- Improved `RecentTransfers` UI and pagination buttons.
- Updated `PriceChart` and `TokenStats` to directly use passed props for token price data.
- Refactored `ContractHeaderUI` to improve layout and social link handling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a customizable grid background pattern component for enhanced visual design.
  * Added support for displaying token price data and analytics on ERC20 public pages, including conditional rendering of token statistics.
  * Enabled tooltip customization for the copy address button.

* **Bug Fixes**
  * The contract creator badge icon is now visible, and spacing between elements has been improved.

* **Refactor**
  * Simplified and unified chart headers and analytics section layouts.
  * Streamlined fetching and handling of token price data with a new asynchronous function and removed the previous hook.
  * Improved layout and container styling across ERC20 and NFT public pages, including card backgrounds, borders, and spacing.
  * Adjusted component structures for better visual separation and consistency.
  * Removed the contract creator badge component and replaced it with a simpler contract owner link.

* **Style**
  * Updated card and header styles for better visual hierarchy and clarity.
  * Enhanced recent transfers and contract header sections with improved padding, borders, and rounded corners.
  * Removed small shadow effects from cards and refined header background and border styles.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-12 05:50:29 +05:30
Manan TankandGitHub 592bf6f1fd [TOOL-5021] SDK: Fix theme in ConnectButton Details Modal Buy screen (#7589) 2025-07-12 09:21:50 +12:00
MananTank 8973174ad5 Dashboard: Fix erc20 asset page crash when number of tokens claimed is a fraction (#7597)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `SupplyClaimedProgress` component to use `claimedSupplyTokens` and `totalSupplyTokens` as `number` types instead of `bigint`, along with minor adjustments in related components and UI elements.

### Detailed summary
- Changed `enable-background` to `enableBackground` in `DiscordIcon.tsx`.
- Updated `SupplyClaimedProgress` props from `claimedSupply` and `totalSupply` (bigint) to `claimedSupplyTokens` and `totalSupplyTokens` (number).
- Adjusted calculations and conditions in `SupplyClaimedProgress` for new props.
- Modified test cases in stories to reflect new prop types.
- Updated UI elements to display supply values correctly based on the new number type.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Refactor**
  * Updated supply progress components and related usage to use number types instead of bigints, with new prop names for clarity.
  * Improved handling and display of "unlimited" supply scenarios in supply progress components.
  * Adjusted percentage calculation and formatting for claimed supply progress.

* **Style**
  * Corrected SVG attribute naming in the Discord icon to ensure proper rendering.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-11 20:38:47 +00:00
Phillip HoandGitHub c160e91c08 chore: redirect /universal-bridge -> /payments (#7593) 2025-07-12 04:20:58 +08:00
gregandGitHub f33e31ad6e [SDK] Fix: only require missing token amount for transaction widget (#7591) 2025-07-11 02:01:57 -07:00
Joaquim VergesandGitHub 4111d0e638 [Dashboard] Add error handling and refactor vault account rotation (#7592) 2025-07-10 19:59:42 -07:00
joaquim-verges ffb7b6487b [Dashboard] use BuyWidget on /bridge (#7590)
Fixes TOOL-5023

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `UniversalBridgeEmbed` component to replace the `PayEmbed` with `BuyWidget` from the `thirdweb` library, modifying how payment options are handled and improving the integration with the `thirdweb` SDK.

### Detailed summary
- Replaced `PayEmbed` component with `BuyWidget`.
- Removed `payOptions` prop and its nested properties.
- Added `amount`, `chain`, and `tokenAddress` props to `BuyWidget`.
- Updated the theme handling to use `getSDKTheme`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Updated the embedded widget in the dashboard to use a new buy widget, offering a simplified and more direct interface for purchasing tokens.

* **Refactor**
  * Streamlined the widget’s input options for a more straightforward user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-10 23:09:34 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
77063e5c85 Version Packages (#7588)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-10 15:51:49 -07:00
Joaquim VergesandGitHub 585eac2a6f [Dashboard] Replace vault access token with project secret key for authentication (#7570) 2025-07-10 15:32:36 -07:00
MananTank c54db522b3 Dashboard: Fix webhooks posthog feature flag conditional rendering (#7585)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a centralized webhooks feature, enhancing the sidebar layout and analytics for webhooks. It adds loading states, integrates feature flags, and modifies the handling of webhooks in various components.

### Detailed summary
- Added `Loading` components using `GenericLoadingPage` in multiple webhook pages.
- Updated `ProjectSidebarLayout` to include `isCentralizedWebhooksFeatureFlagEnabled`.
- Enhanced `ProjectLayout` to fetch and utilize the centralized webhooks feature flag.
- Modified `WebhooksAnalyticsPage` to check for the centralized webhooks feature flag before redirecting.
- Adjusted `WebhooksLayout` to conditionally render links based on the centralized webhooks feature flag.
- Refactored `isFeatureFlagEnabled` function for improved feature flag handling.
- Updated `WebhooksPage` to include centralized webhooks feature flag checks and redirection logic.
- Cleaned up imports and ensured consistent use of `params` across various components.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added multiple loading indicators across webhooks analytics, contracts, universal bridge, and sidebar routes for smoother user experience.
  * Sidebar and tab navigation dynamically update based on the centralized webhooks feature flag.

* **Bug Fixes**
  * Enhanced error handling with 404 responses for missing accounts, projects, or authentication on webhooks pages.
  * Redirects implemented when the centralized webhooks feature flag is disabled.

* **Refactor**
  * Updated feature flag checks to a new cached API accepting structured parameters.
  * Streamlined parameter handling and navigation logic for webhooks pages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-10 20:15:27 +00:00
Joaquim VergesandGitHub d62e9971ee [SDK] Fix inapp wallets showing up in all wallets list (#7586) 2025-07-10 13:14:57 -07:00
MananTank 7d796f5aa5 Dashboard: Fix theme for BuyWidget in chain page (#7583)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `BuyFundsSection` component by integrating theme support for the `BuyWidget` using the `useTheme` hook from `next-themes`. It adjusts the widget's theme based on the current application theme.

### Detailed summary
- Added `useTheme` hook to access the current theme.
- Imported `getSDKTheme` utility for theme handling.
- Passed the correct theme to the `BuyWidget` based on whether the theme is "dark" or "light".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * The Buy Funds section now adapts its appearance based on your selected theme (light or dark), providing a more consistent and personalized user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-10 19:57:29 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
a5bb36141d Version Packages (#7584)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-10 12:50:16 -07:00
Prithvish BaidyaandGitHub f3234c3c41 [thirdweb/server-wallet] fix address used for simulation for ERC4337 (#7581) 2025-07-10 11:55:04 -07:00
91e3781e83 [Dashboard] Improve user filtering functionality (#7572)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-10 11:53:41 -07:00
arcoraven 86e3aa8c04 feat: webhooks list in dashboard (#7505)
# [Dashboard] Feature: Add Webhook Management UI

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/38dbe90b-2bd9-47b6-b190-3c257e99d2fe.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/d0a40295-c1c7-45c5-9b23-224a2a631b83.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/42d5337d-fcfe-4ef7-a349-1f596013e003.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/b7b89fe6-a5f7-4961-b927-bfc754c6665f.png)

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/88916c15-a501-4ceb-9267-a23290f683b9.png)

## Notes for the reviewer
This PR adds a new webhook management UI to the dashboard, allowing users to create, edit, delete, and monitor webhooks. The implementation includes:

- A new overview page for webhooks with a table to display all configured webhooks
- Create/edit webhook modals with form validation
- Topic selector for webhook event subscriptions
- Delete confirmation with activity warning
- Webhook metrics display showing request counts and error rates
- API integration for webhook configuration management

## How to test
Navigate to the webhooks section in a project to view the new UI. Create a new webhook, edit its configuration, and test the delete functionality. Verify that metrics are displayed correctly for existing webhooks.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a comprehensive webhooks management interface, including creation, editing, deletion, and topic selection with optional JSON filters.
  * Added analytics dashboards for webhooks, featuring charts for request status codes and latency percentiles, with filtering by webhook and date range.
  * Implemented feature flag-based tab navigation for "Overview" and "Analytics" in the webhooks section.
  * Provided detailed webhook metrics, including recent activity and error rates.

* **Bug Fixes**
  * Improved error handling and user feedback for webhook configuration and analytics operations.

* **Chores**
  * Added PostHog server-side analytics integration.
  * Updated environment variable naming for analytics configuration.
  * Added new dependency for analytics support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces webhook analytics features and enhances the webhook management system, including new types for webhook statistics, UI components for creating and editing webhooks, and improvements in data fetching and handling.

### Detailed summary
- Added `posthog-node` dependency for server-side analytics.
- Updated environment variable from `NEXT_PUBLIC_POSTHOG_API_KEY` to `NEXT_PUBLIC_POSTHOG_KEY`.
- Introduced interfaces for `WebhookRequestStats`, `WebhookLatencyStats`, and `WebhookSummaryStats`.
- Created `CreateWebhookConfigModal` and `EditWebhookConfigModal` components for managing webhooks.
- Implemented `WebhooksAnalytics` and `WebhookAnalyticsServer` components for displaying analytics data.
- Enhanced `WebhookMetrics` to show metrics and error rates.
- Added `isFeatureFlagEnabled` function for feature flag checks.
- Implemented data fetching functions for webhook metrics in `analytics.ts`.
- Updated the webhook configuration management with new API endpoints and improved error handling.
- Created `TopicSelectorModal` for selecting topics with optional filters.
- Improved UI components for better user experience in managing webhooks.

> The following files were skipped due to too many changes: `pnpm-lock.yaml`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-07-10 17:21:02 +00:00
MananTank aa1035d16c [TOOL-4988] Dashboard, SDK: Add gas sponsorship option for asset creation for in-app wallets (#7566)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the handling of gasless transactions across various components in the `thirdweb` dashboard, specifically for NFT and token creation processes. It introduces new parameters and logic to support gas sponsorship features.

### Detailed summary
- Added `useAuthToken` option in `bundler.ts` fetch requests.
- Enhanced `fetch.ts` to include authentication headers for bundler requests.
- Updated `CreateTokenFunctions` and `CreateNFTCollectionFunctions` to accept `gasless` parameter.
- Modified multiple functions in the NFT and token creation pages to support gasless transactions.
- Implemented UI elements for enabling gas sponsorship in the `LaunchNFT` and `LaunchTokenStatus` components.
- Adjusted error handling for unsupported gas sponsorship on certain chains.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

Here are the updated release notes based on the provided summary:

* **New Features**
  * Added support for gasless transactions when launching NFT collections and tokens, available for eligible team plans and in-app wallets.
  * Introduced a toggle in the launch UI to enable or disable gasless mode for NFT and token creation.
  * Updated UI labels and dialogs for launching NFT collections.

* **Refactor**
  * Standardized function signatures for NFT and token creation to accept a unified parameter object, including a new gasless flag.
  * Centralized account and contract retrieval logic for improved maintainability and consistency.
  * Improved error logging in the token creation workflow.

* **Bug Fixes**
  * Enhanced error handling during token launch to detect unsupported gas sponsorship and provide user-friendly retry options.

* **Chores**
  * Updated request headers logic to properly handle authorization tokens and additional headers for bundler URLs.
  * Enabled authentication token usage in bundler request configurations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-10 15:18:10 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
bd395a3cff Version Packages (#7579)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-10 00:51:14 -07:00
Joaquim VergesandGitHub 446a69b1d1 [SDK] update wallet definitions (#7580) 2025-07-09 21:51:41 -07:00
Manan TankandGitHub 826d9c80a8 Dashboard: Remove OP superchain banner, CTAs, credits (#7569) 2025-07-09 20:10:50 -07:00
Joaquim VergesandGitHub 772eb0cc53 [SDK] Handle different fiat currencies in payment widgets (#7578) 2025-07-09 19:59:35 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
5c6dd874e0 Version Packages (#7577)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-09 16:55:48 -07:00
a9e47e4759 Replace PayEmbed with BuyWidget code (#7574)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-09 15:47:29 -07:00
bfd728a9d1 Add branding hide prop to widgets (#7575)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-09 15:46:29 -07:00
saminacodes 381a2823d7 [Docs] Remove Nebula from portal navigation (#7576)
```
<!--

## title your PR with this format: "[Portal] Feature: Remove Nebula from portal navigation"

## Notes for the reviewer

This PR removes all user-facing references to Nebula from the portal navigation and homepage, as requested.

-   **Key point:** All Nebula pages and underlying content remain untouched; only navigation links and homepage sections were removed.
-   Removed Nebula from the main header navigation and the APIs dropdown.
-   Removed Nebula sections from the homepage (API Reference and Learning Resources).
-   Updated the Vault section icon on the homepage from `NebulaIcon` (which was removed) to `ConnectIcon`.

## How to test

1.  Run the portal locally.
2.  Verify "Nebula" is no longer present in the main navigation bar or the "APIs" dropdown.
3.  On the homepage (`/`), confirm that the "Nebula" cards are removed from the "API Reference" and "Learning Resources" sections.
4.  Confirm that the "Vault" card in the "Learning Resources" section now uses the `ConnectIcon`.
5.  Run `npm run portal:build` to ensure the project builds successfully.

-->
```

---

[Slack Thread](https://thirdwebdev.slack.com/archives/C04DYC3G5NZ/p1752094214240499?thread_ts=1752094214.240499&cid=C04DYC3G5NZ)

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on removing references to `Nebula` from the application, including links and UI components, while retaining and emphasizing `Insight` and `Vault`.

### Detailed summary
- Removed `Nebula` link from `connectLinks` in `Header.tsx`.
- Deleted `Nebula` API reference card from `ReferenceSection` in `page.tsx`.
- Eliminated `Nebula` card from `LearningResourcesSection` in `page.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * None.

* **Bug Fixes**
  * None.

* **Refactor**
  * Removed all references to the "Nebula" feature from navigation menus and resource sections.
  * Updated the icon for the "Vault" article card.

* **Chores**
  * Cleaned up unused imports related to "Nebula".

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-09 21:53:40 +00:00
saminacodes 2111b8b12c Rename Universal Bridge to Payments (#7571)
```
<!--

## title your PR with this format: "[Dashboard] Feature: Rename Universal Bridge to Payments"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

This PR renames all instances of "Universal Bridge" to "Payments" across the projects dashboard. This is a branding update and does not change any underlying functionality or URLs.

Changes include:
- Sidebar navigation label
- Page titles and descriptions
- Callouts and sub-text (e.g., analytics, FTUX)
- Webhooks section (tab name and heading)

## How to test

1. Navigate to any project dashboard.
2. Verify the sidebar now shows "Payments" instead of "Universal Bridge".
3. Click on "Payments" in the sidebar and confirm the page title and description are updated.
4. Check the "Analytics" page to ensure "Universal Bridge" references are updated to "Payments".
5. Go to "Webhooks" and then the "Payments" tab to confirm the heading and tab name are correct.
6. Verify the FTUX section also reflects "Payments".

-->
```

---

[Slack Thread](https://thirdwebdev.slack.com/archives/C08GEMP858V/p1752037029611589?thread_ts=1752037029.611589&cid=C08GEMP858V)

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on renaming references from "Universal Bridge" to "Payments" throughout the codebase, reflecting a change in terminology for a feature that facilitates payments.

### Detailed summary
- Updated `name` in `layout.tsx` from "Universal Bridge" to "Payments".
- Changed `label` in `ProjectSidebarLayout.tsx` from "Universal Bridge" to "Payments".
- Modified `title` in `ProjectFTUX.tsx` from "Universal Bridge" to "Payments".
- Changed heading in `page.tsx` from "Universal Bridge Webhooks" to "Payments Webhooks".
- Updated description in `analytics/page.tsx` from "Universal Bridge" to "Payments".
- Changed description in `sidebar/page.tsx` from "Universal Bridge" to "Payments".
- Updated heading in `universal-bridge/page.tsx` from "Get Started with Universal Bridge" to "Get Started with Payments".
- Changed heading in `universal-bridge/layout.tsx` from "Universal Bridge" to "Payments".
- Updated description in `universal-bridge/layout.tsx` to reflect "Payments" instead of "Universal Bridge".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-07-09 05:13:22 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1665e4d534 Version Packages (#7568)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-08 17:18:24 -07:00
Manan TankandGitHub 692cedf921 [TOOL-4987] SDK: Restore CSS resets, remove biome rules for sorting attributes and properties (#7567) 2025-07-08 15:47:22 -07:00
e1f4901b80 [SDK] Remove page and set up redirect (#7565)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-08 12:06:36 -07:00
MananTank 028f871d40 [TOOL-4972] Dashboard: Add field to configure admins in NFT asset creation (#7542)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the NFT creation process by adding the ability to set admin addresses and refining various components for better user experience and validation.

### Detailed summary
- Added `"set-admins"` step to the NFT asset type.
- Introduced `AdminAddressesFieldset` for managing admin addresses.
- Updated forms to include admin validation.
- Improved UI components with consistent styling.
- Enhanced error handling during admin setting.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added the ability to specify multiple admin wallet addresses when creating an NFT collection, with dynamic form fields and validation.
  * NFT launch workflow now includes a step to assign admin roles to specified addresses.
  * NFT collection info and launch dialogs now display the list of assigned admins.

* **Improvements**
  * The NFT and token creation forms now automatically set the default blockchain network based on the active wallet chain.
  * NFT upload form includes default values for price and supply fields.
  * Visual spacing adjustments in social URL and token launch dialogs for improved UI consistency.

* **Bug Fixes**
  * Ensured at least one admin address is required when creating an NFT collection.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-08 15:37:47 +00:00
2821b4eeb7 Make contract webhook addresses mandatory (#7544)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-08 15:20:49 +02:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
adfa56b2a2 Version Packages (#7555)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-07 18:54:19 -07:00
YashandGitHub 415ad90986 feat: add T-Rex testnet chain (#7540) 2025-07-07 18:17:02 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
afcb7bba84 chore(deps): bump zod from 3.25.71 to 3.25.75 (#7552)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-07 18:15:59 -07:00
Joaquim VergesandGitHub 10c3b6f27f [SDK] Respect fee payer in token payment selection quotes (#7556) 2025-07-07 18:14:50 -07:00
Joaquim VergesandGitHub c64446306e [SDK] Use new BuyWidget in wallet details modal (#7551) 2025-07-07 17:18:28 -07:00
saminaandGitHub 2136c7ba4a [Docs] Wallets Overview (#7543) 2025-07-07 16:21:33 -07:00
MananTank 67c3d861fe [TOOL-4986] Dashboard: Fix ERC20 asset page crash (#7541)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving error handling by adding `try-catch` blocks around asynchronous calls in the `getContractCreator` function. This change ensures that if an error occurs during the execution of `owner` or `getRoleMember`, the function will return `null` instead of throwing an unhandled error.

### Detailed summary
- Wrapped the calls to `owner` and `getRoleMember` in a `try-catch` block.
- Changed the calls to `owner` and `getRoleMember` to use `await` for proper asynchronous handling.
- Ensured that if an error occurs, the function returns `null` instead of failing silently.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved error handling when retrieving contract creator information, ensuring failures no longer cause crashes and instead return a safe null value.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-07 14:15:01 +00:00
d2c12cc6ef Create session key guide and update sidebar (#7538)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-07 03:30:38 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
c1b2e10f34 Version Packages (#7539)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-07 03:29:31 -07:00
Joaquim VergesandGitHub f48d8006bc [SDK] Optimize payment token fetching in payment widgets (#7536) 2025-07-07 02:50:25 -07:00
Joaquim VergesandGitHub 20e323d666 [Dashboard] Fix smart account options validation for non-EIP4337 execution modes (#7537) 2025-07-07 01:20:11 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
0ec6142bf8 Version Packages (#7535)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-06 19:21:21 -07:00
0ea25bb9ae [SDK] Update walletconnect provider to universal (#7532)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-06 16:39:46 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
67293fc269 Version Packages (#7534)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-06 01:17:37 -07:00
Joaquim VergesandGitHub cb77544a46 [SDK] Respect feePayer property in Payment widgets (#7533) 2025-07-06 01:08:46 -07:00
770e7b24da Enhance transaction details with decoded tab (#7531)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-06 00:58:14 -07:00
ff9df497c9 Update branding from Engine Cloud to Transactions (#7516)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-05 13:37:17 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2d6c245b5e Version Packages (#7511)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-06 07:21:32 +12:00
37b3d7fa07 Add activity log section to transaction page (#7529)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-05 01:01:24 -07:00
YashandGitHub 8def4f33f6 Stylus CLI updates (#7502) 2025-07-05 07:47:29 +12:00
saminaandGitHub d92ab6fabe [Docs] Portal Images (#7526) 2025-07-03 21:39:03 -07:00
Joaquim VergesandGitHub 198cfd0f95 [Playground] Add TokenSelector component to Pay embed configuration (#7527) 2025-07-03 21:38:44 -07:00
jnsdls 9fba016cff Remove Plausible analytics integration (#7525)
# Remove Plausible Analytics Integration

This PR removes the Plausible Analytics integration from our applications:

- Removed `next-plausible` dependency from the dashboard app
- Removed Plausible script tags from dashboard, playground-web, and portal layouts
- Removed the Plausible proxy configuration from the Next.js config
- Updated the webpack configuration to work without the Plausible proxy wrapper

<!-- start pr-codex -->

---

## PR-Codex overview
This PR removes the usage of `next-plausible` from various files and updates dependencies accordingly. It also cleans up the code by removing unnecessary `<head>` elements and script imports across multiple layout files.

### Detailed summary
- Removed `next-plausible` dependency from `apps/dashboard/package.json`.
- Deleted `<Script>` components related to Plausible from `layout.tsx` files in `apps/playground-web`, `apps/dashboard`, and `apps/portal`.
- Cleaned up `next.config.ts` by removing `withPlausibleProxy`.
- Updated `pnpm-lock.yaml` to reflect the removal of `next-plausible`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Chores**
  * Removed Plausible analytics integration and related dependencies from the dashboard.
  * Removed external script loading from the layouts of the playground-web and portal apps.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-04 02:35:21 +00:00
Jonas DanielsandGitHub 4b8badba2e upgrade dependencies (#7524) 2025-07-03 19:22:27 -07:00
Joaquim VergesandGitHub 341325f844 [SDK] Show all tokens in payment selection regardless of balance (#7523) 2025-07-03 19:16:17 -07:00
7500d8723f [Dashboard] Fix validation for smart account options (#7522)
Co-authored-by: Cursor Agent <[email protected]>
2025-07-03 18:35:31 -07:00
Jonas DanielsandGitHub fa45dea07d upgrade biome to 2.0.6 (#7517) 2025-07-03 18:32:04 -07:00
Joaquim VergesandGitHub f94226ad7e [SDK] update wallets, add sh.frame (#7521) 2025-07-03 17:43:39 -07:00
Jonas DanielsandGitHub 0e159f776c [Dashboard] Add chain infrastructure deployment and management (#7456) 2025-07-03 17:32:14 -07:00
jnsdls f1a965b046 Enable engineCloud service in project creation modal (#7520)
### TL;DR

Enabled Engine Cloud service in the project creation modal.

### What changed?

Removed the filter that was excluding the "engineCloud" service from the list of available project services in the create project modal. This change allows users to select Engine Cloud when creating a new project.

### How to test?

1. Open the dashboard application
2. Click on "Create Project" button
3. Verify that Engine Cloud appears as an available service option in the project creation modal

### Why make this change?

The Engine Cloud service was previously excluded with a TODO comment indicating it should be enabled once the API server was ready. This change suggests that the API server is now available, so Engine Cloud can be offered as a service option during project creation.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Bug Fixes**
  * Updated project service selection to allow "engineCloud" as an available option.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-03 23:04:16 +00:00
MananTank 9f88b5c2be [TOOL-4951] Dashboard: Show Plan upsell on storage error in asset creation modal (#7512)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces the `teamPlan` property to various components related to NFT and token creation, allowing the application to handle billing plans effectively. It also adds a new component for handling storage limit errors and integrates upsell reporting for plan upgrades.

### Detailed summary
- Added `teamPlan` prop to components: `CreateNFTPage`, `CreateTokenAssetPage`, `CreateNFTPageUI`, `CreateTokenAssetPageUI`, `LaunchNFT`, `LaunchTokenStatus`.
- Introduced `StorageErrorPlanUpsell` component for storage limit handling.
- Implemented upsell reporting functions: `reportUpsellShown`, `reportUpsellClicked`.
- Updated `MultiStepStatus` to use a render function for error messages.
- Changed error message type from `React.ReactNode` to `string` in `MultiStepStatus`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a tailored upsell experience when users on a free plan hit the storage limit during token or NFT creation, including a new prompt to upgrade and real-time detection of plan changes.
  * Added analytics tracking for upsell prompts and upgrade link clicks.

* **Enhancements**
  * Error messages in multi-step workflows can now be customized, allowing for more informative and actionable error displays.
  * Components involved in token and NFT creation now accept and utilize the team's billing plan to enable conditional UI and logic.

* **Storybook**
  * Updated stories to reflect storage limit scenarios and demonstrate the new upsell flow for free plan users.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 20:39:36 +00:00
MananTank 7e73c344f5 Dashboard: asset page header: hide zero-address, fix icon (#7514)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the handling of wallet addresses and token fetching in the application. It enhances the rendering of wallet address components and modifies the fetching logic for token information, including error handling.

### Detailed summary
- Updated rendering of the wallet address in `apps/dashboard/src/@/components/blocks/wallet-address.tsx` and `apps/nebula/src/@/components/blocks/wallet-address.tsx` to include `props.className` and added a `text-xs` class in the latter.
- Enhanced the fetch request in `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_utils/fetch-coin-info.ts` by moving `clientId` to headers and added error logging for failed requests.
- Modified the condition for rendering contract creator in `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx` to check if `contractCreator` is not equal to `ZERO_ADDRESS`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Improved wallet address display to support external styling and smaller text size for the zero address.

* **Bug Fixes**
  * Updated contract header to ensure the contract creator badge is not shown for zero addresses.
  * Enhanced error logging for token info fetching to aid in troubleshooting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 20:15:47 +00:00
iuwqyir 4bd4efce4b add rpc tab with analytics (#7489)
# [Dashboard] Feature: Add RPC Edge analytics page

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the RPC (Remote Procedure Call) analytics feature in the dashboard. It introduces new components, updates existing ones, and adds functionality for fetching and displaying RPC usage data and statistics.

### Detailed summary
- Added `RpcMethodStats` and `RpcUsageTypeStats` interfaces in `analytics.ts`.
- Introduced `getRpcUsageByType` function to fetch RPC usage data.
- Updated `RpcMethodBarChartCardUI` to use new data structure.
- Added new `RPC` link in `ProjectSidebarLayout`.
- Created `RpcAnalyticsFilter` for filtering RPC analytics.
- Implemented `RequestsGraph` to visualize RPC requests over time.
- Developed `TopRPCMethodsTable` to display top EVM methods called.
- Added `RpcFTUX` component for user onboarding in RPC section.
- Updated layout files to integrate new components and improve styling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Introduced a dedicated "RPC" section in the project sidebar for easy access to RPC analytics.
  * Added a comprehensive RPC analytics dashboard, including:
    * Interactive requests graph and top RPC methods table.
    * Date range and interval filtering for analytics.
    * First-time user experience (FTUX) with ready-to-use code examples and documentation links.
  * Enhanced layout and navigation for the new RPC analytics section.

* **Style**
  * Improved UI spacing, sizing, and visual consistency for analytics components and placeholders.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 19:58:55 +00:00
MananTank 84f80437c1 [TOOL-4908] Dashboard: Fix 'Owner only' claim condition phase type condition (#7506)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on adding a condition to check if the `maxClaimablePerWallet` is `"0"` and enhancing the validation of the `phase.snapshot` property within the `claim-conditions-form` component.

### Detailed summary
- Added a condition to check if `phase.maxClaimablePerWallet` is `"0"`.
- Ensured `phase.price` is `"0"`.
- Checked that `phase.snapshot` is not a string and has a length of 1.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved claim condition handling to more accurately identify "creator" claim types based on updated criteria.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 19:11:32 +00:00
iuwqyir ac48b2409b add analytics to insight page (#7488)
<!-- start pr-codex -->

## PR-Codex overview
This PR introduces enhancements to the `Insight` feature in the application, including new analytics components, improved data fetching, and user interface updates for better user experience.

### Detailed summary
- Added `limit` parameter to analytics type definitions.
- Refactored imports in `insight-ftux.tsx`.
- Introduced `InsightAnalyticsFilter` component for filtering analytics data.
- Created `Layout` component with project validation and redirection.
- Added `InsightFooter` for footer links.
- Implemented `TopInsightChainsTable` and `TopInsightEndpointsTable` for displaying analytics data.
- Added `getInsightChainUsage`, `getInsightStatusCodeUsage`, and `getInsightEndpointUsage` API functions for fetching analytics.
- Enhanced `RequestsByStatusGraph` for visualizing status code requests.
- Updated `Page` component to handle authentication and data fetching more efficiently.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a comprehensive analytics dashboard for project insights, including interactive charts and tables for usage, errors, top endpoints, and top chains.
  * Added filters for date range and interval selection, with preferences saved for future visits.
  * Enhanced visualization with a stacked bar chart for HTTP status codes and detailed tables for endpoints and chains.
  * Included a streamlined layout with improved navigation, footer resources, and a "Get Started with Insight" call-to-action.
  * Added new analytics data fetching capabilities covering usage by chain, status code, endpoint, and overall metrics.

* **Refactor**
  * Simplified the insights page by removing redundant logic and focusing on authenticated analytics display.

* **Bug Fixes**
  * Improved error handling during data fetching to ensure UI stability when analytics data is unavailable.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 19:01:44 +00:00
jnsdls bde53fcf34 Remove "starter" plan checks from team invitation logic (#7513)
<!-- start pr-codex -->

## PR-Codex overview
This PR focuses on refining the invitation feature within the onboarding and settings sections of the application. It simplifies the conditions for inviting team members based on the billing plan.

### Detailed summary
- Removed `"Invite Team Members"` from the pricing options in `pricing.tsx`.
- Updated the conditional rendering for the custom CTA in `InviteTeamMembers.tsx` to check only for the `"free"` billing plan.
- Simplified the `inviteEnabled` condition in `InviteSection.tsx` to exclude the `"starter"` plan.
- Adjusted the conditional check for displaying the bottom section in `InviteSection.tsx` to only check for the `"free"` plan.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Updated team plan features by removing "Invite Team Members" from the "growth" plan feature list.

* **Bug Fixes**
  * Adjusted upgrade prompts and invite functionality so that upgrade options and invite restrictions now apply only to teams on the "free" plan, rather than both "free" and "starter" plans.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 18:51:42 +00:00
FirekeeperandGitHub 7437289140 Update import path in createSessionKey example (#7510) 2025-07-02 11:12:23 -07:00
Jonas DanielsandGitHub ca1fb84eba Properly type purchaseData as Record<string, unknown> (#7508) 2025-07-02 11:12:06 -07:00
jnsdls 087c29efdd [Dashboard] Rename RPC Edge to RPC and add redirect (#7509)
# Rename `/rpc-edge` to `/rpc`

This PR renames the `/rpc-edge` route to `/rpc` in the dashboard:

- Updates the route in `framer-rewrites.js`
- Adds a redirect from `/rpc-edge` to `/rpc` to maintain backward compatibility

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added a redirect from /rpc-edge to /rpc for dashboard requests.

* **Chores**
  * Updated references from /rpc-edge to /rpc in the scale category configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 17:58:07 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
9c2b0f7111 Version Packages (#7501)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-02 09:56:04 -07:00
FirekeeperandGitHub fd967ce8e3 Pass purchaseData prop to payment components (#7507) 2025-07-02 09:49:24 -07:00
Joaquim VergesandGitHub 7ab8808b50 [SDK] Handle very large numbers in BuyWidget component (#7503) 2025-07-02 04:18:20 -07:00
Yash094 ec75d9502c feat(chains): add Core testnet and mainnet chains (#7486)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces two new chain definitions for `Core` and `Core Testnet` to the `thirdweb` package, enhancing its blockchain support.

### Detailed summary
- Added `coreMainnet` definition in `core-mainnet.ts` with block explorer and native currency details.
- Added `coreTestnet` definition in `core-testnet.ts` with block explorer, native currency details, and testnet flag.
- Exported both `coreMainnet` and `coreTestnet` in `chains.ts`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added support for the Core mainnet and Core testnet blockchain networks.
  * Users can now interact with these new chains, including viewing block explorer links and using native currency details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 11:03:11 +00:00
85c4ef10ce Added Somnia Testnet (#7474)
Co-authored-by: Joaquim Verges <[email protected]>
2025-07-02 03:20:23 -07:00
Manan TankandGitHub 50e01ce067 SDK: Restore border on embed components (#7487) 2025-07-02 03:19:22 -07:00
Joaquim VergesandGitHub f15f62feec [Porta] fix llm.txt generation (#7500) 2025-07-01 22:45:00 -07:00
Joaquim VergesandGitHub 2d1549bb8b [Portal] Remove unused import from sign-in methods page (#7499) 2025-07-01 22:17:58 -07:00
saminaandGitHub effe60b48f [Docs] Broken Engine Links (#7498)
Signed-off-by: samina <[email protected]>
2025-07-01 21:49:39 -07:00
Joaquim VergesandGitHub 2029869d9c [Dashboard] Add status filter to transactions table (#7497) 2025-07-01 16:03:08 -07:00
jnsdls 02f6f87d08 [Dashboard] Move RPC Edge to scale category and remove redirect (#7495)
### TL;DR

Reorganized navigation structure by adding a "scale category" and removing the RPC Edge redirect.

### What changed?

- Created a new "scale category" in the framer-rewrites.js file that includes:
  - `/rpc-edge`
  - `/insight`
  - `/storage`
- Moved `/storage` from its own category into the new "scale category"
- Moved `/insight` from its own category into the new "scale category"
- Removed the redirect from `/rpc-edge` to the portal URL in redirects.js

### How to test?

1. Verify that the `/rpc-edge`, `/insight`, and `/storage` routes are properly grouped under the "scale category"
2. Confirm that navigating to `/rpc-edge` no longer redirects to the portal URL
3. Check that the other redirects still function as expected

### Why make this change?

This change improves the organization of related services under a logical "scale category" grouping, making the navigation structure more intuitive. It also enables direct access to the RPC Edge page rather than redirecting users to the portal, providing a more seamless user experience.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Refactor**
  * Reorganized and regrouped certain dashboard paths under a new "scale category" for improved clarity.

* **Chores**
  * Removed a redirect rule for the /rpc-edge path.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 20:38:46 +00:00
MananTank 1305527822 [TOOL-4900] Dashboard: Add ERC20 token page links in /routes (#7493)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring components in the `routes-table`, `routelist-card`, and `routelist-row` files to improve structure and readability, while introducing new components like `TokenName` and `TokenInfo` for better token representation.

### Detailed summary
- Replaced `TableContainer` with a simpler structure in `routes-table.tsx`.
- Changed table header structure to improve readability.
- Refactored `routelist-card.tsx` to use `TokenName` for token display.
- Introduced `TokenInfo` component in `routelist-row.tsx` for consistent token representation.
- Removed inline token display logic in favor of new components.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added clickable links to ERC20 token pages for improved navigation and clarity in token displays.
  * Introduced new helper components for consistent token information display.

* **Refactor**
  * Updated token display layouts to use flexbox for better alignment and readability.
  * Consolidated repeated token rendering logic into reusable components.

* **Style**
  * Simplified and removed custom styling from tables and cards for a cleaner appearance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 20:15:55 +00:00
MananTank b882ad7807 Playground: Fix in-app-wallet ConnectEmbed prebuilt ui code snippet (#7492)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `page.tsx` file in the `in-app-wallet` directory to improve the formatting of the `wallets` configuration and the `App` function, ensuring consistent indentation and structure.

### Detailed summary
- Reformatted the `wallets` array for improved readability.
- Changed the indentation of the `auth` and `executionMode` properties.
- Updated the `App` function to have consistent spacing around the return statement.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Style**
  * Improved formatting and readability of code examples and component structure in the in-app wallet integration page. No changes to functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 20:10:18 +00:00
MananTank 030c522816 Dashboard: Add missing asset creation successs tracking for nft (#7494)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the NFT launch functionality by adding a successful asset creation report feature. It imports a new reporting function and invokes it upon successful NFT launch, improving analytics tracking.

### Detailed summary
- Added import for `reportAssetCreationSuccessful` from `@/analytics/report`.
- Called `reportAssetCreationSuccessful` with parameters indicating asset type and contract type upon successful NFT launch.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added a success reporting step after completing the NFT launch process, providing improved feedback for successful NFT creation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-01 20:00:45 +00:00
MananTank c356813852 Dashboard: Remove chakra provider from team/settings/notifications page (#7479)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the notifications settings page by renaming components, updating the layout, and improving the user interface for managing notifications.

### Detailed summary
- Deleted `SettingsNotificationsPage` and replaced it with `Notifications`.
- Updated the main page layout to include a header and description for notifications.
- Enhanced the `Notifications` component with a new background and border styling.
- Added a separator line in the `Notifications` component.
- Removed unnecessary wrapper from `SettingSwitch` layout.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-30 16:14:58 +00:00
MananTank 1c638edd80 Dashboard: Charts style tweaks, Remove unused chart component (#7478)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on modifying the styling and layout of various components within the dashboard, enhancing user interface elements, and removing unused files.

### Detailed summary
- Deleted `CombinedStatBreakdownCard.tsx` and `CombinedStatBreakdownCard.stories.tsx`.
- Updated class names for better styling on `Link` and `Card` components.
- Removed `max-md:border-r-0` and `max-md:border-l-0` classes from several components.
- Adjusted `min-h` properties for `Card` components.
- Centered text in `EmptyStateContent`.
- Streamlined layout in various components for improved spacing.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-30 16:14:58 +00:00
MananTank 2fd5b84505 [PRO-213] Dashboard: Empty chart state copy changes (#7477)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `EmptyStateCard` component across various files, including changes to its props, styling, and the metrics displayed. It simplifies the component's usage and modifies the metrics for clarity and relevance.

### Detailed summary
- Updated `EmptyStateCard` to remove unnecessary props in `RpcMethodBarChartCardUI.tsx`.
- Modified metric and link props in `EngineCloudBarChartCardUI.tsx`.
- Changed `EmptyStateCard` metrics in `EmptyStateCard.stories.tsx` and other files to be more relevant.
- Made `metric` prop optional in `EmptyStateCard.tsx`.
- Enhanced styling for `EmptyStateContent` in `EmptyStateCard.tsx`.
- Adjusted rendering logic for `EmptyStateContent` to improve clarity and user experience.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-30 16:14:58 +00:00
MananTank 2bfc9b2eb2 [PRO-211, PRO-210] Dashboard: Copy changes (#7476)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on making minor adjustments to text labels and descriptions in the application, enhancing consistency in naming and improving grammatical accuracy.

### Detailed summary
- In `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/layout.tsx`, changed `name` from "Contract" to "Contracts".
- In `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/page.tsx`, updated the phrase from "Create and Manage tokens for your project" to "Create and manage tokens for your project".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **Style**
  * Corrected capitalization in the Assets section header for improved readability.
  * Updated a navigation tab label from "Contract" to "Contracts" for clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 16:14:57 +00:00
MananTank e9dc2190a1 [PRO-218] Dashboard: Add product rebrand banner (#7475)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `AnnouncementBanner` component to reflect a rebranding message and a new link to a blog post, replacing the previous announcement about the Nebula App.

### Detailed summary
- Updated `href` to point to "https://blog.thirdweb.com/the-fastest-way-to-build-web3-applications/"
- Changed `label` to "We have re-branded our Engine, Universal Bridge, and Connect products. Please read the full blog post for details on changes"
- Updated `trackingLabel` to "product-rebrand"

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Updated the announcement banner to highlight the rebranding of Engine, Universal Bridge, and Connect products, with a link to a detailed blog post.

* **Style**
  * Refreshed banner text and link to reflect the latest product updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-30 15:47:03 +00:00
Phillip HoandGitHub d0fa1b1e66 chore: Enable telegram support channel, add join link button (#7472) 2025-06-30 18:23:43 +08:00
Joaquim VergesandGitHub 85a5037f50 [Playground] Update product details from hoodie to concert ticket (#7473) 2025-06-29 18:59:11 -07:00
Joaquim VergesandGitHub fd67c5db58 [Dashboard] Add client ID header to embedded wallets fetch request (#7471) 2025-06-29 02:40:26 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
ca65b43566 Version Packages (#7467)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-28 23:57:39 -07:00
Corey RiceandGitHub 1f72396d7f docs: Update imports in react v5 adaptor examples (#7469) 2025-06-29 10:25:27 +12:00
MananTank 08834f6385 Dashboard: Update team layout (#7464)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on refactoring and updating the billing and settings-related components in the dashboard application, changing URLs from `/settings` to `/billing`, and enhancing the user interface for better clarity and usability.

### Detailed summary
- Deleted several unused files related to settings and credits.
- Updated links in various components to redirect from `/settings` to `/billing`.
- Refactored `useActiveSidebarLink` to streamline sidebar link management.
- Enhanced UI elements for better responsiveness and aesthetics.
- Introduced a new `StaffModeNotice` component for staff mode indications.
- Adjusted layout components for consistent styling.
- Reorganized billing-related components into a unified structure.
- Improved pagination button styles for better visibility.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/rpc/page.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Introduced a full-width sidebar layout with collapsible submenus and responsive navigation.
  * Added a team sidebar layout with structured navigation for team dashboards.
  * Added collapsible UI components for use in layouts and menus.
  * Added a reusable StaffModeNotice component for staff mode indication.

* **Bug Fixes**
  * Improved container sizing and maximum width constraints for better layout consistency across analytics, audit log, and ecosystem pages.

* **Refactor**
  * Simplified and reorganized sidebar layouts, removing complex internal logic and mobile navigation from several components.
  * Updated navigation structures to use new sidebar and tab-based layouts.
  * Streamlined and restyled headers, banners, and button components for a more cohesive look.
  * Replaced inline staff mode banners with the StaffModeNotice component.
  * Removed sidebar navigation from usage and settings layouts for a cleaner interface.
  * Removed gas credits settings and related components from the settings area.
  * Refactored ecosystem pages to redirect directly to creation, removing landing page.
  * Updated billing-related URL paths by removing deprecated `/settings` segments for consistency.
  * Removed account plan constants and unused hooks for cleaner codebase.
  * Cleaned up imports and replaced some relative imports with absolute paths.

* **Style**
  * Enhanced visual styling and responsiveness for range selectors, sidebars, and headers.
  * Adjusted text sizes and spacing in mobile navigation and file sections for improved readability.
  * Added rounded corners and adjusted spacing in date and interval selectors.
  * Added responsive minimum widths and consistent borders to pagination buttons and links.

* **Chores**
  * Added a new dependency for collapsible UI support.
  * Updated import paths and added lint suppression comments for code clarity and maintainability.
  * Added responsive minimum widths to pagination buttons and consistent border styling to pagination links.
  * Updated multiple URLs in links and buttons to reflect new billing paths without `/settings` segment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-28 12:10:06 +00:00
Joaquim VergesandGitHub 143ab6d127 [Portal] simplify get started wallet documentation (#7466) 2025-06-28 04:10:53 -07:00
bc512551ab [SDK] Add enableCard prop to control fiat payment visibility (#7465)
Co-authored-by: Claude <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2025-06-28 04:09:52 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8e29d48426 chore(deps): bump @vercel/functions from 2.1.0 to 2.2.2 (#7422)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-28 01:09:38 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
e7e6446e7d chore(deps-dev): bump checkly from 5.6.0 to 6.0.1 (#7424)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-28 01:09:21 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
7113f7c669 Version Packages (#7463)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-27 18:56:26 -07:00
f9d7935d84 Update engine API (#7427)
Signed-off-by: Prithvish Baidya <[email protected]>
Co-authored-by: Prithvish Baidya <[email protected]>
2025-06-27 18:41:37 -07:00
FirekeeperandGitHub acd5656d4d [SDK] EIP-7702 Session Keys (#7432) 2025-06-27 18:11:19 -07:00
gregandGitHub 6d1d344c48 Fix: Exclude IAW when smart wallets are used (#7454) 2025-06-27 13:36:11 -07:00
MananTank 26b8c320ae [TOOL-4899] Dashboard: fetch token icon from bridge api as fallback in coin asset page (#7460)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new utility function to fetch token information from a bridge and integrates it into the `ERC20PublicPage` component to enhance contract metadata with token icons.

### Detailed summary
- Added `fetchTokenInfoFromBridge` function in `fetch-coin-info.ts` to fetch token details from a bridge API.
- Integrated `fetchTokenInfoFromBridge` in the `ERC20PublicPage` component.
- Updated contract metadata to include the token icon if not already present.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Enhanced ERC20 public pages to automatically display token icons when available, enriching token metadata with external information.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 19:46:52 +00:00
Phillip HoandGitHub c7f7f48222 chore: change webhook back to object (#7461) 2025-06-28 02:18:40 +08:00
MananTank e814248d9c [TOOL-4898] Dashboard: Replace PayEmbed with BuyWidget in asset page, add tracking (#7459)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `PayEmbed` component to `BuyWidget` in the `BuyTokenEmbed` function, enhancing the functionality with error reporting and success tracking for asset purchases.

### Detailed summary
- Replaced `PayEmbed` with `BuyWidget` in `BuyTokenEmbed`.
- Added `amount`, `chain`, and `className` props to `BuyWidget`.
- Implemented `onError` and `onSuccess` callbacks for analytics reporting.
- Updated the token address prop to ensure correct type.
- Modified chart className in `contract-analytics.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Updated the buy token section to use an improved widget with enhanced error and success handling, including dynamic titles and analytics reporting.

* **Style**
  * Adjusted the chart's aspect ratio for better display across different screen sizes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 16:43:21 +00:00
MananTank d7a0613067 [TOOL-4897] Dashboard: Add Contract creator badge in Coin and NFT asset page (#7458)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces the `contractCreator` property to multiple components, allowing the display of the contract creator's address in the UI. It also adds a new function, `getContractCreator`, to retrieve the contract creator's information based on the contract's role.

### Detailed summary
- Added `contractCreator` prop to `NFTPublicPageLayout`, `ContractHeaderUI`, and `ContractCreatorBadge`.
- Implemented `getContractCreator` function to fetch the contract creator using `ThirdwebContract`.
- Updated `NFTPublicPage` and `ERC20PublicPage` to call `getContractCreator` and pass the result to the UI.
- Enhanced storybook stories to include `contractCreator` in various scenarios.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added display of contract creator information on ERC20 and NFT public pages.
  * Introduced a badge showing the contract creator's address in the contract header section.

* **Enhancements**
  * Contract headers now conditionally show the creator badge if creator data is available.
  * Storybook stories for contract headers updated to include contract creator scenarios for improved UI previews.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 16:31:14 +00:00
MananTank dbc031664d [TOOL-4867] Dashboard: Fix Coin asset page crash on "unlimited" maxClaimableSupply (#7457)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the handling of the `totalSupply` property in the `SupplyClaimedProgress` component and related files to support the string value `"unlimited"` instead of using a constant value from `thirdweb/utils`.

### Detailed summary
- Changed `totalSupply` type from `bigint` to `bigint | "unlimited"` in `SupplyClaimedProgress`.
- Updated the condition to check for `"unlimited"` instead of `maxUint256`.
- Modified the story for `SupplyClaimedProgress` to use `"unlimited"` instead of `maxUint256`.
- Adjusted `totalSupply` handling in `TokenDropClaim` to return `"unlimited"` if `maxClaimableSupply` equals `maxUint256`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Updated the supply progress display to clearly indicate when the total supply is unlimited.
* **Refactor**
  * Improved internal handling and representation of unlimited supply for better clarity in the UI.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 16:20:18 +00:00
saminacodes 5640d48854 [Docs] Project Rebrand (#7455)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on renaming and rebranding various components and documentation from `Universal Bridge` and `Engine` to `Payments` and `Transactions`, respectively, to better reflect their functionality and purpose.

### Detailed summary
- Renamed `Universal Bridge` to `Payments` across multiple files.
- Renamed `Engine` to `Transactions` across various components and documentation.
- Updated metadata and titles in numerous `.mdx` files to reflect the new branding.
- Changed references in UI components and layout files to match new naming conventions.
- Adjusted descriptions and summaries in documentation to align with the new terms.
- Updated links and API references to point to the correct services.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Expanded the learning resources section with updated and additional cards, including new topics like "Contracts" and "Vault".

* **Style**
  * Updated navigation and sidebar labels for improved clarity (e.g., "Connect" to "Wallets", "Bridge" to "Payments", "Engine" to "Transactions").
  * Swapped the order of the GitHub icon and theme switcher in the header for better usability.

* **Documentation**
  * Renamed all references from "Universal Bridge" to "Payments" and from "Engine" to "Transactions" across guides, FAQs, and documentation.
  * Updated instructions, headings, and content to reflect new product names and improved clarity.
  * Added a new FAQ entry explaining the difference between "Transactions Cloud" and "Dedicated" infrastructure.
  * Updated links and navigation paths to match new terminology.
  * Adjusted terminology in wallet-related documentation to replace "Connect" with "Wallets".
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 15:26:01 +00:00
GiselleNessi 9d6739ea59 updated text support page (#7447)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the descriptions and titles of various features in the support section of the dashboard, as well as changing a header for improved clarity.

### Detailed summary
- Updated `description` and `title` for the wallets feature.
- Changed `description` and `title` for the universal bridge feature, along with its `viewAllUrl`.
- Modified `description` and `title` for the engine feature, including its `viewAllUrl`.
- Revised `description` for the insight feature.
- Changed the header from "Learning Resources" to "Support Articles".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Refactor**
  * Updated product names and descriptions for greater clarity in the Support section.
  * Changed the heading above product cards from "Learning Resources" to "Support Articles."
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 10:52:59 +00:00
GiselleNessi dc49683357 removed next steps chainlist page (#7443)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on removing unused components and updating product descriptions in the `page.tsx` and `products.ts` files.

### Detailed summary
- Deleted `NextSteps` and `ClaimChainSection` components from `page.tsx`.
- Removed related JSX comments in `page.tsx`.
- Updated product descriptions and names in `products.ts`:
  - Changed "Pre-built contracts & deployment tools" to "Create, deploy and manage smart contracts".
  - Changed "Client-side SDKs for wallets and blockchain interactions" to "Create and manage crypto wallets".
  - Changed "Engine" to "Transactions".
  - Changed "Account factory contracts, bundler & paymaster" to "Enable gas sponsorship for seamless transactions".
  - Changed "Point of sale solution for bridging, onramping & swapping" to "Enable payments in any token on any chain".
  - Changed "Query, transform and analyze blockchain data" to "Query and analyze blockchain data".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Refactor**
  * Removed the "Next Steps" and "Claim Chain" sections from the chain page, including related external links and prompts.
* **Documentation**
  * Updated product names and descriptions to use clearer, more user-focused language for better understanding of features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-27 10:42:56 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
30496388c4 Version Packages (#7453)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-27 03:40:38 -07:00
Joaquim VergesandGitHub c2ef5eb51c [SDK] Update zod dependency to 3.25.67 (#7451) 2025-06-27 01:11:51 -07:00
gregandGitHub 277c2e2ed9 Feature: Add fallback when we cant fetch the token in new widgets (#7452) 2025-06-26 16:43:46 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
0ac5e59eb9 Version Packages (#7445)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-26 14:56:22 -07:00
gregfromstl fa5e13b5d3 Feature: Adds onramp webhook schema to sdk (#7450)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on adding onramp webhook parsing functionality to the `Universal Bridge` in the `thirdweb` package, along with updates to existing tests to accommodate new payload structures.

### Detailed summary
- Added onramp webhook parsing for `Universal Bridge`.
- Updated `chainId` and `transactionHash` values in tests.
- Modified the structure of `validWebhook` and `validPayload` in `Webhook.test.ts`.
- Changed `destinationAmount` and `originAmount` types to `bigint`.
- Introduced `onchainWebhookSchema` and `onrampWebhookSchema` in `Webhook.ts`.
- Updated `webhookSchema` to include `onchain` and `onramp` transaction types.
- Enhanced the `parse` function to return a `WebhookPayload` that satisfies the new schema.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Enhanced webhook parsing to support onramp webhooks for the Universal Bridge.

* **Refactor**
  * Improved validation and structure of webhook payloads for clearer distinction between onchain and onramp types.
  * Updated numeric fields to ensure correct data types and improved payload handling.

* **Documentation**
  * Added a changeset file describing the new onramp webhook parsing capability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 21:30:46 +00:00
gregandGitHub 45bb790dd1 Fix: Include correct client in payment link UI (#7449) 2025-06-26 11:21:52 -07:00
0xFirekeeper 102a8c8224 [Portal] EIP-7702 Session Key Docs (.NET) (#7448)
Closes TOOL-4880

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces new features and updates for the `EcosystemWallet` in the Thirdweb .NET SDK, focusing on EIP-7702 functionalities, including session management and permissions.

### Detailed summary
- Added new sidebar links for EIP-7702 actions.
- Updated `CreateSessionKey` function to include EIP-7702 functionalities.
- Introduced detailed documentation for new methods: `SignerHasFullPermissions`, `GetCallPoliciesForSigner`, `GetTransferPoliciesForSigner`, `GetSessionExpirationForSigner`, and `GetSessionStateForSigner`.
- Each method includes usage examples, parameter details, return values, and exception handling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Expanded sidebar navigation with new links for EIP-7702 session key actions under the wallet section.
  * Added documentation for EIP-7702 session key management, including creating session keys, checking signer permissions, retrieving call and transfer policies, session expiration, and session state.

* **Documentation**
  * Introduced detailed guides and usage examples for new EIP-7702 wallet session key features and related methods in the .NET SDK.
  * Clarified sidebar link names to distinguish between EIP-4337 and EIP-7702 session key creation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 16:19:05 +00:00
Phillip HoandGitHub 472e737616 chore: webhook payload must be an array (#7444) 2025-06-26 18:38:21 +08:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
0345492e99 Version Packages (#7433)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-26 03:01:11 -07:00
gregandGitHub e650434061 [SDK] Fix: Chain name label (#7442) 2025-06-25 15:47:17 -07:00
gregandGitHub 6712911950 [SDK] Chore: Remove onrampTokenAddress set to ETH (#7441) 2025-06-25 14:22:20 -07:00
orbuloandGitHub 1387337955 [SDK] Feature: update hey-api version to 0.76.0 (#7431) 2025-06-25 12:30:12 -07:00
Phillip HoandGitHub a2b737e144 fix: typo on a field in webhook event helper (#7440) 2025-06-25 23:19:02 +08:00
Phillip HoandGitHub c5f9921dc9 feat: add webhook producer to service-utils (#7439) 2025-06-25 13:35:19 +08:00
Joaquim VergesandGitHub 830125c920 Add CLAUDE.md (#7438) 2025-06-24 19:11:06 -07:00
Joaquim VergesandGitHub af89836b6c [SDK] Handle sponsored gas on TransactionWidget (#7437) 2025-06-24 19:10:47 -07:00
MananTank d85ee5fac3 Dashboard: add "Contracts" link in contract layout header (#7436)
![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/yNOf1svJ8o3zjO7zQouZ/05f5e0d2-cfee-4604-8567-a630e13f8232.png)

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new optional property, `currentProjectSubpath`, to enhance the `TeamHeader` components by allowing the display of additional project navigation details, including a label, href, and icon.

### Detailed summary
- Added `currentProjectSubpath` property to `TeamHeaderLoggedIn` and `TeamHeaderDesktopUI`.
- Updated `TeamHeaderUI` to render project subpath details if provided.
- Introduced a new story in `TeamHeaderUI.stories.tsx` to showcase the `currentProjectSubpath` feature.
- Integrated `currentProjectSubpath` into the `ContractLayout` component for enhanced navigation.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for displaying an active project subpage link with an icon in the team header, enhancing breadcrumb navigation for projects.
  - Updated the team header to visually indicate the current subpage within a project.

- **Documentation**
  - Added a new Storybook variant to demonstrate the team header with an active subpage link.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 23:37:56 +00:00
MananTank 8bb4d4bc11 Dashboard: remove date selector from UB FTUX, improved skeletons (#7435)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the `Page` component in the `loading.tsx` file and the `PayAnalytics` component in the `PayAnalytics.tsx` file, enhancing the structure and user experience by modifying the rendering of analytics and loading states.

### Detailed summary
- Removed `ResponsiveSuspense` and `PayAnalyticsFilter` from `loading.tsx`.
- Integrated `PayAnalytics` directly into the `Page` component.
- Added `ResponsiveSuspense` with a skeleton loader in `PayAnalytics`.
- Reorganized analytics display in `PayAnalytics`, including filtering and layout adjustments.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Improved the loading experience in the PayAnalytics section with responsive skeleton placeholders during data loading.
  - Updated the layout to display analytics filters above the loading state for better usability.

- **Chores**
  - Removed unused loading and suspense logic from related pages to streamline the user interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 22:27:52 +00:00
MananTank 3c6668b6c8 [TOOL-4833] Add Manage Contract button in new public contract pages (#7434)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the handling of `projectSlug` and `teamSlug` properties across various components in the application, improving navigation and data management related to teams and projects.

### Detailed summary
- Added `projectSlug` and `teamSlug` props in several components including `cards.tsx`, `DeployedContractsPage.tsx`, and `layout.tsx`.
- Updated links to include `teamSlug` and `projectSlug` for better navigation.
- Introduced new API function `getContractImportedProjects` to fetch projects with imported contracts.
- Created `TeamSelectorCard` and `ProjectAndTeamSelectorCard` components for selecting teams and projects.
- Improved UI elements such as buttons and tooltips in `ContractHeaderUI` and `ImportModal`.
- Enhanced type definitions for better type safety and clarity in components.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a team and project selector UI, enabling users to easily select teams or projects from visual cards.
  - Added a project and team selector for associating contracts, allowing users to view, select, or import contracts into projects across teams.
  - Enhanced contract management by providing direct navigation to contract pages based on project selection.
  - Improved contract view links to include team and project information in URLs for clearer navigation.
  - Added functionality to fetch projects that have imported specific contracts within teams.

- **UI Improvements**
  - Updated button styles with rounded edges for a polished look.
  - Added copy address and manage contract buttons with icons and tooltips for enhanced usability.

- **Storybook/Documentation**
  - Added Storybook stories to visually test and demonstrate the new team and project selector components under various scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 21:58:48 +00:00
gregandGitHub 6aa2765a34 Feature: UB Widget Tracking and Docs (#7426) 2025-06-24 13:19:01 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
bbff67db0c Version Packages (#7414)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-23 20:31:12 -07:00
Prithvish BaidyaandGitHub ef2895fa2c Implement support for EOA execution options in server wallets (#7429) 2025-06-23 20:27:59 -07:00
Prithvish BaidyaandGitHub cf44dae9ed add eoa execution options type (#7428) 2025-06-23 19:51:33 -07:00
Joaquim VergesandGitHub c26be2d958 Fix wallet row alignment in wide connect modal (#7425) 2025-06-23 16:38:44 -07:00
MananTank 029741126f [TOOL-4856] Engine Server wallets table UI adjustment, Fix Vault Portal Link (#7419)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing the user interface in the dashboard by improving the handling of server wallets and updating the link for the Vault.

### Detailed summary
- Updated the `href` in the `Link` component to point to `https://portal.thirdweb.com/vault` and added a "Learn more about Vault" text.
- Refactored the rendering logic for wallets:
  - Removed the conditional rendering for "No server wallets found" and replaced it with a new div that displays this message when there are no wallets.
  - Streamlined the mapping of `wallets` to display each wallet's details within a `TableRow`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
	- Improved the display of the "No server wallets found" message, which now appears below the wallets table instead of inside it for better clarity.

- **Style**
	- Updated the "Learn more about Vault" link to display clear link text and corrected its URL for improved user navigation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 23:14:31 +00:00
MananTank b5114dfe22 [TOOL-4858] Update Team Usage Overview page UI for free plan (#7423)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the handling of team usage and upsell features in the dashboard. It introduces new components and logic to display upsell content based on the team's billing plan.

### Detailed summary
- Updated import paths for `getTeamBySlug` and `UpsellWrapper`.
- Added `UpsellContent` component to display upsell information.
- Implemented logic to show upsell content if the team is on a "free" plan.
- Refactored the `UpsellWrapper` to include `UpsellContent`.
- Enhanced rendering of benefits in `UpsellContent`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Improved code structure by extracting upsell card UI into a dedicated component, resulting in cleaner and more maintainable code.
  - Updated import paths for consistency and clarity.

- **Style**
  - Adjusted layout classes for better visual alignment of upsell content.

- **Bug Fixes**
  - Unified error handling for usage page, ensuring a consistent message for all error scenarios. Free plan users now see a clear upgrade prompt.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-23 23:02:36 +00:00
MananTank 66270f7933 Dashboard: group project sidebar links (#7417)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the sidebar layout by introducing new components for better organization and rendering of sidebar links. It refactors the sidebar structure to use `RenderSidebarMenu` and `RenderSidebarGroup`, allowing for grouped sidebar items.

### Detailed summary
- Added `SidebarGroupLabel` and `SidebarMenuSubItem` components.
- Refactored `FullWidthSidebarLayout` to use `RenderSidebarMenu` instead of `RenderSidebarGroup`.
- Updated `RenderSidebarGroup` to include `SidebarGroupLabel` and `SidebarMenuItem`.
- Introduced grouping for sidebar links with `group` and `links` properties.
- Enhanced sidebar link structure to support separators and improved organization.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Improved sidebar navigation by organizing links into hierarchical groups ("Build," "Monetize," "Scale") for better clarity and usability.
  - Updated sidebar rendering for greater modularity and maintainability, with enhanced grouping and link management.

- **Style**
  - Sidebar appearance and structure are updated for a more organized and user-friendly experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-24 02:42:29 +05:30
AmineAfia 11b4d9e780 Add support for tuple types in ABI event and function signatures (#7415)
# [Dashboard] Fix: Improve ABI type handling for tuple types in webhook signatures

## Notes for the reviewer
This PR adds support for properly handling tuple types in ABI event and function signatures. Previously, we were only extracting the basic type string, which doesn't correctly represent tuple structures. Now we recursively build the canonical type representation for tuples, including nested tuples and array dimensions.

## How to test
The changes can be tested by creating webhooks with contracts that use tuple types in their events or functions. The signature extraction should now correctly represent the canonical format for these complex types.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
  - Improved handling of tuple types in ABI inputs to ensure accurate event and function signature generation, especially for nested tuple structures.
- **New Features**
  - Function signature labels in transaction filters are now truncated for better readability without affecting underlying data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily enhances the handling of function signatures in the `FilterDetailsStep.tsx` component and improves the extraction of ABI input types in `abiUtils.ts`. It introduces a helper function to manage tuple types and modifies how function signatures are displayed.

### Detailed summary
- In `FilterDetailsStep.tsx`, updated the label for function signatures to use `truncateMiddle(sig.name, 30, 15)` for better readability.
- Added a new helper function `getCanonicalType` in `abiUtils.ts` to recursively handle tuple types in ABI inputs.
- Modified the extraction of canonical input types in both `extractEventSignatures` and `extractFunctionSignatures` to use `getCanonicalType` instead of directly mapping the type.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-23 13:49:17 +00:00
kilavvyandGitHub ad5aabcb7c Docs: Fix typos in modular contracts guide (#7408)
Signed-off-by: kilavvy <[email protected]>
2025-06-22 18:12:29 -07:00
Joaquim VergesandGitHub 3107ba1c37 [SDK] Handle non-URLs for metadata images in payment widgets (#7413) 2025-06-22 17:54:33 -07:00
MananTank 897bdc75d5 Dashboard: Remove unused assets #2 (#7412)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on the removal of several image files from the project, specifically logos and images used in the dashboard and product pages.

### Detailed summary
- Deleted image files from `apps/dashboard/src/components/partners/logos/`:
  - `aws.png`
  - `xai.png`
  - `ztx.png`
  - `myna.png`
  - `nyfw.png`
  - `paima.png`
  - `layer3.png`
  - `mirror.png`
  - `pixels.png`
  - `torque.png`
  - `unlock.png`
  - `animoca.png`
  - `polygon.png`
  - `rarible.png`
  - `shopify.png`
  - `avacloud.png`
  - `coinbase.png`
  - `coolcats.png`
  - `paradigm.png`
  - `treasure.png`
  - `mcfarlane.png`
  - `aavegotchi.png`
  - `gala_games.png`
  - `infinigods.png`
- Deleted image files from `apps/dashboard/src/components/product-pages/homepage/multi-chain/`:
  - `mobile.svg`
  - `desktop.svg`
  - `mobile-gray.svg`
  - `desktop-gray.svg`
- Deleted `blur.png` from `apps/dashboard/src/components/product-pages/homepage/`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-22 19:29:45 +00:00
MananTank 87c645d633 Dashboard: file organization refactor (no code change) (#7410)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->
2025-06-22 19:29:44 +00:00
MananTank 15b4b4b2f9 Dashboard: Remove unused files (#7409)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on the removal of several unused asset files and CSS modules from the `apps/dashboard` directory, streamlining the project's file structure.

### Detailed summary
- Deleted `misc.svg` from `apps/dashboard/public/assets/support/`
- Deleted `engine.png` from `apps/dashboard/public/assets/support/`
- Deleted `engine.png` from `apps/dashboard/public/assets/og-image/`
- Deleted `account.svg` from `apps/dashboard/public/assets/support/`
- Deleted `wallets.png` from `apps/dashboard/public/assets/support/`
- Deleted `contracts.png` from `apps/dashboard/public/assets/support/`
- Deleted `contracts.png` from `apps/dashboard/public/assets/og-image/`
- Deleted `engine.png` from `apps/dashboard/public/assets/product-icons/`
- Deleted `contracts.png` from `apps/dashboard/public/assets/landingpage/`
- Deleted `wallets.png` from `apps/dashboard/public/assets/product-icons/`
- Deleted `contracts.png` from `apps/dashboard/public/assets/product-icons/`
- Deleted `partner-logo.module.css` from `apps/dashboard/src/components/partners/`
- Deleted `categories.module.css` from `apps/dashboard/src/components/homepage/category/`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Style**
  - Removed custom styles for homepage category components, affecting layout, interactivity, and responsiveness.
  - Removed marquee animation and spacing styles for partner logo elements.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-22 19:29:43 +00:00
arcoraven 18ad1afbde fix: bug with no results on storage page (#7411)
## [Dashboard] Fix: Add optional chaining to prevent undefined errors in YourFilesSection

## Notes for the reviewer

Added optional chaining to prevent potential undefined errors when accessing `pinnedFilesQuery.data.result` properties in the YourFilesSection component. This ensures the component handles cases where the data or result might be undefined more gracefully.

## How to test

Verify that the YourFilesSection component renders correctly when data is loading or when the API returns undefined values.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
	- Improved reliability when displaying pinned files by preventing errors if data is missing or incomplete.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-22 19:19:54 +00:00
e70e9b9fcc Fix comment for max claimable tokens test in drop721.test.ts (#7336)
Signed-off-by: fuder.eth <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2025-06-21 13:19:18 -07:00
Jonas DanielsandGitHub dfe913e2a9 Upgrade Biome from 2.0.0 to 2.0.4 (#7407) 2025-06-21 13:16:45 -07:00
Jonas DanielsandGitHub 5bc50eb339 [Dashboard] Replace Sentry Replay with PostHog integration (#7406) 2025-06-21 13:11:41 -07:00
jnsdls b61ce679e1 Move Sentry config to instrumentation-client.ts (#7405)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Integrated Sentry error monitoring and Session Replay for improved error tracking and diagnostics in the dashboard.
  - Enhanced filtering of irrelevant errors and noise from third-party scripts and browser extensions.

- **Chores**
  - Updated analytics setup to include Sentry alongside existing PostHog integration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on integrating `Sentry` for error tracking and monitoring within the `instrumentation-client.ts` file, alongside an existing `PostHog` setup for analytics.

### Detailed summary
- Removed `sentry.client.config.ts`.
- Added `Sentry` initialization with configuration settings including `allowUrls`, `denyUrls`, and `ignoreErrors`.
- Configured `Sentry` for session replay with `integrations`, `replaysOnErrorSampleRate`, and `tracesSampleRate`.
- Exported `onRouterTransitionStart` for router transition tracking.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-21 19:22:40 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
56495a1217 Version Packages (#7404)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-21 11:45:49 -07:00
MananTank c9b4730ecb Dashboard: Team Overview page UI improvements (#7400)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing UI components in the dashboard application, including pagination buttons, team member invitations, and changelog displays. It also refines layout and styling for better user experience.

### Detailed summary
- Updated `pagination-buttons.stories.tsx` to correct page labels.
- Modified `InviteTeamMembersButton` styling for a more rounded appearance.
- Enhanced layout in `page.tsx` for better responsiveness and spacing.
- Changed `Changelog` component structure for improved visual hierarchy.
- Adjusted `TeamProjectsPage` to refine project display and sorting options.
- Replaced `Select` component with a `DropdownMenu` for sorting.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Changelog section now displays feature images for each entry, with fallback icons if unavailable.
	- Changelog items are shown in a responsive grid layout for improved readability.
	- Changelog header includes a title, description, and "View All" button.

- **Enhancements**
	- Team projects page features a redesigned search input, improved sorting with a dropdown menu, and a more prominent subtitle.
	- "Create Project" and other action buttons have updated styling for better visibility.
	- Invite Team Members button now has a rounded appearance and enhanced background styling.
	- Dashboard layout is streamlined with sequential content flow and consistent maximum width for better usability.
	- Pagination controls updated with fully rounded styling for a modern look.
	- Pagination storybook examples corrected and expanded to accurately represent page counts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-21 18:19:28 +00:00
MananTank ea3c702c4f Fix lint errors (#7401)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `sidebar.tsx` file by modifying the `href` property of a menu item and enhancing `globals.css` to improve code styling, particularly for code spans in both light and dark themes.

### Detailed summary
- In `sidebar.tsx`, the `href` property for the menu item "Get Dedicated Support" was removed.
- In `globals.css`, new styles were added for `code span` to set colors for light and dark themes.
- Redundant `.shiki` styles were removed.
- Existing styles for autofilled inputs and button elements remain unchanged.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Style**
  - Consolidated and reorganized CSS rules for code highlighting to improve maintainability. No visual changes were made.

- **Refactor**
  - Adjusted the order of properties within the sidebar configuration for improved code consistency. No changes to functionality or user experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-21 18:19:28 +00:00
Jonas DanielsandGitHub 51798f09be [Changeset] Remove thirdweb-login from ignore list (#7403) 2025-06-21 11:19:01 -07:00
Jonas DanielsandGitHub 387a739544 [Changeset] Add nebula-app to ignore list and reorder config (#7402) 2025-06-21 11:15:56 -07:00
Phillip HoandGitHub 6fd630af1f docs: Add docs about dedicated support channel (#7399) 2025-06-21 12:13:34 +08:00
Phillip HoandGitHub ff6e2453d0 feat: dedicated support self-serve (#7381) 2025-06-21 10:46:25 +08:00
MananTank eeb672d092 [TOOL-4842] Dashboard navigation changes (#7395)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on restructuring and renaming various components and pages within the application, particularly transitioning terminology from "assets" to "tokens" and reorganizing file paths for clarity. It also includes the deletion of unused files and adjustments in imports.

### Detailed summary
- Deleted unused files related to `nebula` and `in-app-wallets`.
- Renamed components and pages from "assets" to "tokens".
- Updated file paths to reflect the new structure.
- Adjusted imports for consistency with new paths.
- Enhanced UI elements for better user experience.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/create-vault-account.client.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/contracts/layout.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/analytics/ftux.client.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/layout.tsx`, `apps/dashboard/redirects.js`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/contract-webhooks/contract-webhooks-page.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/components/try-it-out.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/layout.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/layout.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/vault/components/key-management.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx`, `apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/page.tsx`, `packages/nebula/package.json`, `pnpm-lock.yaml`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a Vault section for secure key management, including a new layout and key management UI.
  - Added contract webhooks management with improved pages and navigation.

- **Improvements**
  - Renamed "Assets" to "Tokens" and "In-App Wallets" to "Wallets" throughout the dashboard.
  - Updated sidebar navigation labels, icons, and link destinations for clarity and consistency.
  - Enhanced "Transactions" section, replacing previous "Engine" references and updating related routes and UI.
  - Refined onboarding and FTUX experiences with clearer terminology and improved instructional content.
  - Improved contract import and table UI with updated labels and empty state messages.
  - Enhanced Pay analytics with richer code examples and a more flexible FTUX component.
  - Streamlined redirects and updated URL paths to remove deprecated segments for smoother navigation.
  - Improved pagination display and active link detection in navigation components.
  - Adjusted layout spacing, button sizes, and typography for improved visual consistency.
  - Updated footer and sidebar styling for better user experience.

- **Bug Fixes**
  - Fixed various redirect and navigation paths to align with new route structures.
  - Improved handling of pagination and active link states in navigation components.

- **Removals**
  - Removed Nebula analytics pages, components, and related tracking utilities.
  - Deleted unused tracking properties and constants.
  - Removed outdated Vault key management component replaced by new implementation.

- **Documentation**
  - Updated terminology in documentation and UI to reflect the shift from "assets" to "tokens".
  - Revised analytics event descriptions to use "token page" terminology.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-21 00:36:00 +00:00
PaoloRollo 9667c74981 feat: add @thirdweb-dev/nebula package. (#7389)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->
This PR adds the new `@thirdweb-dev/nebula` package. It's an OpenAPI Typescript Wrapper for the new Nebula APIs.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces the initial release of the `@thirdweb-dev/nebula` TypeScript SDK, providing a wrapper for the Nebula API with configuration options and client functionalities.

### Detailed summary
- Added `@thirdweb-dev/nebula` package with initial release.
- Created configuration functions: `configure`, `configureWithClient`, and `getNebulaClient`.
- Generated client and types using `@hey-api/openapi-ts`.
- Included comprehensive README with usage examples.
- Established TypeScript configuration files.

> The following files were skipped due to too many changes: `packages/nebula/src/client/types.gen.ts`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced the Nebula TypeScript SDK as a new package, providing a client for interacting with the Nebula OpenAPI AI agent service.
  - Added configuration utilities for flexible authentication and integration with existing clients.
  - Exposed a comprehensive set of API methods for managing agents, conversations, models, and user data.
  - Extended build scripts to include the Nebula package in relevant workspace commands.

- **Documentation**
  - Added detailed README with setup instructions and usage examples for the Nebula SDK.

- **Chores**
  - Added configuration and build files to support development and compilation of the new package.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-20 23:32:30 +00:00
Jonas DanielsandGitHub 997beeac3a biome 2 (#7398) 2025-06-20 16:14:38 -07:00
gregandGitHub 9fec4ccec4 [SDK] Fix: Deprecate test mode (#7396) 2025-06-20 13:07:52 -07:00
gregandGitHub 9c420c0c9d [SDK] Feature: Update PayEmbed to use new widgets (#7394) 2025-06-20 12:50:06 -07:00
Jonas DanielsandGitHub ffea73c719 [Dashboard] Disable 7-day trial for growth plan (#7392) 2025-06-20 00:22:21 -07:00
Jonas DanielsandGitHub f56cc00187 [Dashboard] Remove phone login option and add info alert (#7391) 2025-06-20 00:09:21 -07:00
gregandGitHub 6be9459361 Refactor: UB widget inputs (#7390) 2025-06-19 16:47:38 -07:00
MananTank 492c6d0194 Dashboard: NFT asset page UI updates (#7388)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `TokenInfoUI` component by adding a new claim condition check, improving the UI for displaying NFT purchase availability, and restructuring the layout for better clarity. It also introduces a tabbed interface for viewing traits and purchasing options for ERC1155 tokens.

### Detailed summary
- Added a new check for claim conditions in `TokenInfoUI`.
- Introduced a "Not available for purchase" message when no claim conditions are set.
- Implemented a tabbed interface for ERC1155 tokens to switch between traits and purchase options.
- Reorganized the layout of the NFT details section for improved readability.
- Adjusted spacing in the `BuyEditionDrop` form for consistency.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a tabbed interface for ERC1155 tokens, allowing users to switch between viewing traits and purchasing options.
	- Added badges displaying token type, token ID, and chain metadata for improved clarity.

- **Improvements**
	- Enhanced handling of claim conditions, now clearly indicating when an NFT is not available for purchase.
	- Refined the display of NFT traits, showing a "No Traits" message if none exist.
	- Updated form and input styling for a cleaner and more consistent appearance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 18:13:48 +00:00
Yash094 787118d367 feat: add berachain and berachain-bepolia chains (#7343)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces the `berachain` and `berachainBepolia` blockchain definitions to the `thirdweb` package, enhancing its chain support. It also updates the `chains` export file to include these new chains.

### Detailed summary
- Added `berachain` and `berachainBepolia` definitions in their respective files.
- Updated `packages/thirdweb/src/exports/chains.ts` to export `berachain` and `berachainBepolia`.
- Defined `berachain` with an ID of 80094 and a native currency of `BERA`.
- Defined `berachainBepolia` with an ID of 80069, marked as a testnet.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for the Berachain mainnet and Berachain Bepolia testnet networks, including native currency details and integrated block explorers for enhanced network visibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 18:03:17 +00:00
MananTank 70e024f43e [TOOL-4831] SDK: Fix MediaRenderer not showing poster for 3d models (#7387)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on fixing the display of the `poster` in the `MediaRenderer` component for 3D models and adding tests to ensure expected behavior.

### Detailed summary
- Updated the `MediaRenderer` component to show a `poster` image for 3D models.
- Added a new test case to verify rendering of the `poster` image when a 3D model is provided.
- Replaced hardcoded image URL with a constant `imageLink` for clarity in tests.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
	- Fixed an issue where the poster image was not displayed when rendering 3D models in the MediaRenderer component. Now, if a poster image is available, it will be shown as a fallback for unsupported 3D models.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 17:16:55 +00:00
Phillip HoandGitHub 4c2988623f chore: add dedicatedSupportChannel to TeamResponse (#7382) 2025-06-19 21:24:50 +08:00
Jonas DanielsandGitHub 5492331263 [Dashboard] Add chain, publisher, and contract data to deploy failure analytics (#7376) 2025-06-18 21:14:01 -07:00
jnsdls 1397adf32e posthog migration: part 5 (#7367)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added event reporting for contract publishing, faucet usage, and custom chain configuration additions.
  - Introduced detailed event reporting for asset purchases, creations, imports, and configuration steps.

- **Refactor**
  - Replaced legacy analytics tracking hooks with centralized reporting functions for key user actions.
  - Updated asset creation flows to report step transitions and outcomes with enhanced detail.

- **Bug Fixes**
  - Clarified faucet claim restriction text to include the "Scale" plan alongside other eligible plans.

- **Chores**
  - Removed all legacy analytics tracking hooks and event calls across the dashboard.
  - Simplified event reporting by eliminating unused tracking utilities and hooks without affecting user workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on removing the `useTrack` analytics hook from various components and replacing it with direct logging or removing tracking functionality entirely.

### Detailed summary
- Deleted `useTrack` imports and instances from multiple files.
- Removed tracking-related code from components such as `LinkWalletPrompt`, `LoginOrSignup`, and `StepCard`.
- Replaced tracking calls with direct logging in error handling.
- Adjusted various components to eliminate unnecessary tracking.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/cloud/vault/components/list-access-tokens.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/primary-sale.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/mint-supply-tab.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/wallet-credentials/components/edit-wallet-credential-button.tsx`, `apps/dashboard/src/@/components/blocks/pricing-card.tsx`, `apps/dashboard/src/components/embedded-wallets/Configure/index.tsx`, `apps/dashboard/src/components/onboarding/ApplyForOpCreditsForm.tsx`, `apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletsTable.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/components/platform-fees.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/burn-tab.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/batch-lazy-mint-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx`, `apps/dashboard/src/components/configure-networks/ConfigureNetworks.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-form.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/burn-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/transfer-button.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/overview/components/backend-wallets-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/admins/components/admins-table.tsx`, `apps/dashboard/src/components/smart-wallets/SponsorshipPolicies/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/relayers/components/relayers-table.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/access-tokens/components/access-tokens-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/claim-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/PayModal.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/settings/ProjectGeneralSettingsPage.tsx`, `apps/dashboard/src/app/(app)/login/onboarding/account-onboarding-ui.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx`, `apps/dashboard/src/components/CustomChat/CustomChatContent.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx`, `apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/cards.tsx`, `apps/dashboard/src/app/(app)/login/onboarding/VerifyEmail/VerifyEmail.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/launch/launch-token.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-edition-drop/buy-edition-drop.client.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token/create-token-page-impl.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx`, `apps/dashboard/src/@/analytics/report.ts`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-19 00:53:58 +00:00
jnsdls 2aa9ce5f78 posthog migration: part 4 (#7366)
# Analytics Event Reporting System

This PR introduces a structured analytics event reporting system for the dashboard app using PostHog. It provides clear guidelines and standardized patterns for tracking user actions.

## Key Features

- Added a centralized analytics reporting system in `src/@/analytics/report.ts`
- Implemented standardized naming conventions for events (`<subject> <verb>`) and reporting functions (`report<Subject><Verb>`)
- Created comprehensive documentation in `apps/dashboard/src/@/analytics/README.md`
- Added mandatory JSDoc requirements to document the purpose and ownership of each event
- Integrated the first event: `reportContractDeployed` to track contract deployments
- Updated the contract deployment form to use the new analytics system

## Guidelines

- Events should only be added when they answer concrete product/business questions
- All events must include typed properties and proper documentation
- Analytics code is client-side only (never import `posthog-js` in server components)
- Developers should notify #core-services before renaming or removing events

This standardized approach will make our analytics more maintainable, discoverable, and purposeful.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Documentation**
  - Added comprehensive guidelines and a README for analytics event reporting, including naming conventions, usage examples, and requirements for event tracking in the dashboard app.

- **New Features**
  - Introduced new analytics events covering contract deployments and multiple stages of team onboarding, such as plan selection, member invitations, and onboarding completion.

- **Refactor**
  - Centralized analytics reporting by replacing generic event tracking with dedicated reporting functions across contract deployment and team onboarding flows.
  - Removed redundant and granular event tracking calls, simplifying analytics integration and improving consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing analytics event reporting for onboarding and contract deployment processes across the application, ensuring better tracking of user interactions and feedback.

### Detailed summary
- Added `.eslintignore` entries for markdown files.
- Updated `InviteTeamMembers` and `InviteSection` to report success counts on invites.
- Introduced new reporting functions in `report.ts` for onboarding and contract events.
- Removed unused `trackEvent` calls, replacing them with specific reporting functions.
- Enhanced documentation for analytics guidelines and event reporting in `README.md` files.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-19 00:53:58 +00:00
jnsdls d9eee50dc1 posthog migration: part 3 (#7365)
# Remove Analytics Tracking Components

This PR removes analytics tracking components and properties from the dashboard app. Key changes include:

- Removed `TrackedLinkTW` and `TrackedUnderlineLink` components, replacing them with standard `Link` and `UnderlineLink` components
- Removed tracking properties from sidebar links and navigation components
- Eliminated tracking metadata from contract cards, NFT cards, and marketplace components
- Removed tracking-related props from various UI components
- Simplified component interfaces by removing tracking-specific parameters
- Replaced legacy tracked button components with standard button components

These changes simplify the codebase by removing the analytics tracking layer while maintaining all core functionality.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing security by adding `rel="noopener noreferrer"` to various `Link` components throughout the codebase to prevent potential security vulnerabilities associated with opening links in new tabs.

### Detailed summary
- Added `rel="noopener noreferrer"` to multiple `Link` components for security.
- Removed `tracking` properties from several components.
- Replaced `TrackedLinkTW` with `Link` or `UnderlineLink` in various files.
- Updated imports to use `Link` from `next/link` instead of custom tracking links.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/metrics/components/EngineSystemMetrics.tsx`, `apps/dashboard/src/tw-components/link.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/NFTCards.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/import/EngineImportPage.tsx`, `apps/dashboard/src/components/explore/upsells/deploy-your-own.tsx`, `apps/dashboard/src/components/contract-functions/interactive-abi-function.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/contract-subscriptions/components/engine-contract-subscription.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(general)/_components.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/engine/dedicated/(instance)/[engineId]/_components/version.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/NFTDetails.tsx`, `apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx`, `apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/PermissionsTable.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/profile/[addressOrEns]/components/PublishedContractTable.tsx`, `apps/dashboard/src/components/explore/contract-card/index.tsx`, `apps/dashboard/src/contract-ui/tabs/code/components/code-overview.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx`, `apps/dashboard/src/components/embedded-wallets/Configure/index.tsx`, `apps/dashboard/src/@/components/blocks/app-footer.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/footer/FooterLinksSection.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/AccountAbstractionPage.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx`, `apps/dashboard/src/components/buttons/MismatchButton.tsx`, `apps/dashboard/src/tw-components/button.tsx`, `apps/dashboard/src/components/smart-wallets/SponsorshipPolicies/index.tsx`, `apps/dashboard/src/components/cmd-k-search/index.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Removed all analytics tracking from links and buttons across the dashboard.
  - Replaced custom tracking link and button components with standard or simplified alternatives.
  - Updated component props and interfaces to eliminate tracking-related fields.
  - Streamlined UI components by removing tracking props and logic, resulting in cleaner navigation and interactions.

- **Style**
  - Added `rel="noopener noreferrer"` attribute to all external links opening in new tabs for improved security and privacy.
  - Minor adjustments to link styling in some components to accommodate new link components.

No changes to core functionality or user workflows; navigation and UI remain consistent.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 00:53:58 +00:00
jnsdls 5f2bca8371 posthog migration: part 2 (#7364)
# Add PostHog Analytics Identification for Accounts and Teams

This PR adds analytics tracking capabilities to identify users and teams in PostHog:

- Created two new hooks:
  - `useIdentifyAccount`: Identifies users by their account ID and optional email
  - `useIdentifyTeam`: Identifies teams by their team ID using PostHog's group functionality

- Implemented these hooks in the `TeamHeaderLoggedIn` component to track both the current user and team

Both hooks include safety checks to ensure PostHog is properly loaded before attempting to identify users or teams.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on integrating `posthog-js` analytics functionalities into various components of the application, specifically for resetting analytics on logout and identifying users and teams.

### Detailed summary
- Added `resetAnalytics` function in `reset.ts` to reset analytics.
- Implemented `useIdentifyTeam` hook in `identify-team.ts` for team identification.
- Implemented `useIdentifyAccount` hook in `identify-account.ts` for account identification.
- Integrated `resetAnalytics` in logout processes across multiple components:
  - `CustomConnectWallet`
  - `AccountHeader`
  - `AccountSettingsPage`
  - `LoginPage`
  - `TeamHeaderLoggedIn`
- Updated ESLint rules to allow direct imports of `posthog-js` within analytics helpers.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced automatic analytics identification for user accounts and teams within the dashboard.
	- Added a function to reset analytics data, now triggered on logout, wallet disconnection, and account deletion.

- **Chores**
	- Updated internal configuration to ensure analytics tracking is consistently managed and restricted to designated areas.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-19 00:53:57 +00:00
jnsdls 6b24fed21f posthog migration: part 1 (#7363)
# Migrate to PostHog US Instance

This PR updates our PostHog integration across all apps to use the US-based PostHog instance instead of the previous self-hosted solution. Key changes include:

- Upgraded PostHog JS SDK from 1.67.1 to 1.252.0
- Added API proxying via Next.js rewrites to route PostHog requests through `/_ph` endpoints
- Implemented a new initialization approach using `instrumentation-client.ts` files
- Removed custom PostHog components and providers in favor of the official SDK's auto-capture functionality
- Configured PostHog to capture page views on history changes automatically
- Disabled session recording and exception capturing for privacy and performance
- Removed the `flat` dependency which is no longer needed

These changes will provide more reliable analytics while improving performance by using PostHog's official CDN and modern SDK features.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for proxying analytics-related requests to external services across multiple apps, enabling seamless integration with analytics providers.

- **Chores**
  - Upgraded the analytics library dependency to the latest version in several apps.
  - Updated environment variable examples to support new analytics configuration.

- **Refactor**
  - Replaced in-app analytics instrumentation with new centralized clients for improved control and consistency.

- **Bug Fixes**
  - Minor CSS z-index syntax adjustments for improved styling consistency.

- **Removed**
  - Eliminated legacy analytics components and tracking from layouts, providers, hooks, and feedback forms, simplifying application structure and reducing external tracking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on the removal of several `Posthog` components and their related files across multiple applications, as well as updating the `posthog-js` library version to `1.252.0`. It also introduces new `rewrites` in various configuration files to accommodate the updated tracking.

### Detailed summary
- Deleted files related to `Posthog` from:
  - `apps/portal/src/lib/env.ts`
  - `apps/portal/src/lib/posthog/Posthog.tsx`
  - `apps/dashboard/src/lib/posthog/Posthog.tsx`
  - `apps/playground-web/src/lib/posthog/Posthog.tsx`
  - `apps/dashboard/src/components/wallets/PosthogIdentifier.tsx`
- Updated `posthog-js` version to `1.252.0` in:
  - `apps/nebula/package.json`
  - `apps/playground-web/package.json`
  - `apps/portal/package.json`
  - `apps/dashboard/package.json`
- Added `NEXT_PUBLIC_POSTHOG_KEY` and `NEXT_PUBLIC_POSTHOG_HOST` to `apps/nebula/.env.example`.
- Introduced new `rewrites` in `next.config.mjs` for `apps/playground-web`, `apps/dashboard`, `apps/nebula`, and `apps/portal` to direct traffic for `Posthog`.
- Removed `Posthog` components from various layouts and providers, simplifying the structure in `apps/dashboard/src/app/pay/components/client/Providers.client.tsx` and `apps/dashboard/src/app/bridge/components/client/Providers.client.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-19 00:53:57 +00:00
gregandGitHub cc3fbba895 Fix: Fallback insight owned tokens request to mainnet (#7375) 2025-06-18 15:38:58 -07:00
Toomas OosaluandGitHub 381e423d59 insight playground - allow array items to be single item (#7373) 2025-06-18 15:14:12 -07:00
Manan TankandGitHub c70d5ab013 [PRO-199] Playground sidebar changes (#7369) 2025-06-18 15:13:30 -07:00
gregandGitHub 3dbf9e16fd Fix: Bridge Playground Chain Input Form (#7371) 2025-06-18 11:58:21 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
be49798e99 Version Packages (#7361)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-18 09:37:52 -07:00
AmineAfia 167f9213ff Add SignatureSelector component for custom signature input in webhooks (#7370)
# [INFRA-1454][Dashboard] Feature: Add SignatureSelector component for improved signature selection

## Notes for the reviewer

This PR introduces a new `SignatureSelector` component that enhances the signature selection experience in the webhooks UI. The component allows users to either select from predefined signatures or enter custom ones, with appropriate UI feedback.

Key improvements:
- Users can now enter custom signatures directly in the input field
- Warning message appears when a custom signature is entered
- Automatic ABI detection for known signatures
- Better handling of signature formats (automatically converts text signatures to hash format)

## How to test

1. Navigate to the webhooks creation flow
2. Test selecting predefined event/function signatures
3. Test entering custom signatures and verify the warning appears
4. Verify that ABIs are properly loaded for known signatures
5. Test the reset functionality

The component is fully integrated with the existing form validation system.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new signature selector with search and custom input support for selecting or entering function signatures.
  - Enhanced dropdown components to allow custom search input elements.

- **Refactor**
  - Replaced the previous signature dropdown with the new selector for improved usability and consistency.
  - Improved ABI input handling, including automatic detection and reset options.

- **Bug Fixes**
  - Improved normalization of signature hash values and ABI fallback logic for webhook payloads.
  - Enhanced address parsing for ABI reset functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces enhancements to the `webhookPayloadUtils`, `MultiSelect`, and `SignatureSelector` components, improving signature handling and custom input functionality. It also updates the `FilterDetailsStep` to utilize the new `SignatureSelector` and remove the deprecated `SignatureDropdown`.

### Detailed summary
- Updated `buildEventWebhookPayload` and `buildTransactionWebhookPayload` functions to handle `sigHash` and `abi` more robustly.
- Added `customSearchInput` prop to `MultiSelect` for enhanced search functionality.
- Implemented `SignatureSelector` component for better signature selection with custom input support.
- Replaced `SignatureDropdown` with `SignatureSelector` in `FilterDetailsStep`.
- Improved handling of custom signatures and ABI management in `FilterDetailsStep`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-18 15:49:37 +00:00
Jonas DanielsandGitHub bb09e20bcb [Dashboard] Update rewrites and redirects for Connect to Build migration (#7362) 2025-06-17 16:51:05 -07:00
gregandGitHub 78b9c8e334 [SDK] Fix: stringify bigint erc20Value in useTransactionDetails (#7360) 2025-06-17 15:32:04 -07:00
Manan TankandGitHub a5163c0c7f Fix z-index issue in NFT asset page (#7359) 2025-06-17 15:04:09 -07:00
gregandGitHub 55baa997f0 Fix: Throw error if amount and gas is more than balance (#7358) 2025-06-17 14:39:55 -07:00
Manan TankandGitHub c75e434498 [TOOL-4827] Move Nebula out of dashboard (#7356) 2025-06-17 14:30:24 -07:00
YashandGitHub 2b5941ff7d Replace CLI login article link (#7355) 2025-06-17 10:12:20 -07:00
Manan TankandGitHub 85b21ec65c Add Empty Nebula project shell (#7357) 2025-06-17 09:38:46 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
508b4c48e5 chore(deps): bump github/codeql-action from 3.28.19 to 3.29.0 (#7348)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 22:19:42 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a5e086f173 chore(deps): bump @sentry/nextjs from 9.28.1 to 9.29.0 (#7351)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-16 22:19:26 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8af6143d53 Version Packages (#7304)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-16 17:56:01 -07:00
ed81006741 Feature: New UB Components (#7354)
Co-authored-by: Joaquim Verges <[email protected]>
2025-06-16 17:07:28 -07:00
MananTank 3f74760113 [TOOL-4819] Dashboard: Load all engine backend wallets, add pagination in table (#7347)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `useEngine` hook and the `BackendWalletsSection` component by adding pagination functionality for backend wallets retrieval, allowing users to navigate through pages of wallet data.

### Detailed summary
- Added optional `limit` and `page` parameters to the `useEngine` hook.
- Updated the fetch URL in the hook to accommodate pagination.
- Introduced pagination controls in `BackendWalletsSection` using `Button` components.
- Managed pagination state with `useState` for current page tracking.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-16 20:59:30 +00:00
MananTank 9253c54cf9 [TOOL-4821] Improve Team members search (#7346)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a search feature for members in the `ManageMembersSection` component by integrating the `Fuse.js` library for fuzzy searching. This enhancement allows users to filter members based on their names and emails more effectively.

### Detailed summary
- Added `Fuse` from `fuse.js` to enable fuzzy searching.
- Created a `membersIndex` using `useMemo` to index `props.members`.
- Updated the filtering logic to use `membersIndex.search(searchTerm)` for searching members.
- Included `membersIndex` in the dependency array of the `membersToShow` memoization.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Improved member search functionality with fuzzy matching, allowing for more flexible and accurate search results based on names and emails.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 20:47:28 +00:00
MananTank 913ea98d23 [TOOL-4802] NFT Asset Page (#7332)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the handling of NFTs and contract components within the application, including updates to types, UI components, and functionality related to NFT collections and claims.

### Detailed summary
- Updated `NFTMetadata` type to include `slug`.
- Added `slug` property in various components.
- Introduced `supplyFormatter` for better NFT supply formatting.
- Changed contract type handling to `NFTCollection`.
- Enhanced `MinimalProject` type to include `slug`.
- Updated UI components for better user interaction.
- Improved pagination and NFT display logic.
- Added new utilities for NFT claim conditions and total counts.
- Refactored claim token UI to utilize new components and structures.
- Implemented responsive layouts for better mobile support.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/nfts-grid.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/overview/buy-nft-drop/buy-nft-drop-ui.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/nft/token-viewer/token-viewer.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced public NFT pages for ERC-721 and ERC-1155 contracts with responsive layouts, NFT grids, token viewer dialogs, and buy functionality.
  - Added components for token price display, supply claimed progress, and enhanced pagination controls.
  - Enabled NFT purchases from drops with dedicated UI and transaction handling for ERC-721 and ERC-1155 standards.
  - Added tabbed navigation for public NFT pages and improved media rendering with loading placeholders.
  - Introduced a responsive layout component for device-specific rendering and customizable wallet address focus behavior.
  - Added new components for buying NFTs and editions with form validation, pricing display, and transaction feedback.
  - Added a token price component with loading skeleton and strikethrough styling.
  - Added a supply claimed progress bar with detailed percentage display.
  - Introduced a token viewer dialog with dynamic data fetching and rich metadata display.
  - Added a paginated NFT grid with detailed claim condition info for ERC-1155 tokens.
  - Added buy NFT drop card components with server and client rendering support.
  - Added a custom media renderer component with loading state management.

- **Enhancements**
  - Improved contract and page header components with customizable styling options.
  - Expanded project and team data structures to include project slugs for better navigation.
  - Updated wallet address and pagination components with additional props for accessibility and styling.
  - Refined tracking of click and keyboard events for asset cards.
  - Simplified purchase UI code by delegating price and supply display to shared components.
  - Enhanced pagination to handle two-page scenarios with simplified controls.
  - Updated public page rendering logic to support multiple ERC standards with unified detection.
  - Improved purchase flows with analytics tracking and toast notifications.
  - Added support for special user pricing and dynamic claim condition fetching.

- **Bug Fixes**
  - Fixed conditional rendering and redirection logic for public NFT pages based on contract type and metadata presence.

- **Documentation**
  - Added Storybook stories for new UI components including supply claimed progress and NFT drop purchase flows.

- **Refactor**
  - Delegated price and supply display logic to shared components for consistency.
  - Updated types and props to support new features and improve maintainability.

- **Chores**
  - Broadened NFT metadata field types for improved compatibility with diverse data formats.
  - Added fallback for React experimental API to prevent errors in unsupported environments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-16 17:56:26 +00:00
gregandGitHub 5ce8a5618f Revert "brige embed (#7222)" (#7345) 2025-06-16 10:39:31 -07:00
35a909a897 WIP brige embed (#7222)
Co-authored-by: gregfromstl <[email protected]>
2025-06-15 18:36:11 -07:00
gregandGitHub 9f6c1a4820 Feature: clarify webhook disclaimer (#7339) 2025-06-15 16:21:26 -07:00
Phillip HoandGitHub e43afa1b4e chore: update team/account docs for team management (#7341) 2025-06-14 14:04:32 +08:00
Jonas DanielsandGitHub 94e2cbc468 [Dashboard] Add Google Tag Manager and PostHog to CSP script sources (#7338) 2025-06-13 15:08:47 -07:00
kumaryash90 64ee04c25d Update implementations (#7335)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `MarketplaceV3` addresses in the `ZKSYNC_IMPLEMENTATIONS` and `ZKSYNC_WETH` records, reflecting new contract addresses for the marketplace.

### Detailed summary
- Updated `MarketplaceV3` address for `[324]` from `0x88e7F2bEf0a23073b7Cc2c79D307Dbd9138Fa79c` to `0xFD5663B3Ed316aEB79c9b5c4A242172273cA3395`.
- Updated `MarketplaceV3` address for `[2741]` from `0x4b14569c7B79DBe686Ac3Ba5996131E7EDaB7a93` to `0x9Fdf34f552cdA8E2B0cD64e2EddcB732a5Ff8455`.
- Added new `MarketplaceV3` address for `[531050104]`: `0x292c324920d4120F928dA6f04548442fa10B8B0f`.
- Added new `MarketplaceV3` address for `[50104]`: `0x292c324920d4120F928dA6f04548442fa10B8B0f`.
- Added new `WETH` address for `[531050104]`: `0x9B7EA63EF5062661570afe548e3AD691D5652527`.
- Added new `WETH` address for `[50104]`: `0x2b1A859dE6A55c553520D7780Bc5805712B128F9`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for MarketplaceV3 contract on two additional networks.
  - Updated MarketplaceV3 contract addresses on existing networks for improved compatibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-13 13:50:20 +00:00
Jonas DanielsandGitHub 680b8cdb16 [Dashboard] Rename getMemberById to getMemberByAccountId and add onboarding banner (#7334) 2025-06-12 16:40:00 -07:00
saminacodes 787db9308d [Docs] UB (#7333)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the documentation for the `Universal Bridge` by adding troubleshooting information and FAQs regarding payment issues and token support.

### Detailed summary
- Added a section for handling "Error 500: Internal Server Error" with upgrade instructions for the SDK.
- Included a new FAQ on supporting tokens on the `Universal Bridge` with criteria and request instructions.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Documentation**
  - Added a new FAQ explaining how to request support for a token on Universal Bridge, including submission steps and expected processing time.
  - Introduced troubleshooting guidance for resolving "Error 500" or "Something went wrong" messages in Universal Bridge, with instructions to update the SDK and contact support if needed.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-12 23:32:30 +00:00
kilavvyandGitHub c152db3e2f Fix Typographical Errors in Documentation and Comments (#7331)
Signed-off-by: kilavvy <[email protected]>
2025-06-12 14:01:03 -07:00
Corey RiceandGitHub 5f57300cf9 docs: fix typos in doc string (#7301) 2025-06-11 23:44:15 -07:00
Jonas DanielsandGitHub db20bd17b1 update deps 2 (#7328) 2025-06-11 23:41:12 -07:00
Jonas DanielsandGitHub 0a85205e4a update storybook (#7327) 2025-06-11 23:24:45 -07:00
Jonas DanielsandGitHub cda390eefe update dependencies (#7326) 2025-06-11 21:23:36 -07:00
leopardracerandGitHub 305f738ff1 Fix typos in comments and test descriptions (#7323)
Signed-off-by: leopardracer <[email protected]>
2025-06-11 21:08:07 -07:00
Jonas DanielsandGitHub a1c875c596 [Dashboard] Add self-service dedicated engine deployment option (#7325) 2025-06-11 19:32:08 -07:00
Jonas DanielsandGitHub 38f1821eb9 [Dashboard] Add plan selection step to team onboarding flow (#7324) 2025-06-11 17:56:00 -07:00
jnsdls 848984481f [Dashboard] Add 7-day free trial for Growth plan (#7322)
# Add 7-day free trial for Growth plan and include Starter plan in team onboarding

This PR adds a 7-day free trial indicator for teams that have just signed up but haven't subscribed yet when selecting the Growth plan. It also updates the team onboarding flow to properly handle the Starter plan.

Changes include:
- Added logic to detect if a team qualifies for the 7-day trial (new signup with no payment on Growth plan)
- Added a "7 day free trial" text display for qualifying teams
- Updated the polling logic to consider both "free" and "starter" plans as non-paid plans
- Modified the onboarding description text to remove reference to "free Starter plan"

## Summary by CodeRabbit

- **New Features**
  - Added a clear "7 day free trial" indicator for eligible Growth plan users.

- **Enhancements**
  - Updated onboarding modal text to remove "free" from the Starter plan description.
  - Modified billing plan polling logic to exclude both "free" and "starter" plans before proceeding.

---

## PR-Codex overview
This PR focuses on updating the logic for determining billing plans and enhancing the user experience regarding trial periods in the `InviteTeamMembers` and `PricingCard` components.

### Detailed summary
- In `InviteTeamMembers.tsx`, updated the condition for `isNonFreePlan` to exclude both "free" and "starter" plans.
- Modified the text in `InviteModalContent` to clarify the Starter plan.
- In `pricing-card.tsx`, added a condition for a 7-day trial for teams with a "growth" billing plan and "noPayment" status.
- Changed the rendering logic for remaining trial days to include a message for the 7-day trial.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the pricing logic and UI in the dashboard. It modifies how pricing is handled, specifically for trial periods, and updates the display of pricing information to better reflect the available options and trials.

### Detailed summary
- Changed `price` type from `string | number` to `number`.
- Updated `isNonFreePlan` logic to exclude "starter" plans.
- Revised promotional text for the Growth plan.
- Added logic for a 7-day free trial for new teams on the Growth plan.
- Updated UI to display a "7 Day Free Trial" badge and adjusted pricing display accordingly.
- Modified call-to-action button text based on trial eligibility.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a "7 Day Free Trial" badge and updated price display for eligible users on the Growth plan.
  - Call-to-action button now shows "Start 7 Day Free Trial" when applicable.

- **Bug Fixes**
  - Improved onboarding flow by updating plan detection logic to better handle "Starter" and "Free" plans.

- **Style**
  - Revised onboarding text to emphasize upgrading to the Growth plan and removed mention of the Starter plan.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-11 19:59:56 +00:00
Jonas DanielsandGitHub 950bbaee1c [Dashboard] Update URL rewrites for grants and superchain pages (#7320) 2025-06-10 18:09:35 -07:00
MananTank 99d6b3b151 Dashboard: Add NFT creation wizard in Asset page (#7315)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the handling of file inputs and media uploads within the application. It introduces new functionalities for managing blob URLs, refines error handling, and enhances the user interface for uploading assets.

### Detailed summary
- Added `fileToBlobUrl` function to convert files to blob URLs.
- Enhanced `FileInput` components to accept a `client` prop for better integration.
- Updated error handling in several components to provide more detailed feedback.
- Refined layouts and styles for asset creation pages.
- Introduced new schemas for validating NFT and social URL data.
- Improved tracking functionality for NFT creation steps.
- Added support for handling multiple file types in uploads.
- Enhanced the user interface for attributes and social URLs input fields.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/upload-nfts.tsx`, `apps/dashboard/src/core-ui/batch-upload/batch-table.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/page.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/sales/sales-settings.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/collection-info/nft-collection-info-fieldset.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/token-info-fieldset.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/components/airdrop-upload.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/nft/NFTMediaFormGroup.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page-ui.tsx`, `apps/dashboard/src/components/shared/FileInput.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/distribution/token-airdrop.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/lazy-mint-form.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/process-files.ts`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/single-upload-nft.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-instructions.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/launch/launch-token.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/create-nft-page.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/batch-upload/batch-upload-nfts.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/launch/launch-nft.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added logic to always display the selected token in token selectors.
  - Introduced a styled drag-and-drop file upload area with error handling and reset options.
  - Added reusable components: file preview for files and URLs, step cards with navigation and tracking, social URLs fieldset, downloadable file button, batch upload instructions, and NFT attribute management.
  - Launched a multi-step NFT creation workflow covering collection info, asset upload (single and batch), sales settings, and launch steps.
  - Added schema validation for NFT metadata including pricing, social URLs, and blockchain addresses.
  - Enabled batch uploading and inline editing of NFTs with price, currency, and supply management.
  - Added advanced sales and royalty settings with real-time validation and analytics tracking.

- **Enhancements**
  - Improved error reporting in toast notifications with detailed parsed messages.
  - Centralized and streamlined media file handling by removing redundant hooks and consolidating upload logic.
  - Enhanced navigation and event tracking across multi-step asset creation flows.
  - Updated UI components to accept client context for consistent file handling.
  - Refined form validation by reusing common schemas.

- **Bug Fixes**
  - Corrected NFT supply column label to "Circulating Supply".
  - Improved loading placeholder text in token selectors.

- **Refactor**
  - Consolidated CSV upload logic and replaced custom drag-and-drop UIs with a unified DropZone component.
  - Replaced multiple media preview components with a single FilePreview component.
  - Updated prop types and component interfaces for better consistency and maintainability.
  - Removed deprecated hooks and unused imports to reduce technical debt.
  - Reorganized and standardized import paths across modules.
  - Simplified step execution logic in launch flows and enhanced retry capabilities.

- **Documentation**
  - Added Storybook stories for DropZone, multi-step status, and NFT upload components to support visual testing and documentation.

- **Chores**
  - Exported utility functions and constants for broader use.
  - Improved styling flexibility by enhancing component className handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-10 21:50:05 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
81c66f4e7b chore(deps): bump github/codeql-action from 3.28.18 to 3.28.19 (#7308)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-10 12:22:11 -07:00
catalyst17 639356071c docs: add webhooks section to agents and LLMs documentation (#7317)
# [Portal] Feature: Add Webhooks Documentation for AI Agents + Example with multiple ABIs for decoding

## Notes for the reviewer

Example with multiple ABIs for decoding ([related PR](https://app.graphite.dev/github/pr/thirdweb-dev/insight-service/268/fix-improve-ABI-validation-to-support-array-format))

1. Added examples on creating events filters with multiple ABI options

Also, this PR adds comprehensive documentation about using webhooks with AI agents in the Insight platform. The documentation covers:

1. Use cases for webhooks with AI agents
2. How to create and manage webhooks
3. Filtering capabilities, including support for multiple ABIs
4. Information about webhook payloads

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Documentation**
  - Added a new "Webhooks" section describing how to use webhooks with the Insight API for real-time blockchain event notifications and event-driven AI agents.
  - Provided use cases, filter examples, and links to detailed webhook and payload documentation.
  - Enhanced webhook filter documentation to clarify support for multiple ABIs, including examples for handling ERC-20 and ERC-721 Transfer events.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-10 18:53:39 +00:00
saminacodes 62af256575 [Docs] Update Broken Link (#7319)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the content in the `page.mdx` file related to fees and support for the `Universal Bridge` feature.

### Detailed summary
- Updated the explanation of fees for "Buy With Crypto" to specify fee settings in the project page.
- Revised the link for supported cryptocurrencies to direct to a new URL with a specific service.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Documentation**
  - Clarified FAQ entry about setting additional fees for swap transactions and provided step-by-step instructions for configuring these fees.
  - Updated the "supported chains" link in the FAQ to use an absolute URL.
  - Removed an unnecessary blank line for improved readability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-10 18:46:55 +00:00
jnsdls eb1c705654 [Dashboard] Improve error handling in billing checkout process (#7318)
# Add "Go back" button to Stripe redirect error page and improve error handling

This PR enhances the Stripe redirect error page by adding a "Go back" button, allowing users to navigate away from error states. It also improves error handling in the billing checkout flow by:

1. Converting `getBillingCheckoutUrl()` to return structured responses with proper error messages
2. Adding specific error messages for different HTTP status codes (402 for outstanding invoices, 429 for rate limiting)
3. Displaying these more descriptive error messages to users when checkout fails

These changes provide a better user experience when errors occur during the checkout process.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added a "Go back" button to the Stripe redirect error page, allowing users to easily return to the previous screen.

- **Bug Fixes**
  - Improved error handling during the checkout process, providing clearer error messages for issues such as authentication, outstanding invoices, rate limiting, and unknown errors. Error messages are now displayed directly on the error page when checkout fails.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-10 18:30:16 +00:00
arcoraven 9643b8d2c5 feat: create/delete teams (#7293)
# [Dashboard] Feature: Add Team Creation and Deletion

## Notes for the reviewer

This PR adds the ability for users to create and delete teams from the dashboard. It includes:

1. Server actions for creating and deleting teams
2. UI integration in the account header, team selector, and account teams page
3. Team deletion functionality in the team settings page

## How to test

- Try creating a new team from the account header dropdown
- Try creating a new team from the account teams page
- Try deleting a team from the team settings page (only available for team owners)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enabled team creation directly from the account and team selection interfaces, allowing users to create a new team and be redirected to its page immediately.
  - Activated the "Create Team" button in relevant menus and headers, making team creation accessible across both desktop and mobile views.

- **Bug Fixes**
  - Improved error handling and user feedback with toast notifications when team creation fails.

- **Refactor**
  - Updated team deletion to use real permission checks and improved the user interface for deleting teams.
  - Added comprehensive handling of authorization and error messages for team creation and deletion operations.
  - Redirected users to the account page when no teams are available.

- **Documentation**
  - Marked the default team retrieval function as deprecated in the documentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing team management functionalities within the application. It introduces the ability to create and delete teams, updates various UI components to accommodate these changes, and ensures proper redirection and error handling during team operations.

### Detailed summary
- Added `createTeam` function in `createTeam.ts` for team creation.
- Introduced `deleteTeam` function in `deleteTeam.ts` for team deletion.
- Updated UI components to include `createTeam` functionality.
- Modified `TeamHeaderLoggedIn`, `AccountHeader`, and other components to handle team creation and deletion.
- Implemented redirection upon successful team creation and deletion.
- Updated `DeleteTeamCard` and `TeamGeneralSettingsPageUI` to manage permissions for team deletion.
- Enhanced error handling and user feedback with toast notifications during team operations.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-10 01:44:58 +00:00
jnsdls 56d27d4c63 [Dashboard] Sort usage categories by total amount in descending order (#7314)
# Sort usage categories by total amount

This PR sorts the usage categories displayed on the team usage page by their total amount in descending order. Categories with higher total costs will now appear at the top of the list, making it easier for users to identify their most significant expenses at a glance.

The implementation:
- Creates a `sortedCategories` array by sorting the usage preview data
- Sorts based on the sum of `amountUsdCents` for each category's line items
- Uses the sorted array in the render function instead of the original data

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Enhancements**
  - Usage categories are now displayed in descending order based on their subtotal amounts, making it easier to identify the highest usage categories at a glance.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-09 20:52:46 +00:00
jnsdls e742929b2c [Dashboard] Add notifications system with unread tracking (#7302)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new notifications system with a bell icon button displaying unread indicators.
  - Added a notifications panel with Inbox and Archive tabs supporting infinite scrolling and marking notifications as read.
  - Implemented a centralized notification state manager with optimized fetching, caching, and mutation handling.
  - Added a UI drawer component for mobile notification display with smooth open/close interactions.

- **Refactor**
  - Replaced legacy notification button and fetching logic with the new unified Notifications button using only account ID.
  - Removed legacy notification callbacks and components from header and navigation for simplified notification handling.

- **Chores**
  - Removed deprecated notification files and Storybook stories.
  - Updated dependencies by replacing "idb-keyval" with "vaul" for UI drawer functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on removing the `NotificationButton` component and its related files, replacing it with a new `NotificationsButton` component that integrates notifications more effectively within the application.

### Detailed summary
- Deleted `NotificationButton.tsx`, `fetch-notifications.ts`, and `NotificationButton.stories.tsx`.
- Added `NotificationsButton` component with enhanced functionality for displaying notifications.
- Updated various components (`AccountHeaderUI`, `SecondaryNav`, `TeamHeaderUI`) to use `NotificationsButton`.
- Removed references to `getInboxNotifications` and `markNotificationAsRead` from multiple components.
- Introduced new notification management logic and UI components in `notification-list.tsx` and `notification-entry.tsx`.
- Updated dependencies in `package.json` to include the new `vaul` library for UI elements.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-09 20:09:05 +00:00
MananTank dacfd94af5 Nebula: Improved toasts in move funds page (#7307)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving error handling and user feedback in the `SendFunds` function by utilizing `toast.promise` for asynchronous operations, enhancing the user experience during token transfers.

### Detailed summary
- Replaced `toast.loading`, `toast.success`, and `toast.error` with `toast.promise` for batch and single token transfers.
- Improved error handling by catching errors without logging them.
- Simplified success and error messages in the toast notifications.
- Removed duration settings for toast notifications.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Toast notifications for sending funds are now streamlined using unified loading, success, and error messages, providing clearer and more consistent feedback during transactions. Error messages are also improved for better clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-09 15:24:28 +00:00
catalyst17 2d15cd6a47 docs: update webhook parameter filtering types and add example (#7295)
# [Portal] Fix: Update webhook parameter filtering documentation

## Notes for the reviewer

This PR updates the webhook filtering documentation to:
1. Correct the type definition for `params` in both events and transactions filters
2. Add a practical example showing how to filter for `Transfer` events with specific parameters

## How to test

Review the updated documentation to ensure the type definitions are correct and the new example is clear and helpful.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `params` property in the webhooks filtering configuration to allow for stricter type definitions, changing it from `Record<string, any>` to `Record<string, string | number>`. It also provides an example of how to filter `Transfer` events.

### Detailed summary
- Changed `params` type in the `webhooks` filtering from `Record<string, any>` to `Record<string, string | number>`.
- Updated `params` type in the `signatures` object from `string[]` to `Record<string, string | number>`.
- Added an example for filtering `Transfer` events with a specific `from` address.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-09 12:00:22 +00:00
catalyst17 62a3cd8348 fix: make contract and to addresses optional in webhook form (#7294)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the handling of contract addresses in the `CreateWebhookModal` and `FilterDetailsStep` components, as well as refining validation logic for addresses in `webhookTypes.ts`. It enhances user experience by clarifying requirements and allowing optional inputs.

### Detailed summary
- In `CreateWebhookModal.tsx`, the `addresses` property now defaults to an empty string if not provided.
- In `FilterDetailsStep.tsx`, the `FormLabel` for "Contract Addresses" and "To Address" no longer includes a required indicator.
- Validation in `webhookTypes.ts` for `addresses`, `fromAddresses`, and `toAddresses` is updated to allow empty inputs and provide clearer error messages.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
	- Removed the required field indicator from "Contract Addresses" and "To Address" labels in the form UI.

- **New Features**
	- Updated form validation to allow "Contract Addresses", "From Address", and "To Address" fields to be optional and accept empty values, with improved error messages for clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-09 12:00:22 +00:00
Phillip HoandGitHub 2a4195b4ad chore: pass authToken to analytics query (#7306) 2025-06-09 17:51:38 +08:00
Phillip HoandGitHub 6378f371c5 chore: pass allowImpersonation flag to /v2/keys/use (#7303) 2025-06-08 17:59:00 +08:00
Jonas DanielsandGitHub b3e42f7407 [Dashboard] Add audit log feature for Scale plan teams (#7300) 2025-06-07 00:37:21 -07:00
MananTank 044f897763 Nebula: Add Move funds page (#7298)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the user experience in the `Nebula` application by adding new features, improving existing components, and ensuring better handling of user authentication and fund transfers.

### Detailed summary
- Updated redirect logic in `middleware.ts` to preserve search params and prevent redirect from certain paths.
- Added `placeholder` prop to `DecimalInput` in `decimal-input.tsx`.
- Integrated `TWAutoConnect` component in `ChatPageLayout.tsx`.
- Enhanced `TransactionButton` in `TransactionButton.tsx` to manage a new `disableNoFundsPopup` prop.
- Refactored `NebulaProviders` to remove redundant `TWAutoConnect` usage.
- Created a new `RecoverPage` component in `move-funds/page.tsx` for fund recovery.
- Introduced `MoveFundsConnectButton` for connecting wallets in `connect-button.tsx`.
- Implemented a new `MoveFundsPage` for managing fund transfers.
- Updated `MismatchButton` to handle the new `disableNoFundsPopup` prop.
- Enhanced token management and user feedback within the `MoveFundsPage`.
- Added new components and functions for improved token selection and balance rendering.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a Move Funds page for transferring cryptocurrency between wallets, featuring wallet connection, chain and token selection, and transaction handling.
	- Added a customizable connect button supporting multiple authentication methods and theme adaptation.
	- Added the ability to display placeholder text in decimal input fields.
	- Enhanced button components with an option to disable the "Not Enough Funds" popup.
	- Added a dedicated page layout combining header, theme toggle, support link, and Move Funds functionality.
	- Integrated automatic wallet connection within the chat page layout for seamless user experience.

- **Bug Fixes**
	- Updated middleware to allow unauthenticated access to the Move Funds page without redirecting to the login page.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-07 00:45:33 +00:00
jnsdls 7fa5be5317 [Dashboard] Add staff mode for viewing teams without membership (#7299)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a "STAFF MODE" warning banner for users viewing a team they do not belong to, with a button to leave staff mode.
- **User Interface**
  - Adjusted the team header layout for improved accessibility, ensuring the team badge is no longer nested inside the team link.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on updating the `TeamHeaderUI` component and enhancing the `TeamLayout` and `ProjectLayout` components to incorporate a "Staff Mode" feature, which restricts user actions based on team membership.

### Detailed summary
- Modified the structure of the `TeamHeaderUI` component to wrap the `Link` inside a `span`.
- Added a "Staff Mode" warning message in `TeamLayout` if the user is not part of the team.
- Implemented the same "Staff Mode" warning in `ProjectLayout`.
- Updated API calls to include `getTeamBySlug` and `getProject`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-06 21:42:16 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2510c4f0c1 Version Packages (#7297)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-06 12:43:05 -05:00
gregandGitHub 69bf925c01 [SDK] Feature: preferred chan id pay embed (#7296) 2025-06-06 11:54:06 -05:00
Yash094 d4aed43b18 feat: add SIWA feedback functionality to dashboard chat (#7272)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the `CustomChatContent` and `CustomChats` components to improve type safety and functionality in handling user messages and feedback. It introduces new types and methods for managing chat messages and feedback submission.

### Detailed summary
- Replaced `NebulaUserMessage` with `UserMessage` and `CustomChatMessage`.
- Added `handleFeedback` function for submitting feedback on messages.
- Updated `CustomChats` component to handle new message types and feedback.
- Modified `sendMessage` logic in `ChatBar` to use the new message structure.
- Introduced `RenderMessage` and `StyledMarkdownRenderer` for rendering chat messages.
- Added feedback buttons for assistant messages in `RenderMessage`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new chat interface supporting multiple message types with distinct visual styles.
  - Enabled users to submit feedback (thumbs up/down) on assistant messages.
  - Enhanced chat experience with auto-scrolling that respects user interactions.

- **Bug Fixes**
  - Prevented duplicate feedback submissions on assistant messages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-06 16:24:33 +00:00
Jonas DanielsandGitHub f89c15c517 [Dashboard] Add detailed usage breakdown and billing preview (#7290) 2025-06-06 00:11:11 -07:00
MananTank c95c0dc5bd Nebula: Fix AutoConnect not using nebula client in root layout (#7291)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `TWAutoConnect` component to accept a `client` prop, allowing for better integration with different third-party clients in the application.

### Detailed summary
- Updated `TWAutoConnect` in `layout.tsx` to accept a `client` prop.
- Introduced `thirdwebClient` in `providers.tsx` to provide the client to `TWAutoConnect`.
- Modified `TWAutoConnect` component to require a `client` prop.
- Updated usage of `TWAutoConnect` in `nebula-app/providers.tsx` to pass in `nebulaAppThirdwebClient`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Improved integration of client context within the auto-connect wallet feature, enhancing authentication and connectivity for users.

- **Refactor**
  - Updated internal handling of client instances for wallet auto-connect components to streamline authentication processes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-06 00:45:26 +00:00
GiselleNessi c77b4d8f85 updated old support links to portal (#7286)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `SupportPage` component in the `page.tsx` file by adding new features, modifying existing sections, and improving the overall structure and content of the help products.

### Detailed summary
- Added new icons: `HomeIcon`, `WalletIcon`, `EngineIcon`, `InsightIcon`, `PayIcon`, and `NebulaIcon`.
- Introduced a new help product: "Playground".
- Replaced "Connect" product icon and updated its description.
- Changed "Contracts" to "Universal Bridge" with a new icon and description.
- Updated "Engine" product with a new icon and description.
- Replaced "Account" with "Insight" and updated its details.
- Replaced "Misc" with "Nebula" and updated its details.
- Changed section title from "Knowledge base" to "Learning Resources".
- Modified product icon rendering from image to component usage.
- Updated button text from "View All" to "View".

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced new products "Playground" and "Nebula" to the support page.
- **Improvements**
  - Updated product categories, icons, and descriptions for a clearer overview.
  - Replaced static images with modern icon components for improved visual consistency.
  - Changed page heading to "Learning Resources."
  - Simplified layout by replacing help article lists with concise product descriptions.
  - Shortened the "View All" button text to "View."
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-05 21:13:38 +00:00
PaoloRollo 5c4c49b90a [Dashboard] Fix: Handle ping event (#7287)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

This PR adds a simple `ping` case in the `promptNebula` function to avoid `console.warn` logs in the browser console.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR adds support for a new event type, `"ping"`, in the `ChatStreamedEvent` type definition and handles the `"ping"` event case in the event processing logic.

### Detailed summary
- Added a new case for `"ping"` in the event handling switch statement.
- Introduced a new type definition for the `"ping"` event in the `ChatStreamedEvent` type, including a `data` field of type `string`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Improved chat event handling with support for a new "ping" event type, enhancing the stability of real-time chat updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-05 18:55:15 +00:00
MananTank a5cd66439c [TOOL-4687] Dashboard: Show Special Price UI in claim tokens card (#7284)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the `RecentTransfers` and `ClaimTokenCardUI` components in a React application by refining state management, simplifying logic, and enhancing UI elements.

### Detailed summary
- Removed `hasFetchedOnce` state in `RecentTransfers`.
- Changed condition for disabling the button in `RecentTransfersUI`.
- Simplified logic for claim parameters in `ClaimTokenCardUI`.
- Introduced `TokenPrice` component to handle price display.
- Added tooltip for special pricing indication.
- Adjusted UI elements for better clarity and organization.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-05 18:44:04 +00:00
MananTank 05f65ec150 [TOOL-4686] Dashboard: Add supply remaining progress in asset page claim tokens card (#7283)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `ClaimTokenCardUI` component by adding a new `SupplyRemaining` feature, which displays the supply of tokens claimed and remaining. It also improves the UI with a progress bar and formatting adjustments.

### Detailed summary
- Added `Progress` component for visual representation of supply sold.
- Introduced `SupplyRemaining` function to show claimed and remaining supply.
- Formatted supply numbers using `compactNumberFormatter`.
- Updated headings and styling for better UI consistency.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a visual display showing claimed versus total claimable token supply, including a progress bar and percentage sold.
- **Style**
  - Improved typography and spacing for headings and token symbol labels for better visual consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-05 18:44:04 +00:00
gregandGitHub 6610633799 [Dashboard] Fix: Async team analytics rendering (#7289) 2025-06-05 12:19:36 -05:00
MananTank 7ab79dc3bb Dashboard: Fix contract deploy page missing last used teamId in client object (#7285)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the authentication mechanism by replacing the usage of `getAuthToken` with `getUserThirdwebClient` in the `page.tsx` and `uri-based-deploy.tsx` files, enhancing the handling of third-party client connections.

### Detailed summary
- Removed `getAuthToken` and its associated logic in `page.tsx`.
- Introduced `getUserThirdwebClient` to fetch the client in `page.tsx`.
- Updated the `isLoggedIn` prop in `PublishedContract` to use `!!account`.
- Adjusted the logic in `uri-based-deploy.tsx` to fetch client and teams without `authToken`.
- Changed the `isLoggedIn` prop to always be `true` in `uri-based-deploy.tsx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Streamlined the process for obtaining the user client, simplifying authentication and client initialization for published contract and deploy flows.
  - Improved logic for login checks and client handling, reducing redundant token fetching and making the login state determination more straightforward.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-05 14:07:42 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2b39669e46 Version Packages (#7277)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-05 05:30:01 -07:00
ArseniiandGitHub e3e3142f7e fix: handle short storage values in beacon proxy pattern (#7282) 2025-06-05 05:21:22 -07:00
ArseniiandGitHub 7c0b80d132 fix: handle short proxyStorage in getBeaconFromStorageSlot (#7281) 2025-06-05 04:45:21 -07:00
Joaquim VergesandGitHub 5c1db8bf27 [Dashboard] Add Sophon testnet to custom claim amounts (#7280) 2025-06-05 04:26:01 -07:00
Phillip HoandGitHub a87446a9e6 fix: invalid handling of ISO time in RPC graphs (#7279) 2025-06-05 17:01:04 +08:00
saminacodes 9493fda7bf [Docs] webhook and ub docs (#7278)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the user experience for webhooks in the thirdweb platform by updating sidebar navigation, adding troubleshooting information, and improving documentation on configuring webhooks.

### Detailed summary
- Updated sidebar in `insight` to rename "Getting Started" to "Get Started".
- Added "Troubleshoot" section with `WrenchIcon` in `pay` sidebar.
- Introduced troubleshooting content in `troubleshoot/page.mdx`.
- Enhanced `webhooks/page.mdx` with new structure and images for configuration steps.
- Revised descriptions and added a "Get started" section in `webhooks/page.mdx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added a "Troubleshoot" section in the sidebar for Universal Bridge, providing guidance for resolving payment card issues.
  - Introduced a troubleshooting article explaining card support errors and suggesting alternative payment methods.

- **Documentation**
  - Enhanced the Insight Webhooks documentation with step-by-step setup instructions, visual aids, and improved metadata description.
  - Added a new "Get started" section to guide users through webhook creation and testing.

- **Style**
  - Renamed the "Getting Started" sidebar link under Webhooks to "Get Started" for consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-04 23:39:32 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
59dbae0c21 chore(deps): bump biomejs/setup-biome from 2.5.0 to 2.5.1 (#7250)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-04 16:00:50 -07:00
Jonas DanielsandGitHub 42236d43a8 [service-utils] Remove starter_legacy plan type (#7276) 2025-06-04 16:00:32 -07:00
jnsdls a920d1ee07 [Dashboard] Restrict billing actions to team owners only (#7274)
# Improve Billing UI for Non-Owner Team Members

This PR enhances the billing UI to properly handle permissions for team members who aren't owners. It:

- Restricts billing actions to team owners only
- Adds tooltips explaining why certain actions are disabled
- Properly disables buttons for non-owner team members
- Improves the Button component to handle disabled state for non-button elements

## Key Changes:

- Added `isOwnerAccount` flag to billing components to conditionally render or disable actions
- Enhanced Button component to properly handle disabled state for non-button elements (like anchor tags)
- Added tooltips to explain why actions are disabled for non-owners
- Restricted the following actions to team owners only:
  - Selecting/changing plans
  - Managing billing
  - Topping up credits
  - Paying invoices

These changes ensure a better UX for team members who don't have billing permissions while maintaining full functionality for team owners.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Added owner-only restrictions for billing and payment actions. Only team owners can change plans, manage billing, top up credits, or pay invoices. Non-owner users now see disabled buttons with tooltips explaining these restrictions.
- **Accessibility**
	- Improved accessibility for disabled buttons by adding appropriate ARIA attributes and visual indicators.
- **User Interface**
	- Updated tooltips and button states to clearly communicate permission-based access to billing features.
	- Enhanced button behavior to consistently reflect disabled states across different elements and contexts.
- **Bug Fixes**
	- Standardized disabled state handling for buttons and interactive elements, ensuring consistent visual and functional behavior.
- **Chores**
	- Replaced internal navigation links with standard anchor elements for external billing-related links, improving security with added link attributes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing user experience by adding an `isOwnerAccount` boolean prop to various components. This prop controls the visibility and functionality of certain actions, ensuring that only team owners can perform specific tasks.

### Detailed summary
- Changed `<Link>` to `<a>` in `billing.tsx` for proper link behavior.
- Added `isOwnerAccount` prop to multiple components and updated their functionality based on ownership status.
- Introduced `ToolTipLabel` to provide contextual information for actions restricted to team owners.
- Updated button states to reflect whether actions are enabled or disabled based on `isOwnerAccount`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-06-04 14:02:54 -07:00
MananTank 2329a22bf1 Dashboard: Poll for active claim condition before continuing with minting in coin launch (#7273)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a polling mechanism to ensure that claim conditions are set before proceeding with token minting in the `CreateTokenAssetPage` component.

### Detailed summary
- Added import for `pollWithTimeout` utility.
- Implemented polling logic to check for active claim conditions before minting.
- Set a timeout of 30 seconds for the polling process.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Improved the token creation process by ensuring minting only begins after claim conditions are confirmed, providing a more reliable experience for users.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-04 20:14:51 +00:00
Jonas DanielsandGitHub b25d2afa8b [Dashboard] Fix peak rate date formatting with error handling (#7271) 2025-06-04 02:19:36 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8910f55ca2 Version Packages (#7245)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-04 00:31:34 -07:00
Joaquim VergesandGitHub b237318b7d [SDK] Support EIP7702 execution for ecosystem wallets (#7268) 2025-06-04 00:09:00 -07:00
Jonas DanielsandGitHub 082d9630f4 [Dashboard] Add crypto payment option for invoices (#7270) 2025-06-04 00:03:15 -07:00
Jonas DanielsandGitHub d4bc8e199d [Dashboard] Fix Stripe balance calculation in getStripeBalance function (#7269) 2025-06-03 22:45:25 -07:00
Jonas DanielsandGitHub 4edf1ebe95 [Dashboard] Add crypto top-up functionality for account credits (#7239) 2025-06-03 22:07:33 -07:00
MananTank b12725b231 [TOOL-4673] Dashboard: Enable posthog session recording for nebula app (#7267)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `PHProvider` component by introducing a `disable_session_recording` prop, allowing for more control over session recording. Additionally, it renames the `Providers` component to `PayProviders` and `BridgeProviders` in their respective files for clarity.

### Detailed summary
- Added `disable_session_recording` prop to `<PHProvider>` in multiple files.
- Renamed `Providers` to `PayProviders` in `Providers.client.tsx` and `pay/layout.tsx`.
- Renamed `Providers` to `BridgeProviders` in `Providers.client.tsx` and `bridge/layout.tsx`.
- Updated the `PHProvider` function signature to accept `disable_session_recording` as a prop.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
	- Added explicit controls to enable or disable session recording across different sections of the dashboard.
- **Refactor**
	- Renamed provider components for improved clarity in the Bridge and Pay sections.
	- Updated component usage to reflect new provider names.
- **Style**
	- No visual changes introduced.
- **Bug Fixes**
	- None.
- **Documentation**
	- None.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-04 04:13:00 +00:00
MananTank 3d1c321bd6 [TOOL-4642] Fix useTxNotifications errors not shown in project contract pages (#7259)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on adding an `ErrorProvider` wrapper around the layout of the `ContractLayout` component to handle errors more effectively.

### Detailed summary
- Added import for `ErrorProvider`.
- Wrapped the main layout in an `ErrorProvider`.
- Removed the previous layout structure while integrating the `ErrorProvider`.
- Maintained the structure of `TeamHeaderLoggedIn`, `SharedContractLayout`, `SaveLastUsedProject`, and `AppFooter` within the new error handling context.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Improved error handling on the contract page with the addition of enhanced error context support.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-03 22:50:54 +00:00
MananTank 810ec6efa7 [TOOL-4651] Dashboard: Show error on invalid token distribution in ERC20 asset creation form (#7260)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `TokenDistributionFieldset` component by adding error handling for token distribution and improving the UI by displaying error messages. It also updates the `StepCard` and `DistributionBarChart` components to accommodate new features.

### Detailed summary
- Added `disabled` prop to `StepCard`.
- Integrated error handling in `TokenDistributionFieldset` for distribution validation.
- Displayed error messages when distribution exceeds supply.
- Improved `DistributionBarChart` to conditionally style text based on segment percentages.
- Introduced `getDistributionError` and `SafeNumber` utility functions for validation logic.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added validation to ensure token distribution does not exceed total supply, with error messages displayed when limits are surpassed.
  - The "Next" submit button in the token creation flow can now be disabled based on validation errors.

- **Bug Fixes**
  - Owner percentage in the distribution chart is now prevented from displaying negative values.

- **Style**
  - Segment labels in the distribution chart legend are visually highlighted if their percentage is outside the 0–100% range.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-03 22:41:55 +00:00
MananTank 1c6ed9bd0d [TOOL-4667] Dashboard: Various improvements in ERC20 asset creation flow (#7264)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on renaming references from "Token" to "Coin" throughout the codebase, along with some improvements in error handling and component structure.

### Detailed summary
- Renamed "Token" to "Coin" in various components and UI elements.
- Updated the `parseError` function to be exported.
- Introduced `ContractTypeCellUI` for better contract type rendering.
- Modified multi-step status handling to include more structured error messages.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Enhanced multi-step status tracking with structured error messages and improved error display in step-based processes.

- **Improvements**
	- Updated all user-facing terminology from "Token" to "Coin" across creation, distribution, and sale interfaces.
	- Distribution and allocation charts now reflect "Coin" terminology and dynamically display the coin symbol when available.
	- Improved contract table to show "Coin" for relevant contract types.
	- Refined event tracking to trigger only when relevant actions occur.

- **Bug Fixes**
	- Error messages in step-based processes are now displayed more clearly with detailed information.

- **Refactor**
	- Streamlined contract type badge rendering for consistency and maintainability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-03 22:33:11 +00:00
MananTank 82035fd0b7 [TOOL-4670] Dashboard: Update Managed Engine CTA, UI tweaks (#7266)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new `bottomLineClassName` prop to the `TabLinks` and `TabPathLinks` components, enhancing customization options for styling. It also simplifies the UI in the `EmptyEngineState` component and updates the layout for better structure and readability.

### Detailed summary
- Added `bottomLineClassName` prop to `TabLinks` and `TabPathLinks`.
- Updated `TabLinks` to use `bottomLineClassName` for styling.
- Simplified `EmptyEngineState` content and button structure.
- Refactored layout in `Layout` component for improved organization.
- Adjusted `EngineLegacyBannerUI` for better spacing and button layout.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Updated navigation layout for the engine section with new tabbed navigation and improved header structure.
  - Adjusted container layouts for more consistent spacing and alignment.

- **Style**
  - Restyled the legacy banner, including button order, alignment, and icon adjustments for a clearer appearance.
  - Enhanced tab navigation with customizable bottom line styling for better visual integration.

- **Bug Fixes**
  - Unified the messaging and actions for adding a managed engine instance, removing plan-based differences for a more consistent user experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-03 22:21:32 +00:00
gregandGitHub 8b324597fb Feature: Update UB Docs for latest SDK and Guides (#7265) 2025-06-03 15:53:14 -05:00
FirekeeperandGitHub 5ebb7549ca [SDK] Force legacy for Plume 98866 (#7263) 2025-06-03 12:14:33 -07:00
MananTank dfe4cf0928 [TOOL-4645] Dashboard: Improve Project overview page loading performance (#7261)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on improving the loading state of various chart components in the dashboard by enhancing the `LoadingChartState` component with additional styling and refactoring the code to utilize asynchronous components for better performance and user experience.

### Detailed summary
- Updated `LoadingChartState` to accept a `className` prop for custom styling.
- Modified `Suspense` components in `Transactions`, `RpcMethodBarChartCard`, and `EngineCloudChartCard` to use improved `LoadingChartState`.
- Introduced new async components: `AsyncTotalSponsoredCard`, `AsyncAuthMethodDistributionCard`, and `AsyncAppHighlightsCard`.
- Refactored fetching logic for analytics data to use async/await pattern, improving readability and maintainability.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Improved loading placeholders across analytics cards by simplifying their appearance and updating styling for a more consistent look.
  - Modularized data fetching for analytics cards, allowing each card to load and handle errors independently for a smoother user experience.

- **New Features**
  - Loading states for analytics cards now display updated visual styles with borders and adjusted heights.

- **Style**
  - Unified and customizable loading chart styles for better visual consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-03 16:31:36 +00:00
Joaquim VergesandGitHub 6cce31d828 [Dashboard] Add support for Sophon mainnet (#7258) 2025-06-03 01:59:10 -07:00
Joaquim VergesandGitHub aaad876a6f [Docs] Add Bundler API reference documentation (#7257) 2025-06-03 01:31:16 -07:00
gregandGitHub de297e4c97 [SDK] Feature: Track insufficient funds error across SDK (#7256) 2025-06-02 17:16:29 -05:00
pinkhoodie 2114e5f91f Add text input option to airdrop setup (#7238)
- Add manual text input alternative to CSV upload for airdrop addresses

- Support multiple input formats: space, comma, equals, and tab separated

- Parse text input and convert to CSV format for existing validation system

- Reuse all existing functionality: ENS resolution, address validation, duplicate removal

- Maintain same validation flow and error handling as CSV upload

- Change button text from 'Upload CSV' to 'Set up Airdrop' for clarity

![image](https://github.com/user-attachments/assets/e43afdd8-eed8-491a-ac93-9f02eb6ee703)
![image](https://github.com/user-attachments/assets/42522fa1-3886-4d68-a113-079d58b3da96)

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the CSV upload functionality in the `TokenAirdropSection` component. It introduces a new method for processing CSV data, allows manual entry of addresses and amounts, and updates UI labels to reflect the new functionality.

### Detailed summary
- Added `processData` function in `useCsvUpload` for processing parsed CSV data.
- Updated `TokenAirdropSection` UI labels from "CSV File Uploaded" to "Airdrop List Set".
- Changed button text from "View CSV" to "View List".
- Introduced `parseTextInput` function for manual input parsing.
- Added text input for entering addresses and amounts.
- Implemented handling for text input submission.
- Updated the layout to separate CSV upload and manual entry sections.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added the ability to manually enter airdrop addresses and amounts using a text area, supporting multiple input formats.
  - Users can now choose between uploading a CSV file or entering addresses and amounts directly.

- **UI Updates**
  - Updated labels and button texts to reflect support for both CSV and manual list input.
  - Improved layout with a visual divider and clear instructions for manual entry.
  - Enhanced reset and validation behaviors for both input methods.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-02 20:57:20 +00:00
Phillip HoandGitHub ca0841745a fix: docs formatting for verified domains page (#7248) 2025-06-02 17:08:03 +08:00
Phillip HoandGitHub d150ea1c91 docs: Add page on domain verification (#7247) 2025-06-02 16:33:17 +08:00
saminacodes f1479b85f0 [Docs] Improvements to acct, ec, and vault docs (#7246)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating various documentation and component links within the `thirdweb` portal, as well as enhancing the content of FAQs and guides to provide clearer information on account management, migration to the TypeScript SDK v5, and Engine Cloud features.

### Detailed summary
- Added `Account` link to `supportLinks` in `Header.tsx`.
- Included warning about deprecation of TypeScript SDK v4 in `page.mdx`.
- Added troubleshooting details for transactions in `Engine Troubleshoot Guide`.
- Updated FAQ on customized plans in `faq/page.mdx`.
- Introduced ownership transfer steps in `manage-team/page.mdx`.
- Removed outdated Nebula access details in `faqs/page.mdx`.
- Added details about server wallet keys and admin key usage in `vault/faqs/page.mdx`.
- Updated pricing explanation and added a new chains support detail in `Engine Cloud` FAQ.
- Introduced a new section on `Smart Server Wallets`, detailing benefits and security in `server-wallets/page.mdx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new documentation page for Smart Server Wallets, outlining features, security, and pricing.
  - Added new FAQ entries to the Vault documentation regarding key requirements for server wallets and admin key handling.
  - Added a new FAQ entry detailing supported chains for Engine Cloud.

- **Improvements**
  - Updated navigation links in the header, moving "Account" to support links and adding a "Status" link.
  - Enhanced troubleshooting guidance for Engine Cloud transactions.
  - Updated Engine Cloud pricing FAQ to reference the pricing page.
  - Added a warning callout about TypeScript SDK v4 deprecation to the migration guide.
  - Expanded billing documentation with a new section on transferring team ownership.
  - Clarified the FAQ about signing up for customized or enterprise plans.

- **Removals**
  - Removed outdated Nebula FAQ entries related to access approval and pricing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-02 02:24:09 +00:00
Joaquim VergesandGitHub 283dc289fc [SDK] Include native tokens in Insight.getOwnedTokens (#7243) 2025-06-01 01:31:23 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8abf3cc777 Version Packages (#7231)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-31 03:55:10 -07:00
Joaquim VergesandGitHub f10fbc8383 [SDK] Optimize fiat conversion query (#7242) 2025-05-31 03:14:45 -07:00
Joaquim VergesandGitHub 38627d352b [SDK] Handle smart account detection for inApp and ecosystem wallets (#7241) 2025-05-31 02:39:26 -07:00
Joaquim VergesandGitHub ad8cc9a1d2 [SDK] Add Bridge.tokens() function to retrieve supported tokens (#7240) 2025-05-31 02:29:12 -07:00
Manan TankandGitHub 4e935392fa SDK: Fallback to insight response if RPC request fails in getNFTs extensions (#7234) 2025-05-30 23:54:24 -07:00
MananTank f44d6ba282 [TOOL-4648] Dashboard: Fix timestamp in sponsored transactions table (#7236)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the rendering logic of the `SponsoredTransactionsTableUI` component to improve clarity and functionality, particularly around handling timestamps and the rendering of table rows.

### Detailed summary
- Changed the way `transaction.timestamp` is handled to ensure it always ends with "Z".
- Simplified the mapping of `props.sponsoredTransactions` to use a block body for clarity.
- Added `client` prop to `ProjectCell`.
- Enhanced readability of the table structure by removing unnecessary code.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
	- Improved accuracy of transaction timestamps by ensuring all are treated as UTC.
	- Enhanced consistency in date and time display for sponsored transactions.

- **New Features**
	- Added support for passing client information to project, chain, and wallet address displays in the transactions table.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 23:41:53 +00:00
MananTank 3678054931 Dashboard: Fix TS errors (#7235)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `clientId` prop being passed to the `PayEmbedFTUX` component in the `PayAnalytics.tsx` file.

### Detailed summary
- Changed the `clientId` prop from `props.clientId` to `props.projectClientId` in the return statement of the `PayEmbedFTUX` component when both `hasVolume` and `hasWallet` are false.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
  - Corrected an issue where the wrong client ID was passed to the PayEmbedFTUX component, ensuring accurate display and functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 21:25:13 +00:00
gregandGitHub 196cb54ae9 [Dashboard] Feature: Adds PostHog tracking to bridge page (#7232) 2025-05-30 13:23:12 -07:00
gregandGitHub ed2d64197d [Dashboard] add empty state for Pay analytics (#7206) 2025-05-30 13:08:28 -07:00
Manan TankandGitHub e141e11ff3 Dashboard import paths cleanup (#7229) 2025-05-30 13:07:39 -07:00
MananTank 6ae54ddd98 Dashboard: Remove useThirdwebClient hook (#7228)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on integrating the `ThirdwebClient` into various components and functions across the application, enhancing the client functionality for better interaction with smart contracts and improving the overall architecture.

### Detailed summary
- Added `client` prop to multiple components for better contract interactions.
- Updated functions to utilize the `contract.client` instead of a generic client.
- Removed redundant imports of `useThirdwebClient`.
- Enhanced several UI components to accept and use the `client` prop.
- Modified API calls to pass the `client` where necessary for fetching data.
- Improved handling of ENS queries by passing the `client` directly.

> The following files were skipped due to too many changes: `apps/dashboard/src/components/contract-components/hooks.ts`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/account-abstraction/factories/page.tsx`, `apps/dashboard/src/components/embedded-wallets/Configure/index.tsx`, `apps/dashboard/src/components/contract-components/contract-publish-form/index.tsx`, `apps/dashboard/src/components/contract-components/contract-deploy-form/custom-contract.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Many components now accept a client instance as a prop, enabling more explicit and flexible client management throughout the dashboard.
- **Refactor**
  - Shifted from internal client initialization to explicit client prop injection across the app, affecting forms, tables, media components, contract publishing, and wallet settings.
  - Updated hooks and utility functions to require a client parameter instead of relying on internal context.
- **Chores**
  - Removed unused files and internal hooks related to client management.
- **Bug Fixes**
  - Improved consistency and reliability when handling authentication and client context in user flows.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 18:51:17 +00:00
gregandGitHub 8245c06b3e [SDK] Fix: Token price cache to use proper address (#7230) 2025-05-30 11:48:33 -07:00
MananTank 1c11f84481 Dashboard: Reduce useThirdwebClient hook usage #4 (#7227)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `TransactionButton` component across various files by adding a `client` prop and other relevant properties to improve transaction handling and user interactions.

### Detailed summary
- Added `client` prop to `TransactionButton` in multiple components for transaction management.
- Included `isLoggedIn`, `txChainID`, and `transactionCount` props where applicable.
- Enhanced user experience by managing loading states and enabling/disabling buttons based on conditions.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - All transaction-related buttons and components now require and receive an explicit client instance, improving reliability and consistency across the dashboard.
- **Refactor**
  - Updated component interfaces to accept a client prop instead of relying on internal hooks.
  - Standardized the way client instances are passed through component hierarchies, including in forms, modals, and tables.
  - Renamed certain props for clarity (e.g., `clientId` to `projectClientId`).
- **Style**
  - No user-facing visual changes.
- **Chores**
  - Improved code maintainability by removing internal hook usage for client access.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 18:35:01 +00:00
MananTank b84db126d7 Dashboard: Reduce useThirdwebClient hook usage #3 (#7226)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on updating the usage of the `client` prop throughout various components in the application, replacing instances of `useThirdwebClient` with a more consistent approach using `getClientThirdwebClient`.

### Detailed summary
- Added `client` prop to multiple components including `AccountPage`, `DeployedContractsPage`, and `FaucetButton`.
- Replaced `useThirdwebClient` with `getClientThirdwebClient` in various files.
- Ensured consistency in passing the `client` prop across components.
- Updated the `ProfileHeader`, `PayModalButton`, and `SendTestTransaction` to accept `client` as a prop.
- Modified forms and sections to utilize the `client` prop for better integration with Thirdweb services.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Updated various components to receive a client instance as a prop instead of obtaining it internally, improving consistency and making client usage more explicit throughout the app.
  - Enhanced component interfaces to require a client prop where necessary, ensuring proper client context is passed across the dashboard.
  - Adjusted authentication and layout flows to support explicit client instantiation and propagation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 18:35:01 +00:00
MananTank a4406214c6 Dashboard: Reduce useThirdwebClient hook usage #2 (#7224)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the functionality of various components by integrating a `client` prop of type `ThirdwebClient` into multiple files. This change improves the interaction with the Thirdweb SDK across the application.

### Detailed summary
- Added `client` prop to components like `IconUpload`, `SolidityInput`, and `CustomConnectWallet`.
- Updated hooks and functions to accept `client` for better SDK integration.
- Modified forms to utilize the `client` for storage uploads and contract deployments.
- Enhanced `AddChainToWallet` and `EcosystemHeader` to support `client`.
- Updated various fieldsets to include `client`, improving data handling and validation.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Components and forms now consistently accept and require a `client` prop, providing improved client context across wallet connection, contract deployment, network configuration, and NFT interactions.

- **Refactor**
  - Updated numerous components and hooks to require explicit passing of the `client` instance, replacing previous internal retrieval methods.
  - Prop types and interfaces were extended to include the new `client` property, ensuring consistent usage throughout the app.

- **Bug Fixes**
  - Addressed missing `client` props in several components to prevent potential issues with client-dependent functionality.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 18:35:01 +00:00
MananTank 02627631b6 Dashboard: Reduce useThirdwebClient hook usage (#7223)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on adding a `client` prop to various components across the dashboard application, enhancing their functionality and ensuring consistent access to the `ThirdwebClient`.

### Detailed summary
- Added `client` prop to `BatchMetadata`, `Royalty`, `Mintable`, `Transferable`, `Claimable`, and other components.
- Updated `WalletAddress` component to accept `client` prop in multiple instances.
- Enhanced various tables and UI components to utilize the `client` prop for improved data handling.
- Refactored existing components to ensure compatibility with the new `client` prop, ensuring consistent client access throughout the application.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Enhanced all WalletAddress displays across the dashboard to accept and utilize a new client context for improved integration and consistency.
- **Refactor**
  - Updated multiple components and their props to require and pass a client instance, ensuring unified client handling throughout tables, modals, and analytics views.
  - Replaced static table column definitions with dynamic, memoized columns that respond to client changes.
  - Standardized prop names related to client identification for clarity and maintainability.
- **Bug Fixes**
  - Ensured client context is consistently propagated to all relevant child components, preventing potential rendering or data issues.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 18:35:00 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
913b243147 Version Packages (#7217)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-30 10:16:10 -07:00
gregGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
3edbe2898c [Dashboard] Fix: Purchase Data (#7225)
Signed-off-by: greg <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-05-30 09:45:34 -07:00
pinkhoodie 926dad4556 Update ChatBar.tsx to allow for copy/paste and drag/drop file uploads (#7153)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `ChatBar` component by adding image upload validation, drag-and-drop functionality, and user feedback through toast notifications. It improves user experience by ensuring only valid images are uploaded and prompts users to sign in if they attempt to upload without permission.

### Detailed summary
- Added `showSigninToUploadImagesToast` function for user notifications.
- Introduced `isDragOver` state for drag-and-drop feedback.
- Updated `handleImageUpload` to validate file types and sizes.
- Implemented drag-and-drop event handlers for image uploads.
- Added clipboard paste support for image uploads.
- Modified `ImageUploadButton` to use validated files directly.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for image uploads via drag-and-drop and clipboard paste in the chat bar.
  - Enhanced visual feedback during drag-and-drop image uploads.
  - Added prompts for users to sign in when attempting image uploads without authorization.

- **Bug Fixes**
  - Improved validation for image uploads, including file size and total image count limits.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 13:46:07 +00:00
Yash094 0639d0d9ea siwa updates and new article (#7197)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the chat functionality within the application by adding a feedback system, updating icons, and improving the knowledge base content related to ERC20 token transfers.

### Detailed summary
- Added a new knowledge base entry for "Transfer Amount Exceeds Allowance".
- Updated `Header` and `Hero` components to replace `BotIcon` with `MessageCircleIcon`.
- Introduced `sendFeedback` function to handle user feedback on chat messages.
- Modified `Chat` component to include feedback buttons (thumbs up/down) for messages.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced feedback buttons (thumbs up/down) for assistant messages in the AI chat, allowing users to rate responses.
	- Added a new "Ask AI" button on the main page, providing quick access to the chat assistant.
	- Added a new knowledge base article explaining the "ERC20: transfer amount exceeds allowance" error and its resolution.
- **Improvements**
	- Enhanced chat message payloads with source identifiers for better context.
	- Updated sidebar navigation with a new troubleshooting entry for ERC20 transfer allowance issues.
	- Updated chat and header icons to use a consistent message circle icon for AI-related features.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 07:58:58 +00:00
Joaquim VergesandGitHub 4fed9f4593 [SDK] Update token price APIs to query from insight directly (#7220) 2025-05-29 22:48:48 -07:00
arcoraven f2e8b9ecab feat: add Engine Cloud analytics to project overview (#7195)
# [Dashboard] Feature: Add Engine Cloud Analytics Charts

Example screenshot:

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/vKjRiOG6EUjD7XH4cppU/73d7e2b9-23bd-46b5-8cae-5564a3630770.png)

## Notes for the reviewer
This PR adds Engine Cloud analytics to the dashboard, displaying request data in a bar chart visualization. The implementation includes:

1. A new API endpoint to fetch Engine Cloud method usage data
2. New UI components for displaying Engine Cloud analytics:
   - `EngineCloudBarChartCardUI` - Shows Engine Cloud requests by pathname
   - `EngineCloudChartCardUI` - Shows Engine Cloud methods usage with percentage breakdown
3. Integration of the new chart into the project analytics page

## How to test
- View the Storybook component at "Analytics/EngineCloudBarChartCard"
- Navigate to a project dashboard to see the Engine Cloud analytics chart
- Verify data is properly fetched and displayed in the chart

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new feature to track and visualize `EngineCloud` statistics in the dashboard, enhancing analytics capabilities with new components and API integrations.

### Detailed summary
- Added `EngineCloudStats` interface in `analytics.ts`.
- Implemented `getEngineCloudMethodUsage` API function.
- Created `EngineCloudChartCard` component for displaying cloud stats.
- Developed `EngineCloudBarChartCardUI` for rendering bar charts.
- Added storybook entries for `EngineCloudBarChartCardUI`.
- Enhanced existing analytics with new data visualizations.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a stacked bar chart visualization for engine cloud request statistics in the analytics dashboard.
  - Added a chart card displaying engine cloud method usage data with loading state support.
  - Enhanced analytics with time series data for multiple API pathnames.
  - Included engine cloud method usage data in the project analytics view.

- **Chores**
  - Updated `.gitignore` to exclude the `.pnpm-store/` directory from version control.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 01:34:51 +00:00
AmineAfia 523412437b Replace Select with Popover in webhook signature selection UI (#7219)
## [Dashboard] Feature: Replace Select with Popover for Event and Function Signature Selection

## Notes for the reviewer
This PR replaces the Select component with a Popover component for both event and function signature selection in the webhook filter details step. The change improves the user experience by providing a more customizable dropdown interface.

Key changes:
- Replaced Select/SelectContent/SelectItem with Popover/PopoverContent/PopoverTrigger
- Added state hooks to manage popover open states
- Improved styling and layout of signature selection options
- Maintained existing functionality for selecting signatures and updating form values

## How to test
Test the webhook creation flow, specifically when selecting event or function signatures. Verify that:
1. The popover opens and closes correctly
2. Selecting a signature properly updates the form
3. The selected signature displays correctly in the trigger button
4. The signature details (name, hash/selector) are properly displayed

<!-- start pr-codex -->

---

## PR-Codex overview
This PR refactors the `FilterDetailsStep` component to replace the `Select` dropdowns with a new `SignatureDropdown` component, enhancing the UI interaction by using a `Popover` for selecting event and function signatures.

### Detailed summary
- Removed `Select` dropdowns for event and function signatures.
- Introduced `SignatureDropdown` component for better UI/UX.
- Integrated `Popover` for displaying signature options.
- Updated state management for selected signatures and ABIs.
- Added new props for `SignatureDropdown` to handle selection and display.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a new dropdown for selecting event and function signatures, offering a clearer and more interactive selection experience.

- **Style**
  - Updated the signature selection interface to use a popover-based dropdown for improved usability and consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 01:19:05 +00:00
arcoraven ac4ade6262 chore: remove Team from confirmEmail response (#7200)
<!-- start pr-codex -->

## PR-Codex overview
This PR focuses on removing references to `Team` in various components related to email verification and onboarding, simplifying the data structure passed around.

### Detailed summary
- Removed `teamStub` import and related references in `VerifyEmail.stories.tsx`.
- Eliminated `Team` type imports in `useApi.ts`, `VerifyEmail.tsx`, and `account-onboarding-ui.tsx`.
- Updated `onEmailConfirmed` and `verifyEmail` props to only handle `account` in `VerifyEmail.tsx` and `account-onboarding-ui.tsx`.
- Adjusted the `onComplete` prop in `AccountOnboardingProps` to reflect the removal of `team`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Simplified onboarding and email verification flows by removing the requirement for team-related data. All relevant callbacks and functions now operate solely with account information.
- **Type Updates**
  - Updated type signatures for onboarding and verification handlers to exclude the team property, streamlining integration for end-users and developers.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 01:03:44 +00:00
Jonas DanielsandGitHub 819ce86c61 [thirdweb] Update dev script to use nodenext module format (#7218) 2025-05-29 18:02:25 -07:00
Jonas DanielsandGitHub 86fd445276 [service-utils] Add platform, SMS, and pay capabilities to TeamCapabilities type (#7210) 2025-05-29 18:01:54 -07:00
joaquim-verges 55fba51dab [Dashboard] Unhide Engine Cloud service (#7215)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating service descriptions and modifying hidden services in the codebase.

### Detailed summary
- Updated the description of the `insight` service to "Indexed data for any EVM chain."
- Changed the title of the `engineCloud` service from "Server wallets" to "Engine Cloud."
- Updated the description of the `engineCloud` service to "Transaction API and Server wallets with high transaction throughput and low latency."
- Removed `engineCloud` from the `HIDDEN_SERVICES` array.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Chores**
  - Updated service descriptions for improved clarity.
  - Refined metadata for select services.
- **Refactor**
  - Adjusted visibility of certain services in API key settings.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 00:33:15 +00:00
jnsdls 7c95211b98 [Dashboard] update pricing plans and UI components (#7208)
# Update Pricing Plans and UI

This PR updates our pricing plans and UI to better align with our new pricing strategy:

- Replaced "Accelerate" plan with "Pro" plan
- Updated pricing: Starter ($5), Growth ($99), Scale ($499), Pro ($1499)
- Added "Starting at" label for Pro plan
- Updated feature lists across all plans
- Changed pricing card UI to use `DollarSignIcon` instead of `CircleDollarSignIcon`
- Added locale formatting for price display
- Updated team onboarding flow to show Growth, Scale and Pro plans
- Removed Cloud Hosted Engine section from Engine Footer Card
- Removed standalone Pro Card from pricing page

These changes ensure our pricing structure is more intuitive and better reflects the value of each tier.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating billing plans and their associated features in the application. It introduces a new `pro` plan, modifies existing plans, and adjusts the UI components to reflect these changes.

### Detailed summary
- Added `"plan:pro"` to billing plans.
- Updated comments from "accelerate" to "growth" for clarity.
- Replaced `CheckIcon` with `DollarSignIcon` in pricing components.
- Adjusted pricing for `starter` (from $9 to $5) and `growth` (from $79 to $99).
- Renamed `accelerate` plan to `scale` with a new price of $499.
- Introduced `pro` plan priced at $1499 with specific features.
- Adjusted invite permissions to restrict `starter` plan.
- Updated billing plan checks throughout components to include new plan logic.
- Removed deprecated `CloudHostedEngineSection` component.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a new "pro" billing plan with updated pricing, features, and dedicated account executive support.
  - Added "scale" plan as a replacement for the previous "accelerate" plan, featuring expanded infrastructure and support options.

- **Enhancements**
  - Improved pricing display formatting for better readability.
  - Updated plan descriptions and feature lists for clarity and consistency across all plans.
  - Refined plan selection and upgrade prompts to reflect the new plan structure.

- **Bug Fixes**
  - Corrected plan requirement messaging for editing SMS countries to accurately reference the "growth" plan.

- **Removals**
  - Removed the "accelerate" and "starter" plans from UI and plan selection.
  - Eliminated the ProCard component and legacy usage credit mentions.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-30 00:16:27 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
3bb1fe0e1f Version Packages (#7214)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-29 17:02:32 -07:00
MananTank a1aba2989e Dashboard: Various Asset page updates (#7212)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing tracking functionality and improving the UI components for better user feedback during token operations in the dashboard application.

### Detailed summary
- Updated `ProjectSidebarLayout.tsx` to simplify the `label` for the Engine section.
- Refactored date formatting in `RecentTransfers.tsx` for improved readability.
- Enhanced error handling and tracking in `launch-token.tsx`, `create-token-page-impl.tsx`, and `tracking.ts`.
- Improved tracking data structure by consolidating parameters in functions.
- Added success and error tracking in `ClaimTokenCardUI` for better user feedback during transactions.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added a success screen after purchasing tokens, displaying confirmation details and options to view the transaction or buy more.
  - Enhanced analytics tracking for token purchase and deployment flows, capturing more detailed error information and contextual metadata.

- **Bug Fixes**
  - Improved timestamp handling for recent transfers to ensure consistent display of relative times.

- **Style**
  - Updated the sidebar to remove the "New" badge from the "Engine" link.

- **Refactor**
  - Streamlined analytics tracking functions to use structured parameter objects and improved error message handling.

- **Chores**
  - Minor cleanup, including removal of unnecessary console logs.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 23:43:42 +00:00
AmineAfia deeca886a4 Add support for chain filtering in webhook creation (#7209)
## [Dashboard] Feature: Add Chain Filtering for Webhooks

## Notes for the reviewer
This PR adds support for filtering available chains in the webhook creation flow. It fetches supported chains from the Insight API and restricts the chain selection in the UI to only those chains that are supported for webhooks.

## How to test
1. Navigate to the webhooks page for a project
2. Verify that the chain selector in the webhook creation modal only shows supported chains
3. Confirm that the API call to fetch supported chains works correctly

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added support for dynamically fetching and displaying supported blockchain networks when creating or managing webhooks.
  - The network selector now only shows networks that are currently supported for webhooks.
  - Users are notified if no supported blockchain networks are available for webhooks.

- **Bug Fixes**
  - Improved error handling and messaging when no supported blockchain networks are available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `NetworkSelectors` and webhook components by adding support for multiple chain IDs, improving the data handling for webhooks, and integrating the fetching of supported chains from an API.

### Detailed summary
- Added `chainIds` prop to `NetworkSelectors` and filtered `allChains` based on it.
- Updated `CreateWebhookModal` to accept `supportedChainIds`.
- Modified `WebhooksTable` to include `supportedChainIds`.
- Introduced `getSupportedWebhookChains` API call to fetch supported chains.
- Updated `FilterDetailsStep` to utilize `supportedChainIds`.
- Adjusted `WebhooksPage` to manage `supportedChainIds` and handle API responses.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-29 23:32:31 +00:00
Joaquim VergesandGitHub 31c4bb22fc [SDK] Add account deletion support when unlinking profiles (#7211) 2025-05-29 16:31:53 -07:00
MananTank 3b1e16c8b7 [TOOL-4621] New ERC20 public contract page (#7177)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing the dashboard's functionality and user interface by updating environment variable usage, improving component layouts, and refining analytics features. It also introduces new components and modifies existing ones for better data handling and presentation.

### Detailed summary
- Added `NEXT_PUBLIC_DASHBOARD_CLIENT_ID` to `public-envs.ts`.
- Updated `CreateTokenAssetPage` to pass `teamSlug` and `projectSlug`.
- Changed `projectSlug` to use `project.slug` in `marketplace` page.
- Enhanced `EmptyChartState` to accept a `type` prop.
- Updated `getTokenStepTrackingData` to include "deploy" action.
- Introduced `LoadingDots` component for loading states.
- Refactored multiple layout components to include `TeamHeader`.
- Added new public page handling logic in various components.
- Updated analytics functions to utilize the new client ID.
- Improved error handling and response management in analytics API calls.
- Added `DecimalInput` component to replace standard input in `token-sale.tsx`.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.stories.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/Analytics.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/RecentTransfers.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/ContractHeader.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/PriceChart.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added new layout components with team headers for various dashboard sections.
  - Introduced `LoadingDots` component for animated loading indicators.
  - Added `PublicPageConnectButton` and `PageHeader` components for public pages.
  - Implemented public ERC-20 token page with price charts, token stats, recent transfers, and buy token embed.
  - Added token claim card UI with transaction step feedback for purchasing tokens.
  - Added hooks for fetching token price data and token transfers.
  - Added utility to fetch currency metadata for tokens.
  - Added comprehensive contract analytics overview component.
  - Introduced `DecimalInput` component for validated decimal input handling.
  - Added new social media brand icons for Discord and Telegram.

- **Improvements**
  - Enhanced area and bar charts with customizable styles, tooltip formatting, and explicit empty state types.
  - Improved empty chart state visuals with new area chart gradients and replaced spinner with animated dots.
  - Unified environment variable usage for client IDs across API calls and client initializations.
  - Updated contract overview to display call-to-action banner linking to public asset pages for ERC-20 tokens.
  - Enhanced contract table to conditionally show contract address or asset page links based on context.
  - Improved primary dashboard button to link to asset pages when applicable.
  - Added redirects to public landing pages for unsupported contract views lacking project metadata.
  - Wrapped existing layouts with conditional team headers for consistent UI in public/private views.
  - Added pagination and detailed tables for recent token transfers.
  - Updated project slug usage in marketplace listings for accuracy.
  - Introduced dynamic time precision handling in analytics charts and tooltips.
  - Added optional balance check control to transaction and mismatch buttons.
  - Replaced local decimal input component with shared validated decimal input component.
  - Added optional target attribute for call-to-action links in upsell banners.
  - Refined accessibility and sizing of icon components.

- **Bug Fixes**
  - Fixed environment variable naming for client IDs to ensure consistent API integration.

- **Refactor**
  - Standardized header and layout components for a unified dashboard experience.
  - Replaced spinner with animated dots in loading states for smoother UX.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 23:03:08 +00:00
jnsdls 1f42ad2a2d [Dashboard] migrate SelectOption to shadcn (#7194)
Migrated the `SelectOption` component in the dashboard batch upload flow to use shadcn/ui primitives and Tailwind classes.

- Replaced Chakra `Tooltip`, `Flex`, and `Radio` usage with `ToolTipLabel` and Tailwind markup
- Switched to shadcn/ui `Card`
- Removed dependency on Chakra typography components
- Updated component props to extend HTML attributes

Fixes migration step towards removing Chakra.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `SelectOption` component to improve its structure and styling. It replaces the `Tooltip` from `@chakra-ui/react` with a custom `ToolTipLabel`, modifies the layout and styling, and enhances the handling of props.

### Detailed summary
- Changed `SelectOptionProps` to extend `React.HTMLAttributes<HTMLDivElement>`.
- Replaced `Tooltip` with `ToolTipLabel`.
- Updated the card styling and structure.
- Modified the layout for `Radio` to a custom implementation.
- Adjusted class names for better styling consistency.
- Changed the rendering of `name` and `description` to use HTML elements directly.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Updated the selection option component with custom UI elements and Tailwind CSS styling, removing dependencies on Chakra UI and previous component libraries.
  - Improved accessibility and styling for tooltips, cards, and selection indicators.
  - Maintained original functionality and interactions with a refreshed look and feel.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 21:25:21 +00:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
0299034fc1 Version Packages (#7207)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-29 13:30:44 -07:00
Joaquim VergesandGitHub 861e623a1b [SDK] Engine search transactions and batch transaction support (#7190) 2025-05-29 13:19:26 -07:00
MananTank 6a335bfa77 Fix requests to thirdwebstorage-dev.com not set with secret-key (#7205)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `fetch.ts` file in the `thirdweb` package to include a new URL for the thirdweb storage service.

### Detailed summary
- Added `".thirdwebstorage-dev.com"` to the list of URLs.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Chores**
  - Updated the list of recognized thirdweb service domains to include ".thirdwebstorage-dev.com".

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 20:09:50 +00:00
AmineAfia cb994dcb8f Re-enable webhooks sidebar link in project dashboard (#7196)
## [Dashboard] Feature: Add Webhooks to Project Sidebar

## Notes for the reviewer

This PR adds the Webhooks option to the project sidebar navigation. The option was previously commented out due to a scrolling issue, which has now been resolved.

## How to test

Navigate to a project page and verify that the Webhooks option appears in the sidebar with a "New" badge.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on refining the handling of webhook payloads and enhancing the `ProjectSidebarLayout` component by reintroducing the webhooks link. It also updates the API fetch calls to ensure they consistently use HTTPS.

### Detailed summary
- Changed `params` type in `webhookPayloadUtils.ts` from `Record<string, unknown> | unknown[]` to `Record<string, unknown>`.
- Updated `params` in the `buildTransactionWebhookPayload` function to use an empty object instead of an empty array.
- Reintroduced the webhooks link in `ProjectSidebarLayout.tsx` with appropriate properties.
- Updated fetch calls in `webhooks.ts` to use HTTPS for the API domain in multiple functions (`getWebhooks`, `deleteWebhook`, `testWebhook`).

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Re-enabled the "Webhooks" link in the project sidebar, now visible with a "New" badge.

- **Bug Fixes**
  - Improved API reliability by ensuring all webhook-related network requests use the correct HTTPS scheme.

- **Refactor**
  - Updated internal data structures for webhook payloads to improve consistency and type safety.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 19:30:57 +00:00
Joaquim VergesandGitHub 4d38a7e8fe Update page.mdx (#7204)
Signed-off-by: Joaquim Verges <[email protected]>
2025-05-29 11:32:36 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
89e6af6baf Version Packages (#7164)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-29 11:10:34 -07:00
catalyst17 b345cc115e docs: add docs on aggregates (#7201)
# [Portal] Feature: Add Aggregation Examples and Documentation to Insight

## Notes for the reviewer

This PR adds comprehensive documentation for the Insight aggregation functionality across multiple pages:

- Added an "Aggregation Examples" section to the LLMs page with code samples
- Added detailed aggregation documentation to the Agents and LLMs page
- Added aggregation examples to the Blueprints page for Events, Transactions, Wallet Transactions, and Blocks
- Added FAQs about aggregation queries
- Added "Using Aggregation Presets" section to the Get Started page
- Enhanced Use Cases page with example aggregations for relevant scenarios

## How to test

Review the documentation for clarity and accuracy. The examples should be consistent with the actual API functionality.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Documentation**
  - Added comprehensive examples and explanations for using aggregation functions in Insight API queries across multiple documentation sections, including blueprints, use cases, FAQs, and getting started guides.
  - Introduced new sections detailing aggregation presets, usage patterns, and code snippets for blockchain data analysis.
  - Enhanced clarity on performing statistical and summary queries, with guidance on leveraging the Insight Playground for interactive exploration.
  - Updated the Insight landing page with a new feature card highlighting powerful aggregation capabilities and improved layout for feature cards.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the documentation for the `Insight` tool by adding new aggregation features, examples, and updating existing content to clarify how to utilize these functionalities effectively.

### Detailed summary
- Added `FunctionSquareIcon` to the import statement in `page.mdx`.
- Updated grid layout class from `lg:grid-cols-2` to `lg:grid-cols-3` in `page.mdx`.
- Introduced a new `FeatureCard` titled "Powerful Aggregations" in `page.mdx`.
- Added sections on aggregation queries and examples in `faqs/page.mdx`, `get-started/page.mdx`, and `agents-and-llms/page.mdx`.
- Provided aggregation examples in `use-cases/page.mdx` and `blueprints/page.mdx`.
- Enhanced documentation for wallet transactions and blocks, including aggregation examples in `agents-and-llms/page.mdx`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-29 17:37:27 +00:00
gregandGitHub 3d3c6f3d45 Fix: Transfer purchase data (#7202) 2025-05-29 10:30:15 -07:00
Robby UitbeijerseandGitHub ff3a79c884 chore: annotate getBuyWithFiatQuote as deprecated (#7198) 2025-05-29 09:00:53 -07:00
kumaryash90 16482cfa6a Stylus ERC20 template for CLI (#7192)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `create.ts` and `builder.ts` files for the Stylus project by adding project type selection and improving contract name handling during ABI processing. It introduces prompts for user input and refines how contract names are extracted and utilized.

### Detailed summary
- In `create.ts`, added prompts for selecting project type (Default or ERC20).
- Updated project creation logic based on the selected type.
- In `builder.ts`, improved contract name extraction to handle multiple contracts.
- Added prompts for selecting the entrypoint if multiple contracts are found.
- Refined usage of selected contract names throughout the build process.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added support for handling multiple contract ABIs, allowing users to select a contract entrypoint when more than one is present.
  - Introduced a prompt to select a project template type ("default" or "erc20") during project creation.

- **Improvements**
  - Enhanced error handling and user guidance when no contract is selected or found.
  - Updated success messages and console output for improved clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 12:12:00 +00:00
jnsdls e8a25d70b9 [Dashboard] replace chakra stats in accounts (#7188)
## Summary
- swap chakra `SimpleGrid`, `Stat`, `Skeleton` for shadcn `StatCard`
- use Tailwind grid utility classes

## Checklist
- [x] `pnpm biome check --apply`
- [x] `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the `AccountsCount` component to replace the `Card` and `SimpleGrid` components from `@chakra-ui/react` with a new layout using `StatCard` from a different module, enhancing the presentation of the total accounts data.

### Detailed summary
- Removed imports for `SimpleGrid`, `Skeleton`, `Stat`, `StatLabel`, and `StatNumber`.
- Added import for `StatCard` from `../../overview/components/stat-card`.
- Changed the layout from `SimpleGrid` and `Card` to a `div` with a grid layout.
- Updated the rendering to use `StatCard` for displaying the total accounts.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Updated the accounts count display to use a new StatCard component with improved layout and styling for a more consistent and responsive user interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-29 00:55:53 +00:00
gregandGitHub 44a7460c83 [SDK] Feature: Remove Switch Network button (#7191) 2025-05-28 17:45:07 -07:00
gregandGitHub 0731831169 Fix: Webhook docs tags (#7189) 2025-05-28 17:11:21 -07:00
AmineAfia 91750eddc6 Temporarily remove webhooks sidebar link until scrolling issue is fixed (#7187)
## [Dashboard] Fix: Temporarily remove Webhooks from sidebar

## Notes for the reviewer

Commented out the Webhooks section in the project sidebar until we resolve a scrolling issue. Also removed the unused BellIcon import.

## How to test

Verify that the Webhooks option no longer appears in the project sidebar navigation.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
  - Temporarily removed the "Webhooks" link from the project sidebar to address a scrolling issue. The link and its badge are no longer visible.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 23:45:59 +00:00
iuwqyir 2fc083f1f2 token owners endpoint in insight playground (#7184)
## [Dashboard] Feature: Update Token and NFT API Endpoints

## Notes for the reviewer

This PR adds a new token endpoint and updates the name of an existing NFT endpoint:

1. Added a new endpoint for getting token owners by contract: `/v1/tokens/owners`
2. Renamed the "Get NFTs by owner" endpoint to simply "Get NFTs" to better reflect its functionality

## How to test

Verify the updated endpoint names appear correctly in the Insight section of the playground.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added a new API endpoint for retrieving token owners by contract.

- **Refactor**
  - Renamed the "Get NFTs by owner" endpoint to "Get NFTs" for improved clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 23:26:30 +00:00
AmineAfia 75ae536e61 Add scrollable overflow to webhook filter select dropdowns (#7186)
## [Dashboard] Fix: Add scrolling to webhook event and function signature dropdowns

## Notes for the reviewer

This PR adds scrolling functionality to the webhook event and function signature dropdown menus by adding `max-h-60 overflow-y-auto` classes. This ensures that when there are many options, users can still navigate through them effectively.

## How to test

1. Navigate to the webhooks section in a project
2. Open the event signature dropdown and verify it scrolls properly when there are many options
3. Similarly, test the function signature dropdown to ensure it maintains its max width while allowing vertical scrolling

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Style**
  - Improved dropdown menus for event and transaction signature selection by limiting their maximum height and enabling vertical scrolling, enhancing usability when many options are available.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `FilterDetailsStep` component by improving the usability of the dropdown content with better scrolling behavior.

### Detailed summary
- Updated the `className` of the first `<SelectContent>` from default to `max-h-60 overflow-y-auto` for better vertical scrolling.
- Updated the second `<SelectContent>` to include `overflow-y-auto` while retaining `max-w-[600px]`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-28 23:11:30 +00:00
gregandGitHub 41e59a9c20 [SDK] Feature: Adds explicit country param to onramps (#7185) 2025-05-28 16:11:09 -07:00
Joey BrightandGitHub fd97406fa2 chore: fix typos (#7180) 2025-05-28 16:10:17 -07:00
AmineAfia c336de3bfb Add webhook creation UI to dashboard (#7174)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `CreateWebhookModal` component and related functionalities in the webhook management system, including form handling, validation, and API integration for creating webhooks.

### Detailed summary
- Changed `createWebhook` function to `export async function createWebhook`.
- Updated `CreateWebhookModal` to accept `clientId` prop.
- Integrated form steps for creating a webhook with validation.
- Added utility functions for parsing addresses and building webhook payloads.
- Improved error handling and user feedback during webhook testing.
- Enhanced UI components for better user experience in the webhook creation process.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a multi-step modal form for creating webhooks, including form validation, ABI integration, and live endpoint testing.
  - Added components for basic info entry, filter configuration, and review before submission.
  - Enabled dynamic ABI fetching and signature extraction for blockchain event and transaction filters.
  - Improved error handling and user feedback throughout the webhook creation flow.

- **Bug Fixes**
  - Enhanced validation and error messages for webhook URLs and date handling in tables.

- **Chores**
  - Added comprehensive utility modules for ABI processing and webhook payload construction.
  - Implemented robust type definitions and validation schemas for webhook forms.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 22:02:27 +00:00
AmineAfia c420099dc3 Add webhook testing functionality to dashboard (#7173)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the webhook testing functionality in the dashboard application by exporting the `testWebhook` function, adding a testing feature in the `WebhooksTable`, and creating a custom hook `useTestWebhook` to manage the testing state and results.

### Detailed summary
- Changed `testWebhook` from a local function to an exported function in `webhooks.ts`.
- Imported `PlayIcon` in `WebhooksTable.tsx` and added it to the UI.
- Implemented `handleTestWebhook` function to test webhooks and display results.
- Created `useTestWebhook` hook to manage testing state and results.
- Added error handling and success notifications for webhook testing.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added the ability to test webhooks directly from the webhooks table with a "Test" button, providing immediate feedback and status indicators during testing.
- **User Interface**
  - Enhanced the actions column in the webhooks table for improved layout and usability, including real-time spinner icons and error notifications during webhook testing.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 22:02:27 +00:00
AmineAfia dcb412fc27 Add webhooks page to project dashboard (#7172)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new `CreateWebhookModal` component and enhances the `Webhooks` functionality in the dashboard. It implements a `WebhooksTable` for displaying webhooks and their details, along with error handling and user notifications for actions like deleting webhooks.

### Detailed summary
- Added `CreateWebhookModal` component for creating new webhooks.
- Updated `ProjectSidebarLayout` to include a link to webhooks with a new badge.
- Changed `WebhookResponse` and `WebhookFilters` interfaces to `export`.
- Modified `WebhooksPage` to handle project and webhook loading with error management.
- Introduced `WebhooksTable` for displaying webhooks with actions.
- Implemented `RelativeTime` component to show formatted timestamps.
- Added deletion functionality for webhooks with user notifications.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a "Webhooks" section in the project sidebar, highlighted with a "New" badge.
  - Added a dedicated Webhooks page displaying a list of webhooks in a sortable table with options to copy URLs and delete entries.
  - Included a "New Webhook" button and modal for future webhook creation.
  - Implemented a component to display relative creation times for webhooks.
- **Bug Fixes**
  - Improved error handling and user feedback for webhook-related actions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 22:02:26 +00:00
catalyst17 4705a599a2 feat: redesign aggregate parameter input with improved UI (#7179)
# [Dashboard] Feature: Redesign Aggregate Parameter Input Component

## Notes for the reviewer

This PR completely redesigns the aggregate parameter input component with a more user-friendly interface. The new design uses a popover pattern instead of the previous MultiSelect approach, making it easier to view and select aggregation presets.

## How to test

1. Open any insight blueprint that uses aggregation
2. Click on the aggregate parameter input
3. Test searching for presets, selecting/deselecting options
4. Verify that manual text entry still works in the textarea
5. Check that the selected aggregations display correctly when the popover is closed
2025-05-28 21:48:48 +00:00
catalyst17 f7331f15a2 feat: enhance aggregate parameter input with multi-select presets (#7168)
## [Dashboard] Feature: Enhance Aggregate Parameter Input with Multi-Select Functionality

## Notes for the reviewer
This PR replaces the simple dropdown select with a more robust multi-select component for aggregate parameter inputs. The new implementation allows users to select multiple presets and displays them as badges.

## How to test
Test the new aggregate parameter input by:
1. Opening the insight blueprint page
2. Selecting multiple presets from the dropdown
3. Verifying that selected values appear as badges
4. Testing the search functionality within the preset selector
5. Confirming that manual input still works alongside preset selection

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enhanced aggregate parameter input with combined manual entry and multi-select for presets.
  - Added search functionality within the multi-select component for easier preset selection.
  - Updated parameter descriptions and examples for "aggregate" to clarify multi-selection usage.
- **Refactor**
  - Made input options optional and improved synchronization between manual input and multi-select.
  - Adjusted tooltip positioning for better UI alignment on aggregate parameters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR enhances the `ParameterSection` and `AggregateParameterInput` components to provide dynamic descriptions and examples based on the parameter type. It also refines the handling of selected values and manual input for aggregations, replacing the `Select` component with a `MultiSelect`.

### Detailed summary
- Updated `description` and `exampleToShow` in `ParameterSection` based on `param.name`.
- Introduced `MultiSelect` in `AggregateParameterInput` for selecting aggregation presets.
- Added state management for manual input and selected values.
- Removed the `Select` component in favor of a more flexible input system.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-28 21:48:47 +00:00
AmineAfia a5d6e769db Add webhook API functions for insight dashboard (#7171)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces functionality for managing webhooks in the application. It includes a temporary `WebhooksPage` for displaying webhook data and implements several API functions for creating, retrieving, deleting, and testing webhooks.

### Detailed summary
- Added `WebhooksPage` component in `page.tsx` to display webhook data.
- Implemented `getWebhooks` function to fetch webhooks from the API.
- Created interfaces for webhook responses and payloads.
- Added `createWebhook`, `deleteWebhook`, and `testWebhook` functions for managing webhooks.
- Handled API errors with appropriate responses.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced the ability to create, view, delete, and test webhooks through the dashboard interface, allowing users to manage webhook integrations more easily.
  - Added a new dashboard page displaying webhook data for better visibility and management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 21:20:24 +00:00
jnsdls 97b8926024 [Dashboard] migrate external links form (#7156)
## Summary
- refactor contract publish resources inputs
- use shadcn/ui Button, Input, and Separator
- apply tailwind classes

## Testing
- `pnpm biome check --apply apps/dashboard/src/components/contract-components/contract-publish-form/external-links-fieldset.tsx apps/dashboard/src/components/contract-components/contract-publish-form/external-links-input.tsx`
- `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the UI components in the `ExternalLinksFieldset` and `ExternalLinksInput` files to improve the styling and structure using custom components instead of those from `tw-components` and `@chakra-ui/react`.

### Detailed summary
- Replaced `Heading` and `Text` with custom HTML elements in `ExternalLinksFieldset`.
- Updated button styles in `ExternalLinksFieldset` to use `variant="outline"` and added a `className`.
- Refactored `ExternalLinksInput` to use custom components (`Button`, `Input`, `Label`, `Separator`) instead of Chakra UI components.
- Changed layout structure in `ExternalLinksInput` to use `div` elements with flexbox for better styling.
- Added error message handling below input fields in `ExternalLinksInput`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Style**
  - Updated form and button components to use new UI primitives and Tailwind CSS classes for a refreshed appearance.
  - Improved accessibility by linking input labels and error messages with appropriate HTML attributes.

- **Refactor**
  - Replaced Chakra UI components with custom or alternative UI components, maintaining existing functionality and validation logic.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-28 15:47:22 +00:00
Joaquim VergesandGitHub 655df037dd [SDK] fix hiddenWallets prop (#7183) 2025-05-28 01:46:03 -07:00
Joaquim VergesandGitHub cbde32e974 [Dashboard] add wallet user search (#7182) 2025-05-28 01:14:14 -07:00
Joaquim VergesandGitHub 8ed5ef3f81 [Dashboard] Change "Network" label to "Select Testnet" in analytics test transaction form (#7178) 2025-05-28 00:52:08 -07:00
Joe-Thirdweb e14a1349e1 [Dashboard] Add token request route to dashboard (#7112)
TOOL-4443
TOOL-4559

How to Test
1. Log into dashboard
2. Select a project
3. Click on Universal Bridge on left hand side
4. Click on Settings
5. Scroll down to add token section

-  Failure input
Chain: Ethereum
Token Address: 0x7613c48e0cd50e42dd9bf0f6c235063145f6f8db

-Success input
Chain: Ethereum
Token Address:0x7613c48e0cd50e42dd9bf0f6c235063145f6f8dc

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces a new validation schema for route discovery, enhances the UI for token submission, and integrates a new `RouteDiscovery` component to facilitate token discovery in the dashboard.

### Detailed summary
- Added `routeDiscoveryValidationSchema` in `validations.ts` for validating token discovery inputs.
- Created `RouteDiscovery` component to handle token submission.
- Updated `page.tsx` to include `RouteDiscovery` below `PayConfig`.
- Implemented `addUniversalBridgeTokenRoute` function in `tokens.ts` for API token submission.
- Added `RouteDiscoveryCard` component for better UI presentation of token discovery.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a Route Discovery workflow, allowing users to submit tokens for route discovery on selected blockchain networks.
  - Added a new card component for displaying route discovery information and actions.
  - Integrated Route Discovery into the Universal Bridge settings page for easier access.

- **Enhancements**
  - Added validation for token address and chain selection to ensure proper input.
  - Provided user feedback through success and error messages, including toast notifications.

- **Style**
  - Minor cleanup of extra blank lines in the Project General Settings page for improved readability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-27 22:14:03 +00:00
gregGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
acd8b9e535 Feat: tokenAddress and amount bridge params (#7176)
Signed-off-by: greg <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-05-27 13:28:36 -07:00
Robby UitbeijerseandGitHub 52d451ff70 [SDK] ensure that the default spinner stroke color gets inherited from the parentnode (#7157) 2025-05-27 12:28:10 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
c03616666b chore(deps): bump @radix-ui/react-select from 2.2.2 to 2.2.5 (#7159)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 12:21:22 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
bb7a8988ef chore(deps): bump @radix-ui/react-separator from 1.1.4 to 1.1.7 (#7161)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 11:51:20 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8d0ffedd41 chore(deps): bump papaparse from 5.5.2 to 5.5.3 (#7162)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-27 11:51:04 -07:00
Jonas DanielsandGitHub 5edfb81ec5 [Dashboard] consolidate solution page rewrites with dynamic slug (#7175) 2025-05-27 11:50:23 -07:00
iuwqyir f115b4d2db new tokens route (#7170)
## [Dashboard] Feature: Add new tokens endpoint and deprecate ERC-20 balances endpoint

## Notes for the reviewer

This PR adds a new endpoint for getting tokens at `/v1/tokens` and marks the existing ERC-20 balances endpoint (`/v1/tokens/erc20/{ownerAddress}`) as deprecated.

## How to test

Verify that the new endpoint is accessible and that the deprecated flag is correctly set for both endpoints in the insight blueprints.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a new "Get tokens" endpoint for accessing token data.

- **Bug Fixes**
  - Marked the older ERC-20 balances endpoint as deprecated to guide users toward the updated endpoint.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-27 17:02:25 +00:00
Joaquim VergesandGitHub 0e4390b2c7 [Docs] Add Onramp extension to sidebar and typedoc (#7167) 2025-05-27 01:18:31 -07:00
Joaquim VergesandGitHub aec8d88af2 [Wallet] Move 7702 batch transaction test to integration tests (#7166) 2025-05-26 20:53:10 -07:00
gregandGitHub 80207ae240 [Dashboard] Refactor: Bridge UI Cleanup and Fixes (#7165) 2025-05-26 19:12:23 -07:00
Joaquim VergesandGitHub ec7bc2bb1e [Insight] Make clientId optional and improve error handling (#7158) 2025-05-26 14:34:12 -07:00
MananTank 12475027d1 Add Contract layout in team/project (#7152)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces enhancements to the handling of contract pages, adding new types for parameters and project metadata, while refactoring existing components to incorporate team and project-specific data.

### Detailed summary
- Added `PublicContractPageParams` and `ProjectContractPageParams` types.
- Introduced `ProjectMeta` type for project metadata.
- Refactored components to accept `teamSlug`, `projectSlug`, and `projectMeta`.
- Updated routing and links to include project-specific paths.
- Enhanced handling of contract page data retrieval and UI rendering.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/AccountPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/TokenIdPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/ContractNFTPage.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.client.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/shared-explorer-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/explorer/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/ContractPermissionsPage.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/ContractChecklist.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/shared-permissions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account-permissions/shared-account-permissions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/permissions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/split/shared-split-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/shared-accounts-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/shared-modules-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/proposals/shared-proposals-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/account/shared-account-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/english-auctions/shared-english-auctions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/direct-listings/shared-direct-listings-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/shared-nfts-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/data-table.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/primary-dashboard-button.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/shared-claim-conditions-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/claim-conditions/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-overview-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/token-id.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/analytics/shared-analytics-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/shared-nfts-token-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/events/events-feed.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/shared-cross-chain-page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/cross-chain/page.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/shared-layout.tsx`, `apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/layout.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Enhanced routing to include project and team slugs, enabling project-aware navigation for contract, NFT, marketplace, analytics, permissions, and proposal pages.
  - Passed project metadata (team and project info) throughout various pages and components for contextual consistency.
  - Introduced shared layout and page components for contract overview, NFTs, analytics, permissions, and settings, streamlining the user experience.

- **Refactor**
  - Removed internal data fetching, validation, and conditional rendering from pages, delegating logic to shared components.
  - Updated navigation links and breadcrumbs to dynamically incorporate project and team slugs when available.
  - Centralized metadata and layout generation into utility functions to reduce duplication.

- **Bug Fixes**
  - Improved handling of missing or invalid project/team data by triggering notFound responses appropriately.

- **Chores**
  - Extended component props and interfaces to accept projectMeta objects.
  - Simplified page components to directly render shared components with minimal logic.
  - Updated URL construction to utilize utility functions for project-aware paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-26 20:59:12 +00:00
catalyst17 9479d252b4 feat: add aggregate parameter input with presets (#7146)
<!-- start pr-codex -->

## PR-Codex overview
This PR introduces the `AggregateParameterInput` component to handle aggregate parameters in the `BlueprintPlayground`. It adds new presets for various data types and modifies the `ParameterSection` to utilize this new component, enhancing the functionality of the parameter input system.

### Detailed summary
- Added `AggregateParameterInput` component to handle aggregate parameters.
- Introduced multiple preset options for aggregates, transactions, events, and blocks.
- Updated `ParameterSection` to include a check for the `aggregate` parameter and render the new component.
- Modified placeholder logic in `ParameterSection` to use `param.description` or `param.name`.
- Passed `endpointPath` prop to `AggregateParameterInput` for context on preset selection.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a specialized input with preset selection for aggregate query parameters, enhancing usability when configuring aggregate values.
  - The playground UI now displays this new input component for aggregate parameters, providing relevant preset options based on the selected endpoint.
- **Improvements**
  - Placeholders for parameter inputs now more accurately reflect the parameter’s description or name for better clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-25 19:14:20 +00:00
Joaquim VergesandGitHub 5139857db9 [Portal] fix portal build (#7154) 2025-05-23 22:56:39 -07:00
Joaquim VergesandGitHub ad4341a7ad [Portal] Add AI chat functionality with markdown support (#7139) 2025-05-23 20:55:13 -07:00
Joaquim VergesandGitHub ebd58f49b6 [Portal] Redesign header with improved mobile menu layout (#7138) 2025-05-23 20:12:18 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
3862bc7a94 Version Packages (#7150)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-23 20:03:03 -07:00
gregfromstl 5277eddb70 [SDK] Fix: Webhook Schema (#7151)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the `Webhook` schema in the `thirdweb` package to enhance the structure of `originToken` and `destinationToken` by replacing simple address strings with detailed objects containing additional properties.

### Detailed summary
- Updated `originToken` and `destinationToken` to be objects with properties:
  - `chainId`
  - `address`
  - `name`
  - `symbol`
  - `decimals`
  - `priceUsd`
  - `iconUri`
- Adjusted the test file to reflect these changes with appropriate object structures.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
  - Enhanced webhook support to include detailed token information such as chain ID, name, symbol, decimals, price, and icon for origin and destination tokens.
- **Tests**
  - Updated test data to match the new detailed token structure in webhook payloads.
- **Chores**
  - Added a changeset to document this patch update.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 23:10:14 +00:00
jnsdls 6c180b5c8a [Dashboard] migrate solidity inputs to shadcn (#7148)
## Summary
- migrate solidity bool, int, bytes, and string inputs to shadcn/ui and tailwind

## Testing
- `pnpm biome check --apply apps/dashboard/src/contract-ui/components/solidity-inputs/bool-input.tsx apps/dashboard/src/contract-ui/components/solidity-inputs/bytes-input.tsx apps/dashboard/src/contract-ui/components/solidity-inputs/int-input.tsx apps/dashboard/src/contract-ui/components/solidity-inputs/string-input.tsx`
- `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the UI components in the `solidity-inputs` directory to use a consistent styling approach and improve the layout by replacing certain components with more flexible alternatives.

### Detailed summary
- Updated imports from `tw-components` to a local `@/components/ui` for `Button` and `Input`.
- Replaced `ButtonGroup` with a `div` for better styling control in `SolidityBoolInput`.
- Adjusted button variants from `solid` to `default` for consistency.
- Introduced a `showConversionButton` flag in `SolidityIntInput` for conditional rendering.
- Changed `InputGroup` to `div` in `SolidityIntInput` and `SolidityStringInput` for layout flexibility.
- Used `cn` utility for conditional class names in `Input` components.
- Updated button and input placements to enhance responsiveness and styling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Style**
  - Updated input components to use custom UI elements and Tailwind CSS for consistent styling.
  - Replaced Chakra UI and third-party components with locally defined UI components and native HTML elements.
  - Improved button and input layouts for better visual consistency across boolean, integer, byte, and string input fields.

- **New Features**
  - Enhanced integer input with conditional display of a conversion button based on input value format.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 22:57:37 +00:00
Joaquim VergesandGitHub 3489ecec98 [SDK] Improve quote error handling (#7147) 2025-05-23 15:43:52 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
f9b34ff2f1 Version Packages (#7149)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-23 14:04:03 -07:00
Jonas DanielsandGitHub f3abea3276 Add webhook verification functionality for secure payload validation (#7103) 2025-05-23 13:59:46 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
adc738e536 Version Packages (#7116)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-23 12:44:58 -07:00
Robby UitbeijerseandGitHub dd2fb1b13d [SDK] Feature: Allow for supported providers to be passed to PayEmbed (#7108) 2025-05-23 12:01:27 -07:00
Joaquim VergesandGitHub 69fdef07f5 [thirdweb] Ensure bigints are stringified before usage with server wallets (#7145) 2025-05-23 11:57:43 -07:00
MananTank 362c086bf6 Dashboard: Move project pages inside (sidebar) layout (#7144)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on refactoring the codebase to organize components and hooks into a new `(sidebar)` directory structure, enhancing modularity and maintainability. It also updates import paths to reflect these changes.

### Detailed summary
- Moved various components and hooks to a new `(sidebar)` directory.
- Updated import paths across multiple files.
- Adjusted layout files to accommodate the new directory structure.
- Ensured proper functionality of components post-migration.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Chores**
  - Updated and standardized import paths across the dashboard and component files for improved code organization and maintainability.
  - No changes to end-user functionality or visible features.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 18:12:01 +00:00
jnsdls f9b609e7a2 [Dashboard] replace Chakra fieldset with shadcn (#7143)
Migrates the NetworksFieldset component from Chakra UI to shadcn/ui and Tailwind.

- Drop Chakra Flex, FormControl and Select
- Use shadcn Select primitives with tailwind classes
- Adjust layout with Tailwind via `cn`

Fixes #0

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the `NetworksFieldset` component in `networks-fieldset.tsx` to use a new `Select` component from the UI library, improving styling and functionality while maintaining the same overall behavior.

### Detailed summary
- Replaced `Flex` and `FormControl` components with a new `div` structure and `Select` component.
- Updated the `Select` component to use `SelectTrigger`, `SelectContent`, and `SelectItem`.
- Changed event handlers from `onChange` to `onValueChange` for better state management.
- Maintained layout and functionality with updated class names for styling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Updated the network selection field to use a custom select component and Tailwind-based layout for a more consistent user interface.
- **Style**
  - Improved the visual appearance and spacing of the network selection field.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 18:00:04 +00:00
MananTank 916ecf494c [TOOL-4591] Fix resolveImplementation jsdoc code example in jsdoc (#7141)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the import path for the `resolveImplementation` function to reflect its new location within the `thirdweb/utils` directory.

### Detailed summary
- Changed import statement for `resolveImplementation` from `thirdweb` to `thirdweb/utils`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Documentation**
  - Updated example import path in documentation for improved clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 17:11:46 +00:00
MananTank d1ca9af2f4 Remove SIWA feedback buttons from nebula (#7142)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on refactoring the `Chats` component and its related functionalities. It removes unused code and simplifies the props being passed, particularly the `teamId`. Additionally, it eliminates the feedback buttons and associated functionality.

### Detailed summary
- Removed `teamId` prop from various instances of the `Chats` component.
- Deleted the `FeedbackButtons` component and its related logic.
- Simplified imports in the `Chats` component by removing unused imports.
- Cleaned up the `RenderMessage` function by omitting `teamId` from props.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
	- None.

- **Bug Fixes**
	- None.

- **Refactor**
	- Removed the feedback feature, including thumbs up/down buttons and related tracking, from chat components.
	- Simplified chat components by removing the unused or redundant team selection prop.

- **Chores**
	- Cleaned up code by deleting unnecessary feedback-related imports and props.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 16:02:33 +00:00
jnsdls 317211a48e [Dashboard] migrate CurrencySelector to shadcn (#7137)
## Summary
- migrate shared CurrencySelector from Chakra UI to shadcn/ui
- use tailwindcss classes and Radix-based Select

## Checklist
- [x] `pnpm biome check apps/dashboard/src/components/shared/CurrencySelector.tsx --apply`
- [ ] `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR refactors the `CurrencySelector` component to improve its structure and styling. It replaces certain UI elements with a new `Select` component, enhances props for better functionality, and updates the layout for a more modern appearance.

### Detailed summary
- Changed `CurrencySelectorProps` to include new props: `onChange`, `className`, `isDisabled`.
- Refactored the component to use a `Select` from the UI library instead of native HTML elements.
- Updated event handling to utilize `onValueChange` for the `Select`.
- Improved styling and layout for better user experience.
- Replaced `Flex` components with `div` and applied conditional class names for styling.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Updated the CurrencySelector component to use custom UI components and Tailwind CSS for styling, replacing Chakra UI elements.
  - Simplified the component's props and adjusted event handling for the new select interface.
  - Maintained existing functionality and behavior while improving consistency with the app's design system.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 04:52:16 +00:00
gregfromstl 6cd64e7368 [Dashboard] Fix: Routes page pagination beyond 1, add og image (#7136)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating titles for better clarity and modifying the pagination logic in the routes table component to directly use `routesToRender`, enhancing the user experience in the dashboard.

### Detailed summary
- Updated `title` in `page.tsx` files for clarity.
- Changed the condition from `paginatedRoutes.length` to `routesToRender.length` in the routes table component.
- Removed pagination logic variables (`activePage`, `pageSize`, `startIndex`, `endIndex`, `paginatedRoutes`).
- Updated pagination component to use `Number(props.searchParams.page) || 1`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Updated page titles and metadata for improved clarity and consistency, including changes from "On-Ramp" to "Onramp" and a new title for the routes page.
- **Refactor**
  - Simplified the routes list rendering by removing local pagination logic, now displaying data directly as provided without client-side slicing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 04:43:14 +00:00
jnsdls 005acce714 Update PostHog import to use React hook (#7135)
# Update PostHog import to use React hook

This PR updates the PostHog implementation in the `useTrack` hook to use the React-specific hook from PostHog instead of the direct import. The changes include:

- Replaced the direct import of `posthog` with `usePostHog` from `posthog-js/react`
- Added the PostHog instance as a dependency to the `useCallback` hook
- Added a null check before calling `posthog.capture()` to handle cases where PostHog might not be initialized

These changes ensure proper React integration with PostHog and prevent potential issues with the hook's dependency array.
2025-05-23 04:34:30 +00:00
jnsdls cde2dd941f Make free plan badge clickable to upgrade (#7134)
# Add Upgrade Paths for Free Plan Teams

This PR enhances the user experience for teams on the free plan by adding clear upgrade paths throughout the dashboard:

- Makes the free plan badge clickable, linking directly to the billing page with pricing modal open
- Adds analytics tracking to billing-related links for better conversion insights
- Implements a new `FreePlanUpsellBannerUI` component on the team dashboard page
- Ensures only one billing alert banner shows at a time (following priority order)
- Updates all `TeamPlanBadge` components to include the team slug parameter
- Improves billing alert banners with proper analytics tracking

These changes aim to increase conversions from free to paid plans by providing contextual upgrade opportunities throughout the product.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a promotional upsell banner for teams on the free plan, encouraging upgrades with a direct link to view available plans.
  - Added a customizable promotional banner component with multiple accent color themes for enhanced marketing displays.

- **Enhancements**
  - Team plan badges now provide direct links to billing settings for teams on the free plan, with analytics tracking for user interactions.
  - Improved analytics tracking on billing-related banners and links throughout the dashboard.

- **Refactor**
  - Updated multiple components to pass team identifiers to plan badges for more contextual display and interaction.
  - Streamlined the display logic for billing-related banners to prioritize service status and plan type.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the `TeamPlanBadge` component by adding a `teamSlug` prop across various files and implementing a new `FreePlanUpsellBannerUI` component to encourage free plan users to upgrade. It also updates links to use `TrackedLinkTW` for better tracking.

### Detailed summary
- Added `teamSlug` prop to `TeamPlanBadge` in multiple components.
- Introduced `FreePlanUpsellBannerUI` to promote upgrades for free plan users.
- Replaced `<Link>` with `<TrackedLinkTW>` for better tracking in several instances.
- Updated conditional rendering logic for billing alerts in the team layout.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-23 04:21:27 +00:00
7130f9a929 [Dashboard] siwa chat widget (#7128)
Co-authored-by: Joaquim Verges <[email protected]>
2025-05-22 21:20:45 -07:00
1e0b1422f3 [SDK] Implement allowedSmsCountryCodes option (#7090)
Co-authored-by: Jonas Daniels <[email protected]>
2025-05-22 21:14:29 -07:00
jnsdls 70a519ada4 [Dashboard] migrate authorized wallets components to shadcn (#7131)
## Summary
- migrate authorized wallets revoke modal from Chakra to shadcn dialog
- replace Chakra button/text in AuthorizedWalletsTable with shadcn + tailwind
- drop Chakra provider wrapper from account devices page
- cleanup modal title/description and remove node cache

## Testing
- `pnpm biome check --apply apps/dashboard/src/components/settings/AuthorizedWallets/AuthorizedWalletRevokeModal.tsx .gitignore`
- `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on refactoring the `AccountDevicesPage` and the `AuthorizedWalletRevokeModal` components to replace the `Chakra UI` modal with a new `Dialog` component. It also updates the `AuthorizedWalletsTable` to use local state for modal visibility and modifies UI elements for consistency.

### Detailed summary
- Removed `ChakraProviderSetup` from `AccountDevicesPage`.
- Replaced `Modal` components with `Dialog` components in `AuthorizedWalletRevokeModal`.
- Updated modal structure and styling in `AuthorizedWalletRevokeModal`.
- Changed state management for modal visibility in `AuthorizedWalletsTable`.
- Updated text rendering from `Text` to `span` for consistency in `AuthorizedWalletsTable`.
- Changed button styles in `AuthorizedWalletsTable` for revocation actions.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**
  - Replaced Chakra UI components with custom UI library components in wallet authorization modals and tables.
  - Updated modal and button styling for a consistent look and feel.
  - Simplified modal state management in the authorized wallets table.

- **Chores**
  - Updated `.gitignore` to exclude dashboard node compilation cache.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-23 03:54:27 +00:00
gregandGitHub 678c00e322 Fix: Update routes page to use server-side pagination and filtering (#7133) 2025-05-22 17:26:36 -07:00
MananTank 5ab59ff400 Dashboard: Add token selector in asset creation wizard (#7132)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the token sale functionality within the application. It introduces new properties, refines existing structures, and improves the token selection process to accommodate native tokens and better handle token sales.

### Detailed summary
- Added `saleTokenAddress` to the form validation schema.
- Updated `CreateTokenAssetPage` to handle native token address logic.
- Changed `TokenSelector` to support selected tokens and improved token address handling.
- Enhanced `TokenSaleSection` to include a currency field for token sales.
- Refined state management in `PaymentLinkForm` for better token handling.
- Modified `TokenInfoFieldset` to trigger updates on chain changes.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-22 23:15:23 +00:00
MananTank 73629e9f0e [TOOL-4531] Dashboard: Add Token Asset creation wizard (#7081)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces several enhancements and features related to asset management, including deployment tracking, UI updates, and new forms for creating and managing tokens. It also refines existing components and adds new functionalities for improved user experience.

### Detailed summary
- Added `deploymentType` and `contractType` properties in various components.
- Introduced `revalidatePathAction` for path revalidation.
- Updated UI components for better asset management.
- Enhanced forms for token creation with validation.
- Implemented multi-step status tracking for token launch processes.
- Improved error handling and user feedback in forms.
- Added new charts for token distribution visualization.

> The following files were skipped due to too many changes: `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/launch/launch-token.tsx`, `apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create/distribution/token-airdrop.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a comprehensive asset management interface for creating, importing, and managing ERC-20 tokens within team and project dashboards.
  - Added a multi-step token creation flow with form validation, including token info, distribution, sale settings, airdrop CSV upload, and launch process with real-time status tracking.
  - Implemented visual token allocation charts and multi-step progress indicators for enhanced user experience.
  - Added a dedicated "Assets" section in the sidebar with a "New" badge.
  - Added a horizontal segmented distribution bar chart component for visualizing token allocations.
  - Introduced a multi-step status component to track asynchronous step executions with retry capabilities.
  - Added token airdrop CSV upload and validation feature with user-friendly UI and error handling.
  - Added token sale configuration section with price and allocation inputs.
  - Enhanced import modal to support both contract and asset imports with contextual UI and behavior.
  - Added new pages and components to support token asset creation and management workflows, including cards for asset actions.
  - Added server-side path revalidation support for pages and layouts.

- **Improvements**
  - Enhanced contract and asset import workflows with clearer UI, context-aware dialogs, and improved contract table variant handling.
  - Updated number input fields to remove browser-native spinners for a cleaner appearance.
  - Improved analytics event tracking for user interactions and deployment steps.
  - Refined UI components for consistent styling and accessibility.
  - Fixed sidebar badge placement and updated UI text for clarity.
  - Updated dialogs and payment embeds to reference transaction chain instead of active wallet chain and set default payment amounts.
  - Changed token supply label to "Circulating Supply" for clarity.
  - Replaced Chakra UI spinner and styled elements with local components for simplified UI.

- **Bug Fixes**
  - Corrected UI typos and improved analytics event tracking for deployment errors.

- **Documentation**
  - Added Storybook stories for new components to facilitate UI testing and documentation.

- **Chores**
  - Refactored and extended types and props to support new asset and contract features, ensuring future extensibility.
  - Added tracking utilities for token deployment and asset creation analytics.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-22 23:15:23 +00:00
23029db9ef Feature: Add image support to payment links (#7129)
Co-authored-by: Claude <[email protected]>
2025-05-22 12:47:05 -07:00
jnsdls 526b6b54cf Add useAuthToken hook for in-app wallet authentication (#7120)
# Add `useAuthToken` hook for in-app wallet authentication

This PR adds a new React hook `useAuthToken()` that returns a JWT authentication token for the currently active in-app wallet. This token can be used to authorize API calls to backend servers.

Key changes:
- Added `useAuthToken()` hook that returns the auth token when an in-app wallet is active
- Modified the `InAppConnector` interface to expose the storage property
- Updated the wallet interface to include a `getAuthToken()` method for in-app wallets
- Implemented token retrieval in the in-app wallet core implementation

The hook ensures the token is only returned when the active wallet is an in-app wallet and matches the active account.

Example usage:
```tsx
function MyComponent() {
  const authToken = useAuthToken();

  const fetchData = async () => {
    const response = await fetch('https://api.example.com/data', {
      headers: {
        'Authorization': `Bearer ${authToken}`
      }
    });
    // ... handle response
  };
}
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a new hook to retrieve authentication tokens for in-app wallets, enabling secure authorization for API calls.
- **Documentation**
	- Added usage examples and clarifications regarding authentication token availability for wallets.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the wallet functionality by introducing an authentication token feature and updating the visibility of certain properties. It adds a method for retrieving an authentication token and modifies the storage property to be public.

### Detailed summary
- Changed `storage` property from `private` to `public` in `native-connector.ts` and `web-connector.ts`.
- Added `getAuthToken` method to the wallet interface in `wallet.ts` with documentation.
- Included `storage` in the `InAppConnector` interface.
- Implemented `authToken` handling in `createInAppWallet` function.
- Created `useAuthToken` hook for retrieving the JWT of the active wallet.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-22 18:01:48 +00:00
Jonas DanielsandGitHub f31116ea5a [SDK] fix avatar image detection on Node (#7123)
Signed-off-by: Jonas Daniels <[email protected]>
2025-05-22 11:00:48 -07:00
arcoraven c1f7aaadc1 chore: redirect /team to /team/~ to select a team (#7124)
## [Dashboard] Fix: Simplify team redirection logic

## Notes for the reviewer
This PR modifies the team redirection logic by:
1. Renaming `getLastVisitedTeamOrDefaultTeam()` to `getLastVisitedTeam()`
2. Removing the fallback to `getDefaultTeam()` when no last visited team is found
3. Updating the team root page to redirect to `/team/~` when no team is found instead of showing a 404

## How to test
Verify that users are properly redirected to their last visited team when available, and to `/team/~` when no team history exists.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Bug Fixes**
	- Improved handling when no last visited team is found by redirecting users to a fallback page instead of showing a not found error.

- **Refactor**
	- Updated team selection logic to remove fallback to a default team and streamline user redirection.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR refactors the `getLastVisitedTeamOrDefaultTeam` function to `getLastVisitedTeam`, changing its behavior to return `null` instead of a default team. It updates the `TeamRootPage` to handle the absence of a team by redirecting to a fallback URL.

### Detailed summary
- Renamed function `getLastVisitedTeamOrDefaultTeam` to `getLastVisitedTeam`.
- Changed return value of `getLastVisitedTeam` from `getDefaultTeam()` to `null`.
- Updated `TeamRootPage` to redirect to `/team/~` if no team is found, instead of calling `notFound()`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-22 06:42:40 +00:00
arcoraven 1ad109f3bc chore: update endpoint to rotate secret key (#7122)
## [Dashboard] Fix: Update Secret Key Rotation API Endpoint

## Notes for the reviewer

This PR updates the secret key rotation functionality to use the new team-based API endpoint structure. The `rotateSecretKeyClient` function now requires both `teamId` and `projectId` parameters, and the API endpoint has been updated to follow the `/v1/teams/{teamId}/projects/{projectId}/rotate-secret-key` pattern.

## How to test

Test the secret key rotation functionality in:
1. Project FTUX
2. Nebula FTUX
3. Project General Settings page

Verify that the secret key can be successfully rotated in all these locations.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Updated secret key rotation to require both team and project identifiers for enhanced security and context.
  - Modified components to include team ID alongside project data, improving integration and user experience in project-related sections.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the handling of project and team identifiers in the `NebulaFTUX` and related components, enhancing the functionality for rotating secret keys by including the `teamId` alongside the `projectId`.

### Detailed summary
- Added `teamId` prop to the `NebulaFTUX` component.
- Passed `teamId` from `NebulaFTUX` to `SecretKeySection`.
- Updated `rotateSecretKeyClient` to accept an object with `teamId` and `projectId`.
- Modified the API call in `rotateSecretKeyClient` to use the new parameters.
- Updated the `SecretKeySection` to handle the new `teamId` prop.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-22 06:25:22 +00:00
376bdb23d2 [Dashboard] Feature: Setup payment link UI (#7121)
Co-authored-by: Claude <[email protected]>
2025-05-21 22:40:59 -07:00
Joaquim VergesandGitHub dcd6b99e67 [SDK] Improve error handling in PayEmbed (#7119) 2025-05-21 21:52:31 -07:00
Jonas DanielsandGitHub 88533d9113 Remove advancedEnabled field from Account interface (#7118) 2025-05-21 16:16:21 -07:00
Jonas DanielsandGitHub 6c3a8d36a7 Remove unused account usage API and interface (#7117) 2025-05-21 16:09:16 -07:00
Robby UitbeijerseandGitHub a31ac0c065 [Docs] Chore: Remove Kado references (#7109) 2025-05-21 15:21:40 -07:00
7b72e88611 [SDK] Fix: Apply accentButtonText theme key to the Spinner inside of PayEmbed Buttons (#7110)
Co-authored-by: Joaquim Verges <[email protected]>
2025-05-21 15:21:14 -07:00
Joaquim VergesandGitHub 4b9a506fdf [service-utils] Improve 403 error messages with team and project details (#7114) 2025-05-21 14:07:40 -07:00
Joaquim VergesandGitHub 77da352366 [Dashboard] Add ecosystem name editing functionality (#7115) 2025-05-21 13:54:12 -07:00
Joaquim VergesandGitHub 72cc27a69a [Dashboard] Add ecosystem logo upload functionality (#7113) 2025-05-21 11:02:18 -07:00
Joaquim VergesGitHubJonas Danielsgraphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
46d1dab11e [Docs] Add Vault SDK documentation and guides (#7054)
Signed-off-by: Joaquim Verges <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-05-21 11:01:56 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
a1c432ca17 Version Packages (#7105)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-21 09:59:10 -07:00
kumaryash90 243c661929 Update deploy config (#7111)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating the value of `DEFAULT_FEE_BPS_NEW` in the `addresses.ts` file to reflect a new default fee setting.

### Detailed summary
- Updated the value of `DEFAULT_FEE_BPS_NEW` from `150` to `200` in `apps/dashboard/src/constants/addresses.ts`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Chores**
  - Updated the default fee value from 150 to 200.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-21 16:07:00 +00:00
GiselleNessi b64ffe369a Gi/portal knowledge base (#6993)
<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing the `thirdweb Knowledge Base` by adding new troubleshooting guides, updating existing resources, and improving documentation structure for better user support.

### Detailed summary
- Added a new troubleshooting guide for `Nebula`.
- Introduced detailed steps for resolving `device link errors` in `thirdweb CLI`.
- Updated support links in `Header.tsx`.
- Created new sections for `batch upload issues` and `airdrop contract troubleshooting`.
- Improved layout in `layout.tsx` with `DocLayout`.
- Removed unused `ContractsIcon` from `page.tsx`.
- Enhanced the `knowledge base` sidebar structure.
- Added visual guides and images in multiple `mdx` files for clarity.
- Improved metadata for better SEO and documentation clarity.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a comprehensive Knowledge Base with structured navigation, guides, and troubleshooting for web3 development and thirdweb support.
  - Added detailed documentation on deploying NFT mint sites, creating soulbound tokens, sharing console errors, and resolving CLI device link errors.
  - Launched troubleshooting guides for airdrop contracts, batch upload issues, embed feature changes, and Nebula-specific support.

- **Improvements**
  - Updated navigation links to add a Nebula API reference and consolidated support links to internal resources.

- **Removals**
  - Removed the "Contracts" article card from the learning resources section.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-21 10:32:06 +00:00
Joaquim VergesandGitHub 30fafd16db [SDK] Fix SIWE auth forcing unnecessary chain switch (#7104) 2025-05-20 23:28:53 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
99901dcfd7 Version Packages (#7079)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-20 15:48:08 -07:00
jnsdls f5072d882e Rename "Secret Key" to "Webhook Secret" for consistency (#7102)
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Style**
  - Updated labels and tooltips to use "Webhook Secret" instead of "Secret Key" for improved clarity in the webhook creation interface.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-20 22:10:27 +00:00
iuwqyir e7f7a32dd4 show block gas limit on the chain page (#7101)
## [Dashboard] Feature: Add Block Gas Limit to Chain Live Stats

## Notes for the reviewer

as requested by @0xFirekeeper

This PR enhances the chain live stats component by adding the block gas limit information. The RPC method has been updated from `eth_blockNumber` to `eth_getBlockByNumber` to fetch additional block data including the gas limit.

## How to test

The block gas limit should now be displayed alongside other chain statistics in the dashboard. The component handles loading and error states appropriately.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added display of the latest block's gas limit in the live stats section, including proper handling of loading, error, and unavailable states.

- **Enhancements**
  - Improved the accuracy of live stats by retrieving and displaying more detailed block information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the `live-stats.tsx` component to fetch the latest block information using the `eth_getBlockByNumber` method instead of `eth_blockNumber`. It also introduces the display of the block gas limit in the UI.

### Detailed summary
- Changed JSON-RPC method from `eth_blockNumber` to `eth_getBlockByNumber`.
- Updated parameters to fetch the latest block.
- Added parsing for `blockGasLimit` from the response.
- Modified return object to include `blockGasLimit`.
- Introduced a new UI section to display the block gas limit.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-20 21:55:31 +00:00
d2098ad0bf [SDK] Fix stray keccak256 reference (#7089)
Co-authored-by: Jonas Daniels <[email protected]>
2025-05-20 14:54:41 -07:00
+1
Joaquim VergesGitHubgregfromstlClaudekumaryash90Prithvish BaidyasaminaMaximilian Hubertgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Jonas Danielsarcoraven
d6239785cf [SDK] Always show pay modal even on non-supported UB chains (#7092)
Signed-off-by: samina <[email protected]>
Signed-off-by: Maximilian Hubert <[email protected]>
Co-authored-by: gregfromstl <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: kumaryash90 <[email protected]>
Co-authored-by: Prithvish Baidya <[email protected]>
Co-authored-by: samina <[email protected]>
Co-authored-by: Maximilian Hubert <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: arcoraven <[email protected]>
2025-05-20 14:51:58 -07:00
iuwqyir 20fdd5b6d7 show deprecation in playground UI (#7100)
<!-- start pr-codex -->

## PR-Codex overview
This PR focuses on adding a `deprecated` property to various types and components within the application, allowing for better handling and display of deprecated links and features in the UI.

### Detailed summary
- Added `deprecated` property to `pathInfo` in `navLinks.ts`.
- Updated `MinimalBlueprintSpec` type in `utils.ts` to include `deprecated`.
- Modified `SidebarLink` type in `sidebar.tsx` to optionally include `crossedOut`.
- Enhanced UI to visually indicate deprecated items in `page.tsx`.
- Included `deprecated` status for various API endpoints in `insightBlueprints.ts`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-20 21:04:28 +00:00
iuwqyir 438c019f01 replace chain with chain_id in insight playground (#7099)
## [Playground] Fix: Update chain parameter handling in blueprint playground

## Notes for the reviewer
This PR updates the blueprint playground to use `chain_id` instead of `chain` parameter throughout the codebase. It also adds logic to remove deprecated parameters from the form schema and specifically removes the `chain` parameter if it's present.

## How to test
Test the blueprint playground with various chain selections to ensure the chain_id parameter is correctly populated and that deprecated parameters are not displayed in the form.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Refactor**
  - Updated all references from "chain" to "chain_id" for improved consistency across the playground interface.
  - Deprecated parameters are now excluded from form generation and display.

- **New Features**
  - Blueprint listings can now indicate if a blueprint is deprecated.

- **Chores**
  - Made the API domain configurable via environment variables with a default fallback.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces changes to the `BlueprintSection`, `fetchBlueprintSpec`, and other components to enhance the handling of blueprint parameters, including the addition of a `deprecated` flag and renaming of parameters for consistency. It also updates the API URL handling.

### Detailed summary
- Added optional `deprecated` property to `blueprints` in `BlueprintSection`.
- Introduced `THIRDWEB_INSIGHT_API_DOMAIN` for dynamic API URL in `fetchBlueprintSpec`.
- Renamed parameter `chain` to `chain_id` in multiple places for consistency.
- Removed `chain` parameter if present in `modifyParametersForPlayground`.
- Updated form handling to use `chain_id` instead of `chain` in `ParameterSection`.
- Skipped deprecated parameters in schema creation with `createParametersFormSchema`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-20 20:46:17 +00:00
Jonas DanielsandGitHub 61044013c8 update dependencies (#7098) 2025-05-20 11:52:26 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
e6213db8af chore(deps-dev): bump @storybook/react-vite from 8.6.12 to 8.6.14 (#7088)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:24:24 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
c46b2597be chore(deps-dev): bump vitest from 3.1.2 to 3.1.4 (#7087)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:24:12 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9ff97688ce chore(deps-dev): bump vite from 6.3.4 to 6.3.5 in the npm_and_yarn group (#7068)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:20:20 -07:00
gregandGitHub b4f5cc7b5a Fix: Bridge jsdoc to not mention ox (#7097) 2025-05-20 11:15:06 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
256850d1c6 chore(deps): bump @next/mdx from 15.3.1 to 15.3.2 (#7085)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:13:10 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
acb2b9f85f chore(deps): bump github/codeql-action from 3.28.17 to 3.28.18 (#7084)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:12:54 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6ac62ffe96 chore(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#7083)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:12:40 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
80f4bd4e53 chore(deps): bump changesets/action from 1.5.0 to 1.5.3 (#7082)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-20 11:12:25 -07:00
Joe-Thirdweb a3072c4335 [Dashboard] Adding EDU Chain custom info + assets (#7095)
Adding custom chain info for
EDU Mainnet ( 41923 )
EDU Testnet ( 656476 )

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces new assets and metadata for an education-focused blockchain initiative, enhancing the dashboard with information about the `EDU Mainnet` and `EDU Testnet`.

### Detailed summary
- Added new image imports: `eduBanner` and `eduCTA`.
- Introduced metadata for `EDU Mainnet` (ID: 41923) with header image, description, and CTA.
- Introduced metadata for `EDU Testnet` (ID: 656476) with similar structure as `EDU Mainnet`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-20 17:53:29 +00:00
saminacodes 3277cf6e8e [Docs] Fixed broken links (#7091)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on updating references from "backend wallets" to "server wallets" across various files and adding a new `ArticleCardIndex` component in the `page.tsx` file.

### Detailed summary
- In `sidebar.tsx`, updated `href` for the "Overview" link.
- Added a new `ArticleCardIndex` for "Universal Bridge" in `page.tsx`.
- Changed text from "backend wallets" to "server wallets" in `page.mdx`.
- Updated link in `engine-overview.tsx` to point to server wallet documentation.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-20 17:44:56 +00:00
Jake LooandGitHub 77938c4d5c Update page.mdx for thirdweb-mcp (#7096)
Signed-off-by: Jake Loo <[email protected]>
2025-05-20 10:15:57 -07:00
Vasiliy KirochkaandGitHub 3080a9baba fixing code snippets (#7094) 2025-05-20 09:04:18 -07:00
Joaquim VergesandGitHub 6cf92c6b11 Add AGENTS.md with guidelines (#7093) 2025-05-20 00:18:02 -07:00
+1
Joaquim VergesGitHubgregfromstlClaudekumaryash90Prithvish BaidyasaminaMaximilian Hubertgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Jonas Danielsarcoraven
89ccc80d9c Add Bridge.Onramp functions + port old functions (#7076)
Signed-off-by: samina <[email protected]>
Signed-off-by: Maximilian Hubert <[email protected]>
Co-authored-by: gregfromstl <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: kumaryash90 <[email protected]>
Co-authored-by: Prithvish Baidya <[email protected]>
Co-authored-by: samina <[email protected]>
Co-authored-by: Maximilian Hubert <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: arcoraven <[email protected]>
2025-05-19 19:24:32 -07:00
saminacodes 713ebe0a2d [Docs] Update Engine Pricing (#7080)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR updates the FAQ section in the `page.mdx` file regarding pricing calculations for Engine Cloud. It clarifies the types of requests that incur costs and modifies the note about legacy pricing plans.

### Detailed summary
- Updated pricing calculation to include both write and sign requests.
- Changed the cost description for requests to specify both write and sign requests.
- Revised the note on legacy pricing plans to include a link to the pricing page and clarify the fee specifics.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-19 15:51:01 +00:00
saminacodes bfdac10dcc [Docs] UB Migration & Other Small Things (#7075)
CORE-0000

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on restructuring the `pay` section of the portal by updating links, modifying sidebar navigation, and adding new assets and pages to improve the user experience and documentation clarity.

### Detailed summary
- Added new links to the `links` array for `Bridge`.
- Updated `href` values in `apisLinks` for the Insight API.
- Modified `FooterLinkItem` labels for consistency.
- Created and adjusted multiple `.mdx` pages for the `pay` section.
- Introduced `payRedirects` for improved navigation.
- Updated the sidebar structure for the `pay` section, including new links and icons.
- Added new layout and metadata to `layout.tsx` for better documentation presentation.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-19 04:26:51 +00:00
+1
gregGitHubClaudeJoaquim Vergeskumaryash90Prithvish BaidyasaminaMaximilian Hubertgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Jonas Danielsarcoraven
64964da22e [SDK] Refactor: Update Pay Functions to use UB (#7064)
Signed-off-by: samina <[email protected]>
Signed-off-by: Maximilian Hubert <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
Co-authored-by: kumaryash90 <[email protected]>
Co-authored-by: Prithvish Baidya <[email protected]>
Co-authored-by: samina <[email protected]>
Co-authored-by: Maximilian Hubert <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: arcoraven <[email protected]>
2025-05-19 16:05:15 +12:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
260c2fd370 Version Packages (#7078)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-18 19:12:58 -07:00
Joaquim VergesandGitHub c61e258ec3 [SDK] Expose getInstalledWallets() utility (#7077) 2025-05-18 19:07:42 -07:00
Joaquim VergesandGitHub fdd344184b [Dashboard] Remove taint for THIRDWEB_ENGINE_URL (#7074) 2025-05-17 00:51:54 -07:00
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
0c853e8709 Version Packages (#7073)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-05-17 00:36:55 -07:00
arcoraven 7d47b4cde0 chore: Update Accelerate features list (#7053)
<!-- start pr-codex -->

## PR-Codex overview
This PR focuses on updating the pricing plans and features for the embedded wallets in the dashboard application. It adjusts the plan requirements and modifies the features associated with different plans.

### Detailed summary
- Changed `authRequiredPlan` from `"accelerate"` to `"growth"`.
- Added `"Custom Wallet Branding & Auth"` to the features list.
- Removed `"Custom Wallet Branding & Auth"` from the `TEAM_PLANS` features.
- Increased `$400 Usage Credits` to `$500 Usage Credits` in the `TEAM_PLANS` features.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2025-05-17 07:01:00 +00:00
Jonas DanielsandGitHub feae304da2 Prioritize JWT over service API keys in authentication (#7020) 2025-05-16 16:39:45 -07:00
Joaquim VergesandGitHub 8f605d989c [SDK] Update package READMEs with correct naming and documentation links (#7071) 2025-05-16 05:55:22 -07:00
5174 changed files with 191166 additions and 112563 deletions
+9 -9
View File
@@ -1,5 +1,11 @@
{
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true,
"updateInternalDependents": "always"
},
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"access": "public",
"baseBranch": "main",
"changelog": [
"@changesets/changelog-github",
{
@@ -7,21 +13,15 @@
}
],
"commit": false,
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"playground-web",
"thirdweb-dashboard",
"wallet-ui",
"portal",
"thirdweb-login"
"nebula-app"
],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always",
"onlyUpdatePeerDependentsWhenOutOfRange": true
},
"snapshot": {
"prereleaseTemplate": "{tag}-{commit}-{datetime}"
}
},
"updateInternalDependencies": "patch"
}
+26 -1
View File
@@ -3,7 +3,6 @@ description: Rules for writing features in apps/dashboard
globs: dashboard
alwaysApply: false
---
# Reusable Core UI Components
- Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.
@@ -101,3 +100,29 @@ Guidelines:
- Keep `queryKey` stable and descriptive for cache hits.
- Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.
- Configure `staleTime` / `cacheTime` according to freshness requirements.
# Analytics Event Reporting
- **Add events intentionally** – only when they answer a concrete product/business question.
- **Event name**: human-readable `<subject> <verb>` phrase (e.g. `"contract deployed"`).
- **Reporting helper**: `report<Subject><Verb>` (PascalCase); all live in `src/@/analytics/report.ts`.
- **Mandatory JSDoc**: explain *Why* the event exists and *Who* owns it (`@username`).
- **Typed properties**: accept a single `properties` object and pass it unchanged to `posthog.capture`.
- **Client-side only**: never import `posthog-js` in server components.
- **Housekeeping**: ping **#core-services** before renaming or removing an event.
```ts
/**
* ### Why do we need to report this event?
* - Tracks number of contracts deployed
*
* ### Who is responsible for this event?
* @jnsdls
*/
export function reportContractDeployed(properties: {
address: string;
chainId: number;
}) {
posthog.capture("contract deployed", properties);
}
```
+3 -3
View File
@@ -61,9 +61,9 @@ jobs:
uses: ./.github/composite-actions/install
- name: Setup Biome
uses: biomejs/setup-biome@f382a98e582959e6aaac8e5f8b17b31749018780 # v2.5.0
uses: biomejs/setup-biome@a9763ed3d2388f5746f9dc3e1a55df7f4609bc89 # v2.5.1
with:
version: latest
version: 2.0.6
- run: pnpm lint
@@ -89,7 +89,7 @@ jobs:
- run: pnpm test
- name: Code Coverage
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
directory: packages/
flags: packages
+3 -3
View File
@@ -46,7 +46,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -59,7 +59,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
uses: github/codeql-action/autobuild@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -72,4 +72,4 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- name: Create release Pull Request or publish to NPM
id: changesets
uses: changesets/action@746c25e23caa47dceb6a48ee85b4cbc5a9f5f293 #v1.4.0
uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba #v1.4.0
with:
publish: pnpm release
version: pnpm version-packages
+3 -1
View File
@@ -16,6 +16,7 @@ yalc.lock
./build/
playwright-report/
.env/
.pnpm-store/
# codecov binary
codecov
@@ -31,4 +32,5 @@ storybook-static
.aider*
tsconfig.tsbuildinfo
.cursor
.cursor
apps/dashboard/node-compile-cache
+26 -27
View File
@@ -1,11 +1,32 @@
{
"editor.formatOnSave": true,
"[css]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports.biome": "explicit",
"quickfix.biome": "explicit"
"quickfix.biome": "explicit",
"source.fixAll.biome": "explicit"
},
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"eslint.workingDirectories": [
{ "pattern": "./packages/*/" },
{ "pattern": "./apps/*/" }
],
"typescript.preferences.autoImportFileExcludePatterns": [
"./packages/thirdweb/src/exports"
],
@@ -15,27 +36,5 @@
"next/dist",
"^lucide-react/dist/lucide-react.suffixed$"
],
"typescript.tsdk": "node_modules/typescript/lib",
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[css]": {
"editor.defaultFormatter": "biomejs.biome"
},
"eslint.workingDirectories": [
{ "pattern": "./packages/*/" },
{ "pattern": "./apps/*/" }
]
"typescript.tsdk": "node_modules/typescript/lib"
}
+160
View File
@@ -0,0 +1,160 @@
🤖 Codex Agent Guidelines for thirdweb-dev/js
Welcome, AI copilots! This guide captures the coding standards, architectural decisions, and workflow conventions that every automated agent (and human contributor!) must follow. Unless a rule explicitly targets a sub‑project, it applies repo‑wide.
⸻
1. GitHub Workflow & Etiquette
- Pull‑request titles must start with the affected workspace in brackets (e.g. [SDK], [Dashboard], [Portal], [Playground]).
- Begin the PR description with a one‑sentence summary, then add a checklist of changes and reference issues with Fixes #123.
- Keep commits small and topical – one logical change per commit.
- Branch names should follow area/brief-topic (e.g. sdk/fix-gas-estimate). Avoid personal names.
- Request at least one core maintainer review. Do not self‑merge unless you are the sole owner of that package.
- All CI checks (type‑check, Biome, tests) must pass before merging.
⸻
2. Formatting & Linting
- Biome governs formatting and linting; its rules live in biome.json.
- Run pnpm biome check --apply before committing.
- Avoid editor‑specific configs; rely on the shared settings.
- make sure everything builds after each file change by running `pnpm build`
⸻
3. TypeScript Style Guide
- Write idiomatic TypeScript: explicit function declarations and return types.
- Limit each file to one stateless, single‑responsibility function for clarity and testability.
- Re‑use shared types from @/types or local types.ts barrels.
- Prefer type aliases over interface except for nominal shapes.
- Avoid any and unknown unless unavoidable; narrow generics whenever possible.
- Choose composition over inheritance; leverage utility types (Partial, Pick, etc.).
⸻
4. Testing Strategy
- Co‑locate tests: foo.ts ↔ foo.test.ts.
- Use real function invocations with stub data; avoid brittle mocks.
- For network interactions, use Mock Service Worker (MSW) to intercept fetch/HTTP calls, mocking only scenarios that are hard to reproduce.
- Keep tests deterministic and side‑effect free; Vitest is pre‑configured.
- to run the tests: `cd packages thirdweb & pnpm test:dev <filename>`
⸻
5. packages/thirdweb
5.1 Public API Surface
- Export everything via the exports/ directory, grouped by feature.
- Every public symbol must have comprehensive TSDoc:
- Include at least one @example block that compiles.
- Tag with one custom annotation (@beta, @internal, @experimental, etc.).
- Comment only ambiguous logic; avoid restating TypeScript in prose.
5.2 Performance
- Lazy‑load heavy dependencies inside async paths to keep the initial bundle lean:
`const { jsPDF } = await import("jspdf");`
⸻
6. apps/dashboard & apps/playground
6.1 Core UI Toolkit
- Import primitives from @/components/ui/\_ (e.g. Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator).
- Use NavLink for internal navigation so active states are handled automatically.
- Group feature‑specific components under feature/components/\_ and expose a barrel index.ts when necessary.
6.2 Styling Conventions
- Tailwind CSS is the styling system – no inline styles or CSS modules.
- Merge class names with cn() from @/lib/utils to keep conditional logic readable.
- Stick to design tokens: backgrounds (bg-card), borders (border-border), muted text (text-muted-foreground), etc.
- Expose a className prop on the root element of every component for overrides.
6.3 Component Patterns
- Server Components (run on the Node edge):
-- Read cookies/headers with next/headers.
-- Access server‑only environment variables or secrets.
-- Perform heavy data fetching that should not ship to the client.
-- Implement redirect logic with redirect() from next/navigation.
-- Start files with import "server-only"; to prevent client bundling.
- Client Components (run in the browser):
-- Begin files with 'use client'; before imports.
-- Handle interactive UI relying on React hooks (useState, useEffect, React Query, wallet hooks).
-- Access browser APIs (localStorage, window, IntersectionObserver, etc.).
-- Support fast transitions where data is prefetched on the client.
6.4 Data Fetching Guidelines
- Server Side
-- Always call getAuthToken() to retrieve the JWT from cookies.
-- Inject the token as an Authorization: Bearer header – never embed it in the URL.
-- Return typed results (Project[], User[], …) – avoid any.
- Client Side
-- Wrap calls in React Query (@tanstack/react-query).
-- Use descriptive, stable queryKeys for cache hits.
-- Configure staleTime / cacheTime based on freshness requirements (default ≥ 60 s).
-- Keep tokens secret by calling internal API routes or server actions.
6.5 Analytics Event Reporting
- **When to create a new event**
-- Only add events that answer a clear product or business question.
-- Check `src/@/analytics/report.ts` first; avoid duplicates.
- **Naming conventions**
-- **Event name**: human-readable phrase in the form `<subject> <verb>` (e.g. "contract deployed").
-- **Reporting function**: `report<Subject><Verb>` (PascalCase).
-- All reporting helpers currently live in the shared `report.ts` file.
- **Boilerplate template**
-- Add a JSDoc header explaining **Why** the event exists and **Who** owns it (`@username`).
-- Accept a single typed `properties` object and forward it unchanged to `posthog.capture`.
-- Example:
```ts
/**
* ### Why do we need to report this event?
* - Tracks number of contracts deployed
*
* ### Who is responsible for this event?
* @jnsdls
*/
export function reportContractDeployed(properties: {
address: string;
chainId: number;
}) {
posthog.capture("contract deployed", properties);
}
```
- **Client-side only**: never import `posthog-js` in server components.
- **Housekeeping**: Inform **#eng-core-services** before renaming or removing an existing event.
⸻
7. Performance & Bundle Size
- Track bundle budgets via package.json#size-limit.
- Lazy‑import optional features; avoid top‑level side‑effects.
- De‑duplicate dependencies across packages through pnpm workspace hoisting.
⸻
8. Documentation & Developer Experience
- Each change in packages/\* should contain a changeset for the appropriate package, with the appropriate version bump
- patch for changes that don't impact the public API
- minor for any new/modified public API
- Surface breaking changes prominently in PR descriptions.
- For new UI components, add Storybook stories (\*.stories.tsx) alongside the code.
+290
View File
@@ -0,0 +1,290 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Development Commands
### Package Management
- Use `pnpm install` (or `pnpm install --ignore-scripts` on Windows)
- Monorepo managed with Turborepo and pnpm workspaces
### Building
```bash
# Build all packages
pnpm build
# Build specific packages with dependencies
turbo run build --filter=./packages/*
# Development with watch mode
pnpm dev # Core thirdweb package
pnpm dashboard # Run dashboard + dependencies
pnpm playground # Run playground + dependencies
pnpm portal # Run portal docs + dependencies
```
### Testing
```bash
# Run all tests
pnpm test
# Interactive testing (thirdweb package)
cd packages/thirdweb && pnpm test:devr
# Test specific file
pnpm test:dev <path-to-test-file>
# E2E testing (dashboard)
cd apps/dashboard && pnpm playwright
```
### Code Quality
```bash
# Lint all packages
pnpm lint
# Auto-fix linting issues
pnpm fix
# Format code
turbo run format
# Biome is the primary linter/formatter
```
### Development Workflow
```bash
# Start development server for dashboard
pnpm dashboard
# Start playground for SDK testing
pnpm playground
# Generate changeset for releases
pnpm changeset
# Version packages
pnpm version-packages
```
## Repository Architecture
### Monorepo Structure
This is a Turborepo monorepo with the main thirdweb v5 SDK consolidated into `/packages/thirdweb/`. Legacy packages are in `/legacy_packages/`.
### Core Package (`/packages/thirdweb/`)
**Main Modules:**
- `client/` - ThirdwebClient foundation
- `chains/` - 50+ supported blockchain definitions
- `contract/` - Contract interaction with automatic ABI resolution
- `transaction/` - Transaction management and execution
- `wallets/` - Comprehensive wallet integration system
- `extensions/` - Modular contract extensions (ERC20, ERC721, etc.)
- `auth/` - SIWE authentication and signature verification
- `pay/` - Fiat and crypto payment infrastructure
- `storage/` - IPFS integration for decentralized storage
- `rpc/` - Low-level blockchain communication
**Exports Structure:**
The SDK uses modular exports from `src/exports/` including:
- `thirdweb.ts` - Core client and utilities
- `chains.ts` - Chain definitions
- `wallets.ts` - Wallet connectors
- `react.ts` - React hooks and components
- `extensions/` - Contract standards and protocols
### Applications (`/apps/`)
- **dashboard** - Web-based developer console (Next.js, Chakra UI)
- **playground-web** - Interactive SDK testing environment
- **portal** - Documentation site with MDX
- **nebula** - Account abstraction and smart wallet management
- **wallet-ui** - Wallet interface and testing
### Key Packages (`/packages/`)
- **thirdweb** - Main SDK (TypeScript, React, React Native)
- **engine** - thirdweb Engine API client
- **insight** - Analytics and data APIs
- **nebula** - Account abstraction client
- **service-utils** - Shared utilities across services
## Development Practices
### GitHub Workflow & Pull Requests
- **PR titles**: Must start with affected workspace in brackets (e.g. `[SDK]`, `[Dashboard]`, `[Portal]`, `[Playground]`)
- **PR descriptions**: Begin with one-sentence summary, add checklist of changes, reference issues with `Fixes #123`
- **Commits**: Keep small and topical – one logical change per commit
- **Branch naming**: Use `area/brief-topic` format (e.g. `sdk/fix-gas-estimate`). Avoid personal names
- **Reviews**: Request at least one core maintainer review. Do not self-merge unless sole package owner
- **CI requirements**: All checks (type-check, Biome, tests) must pass before merging
### Code Quality & Formatting
- **Biome**: Primary linter/formatter (rules in `biome.json`)
- **Pre-commit**: Run `pnpm biome check --apply` before committing
- **Build verification**: Run `pnpm build` after each file change to ensure everything builds
- Avoid editor-specific configs; rely on shared settings
### TypeScript Guidelines
- **Style**: Write idiomatic TypeScript with explicit function declarations and return types
- **File structure**: Limit each file to one stateless, single-responsibility function for clarity
- **Types**: Re-use shared types from `@/types` or local `types.ts` barrels
- **Interfaces vs Types**: Prefer type aliases over interface except for nominal shapes
- **Type safety**: Avoid `any` and `unknown` unless unavoidable; narrow generics when possible
- **Architecture**: Choose composition over inheritance; leverage utility types (`Partial`, `Pick`, etc.)
### Testing Strategy
- **Co-location**: Place tests alongside code: `foo.ts` ↔ `foo.test.ts`
- **Test approach**: Use real function invocations with stub data; avoid brittle mocks
- **Network mocking**: Use Mock Service Worker (MSW) for fetch/HTTP call interception
- **Test quality**: Keep tests deterministic and side-effect free
- **Running tests**: `cd packages/thirdweb && pnpm test:dev <filename>`
- **Test accounts**: Predefined accounts in `test/src/test-wallets.ts`
- **Chain forking**: Use `FORKED_ETHEREUM_CHAIN` for mainnet interactions, `ANVIL_CHAIN` for isolated tests
### SDK Development (`packages/thirdweb`)
#### Public API Guidelines
- **Exports**: Export everything via `exports/` directory, grouped by feature
- **Documentation**: Every public symbol must have comprehensive TSDoc with:
- At least one `@example` block that compiles
- Custom annotation tags (`@beta`, `@internal`, `@experimental`)
- **Comments**: Comment only ambiguous logic; avoid restating TypeScript in prose
#### Performance Optimization
- **Lazy loading**: Load heavy dependencies inside async paths to keep initial bundle lean:
```typescript
const { jsPDF } = await import("jspdf");
```
- **Bundle budgets**: Track via `package.json#size-limit`
- **Dependencies**: De-duplicate across packages through pnpm workspace hoisting
### Dashboard & Playground Development
#### UI Component Standards
- **Core components**: Import primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator)
- **Navigation**: Use `NavLink` for internal navigation with automatic active states
- **Organization**: Group feature-specific components under `feature/components/*` with barrel `index.ts`
#### Styling Conventions
- **CSS framework**: Tailwind CSS only – no inline styles or CSS modules
- **Class merging**: Use `cn()` from `@/lib/utils` for conditional logic
- **Design tokens**: Use design system tokens (backgrounds: `bg-card`, borders: `border-border`, muted text: `text-muted-foreground`)
- **Component API**: Expose `className` prop on root element for overrides
#### Component Architecture
- **Server Components** (Node edge):
- Start files with `import "server-only";`
- Read cookies/headers with `next/headers`
- Access server-only environment variables
- Perform heavy data fetching
- Implement redirect logic with `redirect()` from `next/navigation`
- **Client Components** (browser):
- Begin files with `'use client';`
- Handle interactive UI with React hooks (`useState`, `useEffect`, React Query, wallet hooks)
- Access browser APIs (`localStorage`, `window`, `IntersectionObserver`)
- Support fast transitions with prefetched data
#### Data Fetching Patterns
- **Server Side**:
- Always call `getAuthToken()` to retrieve JWT from cookies
- Use `Authorization: Bearer` header – never embed tokens in URLs
- Return typed results (`Project[]`, `User[]`) – avoid `any`
- **Client Side**:
- Wrap calls in React Query (`@tanstack/react-query`)
- Use descriptive, stable `queryKeys` for cache hits
- Configure `staleTime`/`cacheTime` based on freshness (default ≥ 60s)
- Keep tokens secret via internal API routes or server actions
#### Analytics Event Guidelines
- **When to add**: Only create events that answer clear product/business questions
- **Check duplicates**: Review `src/@/analytics/report.ts` first
- **Naming**:
- Event name: human-readable `<subject> <verb>` (e.g. "contract deployed")
- Function: `report<Subject><Verb>` (PascalCase)
- **Template**:
```typescript
/**
* ### Why do we need to report this event?
* - Tracks number of contracts deployed
*
* ### Who is responsible for this event?
* @username
*/
export function reportContractDeployed(properties: {
address: string;
chainId: number;
}) {
posthog.capture("contract deployed", properties);
}
```
- **Client-side only**: Never import `posthog-js` in server components
- **Changes**: Inform **#eng-core-services** before renaming/removing events
### Extension Development
- Extensions follow modular pattern in `src/extensions/`
- Auto-generated contracts from ABI definitions
- Composable functions with TypeScript safety
- Support for read/write operations
### Wallet Architecture
- Unified `Wallet` and `Account` interfaces
- Support for in-app wallets (social/email login)
- Smart wallets with account abstraction
- EIP-1193, EIP-5792, EIP-7702 standard support
## Contribution Workflow
1. **Fork and Clone**: Create fork, clone, create feature branch
2. **Install**: `pnpm install` (use `--ignore-scripts` on Windows)
3. **Develop**: Use appropriate dev commands above
4. **Test**: Write unit tests, run linting, test on demo apps
5. **Changeset**: Run `pnpm changeset` for semantic versioning
6. **PR**: Submit pull request to main branch
### Release Testing
Comment `/release-pr` on PR to trigger dev release to npm for testing.
### Changeset Guidelines
Each change in `packages/*` should contain a changeset for the appropriate package with the appropriate version bump:
- **patch**: Changes that don't impact the public API
- **minor**: Any new/modified public API
- **major**: Breaking changes (surface prominently in PR descriptions)
### Documentation Standards
- For new UI components, add Storybook stories (`*.stories.tsx`) alongside the code
- Surface breaking changes prominently in PR descriptions
- Keep documentation focused on developer experience and practical usage
## Multi-Platform Support
The SDK supports:
- **Web**: React hooks and components
- **React Native**: Mobile-specific exports and components
- **Node.js**: Server-side functionality
- **Framework Adapters**: Wagmi, Ethers compatibility layers
Key files:
- `src/exports/react.native.ts` - React Native specific exports
- `packages/react-native-adapter/` - Mobile platform shims
- `packages/wagmi-adapter/` - Wagmi ecosystem integration
+1 -12
View File
@@ -37,16 +37,13 @@ NEXT_PUBLIC_TYPESENSE_CONTRACT_API_KEY=
# posthog API key
# - not required for prod/staging
NEXT_PUBLIC_POSTHOG_API_KEY="ignored"
NEXT_PUBLIC_POSTHOG_KEY=""
# Stripe Customer portal
NEXT_PUBLIC_STRIPE_KEY=
NEXT_PUBLIC_STRIPE_PAYMENT_METHOD_CFG_ID=
# Needed for contract analytics / blockchain data information
CHAINSAW_API_KEY=
#
# Private (server)
#
@@ -65,17 +62,11 @@ MORALIS_API_KEY=
# - not required to build (unless testing wallet NFTs)>
SSR_ALCHEMY_KEY=
# beehiiv.com API key (used for newsletter signups)
# - not required to build (unless testing newsletter signups)>
BEEHIIV_API_KEY=
# Hubspot Access Token (used for contact us form)
# - not required to build (unless testing contact us form)>
HUBSPOT_ACCESS_TOKEN=
# Github API Token (used for /open-source)
GITHUB_API_TOKEN="ghp_..."
# Upload server url
NEXT_PUBLIC_DASHBOARD_UPLOAD_SERVER="https://storage.thirdweb-preview.com"
@@ -100,8 +91,6 @@ REDIS_URL=""
ANALYTICS_SERVICE_URL=""
# Required for Nebula Chat
NEXT_PUBLIC_NEBULA_URL=""
# required for billing parts of the dashboard (team -> settings -> billing / invoices)
STRIPE_SECRET_KEY=""
+124 -110
View File
@@ -1,52 +1,98 @@
module.exports = {
env: {
browser: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@next/next/recommended",
"plugin:storybook/recommended",
],
overrides: [
// disable restricted imports in chakra
{
files: "src/chakra/**/*",
rules: {
"no-restricted-imports": ["off"],
},
},
// allow direct PostHog imports inside analytics helpers
{
files: "src/@/analytics/**/*",
rules: {
"no-restricted-imports": ["off"],
},
},
// enable rule specifically for TypeScript files
{
files: ["*.ts", "*.tsx"],
rules: {
"@typescript-eslint/explicit-module-boundary-types": ["off"],
},
},
// in test files, allow null assertions and anys and eslint is sometimes weird about the react-scope thing
{
files: ["*test.ts?(x)"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"react/display-name": "off",
},
},
// allow requires in non-transpiled JS files and logical key ordering in config files
{
files: [
"babel-node.js",
"*babel.config.js",
"env.config.js",
"next.config.js",
"webpack.config.js",
"packages/mobile-web/package-builder/**",
],
rules: {},
},
// setupTests can have separated imports for logical grouping
{
files: ["setupTests.ts"],
rules: {
"import/newline-after-import": "off",
},
},
// turn OFF unused vars via eslint
{
files: ["*.ts", "*.tsx"],
rules: {
"@next/next/no-img-element": "off",
"@typescript-eslint/no-unused-vars": "off",
},
},
// THIS NEEDS TO GO LAST!
{
extends: ["biome"],
files: ["*.ts", "*.js", "*.tsx", "*.jsx"],
},
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: {
impliedStrict: true,
jsx: true,
},
ecmaVersion: 2019,
warnOnUnsupportedTypeScriptVersion: true,
},
plugins: ["@typescript-eslint", "react-compiler"],
rules: {
"react-compiler/react-compiler": "error",
"no-restricted-syntax": [
"error",
{
selector: "CallExpression[callee.name='useEffect']",
message:
'Are you *sure* you need to use "useEffect" here? If you loading any async function prefer using "useQuery".',
},
{
selector: "CallExpression[callee.name='createContext']",
message:
'Are you *sure* you need to use a "Context"? In almost all cases you should prefer passing props directly.',
},
{
selector: "CallExpression[callee.name='defineChain']",
message:
"Use useV5DashboardChain instead if you are using it inside a component",
},
{
selector: "CallExpression[callee.name='defineDashboardChain']",
message:
"Use useV5DashboardChain instead if you are using it inside a component",
},
{
selector: "CallExpression[callee.name='mapV4ChainToV5Chain']",
message:
"Use useV5DashboardChain instead if you are using it inside a component",
},
{
selector: "CallExpression[callee.name='resolveScheme']",
message:
"resolveScheme can throw error if resolution fails. Either catch the error and ignore the lint warning or Use `resolveSchemeWithErrorHandler` / `replaceIpfsUrl` utility in dashboard instead",
},
],
"no-restricted-imports": [
"error",
{
paths: [
{
name: "@chakra-ui/react",
// these are provided by tw-components, so we don't want to import them from chakra directly
// these are provided by chakra folder, so we don't want to import them from chakra directly
importNames: [
"Card",
"Button",
@@ -81,48 +127,72 @@ module.exports = {
"StackProps",
],
message:
'Use the equivalent component from "tw-components" instead.',
'import component from "chakra" folder instead if you have to use chakra component, But use shadcn component otherwise',
name: "@chakra-ui/react",
},
{
name: "@chakra-ui/layout",
message:
"Import from `@chakra-ui/react` instead of `@chakra-ui/layout`.",
name: "@chakra-ui/layout",
},
{
name: "@chakra-ui/button",
message:
"Import from `@chakra-ui/react` instead of `@chakra-ui/button`.",
name: "@chakra-ui/button",
},
{
name: "@chakra-ui/menu",
message:
"Import from `@chakra-ui/react` instead of `@chakra-ui/menu`.",
name: "@chakra-ui/menu",
},
{
name: "next/navigation",
importNames: ["useRouter"],
message:
'Use `import { useDashboardRouter } from "@/lib/DashboardRouter";` instead',
name: "next/navigation",
},
{
name: "lucide-react",
importNames: ["Link", "Table", "Sidebar"],
message:
'This is likely a mistake. If you really want to import this - postfix the imported name with Icon. Example - "LinkIcon"',
'Import "posthog-js" directly only within the analytics helpers ("src/@/analytics/*"). Use the exported helpers from "@/analytics/track" elsewhere.',
name: "posthog-js",
},
],
},
],
},
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "react-compiler"],
parserOptions: {
ecmaVersion: 2019,
ecmaFeatures: {
impliedStrict: true,
jsx: true,
},
warnOnUnsupportedTypeScriptVersion: true,
"no-restricted-syntax": [
"error",
{
message:
'Are you *sure* you need to use "useEffect" here? If you loading any async function prefer using "useQuery".',
selector: "CallExpression[callee.name='useEffect']",
},
{
message:
'Are you *sure* you need to use a "Context"? In almost all cases you should prefer passing props directly.',
selector: "CallExpression[callee.name='createContext']",
},
{
message:
"Use useV5DashboardChain instead if you are using it inside a component",
selector: "CallExpression[callee.name='defineChain']",
},
{
message:
"Use useV5DashboardChain instead if you are using it inside a component",
selector: "CallExpression[callee.name='defineDashboardChain']",
},
{
message:
"Use useV5DashboardChain instead if you are using it inside a component",
selector: "CallExpression[callee.name='mapV4ChainToV5Chain']",
},
{
message:
"resolveScheme can throw error if resolution fails. Either catch the error and ignore the lint warning or Use `resolveSchemeWithErrorHandler` / `replaceIpfsUrl` utility in dashboard instead",
selector: "CallExpression[callee.name='resolveScheme']",
},
],
"react-compiler/react-compiler": "error",
},
settings: {
react: {
@@ -131,60 +201,4 @@ module.exports = {
version: "detect",
},
},
overrides: [
// disable restricted imports in tw-components
{
files: "src/tw-components/**/*",
rules: {
"no-restricted-imports": ["off"],
},
},
// enable rule specifically for TypeScript files
{
files: ["*.ts", "*.tsx"],
rules: {
"@typescript-eslint/explicit-module-boundary-types": ["off"],
},
},
// in test files, allow null assertions and anys and eslint is sometimes weird about the react-scope thing
{
files: ["*test.ts?(x)"],
rules: {
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"react/display-name": "off",
},
},
// allow requires in non-transpiled JS files and logical key ordering in config files
{
files: [
"babel-node.js",
"*babel.config.js",
"env.config.js",
"next.config.js",
"webpack.config.js",
"packages/mobile-web/package-builder/**",
],
rules: {},
},
// setupTests can have separated imports for logical grouping
{
files: ["setupTests.ts"],
rules: {
"import/newline-after-import": "off",
},
},
// THIS NEEDS TO GO LAST!
{
files: ["*.ts", "*.js", "*.tsx", "*.jsx"],
extends: ["biome"],
},
],
env: {
browser: true,
node: true,
},
};
+1 -2
View File
@@ -13,9 +13,8 @@ const config: StorybookConfig = {
addons: [
getAbsolutePath("@storybook/addon-onboarding"),
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@chromatic-com/storybook"),
getAbsolutePath("@storybook/addon-interactions"),
getAbsolutePath("@storybook/addon-docs"),
],
framework: {
name: getAbsolutePath("@storybook/nextjs"),
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Preview } from "@storybook/react";
import type { Preview } from "@storybook/nextjs";
import "../src/global.css";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MoonIcon, SunIcon } from "lucide-react";
+2 -14
View File
@@ -1,16 +1,4 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.2/schema.json",
"extends": ["../../biome.json"],
"overrides": [
{
"include": ["src/css/swagger-ui.css"],
"linter": {
"rules": {
"suspicious": {
"noImportantInKeyframe": "off"
}
}
}
}
]
"$schema": "https://biomejs.dev/schemas/2.0.6/schema.json",
"extends": "//"
}
+12 -12
View File
@@ -2,29 +2,29 @@ import { defineConfig } from "checkly";
import { Frequency } from "checkly/constructs";
export default defineConfig({
projectName: "thirdweb.com",
logicalId: "thirdweb-www",
repoUrl: "https://github.com/thirdweb-dev/dashboard",
checks: {
activated: true,
muted: false,
runtimeId: "2023.09",
frequency: Frequency.EVERY_24H,
locations: ["us-east-1", "eu-west-1"],
tags: ["website"],
browserChecks: {
frequency: Frequency.EVERY_24H,
testMatch: "./tests/**/*.spec.ts",
},
checkMatch: "./**/*.check.ts",
frequency: Frequency.EVERY_24H,
ignoreDirectoriesMatch: [],
locations: ["us-east-1", "eu-west-1"],
muted: false,
playwrightConfig: {
use: {
baseURL: process.env.ENVIRONMENT_URL || "https://thirdweb.com",
},
},
browserChecks: {
frequency: Frequency.EVERY_24H,
testMatch: "./tests/**/*.spec.ts",
},
runtimeId: "2023.09",
tags: ["website"],
},
cli: {
runLocation: "eu-west-1",
},
logicalId: "thirdweb-www",
projectName: "thirdweb.com",
repoUrl: "https://github.com/thirdweb-dev/dashboard",
});
+12 -12
View File
@@ -1,17 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
},
"rsc": true,
"style": "default",
"tailwind": {
"baseColor": "neutral",
"config": "tailwind.config.js",
"css": "src/global.css",
"cssVariables": true,
"prefix": ""
},
"tsx": true
}
+20 -17
View File
@@ -6,31 +6,31 @@ module.exports = [
"/bounties",
"/contact-us",
// -- product landing pages --
// -- connect
"/connect",
"/connect/sign-in",
"/connect/account-abstraction",
"/connect/universal-bridge",
"/connect/auth",
"/connect/in-app-wallets",
// -- storage
// -- build category
"/wallets",
"/account-abstraction",
"/payments",
"/auth",
"/in-app-wallets",
"/transactions",
// -- end build category
// -- scale category
"/rpc",
"/insight",
"/storage",
// -- end scale category
// -- nebula
"/nebula",
// --insight
"/insight",
// -- contracts
"/contracts",
"/contracts/modular-contracts",
"/contracts/explore",
"/contracts/deployment-tool",
// -- engine
"/engine",
// -- solutions pages --
"/solutions/gaming",
"/solutions/consumer-apps",
"/solutions/defi",
"/solutions/ecosystem",
"/solutions/:solution_slug",
// -- campaigns --
// "/unlimited-wallets", -- OFF for now
// -- TPP --
@@ -43,7 +43,8 @@ module.exports = [
"/community/ambassadors",
"/community/startup-program",
// -- grants --
"/grant/superchain",
"/grants",
"/superchain",
// -- templates --
"/templates",
"/templates/:template_slug",
@@ -61,4 +62,6 @@ module.exports = [
// -- universal bridge landing pages --
"/universal-bridge-regions/:region_slug",
"/enterprise",
"/token",
"/vault",
];
+7 -8
View File
@@ -1,19 +1,18 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"next": true,
"ignore": [
"src/@/components/ui/**",
"src/components/notices/AnnouncementBanner.tsx",
"src/components/cmd-k-search/index.tsx",
"src/lib/search.ts"
"src/@/components/misc/AnnouncementBanner.tsx",
"src/@/components/cmd-k-search/index.tsx",
"src/@/lib/search.ts"
],
"project": ["src/**"],
"ignoreBinaries": ["only-allow", "biome"],
"ignoreBinaries": ["only-allow"],
"ignoreDependencies": [
"@storybook/blocks",
"@thirdweb-dev/service-utils",
"@thirdweb-dev/vault-sdk",
"@types/color",
"fast-xml-parser"
]
],
"next": true,
"project": ["src/**"]
}
+34 -34
View File
@@ -44,12 +44,37 @@ async function getSingleChain(chainIdOrSlug) {
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.SITE_URL || "https://thirdweb.com",
additionalPaths: async (config) => {
const [framerUrls, allChains] = await Promise.all([
getFramerXML(),
fetchChainsFromApi(),
]);
return [
...framerUrls.map((url) => {
return {
changefreq: config.changefreq,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
loc: url.loc,
priority: config.priority,
};
}),
...allChains.map((chain) => {
return {
changefreq: config.changefreq,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
loc: `/${chain.slug}`,
priority: config.priority,
};
}),
...(await createSearchRecordSitemaps(config)),
];
},
exclude: ["/chain/validate"],
generateRobotsTxt: true,
robotsTxtOptions: {
policies: [
{
userAgent: "*",
// allow all if production
allow: process.env.VERCEL_ENV === "production" ? ["/"] : [],
// disallow all if not production
@@ -58,10 +83,11 @@ module.exports = {
? ["/"]
: // disallow `/team` and `/team/*` if production
["/team", "/team/*"],
userAgent: "*",
},
],
},
exclude: ["/chain/validate"],
siteUrl: process.env.SITE_URL || "https://thirdweb.com",
transform: async (config, _path) => {
let path = _path;
@@ -75,40 +101,14 @@ module.exports = {
path = path.replace("deployer.thirdweb.eth", "thirdweb.eth");
}
return {
alternateRefs: config.alternateRefs ?? [],
changefreq: config.changefreq,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
// => this will be exported as http(s)://<config.siteUrl>/<path>
loc: path,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
alternateRefs: config.alternateRefs ?? [],
};
},
additionalPaths: async (config) => {
const [framerUrls, allChains] = await Promise.all([
getFramerXML(),
fetchChainsFromApi(),
]);
return [
...framerUrls.map((url) => {
return {
loc: url.loc,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
};
}),
...allChains.map((chain) => {
return {
loc: `/${chain.slug}`,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
};
}),
...(await createSearchRecordSitemaps(config)),
];
},
};
/**
* @param {{ changefreq?: any; priority?: any; autoLastmod?: any; }} config
@@ -131,10 +131,10 @@ async function createSearchRecordSitemaps(config) {
parsedLines.map((parsedLine) => {
return getSingleChain(parsedLine.chain_id)
.then((parsedLineChain) => ({
loc: `/${parsedLineChain.slug}/${parsedLine.contract_address}`,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
loc: `/${parsedLineChain.slug}/${parsedLine.contract_address}`,
priority: config.priority,
}))
.catch(() => null);
}),
+84 -78
View File
@@ -12,7 +12,7 @@ const ContentSecurityPolicy = `
style-src 'self' 'unsafe-inline' vercel.live;
font-src 'self' vercel.live assets.vercel.com framerusercontent.com fonts.gstatic.com;
frame-src * data:;
script-src 'self' 'unsafe-eval' 'unsafe-inline' 'wasm-unsafe-eval' 'inline-speculation-rules' *.thirdweb.com *.thirdweb-dev.com vercel.live js.stripe.com framerusercontent.com events.framer.com challenges.cloudflare.com;
script-src 'self' 'unsafe-eval' 'unsafe-inline' 'wasm-unsafe-eval' 'inline-speculation-rules' *.thirdweb.com *.thirdweb-dev.com vercel.live js.stripe.com framerusercontent.com events.framer.com challenges.cloudflare.com googletagmanager.com us-assets.i.posthog.com edit.framer.com;
connect-src * data: blob:;
worker-src 'self' blob:;
block-all-mixed-content;
@@ -46,91 +46,90 @@ function determineIpfsGateways() {
const remotePatterns: RemotePattern[] = [];
if (process.env.API_ROUTES_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.ipfscdn.io`,
protocol: "https",
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-staging.com`,
protocol: "https",
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.API_ROUTES_CLIENT_ID}.thirdwebstorage-dev.com`,
protocol: "https",
});
} else {
// this should only happen in development
remotePatterns.push({
protocol: "https",
hostname: "ipfs.io",
protocol: "https",
});
}
// also add the dashboard clientId ipfs gateway if it is set
if (process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID) {
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.ipfscdn.io`,
protocol: "https",
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-staging.com`,
protocol: "https",
});
remotePatterns.push({
protocol: "https",
hostname: `${process.env.NEXT_PUBLIC_DASHBOARD_CLIENT_ID}.thirdwebstorage-dev.com`,
protocol: "https",
});
}
return remotePatterns;
}
const SENTRY_OPTIONS: SentryBuildOptions = {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
org: "thirdweb-dev",
project: "dashboard",
// An auth token is required for uploading source maps.
authToken: process.env.SENTRY_AUTH_TOKEN,
// Suppresses source map uploading logs during build
silent: true,
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
tunnelRoute: "/err",
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
// Enables automatic instrumentation of Vercel Cron Monitors.
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: false,
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options
org: "thirdweb-dev",
project: "dashboard",
// Suppresses source map uploading logs during build
silent: true,
// Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)
tunnelRoute: "/err",
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
};
// add additional languages to the framer rewrite paths here (english is already included by default)
const FRAMER_ADDITIONAL_LANGUAGES = ["es"];
const baseNextConfig: NextConfig = {
compiler: {
emotion: true,
},
eslint: {
ignoreDuringBuilds: true,
},
productionBrowserSourceMaps: false,
experimental: {
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
serverSourceMaps: false,
taint: true,
webpackBuildWorker: true,
webpackMemoryOptimizations: true,
},
serverExternalPackages: ["pino-pretty"],
async headers() {
return [
{
// Apply these headers to all routes in your application.
source: "/(.*)",
headers: [
...securityHeaders,
{
@@ -138,56 +137,69 @@ const baseNextConfig: NextConfig = {
value: "sec-ch-viewport-width",
},
],
// Apply these headers to all routes in your application.
source: "/(.*)",
},
];
},
images: {
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
dangerouslyAllowSVG: true,
remotePatterns: [
{
hostname: "**.thirdweb.com",
protocol: "https",
},
...determineIpfsGateways(),
],
},
productionBrowserSourceMaps: false,
reactStrictMode: true,
async redirects() {
return getRedirects();
},
async rewrites() {
return [
{
source: "/thirdweb.eth",
destination: "/deployer.thirdweb.eth",
destination: "https://us-assets.i.posthog.com/static/:path*",
source: "/_ph/static/:path*",
},
{
destination: "https://us.i.posthog.com/:path*",
source: "/_ph/:path*",
},
{
destination: "https://us.i.posthog.com/decide",
source: "/_ph/decide",
},
{
destination: "/deployer.thirdweb.eth",
source: "/thirdweb.eth",
},
{
source: "/thirdweb.eth/:path*",
destination: "/deployer.thirdweb.eth/:path*",
source: "/thirdweb.eth/:path*",
},
// re-write /home to / (this is so that logged in users will be able to go to /home and NOT be redirected to the logged in app)
{
source: "/home",
destination: "https://landing.thirdweb.com",
source: "/home",
},
// flatmap the framer paths for the default language and the additional languages
...FRAMER_PATHS.flatMap((path) => [
{
source: path,
destination: `https://landing.thirdweb.com${path}`,
source: path,
},
// this is for additional languages
...FRAMER_ADDITIONAL_LANGUAGES.map((lang) => ({
source: `/${lang}${path}`,
destination: `https://landing.thirdweb.com/${lang}${path}`,
source: `/${lang}${path}`,
})),
]),
];
},
images: {
dangerouslyAllowSVG: true,
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
remotePatterns: [
{
protocol: "https",
hostname: "**.thirdweb.com",
},
...determineIpfsGateways(),
],
},
compiler: {
emotion: true,
},
reactStrictMode: true,
serverExternalPackages: ["pino-pretty"],
};
function getConfig(): NextConfig {
@@ -196,35 +208,29 @@ function getConfig(): NextConfig {
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withPlausibleProxy } = require("next-plausible");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { withSentryConfig } = require("@sentry/nextjs");
return withBundleAnalyzer(
withPlausibleProxy({
customDomain: "https://pl.thirdweb.com",
scriptName: "pl",
})(
withSentryConfig(
{
...baseNextConfig,
// @ts-expect-error - this is a valid option
webpack: (config) => {
if (config.cache) {
config.cache = Object.freeze({
type: "memory",
});
}
config.module = {
...config.module,
exprContextCritical: false,
};
// Important: return the modified config
return config;
},
withSentryConfig(
{
...baseNextConfig,
// @ts-expect-error - this is a valid option
webpack: (config) => {
if (config.cache) {
config.cache = Object.freeze({
type: "memory",
});
}
config.module = {
...config.module,
exprContextCritical: false,
};
// Important: return the modified config
return config;
},
SENTRY_OPTIONS,
),
},
SENTRY_OPTIONS,
),
);
}
+79 -84
View File
@@ -1,58 +1,37 @@
{
"name": "thirdweb-dashboard",
"version": "3.0.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
"dev": "next dev --turbopack",
"build": "NODE_OPTIONS=--max-old-space-size=6144 next build",
"start": "next start",
"format": "biome format ./src --write",
"lint": "biome check ./src && knip && eslint ./src",
"fix": "biome check ./src --fix && eslint ./src --fix",
"typecheck": "tsc --noEmit",
"gen:theme-typings": "chakra-cli tokens src/theme/index.ts",
"postinstall": "pnpm run gen:theme-typings",
"postbuild": "next-sitemap",
"build:analyze": "ANALYZE=true pnpm run build",
"knip": "knip",
"playwright": "playwright test",
"update-checkly": "npx checkly deploy",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@chakra-ui/react": "^2.8.2",
"@chakra-ui/styled-system": "^2.9.2",
"@chakra-ui/theme-tools": "^2.1.2",
"@emotion/react": "11.14.0",
"@emotion/styled": "11.14.0",
"@emotion/styled": "11.14.1",
"@hookform/resolvers": "^3.9.1",
"@marsidev/react-turnstile": "^1.1.0",
"@radix-ui/react-accordion": "^1.2.7",
"@radix-ui/react-alert-dialog": "^1.1.10",
"@radix-ui/react-avatar": "^1.1.6",
"@radix-ui/react-checkbox": "^1.2.2",
"@radix-ui/react-dialog": "1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.11",
"@radix-ui/react-hover-card": "^1.1.10",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-popover": "^1.1.10",
"@radix-ui/react-progress": "^1.1.4",
"@radix-ui/react-radio-group": "^1.3.3",
"@radix-ui/react-select": "^2.2.2",
"@radix-ui/react-separator": "^1.1.4",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-switch": "^1.2.2",
"@radix-ui/react-tooltip": "1.2.3",
"@scalar/api-reference-react": "^0.6.19",
"@sentry/nextjs": "9.13.0",
"@shazow/whatsabi": "0.21.0",
"@tanstack/react-query": "5.74.4",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-alert-dialog": "^1.1.14",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.14",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.7",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.5",
"@radix-ui/react-tooltip": "1.2.7",
"@scalar/api-reference-react": "0.7.25",
"@sentry/nextjs": "9.34.0",
"@shazow/whatsabi": "0.22.2",
"@tanstack/react-query": "5.81.5",
"@tanstack/react-table": "^8.21.3",
"@thirdweb-dev/service-utils": "workspace:*",
"@thirdweb-dev/vault-sdk": "workspace:*",
"@vercel/functions": "2.0.0",
"@vercel/functions": "2.2.2",
"@vercel/og": "^0.6.8",
"abitype": "1.0.8",
"chakra-react-select": "^4.7.6",
@@ -61,90 +40,106 @@
"color": "5.0.0",
"compare-versions": "^6.1.0",
"date-fns": "4.1.0",
"fast-xml-parser": "^5.2.1",
"fetch-event-stream": "0.1.5",
"flat": "^6.0.1",
"framer-motion": "12.9.2",
"fast-xml-parser": "^5.2.5",
"framer-motion": "12.23.0",
"fuse.js": "7.1.0",
"idb-keyval": "^6.2.1",
"input-otp": "^1.4.1",
"ioredis": "^5.6.1",
"ipaddr.js": "^2.2.0",
"lucide-react": "0.503.0",
"next": "15.3.1",
"next-plausible": "^3.12.4",
"lucide-react": "0.525.0",
"next": "15.3.5",
"next-themes": "^0.4.6",
"nextjs-toploader": "^1.6.12",
"nuqs": "^2.4.3",
"p-limit": "^6.2.0",
"papaparse": "^5.5.2",
"papaparse": "^5.5.3",
"pluralize": "^8.0.0",
"posthog-js": "1.67.1",
"prettier": "3.5.3",
"posthog-js": "1.256.1",
"posthog-node": "^5.4.0",
"prettier": "3.6.2",
"qrcode": "^1.5.3",
"react": "19.1.0",
"react-children-utilities": "^2.10.0",
"react-day-picker": "^8.10.1",
"react-dom": "19.1.0",
"react-dropzone": "^14.3.8",
"react-error-boundary": "^5.0.0",
"react-error-boundary": "6.0.0",
"react-hook-form": "7.55.0",
"react-markdown": "^9.0.1",
"react-markdown": "10.1.0",
"react-table": "^7.8.0",
"recharts": "2.15.3",
"remark-gfm": "4.0.1",
"responsive-rsc": "0.0.7",
"server-only": "^0.0.1",
"shiki": "1.27.0",
"sonner": "2.0.3",
"sonner": "2.0.6",
"spdx-correct": "^3.2.0",
"stripe": "17.7.0",
"swagger-ui-react": "^5.21.0",
"swagger-ui-react": "^5.24.1",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"thirdweb": "workspace:*",
"tiny-invariant": "^1.3.3",
"use-debounce": "^10.0.4",
"zod": "3.24.3"
"use-debounce": "^10.0.5",
"vaul": "^1.1.2",
"zod": "3.25.75"
},
"devDependencies": {
"@biomejs/biome": "2.0.6",
"@chakra-ui/cli": "^2.4.1",
"@chromatic-com/storybook": "3.2.6",
"@next/bundle-analyzer": "15.3.1",
"@next/eslint-plugin-next": "15.3.1",
"@playwright/test": "1.52.0",
"@storybook/addon-essentials": "8.6.12",
"@storybook/addon-interactions": "8.6.12",
"@storybook/addon-links": "8.6.12",
"@storybook/addon-onboarding": "8.6.12",
"@storybook/addon-viewport": "8.6.12",
"@storybook/blocks": "8.6.12",
"@storybook/nextjs": "8.6.12",
"@storybook/react": "8.6.12",
"@storybook/test": "8.6.12",
"@chromatic-com/storybook": "4.0.1",
"@next/bundle-analyzer": "15.3.5",
"@next/eslint-plugin-next": "15.3.5",
"@playwright/test": "1.53.2",
"@storybook/addon-docs": "9.0.15",
"@storybook/addon-links": "9.0.15",
"@storybook/addon-onboarding": "9.0.15",
"@storybook/nextjs": "9.0.15",
"@types/color": "4.2.0",
"@types/node": "22.14.1",
"@types/papaparse": "^5.3.15",
"@types/papaparse": "^5.3.16",
"@types/pluralize": "^0.0.33",
"@types/qrcode": "^1.5.5",
"@types/react": "19.1.2",
"@types/react-dom": "19.1.2",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@types/react-table": "^7.7.20",
"@types/spdx-correct": "^3.1.3",
"@types/swagger-ui-react": "^5.18.0",
"@typescript-eslint/eslint-plugin": "7.14.1",
"@typescript-eslint/parser": "7.14.1",
"autoprefixer": "^10.4.21",
"checkly": "5.2.0",
"checkly": "6.0.1",
"eslint": "8.57.0",
"eslint-config-biome": "1.9.4",
"eslint-plugin-react-compiler": "19.0.0-beta-e993439-20250405",
"eslint-plugin-storybook": "0.12.0",
"knip": "5.50.5",
"eslint-plugin-react-compiler": "19.1.0-rc.2",
"eslint-plugin-storybook": "9.0.15",
"knip": "5.60.2",
"next-sitemap": "^4.2.3",
"postcss": "8.5.3",
"storybook": "8.6.12",
"postcss": "8.5.6",
"storybook": "9.0.15",
"tailwindcss": "3.4.17",
"typescript": "5.8.3"
}
},
"name": "thirdweb-dashboard",
"private": true,
"scripts": {
"build": "NODE_OPTIONS=--max-old-space-size=6144 next build",
"build-storybook": "storybook build",
"build:analyze": "ANALYZE=true pnpm run build",
"dev": "next dev --turbopack",
"fix": "biome check ./src --fix && eslint ./src --fix",
"format": "biome format ./src --write",
"gen:theme-typings": "chakra-cli tokens src/chakra/theme/index.ts",
"knip": "knip",
"lint": "biome check ./src && knip && eslint ./src",
"playwright": "playwright test",
"postbuild": "next-sitemap",
"postinstall": "pnpm run gen:theme-typings",
"preinstall": "npx only-allow pnpm",
"start": "next start",
"storybook": "storybook dev -p 6006",
"typecheck": "tsc --noEmit",
"update-checkly": "npx checkly deploy"
},
"version": "3.0.0"
}
+18 -18
View File
@@ -10,25 +10,10 @@ import { defineConfig, devices } from "@playwright/test";
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: process.env.ENVIRONMENT_URL || "http://127.0.0.1:3000",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Configure projects for major browsers */
projects: [
@@ -67,13 +52,28 @@ export default defineConfig({
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
testDir: "./tests",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: process.env.ENVIRONMENT_URL || "http://127.0.0.1:3000",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Run your local dev server before starting the tests */
webServer: process.env.CI
? undefined
: {
command: "pnpm run start",
url: "http://127.0.0.1:3000",
reuseExistingServer: !process.env.CI,
url: "http://127.0.0.1:3000",
},
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
});
+1 -1
View File
@@ -1,6 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
tailwindcss: {},
},
};
Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

@@ -1,3 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.33106 4.3C8.33109 4.3 7.52045 5.11064 7.52045 6.11061C7.52045 7.11058 8.33109 7.92121 9.33106 7.92121C10.331 7.92121 11.1417 7.11058 11.1417 6.11061C11.1417 5.11064 10.331 4.3 9.33106 4.3ZM5.22045 6.11061C5.22045 3.84038 7.06084 2 9.33106 2C11.6013 2 13.4417 3.84038 13.4417 6.11061C13.4417 8.38083 11.6013 10.2212 9.33106 10.2212C7.06084 10.2212 5.22045 8.38083 5.22045 6.11061ZM4.20397 12.0858C4.97486 11.3149 6.0204 10.8818 7.11061 10.8818H11.5515C12.6417 10.8818 13.6873 11.3149 14.4581 12.0858C14.9073 12.5349 14.9073 13.263 14.4581 13.7121C14.009 14.1612 13.2809 14.1612 12.8318 13.7121C12.4922 13.3726 12.0317 13.1818 11.5515 13.1818H7.11061C6.6304 13.1818 6.16987 13.3726 5.83031 13.7121C5.49076 14.0517 5.3 14.5122 5.3 14.9924V16.4727C5.3 17.1079 4.78513 17.6227 4.15 17.6227C3.51487 17.6227 3 17.1079 3 16.4727V14.9924C3 13.9022 3.43308 12.8567 4.20397 12.0858ZM17.5457 14.9598C17.9948 14.5107 17.9948 13.7825 17.5457 13.3334C17.0966 12.8843 16.3685 12.8843 15.9194 13.3334L13.7719 15.4808L13.1048 14.8137C12.6557 14.3646 11.9276 14.3646 11.4785 14.8137C11.0294 15.2628 11.0294 15.991 11.4785 16.4401L12.9588 17.9204C13.4079 18.3695 14.136 18.3695 14.5851 17.9204L17.5457 14.9598Z" fill="#646D7A"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

@@ -1,4 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.4444 3H4.55556C3.69645 3 3 3.69645 3 4.55556V15.4444C3 16.3036 3.69645 17 4.55556 17H15.4444C16.3036 17 17 16.3036 17 15.4444V4.55556C17 3.69645 16.3036 3 15.4444 3Z" stroke="#646D7A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.3333 7.66666L7.66663 12.3333" stroke="#646D7A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

+190 -107
View File
@@ -1,64 +1,132 @@
const legacyDashboardToTeamRedirects = [
{
source: "/dashboard",
destination: "/team",
permanent: false,
source: "/dashboard",
},
{
source: "/dashboard/contracts/:path*",
destination: "/team/~/~/contracts",
permanent: false,
source: "/dashboard/contracts/:path*",
},
{
source: "/dashboard/connect/ecosystem/:path*",
destination: "/team/~/~/ecosystem/:path*",
permanent: false,
source: "/dashboard/connect/ecosystem/:path*",
},
{
source: "/dashboard/engine/:path*",
destination: "/team/~/~/engine/:path*",
permanent: false,
source: "/dashboard/engine/:path*",
},
{
source: "/dashboard/settings/api-keys",
destination: "/team",
permanent: false,
source: "/dashboard/settings/api-keys",
},
{
source: "/dashboard/settings/devices",
destination: "/account/devices",
permanent: false,
source: "/dashboard/settings/devices",
},
{
source: "/dashboard/settings/billing",
destination: "/team/~/~/settings/billing",
permanent: false,
source: "/dashboard/settings/billing",
},
{
source: "/dashboard/settings/gas-credits",
destination: "/team/~/~/settings/credits",
permanent: false,
source: "/dashboard/settings/gas-credits",
},
{
source: "/dashboard/settings/usage",
destination: "/team/~/~/usage",
permanent: false,
source: "/dashboard/settings/usage",
},
{
source: "/dashboard/settings/storage",
destination: "/team/~/~/usage/storage",
permanent: false,
source: "/dashboard/settings/storage",
},
{
source: "/dashboard/settings/notifications",
destination: "/team/~/~/settings/notifications",
permanent: false,
source: "/dashboard/settings/notifications",
},
// rest of the /dashboard/* routes
{
source: "/dashboard/:path*",
destination: "/team",
permanent: false,
source: "/dashboard/:path*",
},
];
const projectRoute = "/team/:team_slug/:project_slug";
const projectPageRedirects = [
{
destination: `${projectRoute}/universal-bridge/:path*`,
permanent: false,
source: `${projectRoute}/connect/pay/:path*`,
},
{
destination: `${projectRoute}/universal-bridge/:path*`,
permanent: false,
source: `${projectRoute}/connect/universal-bridge/:path*`,
},
{
destination: `${projectRoute}/account-abstraction/:path*`,
permanent: false,
source: `${projectRoute}/connect/account-abstraction/:path*`,
},
{
destination: `${projectRoute}/wallets/:path*`,
permanent: false,
source: `${projectRoute}/connect/in-app-wallets/:path*`,
},
{
destination: `${projectRoute}/vault/:path*`,
permanent: false,
source: `${projectRoute}/engine/cloud/vault/:path*`,
},
{
destination: `${projectRoute}/transactions/:path*`,
permanent: false,
source: `${projectRoute}/engine/cloud/:path*`,
},
{
destination: `${projectRoute}/tokens/:path*`,
permanent: false,
source: `${projectRoute}/assets/:path*`,
},
{
destination: projectRoute,
permanent: false,
source: `${projectRoute}/nebula/:path*`,
},
{
destination: `${projectRoute}`,
permanent: false,
source: `${projectRoute}/connect/analytics`,
},
];
const teamPageRedirects = [
{
destination: "/team/:team_slug/~/billing/:path*",
permanent: false,
source: "/team/:team_slug/~/settings/billing/:path*",
},
{
destination: "/team/:team_slug/~/billing/invoices/:path*",
permanent: false,
source: "/team/:team_slug/~/settings/invoices/:path*",
},
{
destination: "/team/:team_slug/~/billing",
permanent: false,
source: "/team/:team_slug/~/settings/credits",
},
];
@@ -66,310 +134,325 @@ const legacyDashboardToTeamRedirects = [
async function redirects() {
return [
{
source: "/portal/:match*",
destination: "https://portal.thirdweb.com/:match*",
permanent: true,
source: "/portal/:match*",
},
{
source: "/solutions/appchain-api",
destination: "/solutions/chains",
permanent: true,
source: "/solutions/appchain-api",
},
{
source: "/contracts/release",
destination: "/contracts/publish",
permanent: false,
source: "/contracts/release",
},
{
source: "/contracts/release/:path*",
destination: "/contracts/publish/:path*",
permanent: false,
source: "/contracts/release/:path*",
},
{
source: "/release",
destination: "/publish",
permanent: false,
source: "/release",
},
{
source: "/release/:path*",
destination: "/publish/:path*",
permanent: false,
source: "/release/:path*",
},
{
source: "/authentication",
destination: "/auth",
permanent: false,
source: "/authentication",
},
{
source: "/extensions",
destination: "/build",
permanent: false,
source: "/extensions",
},
{
source: "/contractkit",
destination: "/build",
permanent: true,
source: "/contractkit",
},
// old (deprecated) routes
{
source:
"/:network/(edition|nft-collection|token|nft-drop|signature-drop|edition-drop|token-drop|vote)/:address",
destination: "/:network/:address",
permanent: false,
source:
"/:network/(edition|nft-collection|token|nft-drop|signature-drop|edition-drop|token-drop|vote)/:address",
},
// prebuilt contract deploys
{
source: "/contracts/new/:slug*",
destination: "/explore",
permanent: false,
source: "/contracts/new/:slug*",
},
// deployer to non-deployer url
// handled directly in SSR as well
{
source: "/deployer.thirdweb.eth",
destination: "/thirdweb.eth",
permanent: true,
source: "/deployer.thirdweb.eth",
},
{
source: "/deployer.thirdweb.eth/:path*",
destination: "/thirdweb.eth/:path*",
permanent: true,
source: "/deployer.thirdweb.eth/:path*",
},
{
source: "/chains",
destination: "/chainlist",
permanent: true,
source: "/chains",
},
// polygon zkevm beta to non-beta
{
source: "/polygon-zkevm-beta",
destination: "/polygon-zkevm",
permanent: false,
source: "/polygon-zkevm-beta",
},
// backwards compat: page moved to pages/settings/devices
{
source: "/template/nft-drop",
destination: "/template/erc721",
permanent: false,
source: "/template/nft-drop",
},
{
destination: "/team",
permanent: false,
source: "/create-api-key",
destination: "/team",
permanent: false,
},
{
destination: "/team",
permanent: false,
source: "/dashboard/settings",
destination: "/team",
permanent: false,
},
{
source: "/dashboard/connect/playground",
destination: "https://playground.thirdweb.com/connect/sign-in/button",
permanent: false,
source: "/dashboard/connect/playground",
},
{
source: "/dashboard/infrastructure/storage",
destination: "/dashboard/settings/storage",
permanent: false,
source: "/dashboard/infrastructure/storage",
},
{
source: "/dashboard/infrastructure/rpc-edge",
destination: "/chainlist",
permanent: false,
source: "/dashboard/infrastructure/rpc-edge",
},
{
source: "/solutions/commerce",
destination: "/solutions/loyalty",
permanent: false,
source: "/solutions/commerce",
},
{
source: "/hackathon/base-consumer-crypto",
destination: "/hackathon/consumer-crypto",
permanent: false,
source: "/hackathon/base-consumer-crypto",
},
{
source: "/bear-market-airdrop",
destination: "/",
permanent: false,
source: "/bear-market-airdrop",
},
{
source: "/drops/optimism",
destination: "/optimism",
permanent: false,
source: "/drops/optimism",
},
// Redirecting as ambassadors lives in community now
{
source: "/ambassadors",
destination: "/community/ambassadors",
permanent: false,
source: "/ambassadors",
},
{
source: "/embedded-wallets",
destination: "/in-app-wallets",
permanent: false,
source: "/embedded-wallets",
},
// temporarily redirect cli login to support page
{
source: "/cli/login",
destination:
"https://support.thirdweb.com/troubleshooting-errors/7Y1BqKNvtLdBv5fZkRZZB3/issue-linking-device-on-the-authorization-page-via-thirdweb-cli/cn9LRA3ax7XCP6uxwRYdvx",
"https://portal.thirdweb.com/knowledge-base/onchain-common-errors/thirdweb-cli/device-link-error",
permanent: false,
source: "/cli/login",
},
// temporary redirect gas -> explore page
{
source: "/gas",
destination: "/explore",
permanent: false,
source: "/gas",
},
{
destination: "/contracts/deployment-tool",
permanent: false,
source: "/deploy",
destination: "/contracts/deployment-tool",
permanent: false,
},
{
destination: "/contracts/deployment-tool",
permanent: false,
source: "/publish",
destination: "/contracts/deployment-tool",
permanent: false,
},
{
source: "/smart-contracts",
destination: "/contracts/explore",
permanent: false,
source: "/smart-contracts",
},
{
source: "/build",
destination: "/contracts/modular-contracts",
destination: "/sdk",
permanent: false,
},
{
source: "/ui-components",
destination: "/sdk",
permanent: false,
},
{
destination: "/sdk",
permanent: false,
source: "/interact",
destination: "/sdk",
permanent: false,
},
{
source: "/sponsored-transactions",
destination: "/account-abstraction",
permanent: false,
source: "/sponsored-transactions",
},
// redirect /solutions/chains to /solutions/ecosystem
{
source: "/solutions/chains",
destination: "/solutions/ecosystem",
permanent: false,
},
// redirect /rpc to portal
{
source: "/rpc-edge",
destination:
"https://portal.thirdweb.com/infrastructure/rpc-edge/overview",
permanent: false,
source: "/solutions/chains",
},
// redirect /sdk to portal
{
source: "/sdk",
destination: "https://portal.thirdweb.com/connect/blockchain-api",
permanent: false,
source: "/sdk",
},
// redirect `/events` to homepage
{
source: "/events",
destination: "/",
permanent: false,
source: "/events",
},
// redirect /community to /community/ambassadors
{
source: "/community",
destination: "/community/ambassadors",
permanent: false,
source: "/community",
},
// redirect `/tos` to `/terms`
{
source: "/tos",
destination: "/terms",
permanent: false,
source: "/tos",
},
// redirect `/privacy` to `/privacy-policy`
{
source: "/privacy",
destination: "/privacy-policy",
permanent: false,
source: "/privacy",
},
// redirect `/mission` to `/home`
{
source: "/mission",
destination: "/home",
permanent: false,
source: "/mission",
},
// redirect "/open-source" to "/bounties"
{
source: "/open-source",
destination: "/bounties",
permanent: false,
source: "/open-source",
},
// redirect /template/<slug> to /templates/<slug>
{
source: "/template/:slug",
destination: "/templates/:slug",
permanent: false,
source: "/template/:slug",
},
// redirect /account-abstraction to /connect/account-abstraction
// redirect /connect/pay to /universal-bridge
{
source: "/account-abstraction",
destination: "/connect/account-abstraction",
destination: "/universal-bridge",
permanent: false,
},
// redirect /connect/pay to /connect/universal-bridge
{
source: "/connect/pay",
destination: "/connect/universal-bridge",
permanent: false,
},
// redirect /auth to /connect/auth
{
source: "/auth",
destination: "/connect/auth",
permanent: false,
},
// redirect /in-app-wallets to /connect/in-app-wallets
{
source: "/in-app-wallets",
destination: "/connect/in-app-wallets",
permanent: false,
},
// PREVIOUS CAMPAIGNS
{
source: "/unlimited-wallets",
destination: "/",
permanent: false,
source: "/unlimited-wallets",
},
// pay > universal-bridge redirect
{
source: "/team/:team_slug/:project_slug/connect/pay/:path*",
destination:
"/team/:team_slug/:project_slug/connect/universal-bridge/:path*",
permanent: false,
},
// all /learn/tutorials (and sub-routes) -> /learn/guides
{
source: "/learn/tutorials/:path*",
destination: "/learn/guides/:path*",
permanent: false,
source: "/learn/tutorials/:path*",
},
{
source: "/learn/tutorials",
destination: "/learn/guides",
permanent: false,
source: "/learn/tutorials",
},
// redirect to /grant/superchain to /superchain
{
destination: "/superchain",
permanent: false,
source: "/grant/superchain",
},
// connect -> build redirects
{
destination: "/wallets",
permanent: false,
source: "/connect",
},
{
destination: "/account-abstraction",
permanent: false,
source: "/connect/account-abstraction",
},
{
destination: "/payments",
permanent: false,
source: "/connect/universal-bridge",
},
{
destination: "/auth",
permanent: false,
source: "/connect/auth",
},
{
destination: "/in-app-wallets",
permanent: false,
source: "/connect/in-app-wallets",
},
{
destination: "/transactions",
permanent: false,
source: "/engine",
},
{
destination: "/rpc",
permanent: false,
source: "/rpc-edge",
},
{
destination: "/payments",
permanent: false,
source: "/universal-bridge",
},
...legacyDashboardToTeamRedirects,
...projectPageRedirects,
...teamPageRedirects,
{
source: "/support/:path*",
destination: "/team/~/~/support",
permanent: false,
},
];
}
+9 -9
View File
@@ -1,7 +1,7 @@
"use server";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function acceptInvite(options: {
teamId: string;
@@ -11,20 +11,20 @@ export async function acceptInvite(options: {
if (!token) {
return {
ok: false,
errorMessage: "You are not authorized to perform this action",
ok: false,
};
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}/invites/${options.inviteId}/accept`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
@@ -42,8 +42,8 @@ export async function acceptInvite(options: {
} catch {}
return {
ok: false,
errorMessage,
ok: false,
};
}
@@ -1,10 +1,6 @@
"use server";
import "server-only";
import { COOKIE_ACTIVE_ACCOUNT, COOKIE_PREFIX_TOKEN } from "@/constants/cookie";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { API_SERVER_SECRET } from "@/constants/server-envs";
import { isVercel } from "lib/vercel-utils";
import { cookies } from "next/headers";
import { getAddress } from "thirdweb";
import type {
@@ -12,7 +8,11 @@ import type {
LoginPayload,
VerifyLoginPayloadParams,
} from "thirdweb/auth";
import { verifyTurnstileToken } from "./verifyTurnstileToken";
import { COOKIE_ACTIVE_ACCOUNT, COOKIE_PREFIX_TOKEN } from "@/constants/cookie";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { API_SERVER_SECRET } from "@/constants/server-envs";
import { isVercel } from "@/utils/vercel";
import { verifyTurnstileToken } from "../../app/login/verifyTurnstileToken";
export async function getLoginPayload(
params: GenerateLoginPayloadParams,
@@ -21,15 +21,15 @@ export async function getLoginPayload(
throw new Error("API_SERVER_SECRET is not set");
}
const res = await fetch(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v2/siwe/payload`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-service-api-key": API_SERVER_SECRET,
},
body: JSON.stringify({
address: params.address,
chainId: params.chainId?.toString(),
}),
headers: {
"Content-Type": "application/json",
"x-service-api-key": API_SERVER_SECRET,
},
method: "POST",
});
if (!res.ok) {
@@ -58,8 +58,8 @@ export async function doLogin(
const result = await verifyTurnstileToken(turnstileToken);
if (!result.success) {
return {
error: "Invalid captcha. Please try again.",
context: result.context,
error: "Invalid captcha. Please try again.",
};
}
}
@@ -80,13 +80,13 @@ export async function doLogin(
// forward the request to the API server
const res = await fetch(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v2/siwe/login`, {
method: "POST",
// set the createAccount flag to true to create a new account if it does not exist
body: JSON.stringify({ ...payload, createAccount: true, utm: utmCookies }),
headers: {
"Content-Type": "application/json",
"x-service-api-key": API_SERVER_SECRET,
},
// set the createAccount flag to true to create a new account if it does not exist
body: JSON.stringify({ ...payload, createAccount: true, utm: utmCookies }),
method: "POST",
});
// if the request failed, log the error and throw an error
@@ -142,20 +142,20 @@ export async function doLogin(
jwt,
{
httpOnly: true,
secure: true,
sameSite: "strict",
// 3 days
maxAge: 3 * 24 * 60 * 60,
sameSite: "strict",
secure: true,
},
);
// set the active account cookie
cookieStore.set(COOKIE_ACTIVE_ACCOUNT, getAddress(payload.payload.address), {
httpOnly: true,
secure: true,
sameSite: "strict",
// 3 days
maxAge: 3 * 24 * 60 * 60,
sameSite: "strict",
secure: true,
});
return {
@@ -186,11 +186,11 @@ export async function isLoggedIn(address: string) {
}
const res = await fetch(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/account/me`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "GET",
});
if (!res.ok) {
@@ -216,10 +216,10 @@ export async function isLoggedIn(address: string) {
// set the active account cookie again
cookieStore.set(COOKIE_ACTIVE_ACCOUNT, getAddress(address), {
httpOnly: false,
secure: true,
sameSite: "strict",
// 3 days
maxAge: 3 * 24 * 60 * 60,
sameSite: "strict",
secure: true,
});
return true;
}
+94 -8
View File
@@ -1,7 +1,10 @@
"use server";
import "server-only";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import type { ChainInfraSKU } from "@/types/billing";
import { getAbsoluteUrl } from "@/utils/vercel";
export async function reSubscribePlan(options: {
teamId: string;
@@ -14,14 +17,17 @@ export async function reSubscribePlan(options: {
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}/checkout/resubscribe-plan`,
new URL(
`/v1/teams/${options.teamId}/checkout/resubscribe-plan`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
),
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "PUT",
},
);
@@ -35,3 +41,83 @@ export async function reSubscribePlan(options: {
status: 200,
};
}
export async function getChainInfraCheckoutURL(options: {
teamSlug: string;
skus: ChainInfraSKU[];
chainId: number;
annual: boolean;
}) {
const token = await getAuthToken();
if (!token) {
return {
error: "You are not logged in",
status: "error",
} as const;
}
const res = await fetch(
new URL(
`/v1/teams/${options.teamSlug}/checkout/create-link`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
),
{
body: JSON.stringify({
annual: options.annual,
baseUrl: getAbsoluteUrl(),
chainId: options.chainId,
skus: options.skus,
}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
if (!res.ok) {
const text = await res.text();
console.error("Failed to create checkout link", text, res.status);
switch (res.status) {
case 402: {
return {
error:
"You have outstanding invoices, please pay these first before re-subscribing.",
status: "error",
} as const;
}
case 429: {
return {
error: "Too many requests, please try again later.",
status: "error",
} as const;
}
case 403: {
return {
error: "You are not authorized to deploy infrastructure.",
status: "error",
} as const;
}
default: {
return {
error: "An unknown error occurred, please try again later.",
status: "error",
} as const;
}
}
}
const json = await res.json();
if (!json.result) {
return {
error: "An unknown error occurred, please try again later.",
status: "error",
} as const;
}
return {
data: json.result as string,
status: "success",
} as const;
}
+7 -7
View File
@@ -1,7 +1,7 @@
"use server";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function confirmEmailWithOTP(otp: string) {
const token = await getAuthToken();
@@ -15,14 +15,14 @@ export async function confirmEmailWithOTP(otp: string) {
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/account/confirmEmail`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
confirmationToken: otp,
}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "PUT",
},
);
@@ -0,0 +1,72 @@
"use server";
import "server-only";
// biome-ignore lint/style/useNodejsImportProtocol: breaks storybook if it's `node:` prefixed
import { randomBytes } from "crypto";
import { format } from "date-fns";
import { getAuthToken } from "@/api/auth-token";
import type { Team } from "@/api/team";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function createTeam(options?: { name?: string; slug?: string }) {
const token = await getAuthToken();
if (!token) {
return {
errorMessage: "You are not authorized to perform this action",
status: "error",
} as const;
}
const res = await fetch(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams`, {
body: JSON.stringify({
billingEmail: null,
image: null,
name:
options?.name ?? `Your Projects ${format(new Date(), "MMM d yyyy")}`,
slug: options?.slug ?? randomBytes(20).toString("hex"),
}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
});
if (!res.ok) {
const reason = await res.text();
console.error("failed to create team", {
reason,
status: res.status,
});
switch (res.status) {
case 400: {
return {
errorMessage: "Invalid team name or slug.",
status: "error",
} as const;
}
case 401: {
return {
errorMessage: "You are not authorized to perform this action.",
status: "error",
} as const;
}
default: {
return {
errorMessage: "An unknown error occurred.",
status: "error",
} as const;
}
}
}
const json = (await res.json()) as {
result: Team;
};
return {
data: json.result,
status: "success",
} as const;
}
@@ -0,0 +1,68 @@
"use server";
import "server-only";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function deleteTeam(options: { teamId: string }) {
const token = await getAuthToken();
if (!token) {
return {
errorMessage: "You are not authorized to perform this action.",
status: "error",
} as const;
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
method: "DELETE",
},
);
// handle errors
if (!res.ok) {
const reason = await res.text();
console.error("failed to delete team", {
reason,
status: res.status,
});
switch (res.status) {
case 400: {
return {
errorMessage: "Invalid team ID.",
status: "error",
} as const;
}
case 401: {
return {
errorMessage: "You are not authorized to perform this action.",
status: "error",
} as const;
}
case 403: {
return {
errorMessage: "You do not have permission to delete this team.",
status: "error",
} as const;
}
case 404: {
return {
errorMessage: "Team not found.",
status: "error",
} as const;
}
default: {
return {
errorMessage: "An unknown error occurred.",
status: "error",
} as const;
}
}
}
return {
status: "success",
} as const;
}
@@ -1,9 +1,9 @@
"use server";
import { defineDashboardChain } from "lib/defineDashboardChain";
import { ZERO_ADDRESS, isAddress, toTokens } from "thirdweb";
import { isAddress, toTokens, ZERO_ADDRESS } from "thirdweb";
import { getWalletBalance } from "thirdweb/wallets";
import { MORALIS_API_KEY } from "../constants/server-envs";
import { serverThirdwebClient } from "../constants/thirdweb-client.server";
import { MORALIS_API_KEY } from "@/constants/server-envs";
import { serverThirdwebClient } from "@/constants/thirdweb-client.server";
import { defineDashboardChain } from "@/lib/defineDashboardChain";
type BalanceQueryResponse = Array<{
balance: string;
@@ -43,12 +43,12 @@ export async function getTokenBalancesFromMoralis(params: {
});
return [
{
token_address: ZERO_ADDRESS,
symbol: balance.symbol,
name: "Native Token",
decimals: balance.decimals,
balance: balance.value.toString(),
decimals: balance.decimals,
display_balance: toTokens(balance.value, balance.decimals),
name: "Native Token",
symbol: balance.symbol,
token_address: ZERO_ADDRESS,
},
];
};
@@ -59,10 +59,10 @@ export async function getTokenBalancesFromMoralis(params: {
const tokenBalanceEndpoint = `https://deep-index.moralis.io/api/v2/${_address}/erc20?chain=${_chain}`;
const resp = await fetch(tokenBalanceEndpoint, {
method: "GET",
headers: {
"x-api-key": MORALIS_API_KEY,
},
method: "GET",
});
if (!resp.ok) {
@@ -83,7 +83,7 @@ export async function getTokenBalancesFromMoralis(params: {
]);
return {
error: undefined,
data: [...nativeBalance, ...tokenBalances],
error: undefined,
};
}
+25 -25
View File
@@ -1,19 +1,19 @@
"use server";
import { NEXT_PUBLIC_DASHBOARD_CLIENT_ID } from "@/constants/public-envs";
import { MORALIS_API_KEY } from "@/constants/server-envs";
import {
generateAlchemyUrl,
transformAlchemyResponseToNFT,
} from "lib/wallet/nfts/alchemy";
} from "@/lib/wallet/nfts/alchemy";
import {
generateMoralisUrl,
transformMoralisResponseToNFT,
} from "lib/wallet/nfts/moralis";
import type { WalletNFT } from "lib/wallet/nfts/types";
import { getVercelEnv } from "../../lib/vercel-utils";
import { isAlchemySupported } from "../../lib/wallet/nfts/isAlchemySupported";
import { isMoralisSupported } from "../../lib/wallet/nfts/isMoralisSupported";
import { NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID } from "../constants/public-envs";
import { MORALIS_API_KEY } from "../constants/server-envs";
} from "@/lib/wallet/nfts/moralis";
import type { WalletNFT } from "@/lib/wallet/nfts/types";
import { getVercelEnv } from "@/utils/vercel";
import { isAlchemySupported } from "../lib/wallet/nfts/isAlchemySupported";
import { isMoralisSupported } from "../lib/wallet/nfts/isMoralisSupported";
type WalletNFTApiReturn =
| { result: WalletNFT[]; error?: undefined }
@@ -53,7 +53,7 @@ export async function getWalletNFTs(params: {
const parsedResponse = await response.json();
const result = await transformAlchemyResponseToNFT(parsedResponse, owner);
return { result, error: undefined };
return { error: undefined, result };
} catch (err) {
console.error("Error fetching NFTs", err);
return { error: "error parsing response" };
@@ -64,10 +64,10 @@ export async function getWalletNFTs(params: {
const url = generateMoralisUrl({ chainId, owner });
const response = await fetch(url, {
method: "GET",
headers: {
"X-API-Key": MORALIS_API_KEY,
},
method: "GET",
next: {
revalidate: 10, // cache for 10 seconds
},
@@ -149,15 +149,15 @@ async function getWalletNFTsFromInsight(params: {
const response = await fetch(url, {
headers: {
"x-client-id": NET_PUBLIC_DASHBOARD_THIRDWEB_CLIENT_ID,
"x-client-id": NEXT_PUBLIC_DASHBOARD_CLIENT_ID,
},
});
if (!response.ok) {
const errorMessage = await response.text();
return {
ok: false,
error: errorMessage,
ok: false,
};
}
@@ -172,32 +172,32 @@ async function getWalletNFTsFromInsight(params: {
const walletNFTs = nftsResponse.data.map((nft) => {
const walletNFT: WalletNFT = {
id: nft.token_id,
chainId: nft.contract.chain_id,
contractAddress: nft.contract.address,
id: nft.token_id,
metadata: {
uri: isDev
? nft.metadata_url.replace("ipfscdn.io/", "thirdwebstorage-dev.com/")
: nft.metadata_url,
name: nft.name,
description: nft.description,
image: isDev
? nft.image_url.replace("ipfscdn.io/", "thirdwebstorage-dev.com/")
: nft.image_url,
animation_url: isDev
? nft.extra_metadata.animation_original_url?.replace(
"ipfscdn.io/",
"thirdwebstorage-dev.com/",
)
: nft.extra_metadata.animation_original_url,
external_url: nft.external_url,
background_color: nft.background_color,
description: nft.description,
external_url: nft.external_url,
image: isDev
? nft.image_url.replace("ipfscdn.io/", "thirdwebstorage-dev.com/")
: nft.image_url,
name: nft.name,
uri: isDev
? nft.metadata_url.replace("ipfscdn.io/", "thirdwebstorage-dev.com/")
: nft.metadata_url,
},
owner: params.owner,
tokenURI: nft.metadata_url,
type: nft.token_type === "erc721" ? "ERC721" : "ERC1155",
supply: nft.balance,
tokenAddress: nft.contract.address,
chainId: nft.contract.chain_id,
tokenURI: nft.metadata_url,
type: nft.token_type === "erc721" ? "ERC721" : "ERC1155",
};
return walletNFT;
+11 -11
View File
@@ -1,11 +1,11 @@
"use server";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { getAuthToken } from "@/api/auth-token";
import {
NEXT_PUBLIC_ENGINE_CLOUD_URL,
NEXT_PUBLIC_THIRDWEB_API_HOST,
} from "../constants/public-envs";
import { ANALYTICS_SERVICE_URL } from "../constants/server-envs";
} from "@/constants/public-envs";
import { ANALYTICS_SERVICE_URL } from "@/constants/server-envs";
type ProxyActionParams = {
pathname: string;
@@ -47,35 +47,35 @@ async function proxy<T>(
}
const res = await fetch(url, {
method: params.method,
body: params.body,
headers: {
...params.headers,
...(authToken ? { Authorization: `Bearer ${authToken}` } : {}),
},
body: params.body,
method: params.method,
});
if (!res.ok) {
try {
const errorMessage = await res.text();
return {
status: res.status,
ok: false,
error: errorMessage || res.statusText,
ok: false,
status: res.status,
};
} catch {
return {
status: res.status,
ok: false,
error: res.statusText,
ok: false,
status: res.status,
};
}
}
return {
status: res.status,
ok: true,
data: params.parseAsText ? await res.text() : await res.json(),
ok: true,
status: res.status,
};
}
@@ -0,0 +1,10 @@
"use server";
import { revalidatePath } from "next/cache";
export async function revalidatePathAction(
path: string,
type: "page" | "layout",
) {
revalidatePath(path, type);
}
@@ -1,7 +1,7 @@
"use server";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function sendTeamInvites(options: {
teamId: string;
@@ -20,8 +20,8 @@ export async function sendTeamInvites(options: {
if (!token) {
return {
ok: false,
errorMessage: "You are not authorized to perform this action",
ok: false,
};
}
@@ -43,15 +43,15 @@ async function sendInvite(
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamId}/invites`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
inviteEmail: invite.email,
inviteRole: invite.role,
}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
@@ -59,8 +59,8 @@ async function sendInvite(
const errorMessage = await res.text();
return {
email: invite.email,
ok: false,
errorMessage,
ok: false,
};
}
+15 -2
View File
@@ -1,8 +1,8 @@
import "server-only";
import Stripe from "stripe";
import type { Team } from "../api/team";
import { STRIPE_SECRET_KEY } from "../constants/server-envs";
import type { Team } from "@/api/team";
import { STRIPE_SECRET_KEY } from "@/constants/server-envs";
let existingStripe: Stripe | undefined;
@@ -59,3 +59,16 @@ export async function getTeamInvoices(
throw new Error("Failed to fetch billing history");
}
}
async function getStripeCustomer(customerId: string) {
return await getStripe().customers.retrieve(customerId);
}
export async function getStripeBalance(customerId: string) {
const customer = await getStripeCustomer(customerId);
if (customer.deleted) {
return 0;
}
// Stripe returns a positive balance for credits, so we need to divide by -100 to get the actual balance (as long as the balance is not 0)
return customer.balance === 0 ? 0 : customer.balance / -100;
}
@@ -1,6 +1,6 @@
"use server";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export async function updateAccount(values: {
name?: string;
@@ -14,12 +14,12 @@ export async function updateAccount(values: {
}
const res = await fetch(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/account`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(values),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "PUT",
});
if (!res.ok) {
+67
View File
@@ -0,0 +1,67 @@
# Analytics Guidelines
This folder centralises the **PostHog** tracking logic for the dashboard app.
Most developers will only need to add or extend _event-reporting_ functions in `report.ts`.
---
## 1. When to add an event
1. Ask yourself if the data will be **actionable**. Every event should have a clear product or business question it helps answer.
2. Check if a similar event already exists in `report.ts`. Avoid duplicates.
---
## 2. Naming conventions
| Concept | Convention | Example |
|---------|------------|---------|
| **Event name** (string sent to PostHog) | Human-readable phrase formatted as `<subject> <verb>` | `"contract deployed"` |
| **Reporting function** | `report<Subject><Verb>` (PascalCase) | `reportContractDeployed` |
| **File** | All event functions live in the shared `report.ts` file (for now) | — |
> Keeping names predictable makes it easy to search both code and analytics.
---
## 3. Boilerplate / template
Add a new function to `report.ts` following this pattern:
```ts
/**
* ### Why do we need to report this event?
* - _Add bullet points explaining the product metrics/questions this event answers._
*
* ### Who is responsible for this event?
* @your-github-handle
*/
export function reportExampleEvent(properties: {
/* Add typed properties here */
}) {
posthog.capture("example event", {
/* Pass the same properties here */
});
}
```
Guidelines:
1. **Explain the "why".** The JSDoc block is mandatory so future contributors know the purpose.
2. **Type everything.** The `properties` object should be fully typed—this doubles as documentation.
3. **Client-side only.** `posthog-js` must never run on the server. Call these reporting helpers from client components, event handlers, etc.
---
## 4. Editing or removing events
1. Update both the function and the PostHog event definition (if required).
2. Inform the core services team before removing or renaming an event.
---
## 5. Identification & housekeeping (FYI)
Most devs can ignore this section, but for completeness:
- `hooks/identify-account.ts` and `hooks/identify-team.ts` wrap `posthog.identify`/`group` calls.
- `resetAnalytics` clears identity state (used on logout).
---
## 6. Need help?
Ping #eng-core-services in slack.
@@ -0,0 +1,20 @@
"use client";
import posthog from "posthog-js";
import { useEffect } from "react";
export function useIdentifyAccount(opts?: {
accountId: string;
email?: string;
}) {
// eslint-disable-next-line no-restricted-syntax
useEffect(() => {
// if no accountId, don't identify
if (!opts?.accountId) {
return;
}
// if email is provided, add it to the identify
posthog.identify(opts.accountId, opts.email ? { email: opts.email } : {});
}, [opts?.accountId, opts?.email]);
}
@@ -0,0 +1,17 @@
"use client";
import posthog from "posthog-js";
import { useEffect } from "react";
export function useIdentifyTeam(opts?: { teamId: string }) {
// eslint-disable-next-line no-restricted-syntax
useEffect(() => {
// if no teamId, don't identify
if (!opts?.teamId) {
return;
}
// identify the team
posthog.group("team", opts.teamId);
}, [opts?.teamId]);
}
@@ -0,0 +1,57 @@
import "server-only";
import { unstable_cache } from "next/cache";
import { PostHog } from "posthog-node";
let _posthogClient: PostHog | null = null;
function getPostHogServer(): PostHog | null {
if (!_posthogClient && process.env.NEXT_PUBLIC_POSTHOG_KEY) {
_posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
host: "https://us.i.posthog.com",
});
}
return _posthogClient;
}
/**
* Check if a feature flag is enabled for a specific user
* @param flagKey - The feature flag key
* @param userEmail - The user's email address for filtering
*/
export const isFeatureFlagEnabled = unstable_cache(
async (params: {
flagKey: string;
accountId: string;
email: string | undefined;
}): Promise<boolean> => {
const posthogClient = getPostHogServer();
if (!posthogClient) {
console.warn("Posthog client not set");
return true;
}
const { flagKey, accountId, email } = params;
try {
if (posthogClient && accountId) {
const isEnabled = await posthogClient.isFeatureEnabled(
flagKey,
accountId,
{
personProperties: email ? { email } : undefined,
},
);
if (isEnabled !== undefined) {
return isEnabled;
}
}
} catch (error) {
console.error(`Error checking feature flag ${flagKey}:`, error);
}
return false;
},
["is-feature-flag-enabled"],
{
revalidate: 3600, // 1 hour
},
);
+415
View File
@@ -0,0 +1,415 @@
import posthog from "posthog-js";
import type { Team } from "@/api/team";
import type { ProductSKU } from "../types/billing";
// ----------------------------
// CONTRACTS
// ----------------------------
/**
* ### Why do we need to report this event?
* - To track the number of contracts deployed
* - To track the number of contracts deployed on each chain
* - To track if the contract was deployed on the token page vs on the deploy page
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportContractDeployed(properties: {
address: string;
chainId: number;
publisher: string | undefined;
contractName: string | undefined;
deploymentType?: "asset";
}) {
posthog.capture("contract deployed", properties);
}
/**
* ### Why do we need to report this event?
* - To track the number of contracts that failed to deploy
* - To track the error message of the failed contract deployment (so we can fix it / add workarounds)
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportContractDeployFailed(properties: {
errorMessage: string;
chainId: number;
publisher: string | undefined;
contractName: string | undefined;
}) {
posthog.capture("contract deploy failed", properties);
}
/**
* ### Why do we need to report this event?
* - To track the number of contracts published
* - To understand the type of contracts published
* - To understand who publishes contracts
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportContractPublished(properties: {
publisher: string;
contractName: string;
version: string;
deployType: string | undefined;
}) {
posthog.capture("contract published", properties);
}
// ----------------------------
// ONBOARDING (TEAM)
// ----------------------------
/**
* ### Why do we need to report this event?
* - To track the number of teams that enter the onboarding flow
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingStarted() {
posthog.capture("onboarding started");
}
/**
* ### Why do we need to report this event?
* - To track the number of teams that select a paid plan during onboarding
* - To know **which** plan was selected
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingPlanSelected(properties: {
plan: Team["billingPlan"];
}) {
posthog.capture("onboarding plan selected", properties);
}
/**
* ### Why do we need to report this event?
* - To track the number of teams that skip the plan-selection step during onboarding
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingPlanSelectionSkipped() {
posthog.capture("onboarding plan selection skipped");
}
/**
* ### Why do we need to report this event?
* - To track the number of teams that invite members during onboarding
* - To track **how many** members were invited
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingMembersInvited(properties: { count: number }) {
posthog.capture("onboarding members invited", {
count: properties.count,
});
}
/**
* ### Why do we need to report this event?
* - To track the number of teams that skip inviting members during onboarding
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingMembersSkipped() {
posthog.capture("onboarding members skipped");
}
/**
* ### Why do we need to report this event?
* - To track how many teams click the upsell (upgrade) button on the member-invite step during onboarding
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingMembersUpsellButtonClicked() {
posthog.capture("onboarding members upsell clicked");
}
/**
* ### Why do we need to report this event?
* - To track which plan is selected from the members-step upsell during onboarding
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingMembersUpsellPlanSelected(properties: {
plan: Team["billingPlan"];
}) {
posthog.capture("onboarding members upsell plan selected", properties);
}
/**
* ### Why do we need to report this event?
* - To track the number of teams that completed onboarding
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportOnboardingCompleted() {
posthog.capture("onboarding completed");
}
// ----------------------------
// FAUCET
// ----------------------------
/**
* ### Why do we need to report this event?
* - To track which chain the faucet was used on
* - To track how popular specific faucets are
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportFaucetUsed(properties: { chainId: number }) {
posthog.capture("faucet used", {
chainId: properties.chainId,
});
}
// ----------------------------
// CHAIN CONFIGURATION
// ----------------------------
/**
* ### Why do we need to report this event?
* - To track which custom chains customers are adding that we may want to add to the app
*
* ### Who is responsible for this event?
* @jnsdls
*
*/
export function reportChainConfigurationAdded(properties: {
chainId: number;
chainName: string;
rpcURLs: readonly string[];
nativeCurrency: {
name: string;
symbol: string;
decimals: number;
};
}) {
posthog.capture("chain configuration added", {
chainId: properties.chainId,
chainName: properties.chainName,
nativeCurrency: properties.nativeCurrency,
rpcURLs: properties.rpcURLs,
});
}
// ----------------------------
// ASSETS
// ----------------------------
type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721";
/**
* ### Why do we need to report this event?
* - To track number of successful asset purchases from the token page
* - To track which asset and contract types are being purchased the most
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetBuySuccessful(properties: {
chainId: number;
contractType: AssetContractType;
assetType: "nft" | "coin";
}) {
posthog.capture("asset buy successful", {
assetType: properties.assetType,
chainId: properties.chainId,
contractType: properties.contractType,
});
}
/**
* ### Why do we need to report this event?
* - To track number of failed asset purchases from the token page
* - To track the errors that users encounter when trying to purchase an asset
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetBuyFailed(properties: {
chainId: number;
contractType: AssetContractType;
assetType: "nft" | "coin";
error: string;
}) {
posthog.capture("asset buy failed", {
assetType: properties.assetType,
chainId: properties.chainId,
contractType: properties.contractType,
error: properties.error,
});
}
// Assets Landing Page ----------------------------
/**
* ### Why do we need to report this event?
* - To track number of asset creation started from the assets page
* - To track which asset types are being created the most
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetCreationStarted(properties: {
assetType: "nft" | "coin";
}) {
posthog.capture("asset creation started", {
assetType: properties.assetType,
});
}
/**
* ### Why do we need to report this event?
* - To track number of assets imported successfully from the assets page
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetImportSuccessful() {
posthog.capture("asset import successful");
}
/**
* ### Why do we need to report this event?
* - To track number of asset import started in the assets page
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetImportStarted() {
posthog.capture("asset import started");
}
/**
* ### Why do we need to report this event?
* - To track the steps users are configuring in the asset creation to understand if there are any drop-offs
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetCreationStepConfigured(
properties:
| {
assetType: "nft";
step: "collection-info" | "upload-assets" | "sales-settings";
}
| {
assetType: "coin";
step: "coin-info" | "token-distribution" | "launch-coin";
},
) {
posthog.capture("asset creation step configured", {
assetType: properties.assetType,
step: properties.step,
});
}
/**
* ### Why do we need to report this event?
* - To track number of successful asset creations
* - To track which asset types are being created the most
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetCreationSuccessful(properties: {
assetType: "nft" | "coin";
contractType: AssetContractType;
}) {
posthog.capture("asset creation successful", {
assetType: properties.assetType,
contractType: properties.contractType,
});
}
/**
* ### Why do we need to report this event?
* - To track number of failed asset creations
* - To track the errors that users encounter when trying to create an asset
* - To track the step that is failing in the asset creation
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportAssetCreationFailed(
properties: { contractType: AssetContractType; error: string } & (
| {
assetType: "nft";
step:
| "deploy-contract"
| "mint-nfts"
| "set-claim-conditions"
| "set-admins";
}
| {
assetType: "coin";
step:
| "deploy-contract"
| "set-claim-conditions"
| "mint-tokens"
| "airdrop-tokens";
}
),
) {
posthog.capture("asset creation failed", {
assetType: properties.assetType,
contractType: properties.contractType,
error: properties.error,
step: properties.step,
});
}
type UpsellParams = {
content: "storage-limit";
campaign: "create-coin" | "create-nft";
sku: Exclude<ProductSKU, null>;
};
/**
* ### Why do we need to report this event?
* - To track how effective the upsells are in driving users to upgrade
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportUpsellShown(properties: UpsellParams) {
posthog.capture("upsell shown", properties);
}
/**
* ### Why do we need to report this event?
* - To track how effective the upsells are in driving users to upgrade
*
* ### Who is responsible for this event?
* @MananTank
*/
export function reportUpsellClicked(properties: UpsellParams) {
posthog.capture("upsell clicked", properties);
}
+7
View File
@@ -0,0 +1,7 @@
"use client";
import posthog from "posthog-js";
export function resetAnalytics() {
posthog.reset();
}
+237 -42
View File
@@ -1,27 +1,64 @@
import "server-only";
import { ANALYTICS_SERVICE_URL } from "@/constants/server-envs";
import type {
AnalyticsQueryParams,
EcosystemWalletStats,
EngineCloudStats,
InAppWalletStats,
RpcMethodStats,
TransactionStats,
UniversalBridgeStats,
UniversalBridgeWalletStats,
UserOpStats,
WalletStats,
WalletUserStats,
} from "types/analytics";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { ANALYTICS_SERVICE_URL } from "../constants/server-envs";
WebhookLatencyStats,
WebhookRequestStats,
WebhookSummaryStats,
} from "@/types/analytics";
import { getAuthToken } from "./auth-token";
import { getChains } from "./chain";
export interface InsightChainStats {
date: string;
chainId: string;
totalRequests: number;
}
export interface InsightStatusCodeStats {
date: string;
httpStatusCode: number;
totalRequests: number;
}
export interface InsightEndpointStats {
date: string;
endpoint: string;
totalRequests: number;
}
interface InsightUsageStats {
date: string;
totalRequests: number;
}
export interface RpcMethodStats {
date: string;
evmMethod: string;
count: number;
}
export interface RpcUsageTypeStats {
date: string;
usageType: string;
count: number;
}
async function fetchAnalytics(
input: string | URL,
init?: RequestInit,
): Promise<Response> {
const token = await getAuthToken();
if (!token) {
throw new Error("You are not authorized to perform this action");
}
@@ -47,22 +84,11 @@ async function fetchAnalytics(
decodeURIComponent(value),
);
}
// client id DEBUG OVERRIDE
// analyticsServiceUrl.searchParams.delete("projectId");
// analyticsServiceUrl.searchParams.delete("teamId");
// analyticsServiceUrl.searchParams.append(
// "teamId",
// "team_cm0lde33r02344w129k5hm2xz",
// );
// analyticsServiceUrl.searchParams.append(
// "projectId",
// "prj_cm4rqwx9b002qrnsnr37wqpo6",
// );
return fetch(analyticsServiceUrl, {
...init,
headers: {
"content-type": "application/json",
Authorization: `Bearer ${token}`,
...init?.headers,
},
});
@@ -87,6 +113,9 @@ function buildSearchParams(params: AnalyticsQueryParams): URLSearchParams {
if (params.period) {
searchParams.append("period", params.period);
}
if (params.limit) {
searchParams.append("limit", params.limit.toString());
}
return searchParams;
}
@@ -98,7 +127,6 @@ export async function getWalletConnections(
`v2/sdk/wallet-connects?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -122,7 +150,6 @@ export async function getInAppWalletUsage(
`v2/wallet/connects?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -146,7 +173,6 @@ export async function getUserOpUsage(
`v2/bundler/usage?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -189,9 +215,9 @@ export async function getAggregateUserOpUsage(
},
{
date: (params.from || new Date()).toISOString(),
successful: 0,
failed: 0,
sponsoredUsd: 0,
successful: 0,
},
);
}
@@ -204,7 +230,6 @@ export async function getClientTransactions(
`v2/sdk/contract-transactions?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -228,7 +253,6 @@ export async function getRpcMethodUsage(
`v2/rpc/evm-methods?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -241,6 +265,26 @@ export async function getRpcMethodUsage(
return json.data as RpcMethodStats[];
}
export async function getRpcUsageByType(
params: AnalyticsQueryParams,
): Promise<RpcUsageTypeStats[]> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/rpc/usage-types?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
console.error("Failed to fetch RPC usage");
return [];
}
const json = await res.json();
return json.data as RpcUsageTypeStats[];
}
export async function getWalletUsers(
params: AnalyticsQueryParams,
): Promise<WalletUserStats[]> {
@@ -249,7 +293,6 @@ export async function getWalletUsers(
`v2/sdk/wallet-connects/users?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -286,7 +329,6 @@ export async function isProjectActive(params: {
`v2/active-usage?${searchParams.toString()}`,
{
method: "GET",
headers: { "Content-Type": "application/json" },
},
);
@@ -297,14 +339,14 @@ export async function isProjectActive(params: {
);
return {
bundler: false,
storage: false,
rpc: false,
nebula: false,
sdk: false,
insight: false,
pay: false,
inAppWallet: false,
ecosystemWallet: false,
inAppWallet: false,
insight: false,
nebula: false,
pay: false,
rpc: false,
sdk: false,
storage: false,
} as ActiveStatus;
}
@@ -356,9 +398,6 @@ export async function getEcosystemWalletUsage(args: {
`v2/wallet/connects?${searchParams.toString()}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
@@ -385,9 +424,6 @@ export async function getUniversalBridgeUsage(args: {
const searchParams = buildSearchParams(args);
const res = await fetchAnalytics(`v2/universal?${searchParams.toString()}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
if (res?.status !== 200) {
@@ -414,9 +450,6 @@ export async function getUniversalBridgeWalletUsage(args: {
`v2/universal/wallets?${searchParams.toString()}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
@@ -425,9 +458,171 @@ export async function getUniversalBridgeWalletUsage(args: {
console.error(
`Failed to fetch universal bridge wallet stats: ${res?.status} - ${res.statusText} - ${reason}`,
);
return null;
return [];
}
const json = await res.json();
return json.data as UniversalBridgeWalletStats[];
}
export async function getEngineCloudMethodUsage(
params: AnalyticsQueryParams,
): Promise<EngineCloudStats[]> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/engine-cloud/requests?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
console.error("Failed to fetch Engine Cloud method usage");
return [];
}
const json = await res.json();
return json.data as EngineCloudStats[];
}
export async function getWebhookSummary(
params: AnalyticsQueryParams & { webhookId: string },
): Promise<{ data: WebhookSummaryStats[] } | { error: string }> {
const searchParams = buildSearchParams(params);
searchParams.append("webhookId", params.webhookId);
const res = await fetchAnalytics(
`v2/webhook/summary?${searchParams.toString()}`,
);
if (!res.ok) {
const reason = await res.text();
return { error: reason };
}
return (await res.json()) as { data: WebhookSummaryStats[] };
}
export async function getWebhookRequests(
params: AnalyticsQueryParams & { webhookId?: string },
): Promise<{ data: WebhookRequestStats[] } | { error: string }> {
const searchParams = buildSearchParams(params);
if (params.webhookId) {
searchParams.append("webhookId", params.webhookId);
}
const res = await fetchAnalytics(
`v2/webhook/requests?${searchParams.toString()}`,
);
if (!res.ok) {
const reason = await res.text();
return { error: reason };
}
return (await res.json()) as { data: WebhookRequestStats[] };
}
export async function getWebhookLatency(
params: AnalyticsQueryParams & { webhookId?: string },
): Promise<{ data: WebhookLatencyStats[] } | { error: string }> {
const searchParams = buildSearchParams(params);
if (params.webhookId) {
searchParams.append("webhookId", params.webhookId);
}
const res = await fetchAnalytics(
`v2/webhook/latency?${searchParams.toString()}`,
);
if (!res.ok) {
const reason = await res.text();
return { error: reason };
}
return (await res.json()) as { data: WebhookLatencyStats[] };
}
export async function getInsightChainUsage(
params: AnalyticsQueryParams,
): Promise<{ data: InsightChainStats[] } | { errorMessage: string }> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/insight/usage/by-chain?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
const reason = await res?.text();
const errMsg = `Failed to fetch Insight chain usage: ${res?.status} - ${res.statusText} - ${reason}`;
console.error(errMsg);
return { errorMessage: errMsg };
}
const json = await res.json();
return { data: json.data as InsightChainStats[] };
}
export async function getInsightStatusCodeUsage(
params: AnalyticsQueryParams,
): Promise<{ data: InsightStatusCodeStats[] } | { errorMessage: string }> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/insight/usage/by-status-code?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
const reason = await res?.text();
const errMsg = `Failed to fetch Insight status code usage: ${res?.status} - ${res.statusText} - ${reason}`;
console.error(errMsg);
return { errorMessage: errMsg };
}
const json = await res.json();
return { data: json.data as InsightStatusCodeStats[] };
}
export async function getInsightEndpointUsage(
params: AnalyticsQueryParams,
): Promise<{ data: InsightEndpointStats[] } | { errorMessage: string }> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/insight/usage/by-endpoint?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
const reason = await res?.text();
const errMsg = `Failed to fetch Insight endpoint usage: ${res?.status} - ${res.statusText} - ${reason}`;
console.error(errMsg);
return { errorMessage: errMsg };
}
const json = await res.json();
return { data: json.data as InsightEndpointStats[] };
}
export async function getInsightUsage(
params: AnalyticsQueryParams,
): Promise<{ data: InsightUsageStats[] } | { errorMessage: string }> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/insight/usage?${searchParams.toString()}`,
{
method: "GET",
},
);
if (res?.status !== 200) {
const reason = await res?.text();
const errMsg = `Failed to fetch Insight usage: ${res?.status} - ${res.statusText} - ${reason}`;
console.error(errMsg);
return { errorMessage: errMsg };
}
const json = await res.json();
return { data: json.data as InsightUsageStats[] };
}
+91
View File
@@ -0,0 +1,91 @@
"use server";
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type AuditLogEntry = {
who: {
text: string;
metadata?: {
email?: string;
image?: string;
wallet?: string;
clientId?: string;
};
type: "user" | "apikey" | "system";
path?: string;
};
what: {
text: string;
action: "create" | "update" | "delete";
path?: string;
in?: {
text: string;
path?: string;
};
description?: string;
resourceType:
| "team"
| "project"
| "team-member"
| "team-invite"
| "contract"
| "secret-key";
};
when: string;
};
type AuditLogApiResponse = {
result: AuditLogEntry[];
nextCursor?: string;
hasMore: boolean;
};
export async function getAuditLogs(teamSlug: string, cursor?: string) {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const url = new URL(
`/v1/teams/${teamSlug}/audit-log`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
);
if (cursor) {
url.searchParams.set("cursor", cursor);
}
// artifically limit page size to 15 for now
url.searchParams.set("take", "15");
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${authToken}`,
},
next: {
// revalidate this query once per 10 seconds (does not need to be more granular than that)
revalidate: 10,
},
});
if (!response.ok) {
// if the status is 402, the most likely reason is that the team is on a free plan
if (response.status === 402) {
return {
reason: "higher_plan_required",
status: "error",
} as const;
}
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
const data = (await response.json()) as AuditLogApiResponse;
return {
data,
status: "success",
} as const;
}
@@ -1,7 +1,7 @@
import { COOKIE_ACTIVE_ACCOUNT, COOKIE_PREFIX_TOKEN } from "@/constants/cookie";
import { LAST_USED_TEAM_ID } from "constants/cookies";
import { cookies } from "next/headers";
import { getClientThirdwebClient } from "../../../../@/constants/thirdweb-client.client";
import { COOKIE_ACTIVE_ACCOUNT, COOKIE_PREFIX_TOKEN } from "@/constants/cookie";
import { LAST_USED_TEAM_ID } from "@/constants/cookies";
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
export async function getAuthToken() {
const cookiesManager = await cookies();
@@ -29,8 +29,18 @@ export async function getAuthTokenWalletAddress() {
return null;
}
export async function getUserThirdwebClient() {
export async function getUserThirdwebClient(params: {
teamId: string | undefined;
}) {
const authToken = await getAuthToken();
if (params.teamId) {
return getClientThirdwebClient({
jwt: authToken,
teamId: params.teamId,
});
}
const cookiesManager = await cookies();
const lastUsedTeamId = cookiesManager.get(LAST_USED_TEAM_ID)?.value;
+2 -38
View File
@@ -1,43 +1,7 @@
import "server-only";
import type { ChainMetadata } from "thirdweb/chains";
import type { ChainService } from "../../app/(app)/(dashboard)/(chain)/types/chain";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { API_SERVER_SECRET } from "../constants/server-envs";
export async function getGasSponsoredChains() {
if (!API_SERVER_SECRET) {
throw new Error("API_SERVER_SECRET is not set");
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/chains/gas-sponsored`,
{
headers: {
"Content-Type": "application/json",
"x-service-api-key": API_SERVER_SECRET,
},
next: {
revalidate: 15 * 60, //15 minutes
},
},
);
if (!res.ok) {
console.error(
"Failed to fetch gas sponsored chains",
res.status,
res.statusText,
);
res.body?.cancel();
return [];
}
try {
return (await res.json()).data as number[];
} catch (e) {
console.error("Failed to parse gas sponsored chains", e);
return [];
}
}
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import type { ChainService } from "@/types/chain";
export function getChains() {
return fetch(
@@ -0,0 +1,40 @@
"use server";
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export async function createDedicatedSupportChannel(
teamIdOrSlug: string,
channelType: "slack" | "telegram",
): Promise<{ error: string | null }> {
const token = await getAuthToken();
if (!token) {
return { error: "Unauthorized" };
}
const res = await fetch(
new URL(
`/v1/teams/${teamIdOrSlug}/dedicated-support-channel`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
),
{
body: JSON.stringify({
type: channelType,
}),
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
if (!res.ok) {
const json = await res.json();
return {
error:
json.error?.message ?? "Failed to create dedicated support channel.",
};
}
return { error: null };
}
@@ -1,22 +1,26 @@
export const authOptions = [
"email",
"phone",
"passkey",
"siwe",
"guest",
"google",
"facebook",
"x",
"discord",
"farcaster",
"telegram",
"github",
"twitch",
"steam",
"apple",
"coinbase",
"line",
] as const;
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type AuthOption =
| "email"
| "phone"
| "passkey"
| "siwe"
| "guest"
| "google"
| "facebook"
| "x"
| "discord"
| "farcaster"
| "telegram"
| "github"
| "twitch"
| "steam"
| "apple"
| "coinbase"
| "line";
export type Ecosystem = {
name: string;
@@ -24,7 +28,7 @@ export type Ecosystem = {
id: string;
slug: string;
permission: "PARTNER_WHITELIST" | "ANYONE";
authOptions: (typeof authOptions)[number][];
authOptions: AuthOption[];
customAuthOptions?: {
authEndpoint?: {
url: string;
@@ -38,7 +42,8 @@ export type Ecosystem = {
smartAccountOptions?: {
defaultChainId: number;
sponsorGas: boolean;
accountFactoryAddress: string;
accountFactoryAddress?: string;
executionMode?: "EIP4337" | "EIP7702";
} | null;
url: string;
status: "active" | "requested" | "paymentFailed";
@@ -46,6 +51,54 @@ export type Ecosystem = {
updatedAt: string;
};
export async function fetchEcosystemList(teamIdOrSlug: string) {
const token = await getAuthToken();
if (!token) {
return [];
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamIdOrSlug}/ecosystem-wallet`,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
if (!res.ok) {
return [];
}
return (await res.json()).result as Ecosystem[];
}
export async function fetchEcosystem(slug: string, teamIdOrSlug: string) {
const token = await getAuthToken();
if (!token) {
return null;
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamIdOrSlug}/ecosystem-wallet/${slug}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
},
);
if (!res.ok) {
const data = await res.json();
console.error(data);
return null;
}
const data = (await res.json()) as { result: Ecosystem };
return data.result;
}
type PartnerPermission = "PROMPT_USER_V1" | "FULL_CONTROL_V1";
export type Partner = {
id: string;
@@ -0,0 +1,86 @@
import "server-only";
import { getAddress } from "thirdweb";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export type ProjectContract = {
id: string;
contractAddress: string;
chainId: string;
createdAt: string;
updatedAt: string;
deploymentType: string | null;
contractType: string | null;
};
export async function getProjectContracts(options: {
teamId: string;
projectId: string;
authToken: string;
deploymentType: string | undefined;
}) {
const url = new URL(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}/projects/${options.projectId}/contracts`,
);
if (options.deploymentType) {
url.searchParams.set("deploymentType", options.deploymentType);
}
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${options.authToken}`,
},
});
if (!res.ok) {
const errorMessage = await res.text();
console.error("Error fetching project contracts");
console.error(errorMessage);
return [];
}
const data = (await res.json()) as {
result: ProjectContract[];
};
return data.result;
}
export type PartialProject = {
id: string;
name: string;
slug: string;
image: string | null;
};
/**
* get a list of projects within a team that have a given contract imported
*/
export async function getContractImportedProjects(options: {
teamId: string;
authToken: string;
chainId: number;
contractAddress: string;
}) {
const url = new URL(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${options.teamId}/projects/contracts/lookup?chainId=${options.chainId}&contractAddress=${getAddress(options.contractAddress)}`,
);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${options.authToken}`,
},
});
if (!res.ok) {
const errorMessage = await res.text();
console.error("Error fetching: /projects/contracts/lookup");
console.error(errorMessage);
return [];
}
const data = (await res.json()) as {
result: PartialProject[];
};
return data.result;
}
@@ -0,0 +1,239 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
"use server";
import { getAuthToken } from "@/api/auth-token";
import { THIRDWEB_INSIGHT_API_DOMAIN } from "@/constants/urls";
export interface WebhookResponse {
id: string;
name: string;
team_id: string;
project_id: string;
webhook_url: string;
webhook_secret: string;
filters: WebhookFilters;
suspended_at: string | null;
suspended_reason: string | null;
disabled: boolean;
created_at: string;
updated_at: string | null;
}
export interface WebhookFilters {
"v1.events"?: {
chain_ids?: string[];
addresses?: string[];
signatures?: Array<{
sig_hash: string;
abi?: string;
params?: Record<string, unknown>;
}>;
};
"v1.transactions"?: {
chain_ids?: string[];
from_addresses?: string[];
to_addresses?: string[];
signatures?: Array<{
sig_hash: string;
abi?: string;
params?: Record<string, unknown>;
}>;
};
}
interface CreateWebhookPayload {
name: string;
webhook_url: string;
filters: WebhookFilters;
}
interface WebhooksListResponse {
data: WebhookResponse[];
error?: string;
}
interface WebhookSingleResponse {
data: WebhookResponse | null;
error?: string;
}
interface TestWebhookPayload {
webhook_url: string;
type?: "event" | "transaction";
}
interface TestWebhookResponse {
success: boolean;
error?: string;
}
type SupportedWebhookChainsResponse =
| { chains: Array<number> }
| { error: string };
export async function createWebhook(
payload: CreateWebhookPayload,
clientId: string,
): Promise<WebhookSingleResponse> {
try {
const authToken = await getAuthToken();
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks`,
{
body: JSON.stringify(payload),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": clientId,
},
method: "POST",
},
);
if (!response.ok) {
const errorText = await response.text();
return {
data: null,
error: `Failed to create webhook: ${errorText}`,
};
}
return (await response.json()) as WebhookSingleResponse;
} catch (error) {
return {
data: null,
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
export async function getWebhooks(
clientId: string,
): Promise<WebhooksListResponse> {
try {
const authToken = await getAuthToken();
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"x-client-id": clientId,
},
method: "GET",
},
);
if (!response.ok) {
const errorText = await response.text();
return {
data: [],
error: `Failed to get webhooks: ${errorText}`,
};
}
return (await response.json()) as WebhooksListResponse;
} catch (error) {
return {
data: [],
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
export async function deleteWebhook(
webhookId: string,
clientId: string,
): Promise<WebhookSingleResponse> {
try {
const authToken = await getAuthToken();
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks/${encodeURIComponent(webhookId)}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"x-client-id": clientId,
},
method: "DELETE",
},
);
if (!response.ok) {
const errorText = await response.text();
return {
data: null,
error: `Failed to delete webhook: ${errorText}`,
};
}
return (await response.json()) as WebhookSingleResponse;
} catch (error) {
return {
data: null,
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
export async function testWebhook(
payload: TestWebhookPayload,
clientId: string,
): Promise<TestWebhookResponse> {
try {
const authToken = await getAuthToken();
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks/test`,
{
body: JSON.stringify(payload),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": clientId,
},
method: "POST",
},
);
if (!response.ok) {
const errorText = await response.text();
return {
error: `Failed to test webhook: ${errorText}`,
success: false,
};
}
return (await response.json()) as TestWebhookResponse;
} catch (error) {
return {
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
success: false,
};
}
}
export async function getSupportedWebhookChains(): Promise<SupportedWebhookChainsResponse> {
try {
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/service/chains`,
{
headers: {
"x-service-api-key": process.env.INSIGHT_SERVICE_API_KEY || "",
},
method: "GET",
},
);
if (!response.ok) {
const errorText = await response.json();
return { error: `Failed to fetch supported chains: ${errorText.error}` };
}
const data = await response.json();
if (Array.isArray(data.data)) {
return { chains: data.data };
}
return { error: "Unexpected response format" };
} catch (error) {
console.error("Error fetching supported chains:", error);
return { error: `Failed to fetch supported chains: ${error}` };
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type LinkedWallet = {
createdAt: string;
+157
View File
@@ -0,0 +1,157 @@
"use server";
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type Notification = {
id: string;
createdAt: string;
accountId: string;
teamId: string | null;
description: string;
readAt: string | null;
ctaText: string;
ctaUrl: string;
};
export type NotificationsApiResponse = {
result: Notification[];
nextCursor?: string;
};
export async function getUnreadNotifications(cursor?: string) {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const url = new URL(
"/v1/dashboard-notifications/unread",
NEXT_PUBLIC_THIRDWEB_API_HOST,
);
if (cursor) {
url.searchParams.set("cursor", cursor);
}
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${authToken}`,
},
});
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
const data = (await response.json()) as NotificationsApiResponse;
return {
data,
status: "success",
} as const;
}
export async function getArchivedNotifications(cursor?: string) {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const url = new URL(
"/v1/dashboard-notifications/archived",
NEXT_PUBLIC_THIRDWEB_API_HOST,
);
if (cursor) {
url.searchParams.set("cursor", cursor);
}
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${authToken}`,
},
});
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
const data = (await response.json()) as NotificationsApiResponse;
return {
data,
status: "success",
} as const;
}
export async function getUnreadNotificationsCount() {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const url = new URL(
"/v1/dashboard-notifications/unread-count",
NEXT_PUBLIC_THIRDWEB_API_HOST,
);
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${authToken}`,
},
});
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
const data = (await response.json()) as {
result: {
unreadCount: number;
};
};
return {
data,
status: "success",
} as const;
}
export async function markNotificationAsRead(notificationId?: string) {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const url = new URL(
"/v1/dashboard-notifications/mark-as-read",
NEXT_PUBLIC_THIRDWEB_API_HOST,
);
const response = await fetch(url, {
// if notificationId is provided, mark it as read, otherwise mark all as read
body: JSON.stringify(notificationId ? { notificationId } : {}),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "PUT",
});
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
return {
status: "success",
} as const;
}
+2 -2
View File
@@ -1,7 +1,7 @@
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import type { ProjectResponse } from "@thirdweb-dev/service-utils";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type Project = ProjectResponse;
+2 -2
View File
@@ -1,6 +1,6 @@
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { API_SERVER_SECRET } from "../constants/server-envs";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { API_SERVER_SECRET } from "@/constants/server-envs";
export type SMSCountryTiers = {
tier1: string[];
+143
View File
@@ -0,0 +1,143 @@
"use server";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import type { SupportTicket } from "../../app/(app)/team/[team_slug]/(team)/~/support/types/tickets";
import { getAuthToken, getAuthTokenWalletAddress } from "./auth-token";
const ESCALATION_FEEDBACK_RATING = 9999;
export async function createSupportTicket(params: {
message: string;
teamSlug: string;
teamId: string;
title: string;
conversationId?: string;
}): Promise<{ data: SupportTicket } | { error: string }> {
const token = await getAuthToken();
if (!token) {
return { error: "No auth token available" };
}
try {
const walletAddress = await getAuthTokenWalletAddress();
const encodedTeamSlug = encodeURIComponent(params.teamSlug);
const apiUrl = `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodedTeamSlug}/support-conversations`;
// Build the payload for creating a conversation
// If the message does not already include wallet address, prepend it
let message = params.message;
if (!message.includes("Wallet address:")) {
message = `Wallet address: ${String(walletAddress || "-")}\n${message}`;
}
const payload = {
markdown: message.trim(),
title: params.title,
};
const body = JSON.stringify(payload);
const headers: Record<string, string> = {
Accept: "application/json",
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
"Accept-Encoding": "identity",
};
const response = await fetch(apiUrl, {
body,
headers,
method: "POST",
});
if (!response.ok) {
const errorText = await response.text();
return { error: `API Server error: ${response.status} - ${errorText}` };
}
const createdConversation: SupportTicket = await response.json();
// Escalate to SIWA feedback endpoint if conversationId is provided
if (params.conversationId) {
try {
const siwaUrl = process.env.NEXT_PUBLIC_SIWA_URL;
if (siwaUrl) {
await fetch(`${siwaUrl}/v1/chat/feedback`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...(params.teamId ? { "x-team-id": params.teamId } : {}),
},
body: JSON.stringify({
conversationId: params.conversationId,
feedbackRating: ESCALATION_FEEDBACK_RATING,
}),
});
}
} catch (error) {
// Log error but don't fail the ticket creation
console.error("Failed to escalate to SIWA feedback:", error);
}
}
return { data: createdConversation };
} catch (error) {
return {
error: `Failed to create support ticket: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
export async function sendMessageToTicket(request: {
ticketId: string;
teamSlug: string;
teamId: string;
message: string;
}): Promise<{ success: true } | { error: string }> {
if (!request.ticketId || !request.teamSlug) {
return { error: "Ticket ID and team slug are required" };
}
const token = await getAuthToken();
if (!token) {
return { error: "No auth token available" };
}
try {
const encodedTeamSlug = encodeURIComponent(request.teamSlug);
const encodedTicketId = encodeURIComponent(request.ticketId);
const apiUrl = `${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${encodedTeamSlug}/support-conversations/${encodedTicketId}/messages`;
// Append /unthread send for customer messages to ensure proper routing
const messageWithUnthread = `${request.message.trim()}\n/unthread send`;
const payload = {
markdown: messageWithUnthread,
};
const body = JSON.stringify(payload);
const headers: Record<string, string> = {
Accept: "application/json",
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
"Accept-Encoding": "identity",
...(request.teamId ? { "x-team-id": request.teamId } : {}),
};
const response = await fetch(apiUrl, {
body,
headers,
method: "POST",
});
if (!response.ok) {
const errorText = await response.text();
return { error: `API Server error: ${response.status} - ${errorText}` };
}
return { success: true };
} catch (error) {
return {
error: `Failed to send message: ${error instanceof Error ? error.message : "Unknown error"}`,
};
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type TeamInvite = {
id: string;
+11 -5
View File
@@ -1,10 +1,10 @@
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { getAuthToken } from "./auth-token";
const TeamAccountRole = {
OWNER: "OWNER",
MEMBER: "MEMBER",
OWNER: "OWNER",
} as const;
export type TeamAccountRole =
@@ -33,7 +33,7 @@ export async function getMembers(teamSlug: string) {
}
const teamsRes = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamSlug}/members`,
new URL(`/v1/teams/${teamSlug}/members`, NEXT_PUBLIC_THIRDWEB_API_HOST),
{
headers: {
Authorization: `Bearer ${token}`,
@@ -48,7 +48,10 @@ export async function getMembers(teamSlug: string) {
return undefined;
}
export async function getMemberById(teamSlug: string, memberId: string) {
export async function getMemberByAccountId(
teamSlug: string,
accountId: string,
) {
const token = await getAuthToken();
if (!token) {
@@ -56,7 +59,10 @@ export async function getMemberById(teamSlug: string, memberId: string) {
}
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamSlug}/members/${memberId}`,
new URL(
`/v1/teams/${teamSlug}/members/${accountId}`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
),
{
headers: {
Authorization: `Bearer ${token}`,
+69 -4
View File
@@ -1,6 +1,6 @@
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import type { ProductSKU } from "../lib/billing";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import type { ChainInfraSKU, ProductSKU } from "@/types/billing";
type InvoiceLine = {
// amount for this line item
@@ -22,7 +22,7 @@ type Invoice = {
export type TeamSubscription = {
id: string;
type: "PLAN" | "USAGE" | "PLAN_ADD_ON" | "PRODUCT";
type: "PLAN" | "USAGE" | "PLAN_ADD_ON" | "PRODUCT" | "CHAIN";
status:
| "incomplete"
| "incomplete_expired"
@@ -37,6 +37,13 @@ export type TeamSubscription = {
trialStart: string | null;
trialEnd: string | null;
upcomingInvoice: Invoice;
skus: (ProductSKU | ChainInfraSKU)[];
};
type ChainTeamSubscription = Omit<TeamSubscription, "skus"> & {
chainId: string;
skus: ChainInfraSKU[];
isLegacy: boolean;
};
export async function getTeamSubscriptions(slug: string) {
@@ -60,3 +67,61 @@ export async function getTeamSubscriptions(slug: string) {
}
return null;
}
const CHAIN_PLAN_TO_INFRA = {
"chain:plan:gold": ["chain:infra:rpc", "chain:infra:account_abstraction"],
"chain:plan:platinum": [
"chain:infra:rpc",
"chain:infra:insight",
"chain:infra:account_abstraction",
],
"chain:plan:ultimate": [
"chain:infra:rpc",
"chain:infra:insight",
"chain:infra:account_abstraction",
],
};
export async function getChainSubscriptions(slug: string) {
const allSubscriptions = await getTeamSubscriptions(slug);
if (!allSubscriptions) {
return null;
}
// first replace any sku that MIGHT match a chain plan
const updatedSubscriptions = allSubscriptions
.filter((s) => s.type === "CHAIN")
.map((s) => {
const skus = s.skus;
const updatedSkus = skus.flatMap((sku) => {
const plan =
CHAIN_PLAN_TO_INFRA[sku as keyof typeof CHAIN_PLAN_TO_INFRA];
return plan ? plan : sku;
});
return {
...s,
isLegacy: updatedSkus.length !== skus.length,
skus: updatedSkus,
};
});
return updatedSubscriptions.filter(
(s): s is ChainTeamSubscription =>
"chainId" in s && typeof s.chainId === "string",
);
}
export async function getChainSubscriptionForChain(
slug: string,
chainId: number,
) {
const chainSubscriptions = await getChainSubscriptions(slug);
if (!chainSubscriptions) {
return null;
}
return (
chainSubscriptions.find((s) => s.chainId === chainId.toString()) ?? null
);
}
+30 -7
View File
@@ -1,10 +1,12 @@
import "server-only";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { API_SERVER_SECRET } from "@/constants/server-envs";
import type { TeamResponse } from "@thirdweb-dev/service-utils";
import { cookies } from "next/headers";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { LAST_USED_TEAM_ID } from "../../constants/cookies";
import { LAST_USED_TEAM_ID } from "@/constants/cookies";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { API_SERVER_SECRET } from "@/constants/server-envs";
import { getValidAccount } from "../../app/(app)/account/settings/getAccount";
import { getAuthToken } from "./auth-token";
import { getMemberByAccountId } from "./team-members";
export type Team = TeamResponse & { stripeCustomerId: string | null };
@@ -46,7 +48,7 @@ export async function service_getTeamBySlug(slug: string) {
return null;
}
export function getTeamById(id: string) {
function getTeamById(id: string) {
return getTeamBySlug(id);
}
@@ -67,6 +69,7 @@ export async function getTeams() {
return null;
}
/** @deprecated */
export async function getDefaultTeam() {
const token = await getAuthToken();
if (!token) {
@@ -84,7 +87,7 @@ export async function getDefaultTeam() {
return null;
}
export async function getLastVisitedTeamOrDefaultTeam() {
export async function getLastVisitedTeam() {
const token = await getAuthToken();
if (!token) {
return null;
@@ -100,5 +103,25 @@ export async function getLastVisitedTeamOrDefaultTeam() {
}
}
return getDefaultTeam();
return null;
}
export async function hasToCompleteTeamOnboarding(
team: Team,
pagePath: string,
) {
// if the team is already onboarded, we don't need to check anything else here
if (team.isOnboarded) {
return false;
}
const account = await getValidAccount(pagePath);
const teamMember = await getMemberByAccountId(team.slug, account.id);
// if the team member is not an owner (or we cannot find them), they cannot complete onboarding anyways
if (teamMember?.role !== "OWNER") {
return false;
}
// if we get here the team is not onboarded and the team member is an owner, so we need to show the onboarding page
return true;
}
@@ -1,6 +1,6 @@
"use server";
import { getAuthToken } from "app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_BRIDGE_HOST } from "../../constants/public-envs";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_BRIDGE_HOST } from "@/constants/public-envs";
const UB_BASE_URL = NEXT_PUBLIC_THIRDWEB_BRIDGE_HOST;
@@ -14,19 +14,16 @@ type Webhook = {
version?: number; // TODO (UB) make this mandatory after migration
};
export async function getWebhooks(props: {
clientId: string;
teamId: string;
}) {
export async function getWebhooks(props: { clientId: string; teamId: string }) {
const authToken = await getAuthToken();
const res = await fetch(`${UB_BASE_URL}/v1/developer/webhooks`, {
method: "GET",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
Authorization: `Bearer ${authToken}`,
},
method: "GET",
});
if (!res.ok) {
@@ -47,27 +44,21 @@ export async function createWebhook(props: {
secret?: string;
}) {
const authToken = await getAuthToken();
console.log(
"UB_BASE_URL",
UB_BASE_URL,
props.clientId,
props.teamId,
authToken,
);
const res = await fetch(`${UB_BASE_URL}/v1/developer/webhooks`, {
method: "POST",
body: JSON.stringify({
url: props.url,
label: props.label,
version: props.version,
secret: props.secret,
url: props.url,
version: props.version,
}),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
Authorization: `Bearer ${authToken}`,
},
method: "POST",
});
if (!res.ok) {
@@ -87,13 +78,13 @@ export async function deleteWebhook(props: {
const res = await fetch(
`${UB_BASE_URL}/v1/developer/webhooks/${props.webhookId}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
Authorization: `Bearer ${authToken}`,
},
method: "DELETE",
},
);
@@ -112,19 +103,16 @@ export type Fee = {
updatedAt: string;
};
export async function getFees(props: {
clientId: string;
teamId: string;
}) {
export async function getFees(props: { clientId: string; teamId: string }) {
const authToken = await getAuthToken();
const res = await fetch(`${UB_BASE_URL}/v1/developer/fees`, {
method: "GET",
headers: {
"Content-Type": "application/json",
"x-team-id": props.teamId,
"x-client-id": props.clientId,
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
},
method: "GET",
});
if (!res.ok) {
@@ -144,17 +132,17 @@ export async function updateFee(props: {
}) {
const authToken = await getAuthToken();
const res = await fetch(`${UB_BASE_URL}/v1/developer/fees`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"x-team-id": props.teamId,
"x-client-id": props.clientId,
Authorization: `Bearer ${authToken}`,
},
body: JSON.stringify({
feeRecipient: props.feeRecipient,
feeBps: props.feeBps,
feeRecipient: props.feeRecipient,
}),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
},
method: "PUT",
});
if (!res.ok) {
@@ -231,13 +219,13 @@ export async function getPayments(props: {
}
const res = await fetch(url, {
method: "GET",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.clientId,
"x-team-id": props.teamId,
Authorization: `Bearer ${authToken}`,
},
method: "GET",
});
if (!res.ok) {
@@ -0,0 +1,45 @@
import "server-only";
import { DASHBOARD_THIRDWEB_SECRET_KEY } from "@/constants/server-envs";
import { UB_BASE_URL } from "./constants";
type PaymentLink = {
clientId: string;
title?: string;
imageUrl?: string;
receiver: string;
destinationToken: {
address: string;
symbol: string;
decimals: number;
chainId: number;
};
amount: bigint | undefined;
purchaseData: Record<string, unknown> | undefined;
};
export async function getPaymentLink(props: { paymentId: string }) {
const res = await fetch(`${UB_BASE_URL}/v1/links/${props.paymentId}`, {
headers: {
"Content-Type": "application/json",
"x-secret-key": DASHBOARD_THIRDWEB_SECRET_KEY,
},
method: "GET",
});
if (!res.ok) {
const text = await res.text();
throw new Error(text);
}
const { data } = await res.json();
return {
amount: data.amount ? BigInt(data.amount) : undefined,
clientId: data.clientId,
destinationToken: data.destinationToken,
imageUrl: data.imageUrl,
purchaseData: data.purchaseData,
receiver: data.receiver,
title: data.title,
} as PaymentLink;
}
@@ -1,4 +1,6 @@
"use server";
import type { ProjectResponse } from "@thirdweb-dev/service-utils";
import { getAuthToken } from "@/api/auth-token";
import { DASHBOARD_THIRDWEB_SECRET_KEY } from "@/constants/server-envs";
import { UB_BASE_URL } from "./constants";
@@ -11,9 +13,7 @@ export type TokenMetadata = {
iconUri?: string;
};
export async function getUniversalBridgeTokens(props: {
chainId?: number;
}) {
export async function getUniversalBridgeTokens(props: { chainId?: number }) {
const url = new URL(`${UB_BASE_URL}/v1/tokens`);
if (props.chainId) {
@@ -22,11 +22,41 @@ export async function getUniversalBridgeTokens(props: {
url.searchParams.append("limit", "1000");
const res = await fetch(url.toString(), {
method: "GET",
headers: {
"Content-Type": "application/json",
"x-secret-key": DASHBOARD_THIRDWEB_SECRET_KEY,
} as Record<string, string>,
method: "GET",
});
if (!res.ok) {
const text = await res.text();
throw new Error(text);
}
const json = await res.json();
return json.data as Array<TokenMetadata>;
}
export async function addUniversalBridgeTokenRoute(props: {
chainId: number;
tokenAddress: string;
project: ProjectResponse;
}) {
const authToken = await getAuthToken();
const url = new URL(`${UB_BASE_URL}/v1/tokens`);
const res = await fetch(url.toString(), {
body: JSON.stringify({
chainId: props.chainId,
tokenAddress: props.tokenAddress,
}),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
"x-client-id": props.project.publishableKey,
} as Record<string, string>,
method: "POST",
});
if (!res.ok) {
@@ -0,0 +1,66 @@
import "server-only";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
type LineItem = {
quantity: number;
amountUsdCents: number;
unitAmountUsdCents: string;
description: string;
};
export type UsageCategory = {
category: string;
unitName: string;
lineItems: LineItem[];
};
type UsageApiResponse = {
result: UsageCategory[];
periodStart: string;
periodEnd: string;
planVersion: number;
};
export async function getBilledUsage(teamSlug: string) {
const authToken = await getAuthToken();
if (!authToken) {
throw new Error("No auth token found");
}
const response = await fetch(
new URL(
`/v1/teams/${teamSlug}/billing/billed-usage`,
NEXT_PUBLIC_THIRDWEB_API_HOST,
),
{
headers: {
Authorization: `Bearer ${authToken}`,
},
next: {
// revalidate this query once per minute (does not need to be more granular than that)
revalidate: 60,
},
},
);
if (!response.ok) {
// if the status is 404, the most likely reason is that the team is on a free plan
if (response.status === 404) {
return {
reason: "free_plan",
status: "error",
} as const;
}
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
} as const;
}
const data = (await response.json()) as UsageApiResponse;
return {
data,
status: "success",
} as const;
}
+4 -60
View File
@@ -1,58 +1,6 @@
import "server-only";
import { unstable_cache } from "next/cache";
import { ANALYTICS_SERVICE_URL } from "../../constants/server-envs";
export type RPCUsageDataItem = {
date: string;
usageType: "included" | "overage" | "rate-limit";
count: string;
};
export const fetchRPCUsage = unstable_cache(
async (params: {
teamId: string;
projectId?: string;
authToken: string;
from: string;
to: string;
period: "day" | "week" | "month" | "year" | "all";
}) => {
const analyticsEndpoint = ANALYTICS_SERVICE_URL;
const url = new URL(`${analyticsEndpoint}/v2/rpc/usage-types`);
url.searchParams.set("teamId", params.teamId);
if (params.projectId) {
url.searchParams.set("projectId", params.projectId);
}
url.searchParams.set("from", params.from);
url.searchParams.set("to", params.to);
url.searchParams.set("period", params.period);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${params.authToken}`,
},
});
if (!res.ok) {
const error = await res.text();
return {
ok: false as const,
error: error,
};
}
const resData = await res.json();
return {
ok: true as const,
data: resData.data as RPCUsageDataItem[],
};
},
["rpc-usage"],
{
revalidate: 60 * 60, // 1 hour
},
);
import { ANALYTICS_SERVICE_URL } from "@/constants/server-envs";
type Last24HoursRPCUsageApiResponse = {
peakRate: {
@@ -75,11 +23,7 @@ type Last24HoursRPCUsageApiResponse = {
};
export const getLast24HoursRPCUsage = unstable_cache(
async (params: {
teamId: string;
projectId?: string;
authToken: string;
}) => {
async (params: { teamId: string; projectId?: string; authToken: string }) => {
const analyticsEndpoint = ANALYTICS_SERVICE_URL;
const url = new URL(`${analyticsEndpoint}/v2/rpc/24-hours`);
url.searchParams.set("teamId", params.teamId);
@@ -96,16 +40,16 @@ export const getLast24HoursRPCUsage = unstable_cache(
if (!res.ok) {
const error = await res.text();
return {
ok: false as const,
error: error,
ok: false as const,
};
}
const resData = await res.json();
return {
ok: true as const,
data: resData.data as Last24HoursRPCUsageApiResponse,
ok: true as const,
};
},
["rpc-usage-last-24-hours:v2"],
+4 -4
View File
@@ -1,8 +1,8 @@
"use server";
import "server-only";
import { getAuthToken } from "../../app/(app)/api/lib/getAuthToken";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "../constants/public-envs";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { getAuthToken } from "./auth-token";
export type VerifiedDomainResponse =
| {
@@ -56,12 +56,12 @@ export async function createDomainVerification(
const res = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${teamIdOrSlug}/verified-domain`,
{
method: "POST",
body: JSON.stringify({ domain }),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
+362
View File
@@ -0,0 +1,362 @@
"use server";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
export interface WebhookConfig {
id: string;
teamId: string;
projectId: string;
destinationUrl: string;
description: string;
pausedAt: string | null;
webhookSecret: string;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
topics: {
id: string;
serviceName: string;
description: string;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
filters: object | null;
}[];
}
type WebhookConfigsResponse =
| {
data: WebhookConfig[];
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
interface CreateWebhookConfigRequest {
topicIdsWithFilters: { id: string; filters: object | null }[];
destinationUrl: string;
description: string;
isPaused?: boolean;
}
type CreateWebhookConfigResponse =
| {
data: WebhookConfig;
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
export interface Topic {
id: string;
serviceName: string;
description: string;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
}
type TopicsResponse =
| {
data: Topic[];
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
interface UpdateWebhookConfigRequest {
destinationUrl?: string;
topicIdsWithFilters?: { id: string; filters: object | null }[];
description?: string;
isPaused?: boolean;
}
type UpdateWebhookConfigResponse =
| {
data: WebhookConfig;
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
type DeleteWebhookConfigResponse =
| {
data: WebhookConfig;
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
export async function getWebhookConfigs(props: {
teamIdOrSlug: string;
projectIdOrSlug: string;
}): Promise<WebhookConfigsResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const response = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${props.teamIdOrSlug}/projects/${props.projectIdOrSlug}/webhook-configs`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "GET",
},
);
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
};
}
const result = await response.json();
return {
data: result.data,
status: "success",
};
}
export async function createWebhookConfig(props: {
teamIdOrSlug: string;
projectIdOrSlug: string;
config: CreateWebhookConfigRequest;
}): Promise<CreateWebhookConfigResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const response = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${props.teamIdOrSlug}/projects/${props.projectIdOrSlug}/webhook-configs`,
{
body: JSON.stringify(props.config),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
};
}
const result = await response.json();
return {
data: result.data,
status: "success",
};
}
export async function getAvailableTopics(): Promise<TopicsResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const response = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/webhook-topics`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "GET",
},
);
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
};
}
const result = await response.json();
return {
data: result.data,
status: "success",
};
}
export async function updateWebhookConfig(props: {
teamIdOrSlug: string;
projectIdOrSlug: string;
webhookConfigId: string;
config: UpdateWebhookConfigRequest;
}): Promise<UpdateWebhookConfigResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const response = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${props.teamIdOrSlug}/projects/${props.projectIdOrSlug}/webhook-configs/${props.webhookConfigId}`,
{
body: JSON.stringify(props.config),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "PATCH",
},
);
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
};
}
const result = await response.json();
return {
data: result.data,
status: "success",
};
}
export async function deleteWebhookConfig(props: {
teamIdOrSlug: string;
projectIdOrSlug: string;
webhookConfigId: string;
}): Promise<DeleteWebhookConfigResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const response = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${props.teamIdOrSlug}/projects/${props.projectIdOrSlug}/webhook-configs/${props.webhookConfigId}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "DELETE",
},
);
if (!response.ok) {
const body = await response.text();
return {
body,
reason: "unknown",
status: "error",
};
}
const result = await response.json();
return {
data: result.data,
status: "success",
};
}
type TestDestinationUrlResponse =
| {
result: {
httpStatusCode: number;
httpResponseBody: string;
};
status: "success";
}
| {
body: string;
reason: string;
status: "error";
};
export async function testDestinationUrl(props: {
teamIdOrSlug: string;
projectIdOrSlug: string;
destinationUrl: string;
}): Promise<TestDestinationUrlResponse> {
const authToken = await getAuthToken();
if (!authToken) {
return {
body: "Authentication required",
reason: "no_auth_token",
status: "error",
};
}
const resp = await fetch(
`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v1/teams/${props.teamIdOrSlug}/projects/${props.projectIdOrSlug}/webhook-configs/test-destination-url`,
{
body: JSON.stringify({ destinationUrl: props.destinationUrl }),
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
method: "POST",
},
);
if (!resp.ok) {
return {
body: await resp.text(),
reason: "unknown",
status: "error",
};
}
return await resp.json();
}
@@ -1,3 +1,4 @@
import { differenceInCalendarDays, format, subDays } from "date-fns";
import { DatePickerWithRange } from "@/components/ui/DatePickerWithRange";
import {
Select,
@@ -7,12 +8,13 @@ import {
SelectValue,
} from "@/components/ui/select";
import { normalizeTime } from "@/lib/time";
import { differenceInCalendarDays, format, subDays } from "date-fns";
import { cn } from "@/lib/utils";
export function DateRangeSelector(props: {
range: Range;
setRange: (range: Range) => void;
popoverAlign?: "start" | "end" | "center";
className?: string;
}) {
const { range, setRange } = props;
const daysDiff = differenceInCalendarDays(range.to, range.from);
@@ -26,30 +28,15 @@ export function DateRangeSelector(props: {
return (
<DatePickerWithRange
className={cn("w-auto bg-card", props.className)}
from={range.from}
to={range.to}
popoverAlign={props.popoverAlign}
setFrom={(from) =>
setRange({
from,
to: range.to,
type: "custom",
})
}
setTo={(to) =>
setRange({
from: range.from,
to,
type: "custom",
})
}
header={
<div className="mb-2 border-border border-b p-4">
<Select
value={rangeType}
onValueChange={(id: DurationId) => {
setRange(getLastNDaysRange(id));
}}
value={rangeType}
>
<SelectTrigger className="flex bg-transparent">
<SelectValue placeholder="Select" />
@@ -72,7 +59,22 @@ export function DateRangeSelector(props: {
</div>
}
labelOverride={rangeLabel}
className="w-auto bg-card"
popoverAlign={props.popoverAlign}
setFrom={(from) =>
setRange({
from,
to: range.to,
type: "custom",
})
}
setTo={(to) =>
setRange({
from: range.from,
to,
type: "custom",
})
}
to={range.to}
/>
);
}
@@ -86,10 +88,10 @@ export function getLastNDaysRange(id: DurationId) {
const todayDate = new Date(Date.now() + 1000 * 60 * 60 * 24); // add 1 day to avoid timezone issues
const value: Range = {
type: id,
from: subDays(todayDate, durationInfo.days),
to: todayDate,
label: durationInfo.name,
to: todayDate,
type: id,
};
return value;
@@ -97,24 +99,24 @@ export function getLastNDaysRange(id: DurationId) {
const durationPresets = [
{
name: "Last 7 Days",
id: "last-7",
days: 7,
id: "last-7",
name: "Last 7 Days",
},
{
name: "Last 30 Days",
id: "last-30",
days: 30,
id: "last-30",
name: "Last 30 Days",
},
{
name: "Last 60 Days",
id: "last-60",
days: 60,
id: "last-60",
name: "Last 60 Days",
},
{
name: "Last 120 Days",
id: "last-120",
days: 120,
id: "last-120",
name: "Last 120 Days",
},
] as const;
@@ -0,0 +1,104 @@
"use client";
import { useId, useMemo } from "react";
import { Area, AreaChart, Bar, BarChart } from "recharts";
import { type ChartConfig, ChartContainer } from "@/components/ui/chart";
import { LoadingDots } from "@/components/ui/LoadingDots";
import { cn } from "@/lib/utils";
type FakeCartData = {
value: number;
};
function generateRandomData(): FakeCartData[] {
return Array.from({ length: 30 }, () => ({
value: Math.floor(Math.random() * 100 + 30),
}));
}
const skeletonChartConfig = {
value: {
color: "hsl(var(--muted)/90%)",
label: "Value",
},
} satisfies ChartConfig;
export function EmptyChartState({
children,
type,
}: {
children?: React.ReactNode;
type: "bar" | "area";
}) {
const barChartData = useMemo(() => generateRandomData(), []);
return (
<div className="relative z-0 h-full w-full">
<div className="absolute inset-0 z-[1] flex flex-col items-center justify-center font-medium text-base text-muted-foreground">
{children ?? "No data available"}
</div>
<SkeletonBarChart data={barChartData} type={type} />
</div>
);
}
export function LoadingChartState({ className }: { className?: string }) {
return (
<div
className={cn(
"pointer-events-none flex h-full w-full items-center justify-center rounded-lg bg-muted/30",
className,
)}
>
<LoadingDots />
</div>
);
}
function SkeletonBarChart(props: {
data: FakeCartData[];
type: "bar" | "area";
}) {
const fillAreaSkeletonId = useId();
return (
<ChartContainer
className="pointer-events-none h-full w-full blur-[5px]"
config={skeletonChartConfig}
>
{props.type === "bar" ? (
<BarChart
data={props.data}
margin={{
top: 20,
}}
>
<Bar dataKey="value" fill="var(--color-value)" radius={8} />
</BarChart>
) : (
<AreaChart
data={props.data}
margin={{
top: 20,
}}
>
<defs>
<linearGradient id={fillAreaSkeletonId} x1="0" x2="0" y1="0" y2="1">
<stop
offset="5%"
stopColor={"hsl(var(--muted-foreground)/0.5)"}
stopOpacity={0.8}
/>
<stop offset="95%" stopColor="transparent" stopOpacity={0.1} />
</linearGradient>
</defs>
<Area
dataKey="value"
fill={`url(#${fillAreaSkeletonId})`}
radius={8}
stroke="hsl(var(--muted-foreground))"
type="natural"
/>
</AreaChart>
)}
</ChartContainer>
);
}
@@ -14,10 +14,10 @@ export function IntervalSelector(props: {
}) {
return (
<Select
value={props.intervalType}
onValueChange={(value: "day" | "week") => {
props.setIntervalType(value);
}}
value={props.intervalType}
>
<SelectTrigger
className={cn("w-auto bg-card md:w-[120px]", props.className)}
@@ -1,22 +1,25 @@
"use client";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { useQuery } from "@tanstack/react-query";
import {
DateRangeSelector,
getLastNDaysRange,
} from "components/analytics/date-range-selector";
import { usePathname, useSearchParams } from "next/navigation";
import { useState } from "react";
import type {
DurationId,
Range,
} from "components/analytics/date-range-selector";
import { IntervalSelector } from "components/analytics/interval-selector";
import { usePathname, useSearchParams } from "next/navigation";
import { useState } from "react";
} from "@/components/analytics/date-range-selector";
import {
DateRangeSelector,
getLastNDaysRange,
} from "@/components/analytics/date-range-selector";
import { IntervalSelector } from "@/components/analytics/interval-selector";
import { useDashboardRouter } from "@/lib/DashboardRouter";
export function RangeSelector({
range,
interval,
}: { range?: Range; interval: "day" | "week" }) {
}: {
range?: Range;
interval: "day" | "week";
}) {
const pathname = usePathname();
const searchParams = useSearchParams();
const router = useDashboardRouter();
@@ -26,7 +29,6 @@ export function RangeSelector({
const [localInterval, setInterval] = useState<"day" | "week">(interval);
useQuery({
queryKey: ["analytics-range", searchParams?.toString(), range],
queryFn: async () => {
if (range) {
setRange(range);
@@ -46,11 +48,11 @@ export function RangeSelector({
}
return getLastNDaysRange("last-120");
},
queryKey: ["analytics-range", searchParams?.toString(), range],
});
// prefetch for each interval and default range
useQuery({
queryKey: ["analytics-range", searchParams?.toString()],
queryFn: async () => {
const newSearchParams = new URLSearchParams(searchParams || {});
for (const interval of ["day", "week"] as const) {
@@ -70,11 +72,13 @@ export function RangeSelector({
}
return true;
},
queryKey: ["analytics-range", searchParams?.toString()],
});
return (
<div className="flex justify-end gap-4">
<div className="flex justify-end gap-3 flex-col lg:flex-row">
<DateRangeSelector
className="rounded-full"
range={localRange}
setRange={(newRange) => {
setRange(newRange);
@@ -86,7 +90,7 @@ export function RangeSelector({
}}
/>
<IntervalSelector
className="bg-card"
className="bg-card rounded-full"
intervalType={localInterval}
setIntervalType={(newInterval) => {
setInterval(newInterval);
@@ -1,4 +1,4 @@
import { Skeleton } from "../../@/components/ui/skeleton";
import { Skeleton } from "@/components/ui/skeleton";
export const StatCard: React.FC<{
label: string;
@@ -1,6 +1,5 @@
"use client";
import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox";
import {
Alert,
AlertIcon,
@@ -12,27 +11,24 @@ import {
Textarea,
} from "@chakra-ui/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { TransactionButton } from "components/buttons/TransactionButton";
import { FileInput } from "components/shared/FileInput";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { Button } from "chakra/button";
import { FormErrorMessage, FormHelperText, FormLabel } from "chakra/form";
import { Heading } from "chakra/heading";
import { Text } from "chakra/text";
import { ChevronLeftIcon, EyeIcon, EyeOffIcon } from "lucide-react";
import { useRef, useState } from "react";
import { useDropzone } from "react-dropzone";
import { useForm } from "react-hook-form";
import type { ThirdwebClient } from "thirdweb";
import type { CreateDelayedRevealBatchParams } from "thirdweb/extensions/erc721";
import type { NFTInput } from "thirdweb/utils";
import {
Button,
FormErrorMessage,
FormHelperText,
FormLabel,
Heading,
Text,
TrackedLink,
} from "tw-components";
import type { ComponentWithChildren } from "types/component-with-children";
import { processInputData, shuffleData } from "utils/batch";
import { z } from "zod";
import { FileInput } from "@/components/blocks/FileInput";
import { TransactionButton } from "@/components/tx-button";
import { Checkbox, CheckboxWithLabel } from "@/components/ui/checkbox";
import { UnderlineLink } from "@/components/ui/UnderlineLink";
import type { ComponentWithChildren } from "@/types/component-with-children";
import { processInputData, shuffleData } from "@/utils/batch";
import { BatchTable } from "./batch-table";
import { SelectOption } from "./lazy-mint-form/select-option";
import { UploadStep } from "./upload-step";
@@ -53,33 +49,34 @@ interface BatchLazyMintEVMProps {
canCreateDelayedRevealBatch: boolean;
onSubmit: (formData: SubmitType) => Promise<unknown>;
chainId: number;
client: ThirdwebClient;
}
type BatchLazyMintProps = BatchLazyMintEVMProps;
const BatchLazyMintFormSchema = z
.object({
// delayed reveal placeholder
placeHolder: z
.object({
name: z.string().min(1, "A name is required"),
image: z.any().optional(),
description: z.string().or(z.string().length(0)).optional(),
})
.optional(),
// delayed reveal password logic
password: z.string().min(1, "A password is required.").optional(),
confirmPassword: z
.string()
.min(1, "Please confirm your password.")
.optional(),
// shared logic
shuffle: z.boolean().default(false),
revealType: z.literal("instant").or(z.literal("delayed")).optional(),
// metadata
metadatas: z.array(z.any()),
// delayed reveal password logic
password: z.string().min(1, "A password is required.").optional(),
// delayed reveal placeholder
placeHolder: z
.object({
description: z.string().or(z.string().length(0)).optional(),
image: z.any().optional(),
name: z.string().min(1, "A name is required"),
})
.optional(),
revealType: z.literal("instant").or(z.literal("delayed")).optional(),
// shared logic
shuffle: z.boolean().default(false),
})
.refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
@@ -92,12 +89,12 @@ type BatchLazyMintFormType = z.output<typeof BatchLazyMintFormSchema> & {
function useBatchLazyMintForm() {
return useForm<BatchLazyMintFormType>({
resolver: zodResolver(BatchLazyMintFormSchema),
defaultValues: {
metadatas: [],
revealType: undefined,
shuffle: false,
},
resolver: zodResolver(BatchLazyMintFormSchema),
});
}
@@ -149,8 +146,8 @@ export const BatchLazyMint: ComponentWithChildren<
// check submit is instant
if (data.revealType === "instant") {
return props.onSubmit({
revealType: "instant",
data: { metadatas: shuffledMetadatas },
revealType: "instant",
});
}
// validate password
@@ -170,16 +167,16 @@ export const BatchLazyMint: ComponentWithChildren<
}
// submit
return props.onSubmit({
revealType: "delayed",
data: {
metadata: shuffledMetadatas,
password: data.password,
placeholderMetadata: {
name: data.placeHolder?.name,
description: data.placeHolder?.description,
image: data.placeHolder?.image,
name: data.placeHolder?.name,
},
},
revealType: "delayed",
});
})}
>
@@ -188,9 +185,10 @@ export const BatchLazyMint: ComponentWithChildren<
{nftMetadatas.length > 0 ? (
<>
<BatchTable
portalRef={paginationPortalRef}
client={props.client}
data={nftMetadatas}
nextTokenIdToMint={props.nextTokenIdToMint}
portalRef={paginationPortalRef}
/>
<div className="border-border border-t">
<div className="flex flex-col items-center justify-between p-0 md:flex-row md:p-4">
@@ -220,8 +218,8 @@ export const BatchLazyMint: ComponentWithChildren<
</>
) : (
<UploadStep
getRootProps={getRootProps}
getInputProps={getInputProps}
getRootProps={getRootProps}
hasFailed={hasError}
isDragActive={isDragActive}
/>
@@ -229,30 +227,31 @@ export const BatchLazyMint: ComponentWithChildren<
</div>
) : (
<>
<Flex align="center" justify="space-between" py={4} w="100%" mb={2}>
<Flex align="center" justify="space-between" mb={2} py={4} w="100%">
<div className="flex flex-row items-center gap-2">
<Button
className="text-muted-foreground"
variant="ghost"
onClick={() => setStep(0)}
variant="ghost"
>
<ChevronLeftIcon className="size-5 cursor-pointer" />
</Button>
<Heading size="title.md" className="my-auto">
<Heading className="my-auto" size="title.md">
When will you reveal your NFTs?
</Heading>
</div>
</Flex>
<SelectReveal
form={form}
canCreateDelayedRevealBatch={props.canCreateDelayedRevealBatch}
client={props.client}
form={form}
/>
{form.watch("revealType") && (
<>
<CheckboxWithLabel>
<Checkbox
className="mt-3"
checked={form.watch("shuffle")}
className="mt-3"
onCheckedChange={(val) => form.setValue("shuffle", !!val)}
/>
<div className="flex flex-col items-center gap-1 md:flex-row">
@@ -262,13 +261,14 @@ export const BatchLazyMint: ComponentWithChildren<
</CheckboxWithLabel>
<div className="w-full md:w-[61%]">
<TransactionButton
txChainID={props.chainId}
className="mt-4 w-full"
transactionCount={1}
client={props.client}
disabled={!nftMetadatas.length}
type="submit"
isPending={form.formState.isSubmitting}
isLoggedIn={props.isLoggedIn}
isPending={form.formState.isSubmitting}
transactionCount={1}
txChainID={props.chainId}
type="submit"
>
{form.formState.isSubmitting
? `Uploading ${nftMetadatas.length} NFTs`
@@ -276,15 +276,15 @@ export const BatchLazyMint: ComponentWithChildren<
</TransactionButton>
{props.children}
</div>
<Text size="body.sm" mt={2}>
<TrackedLink
<Text mt={2} size="body.sm">
<UnderlineLink
className="text-primary-500"
href="https://support.thirdweb.com/dashboard/n5evQ4EfEjEifczEQaZ1hL/batch-upload-troubleshooting/5WMQFqfaUTU1C8NM8FtJ2X"
isExternal
category="batch-upload"
label="issues"
rel="noopener noreferrer"
target="_blank"
>
Experiencing issues uploading your files?
</TrackedLink>
</UnderlineLink>
</Text>
</>
)}
@@ -297,42 +297,45 @@ export const BatchLazyMint: ComponentWithChildren<
interface SelectRevealProps {
form: ReturnType<typeof useBatchLazyMintForm>;
canCreateDelayedRevealBatch: boolean;
client: ThirdwebClient;
}
const SelectReveal: React.FC<SelectRevealProps> = ({
form,
client,
canCreateDelayedRevealBatch,
}) => {
const [show, setShow] = useState(false);
const imageUrl = useImageFileOrUrl(form.watch("placeHolder.image"));
const imageUrl = form.watch("placeHolder.image");
return (
<Flex flexDir="column">
<Flex
flexDir={{ base: "column", md: "row" }}
gap={{ base: 3, md: 6 }}
mb={6}
flexDir={{ base: "column", md: "row" }}
>
<SelectOption
name="Reveal upon mint"
description="Collectors will immediately see the final NFT when they complete the minting"
isActive={form.watch("revealType") === "instant"}
name="Reveal upon mint"
onClick={() => form.setValue("revealType", "instant")}
/>
<SelectOption
name="Delayed Reveal"
description="Collectors will mint your placeholder image, then you reveal at a later time"
isActive={form.watch("revealType") === "delayed"}
onClick={() => form.setValue("revealType", "delayed")}
disabled={!canCreateDelayedRevealBatch}
disabledText="This contract doesn't implement Delayed Reveal"
isActive={form.watch("revealType") === "delayed"}
name="Delayed Reveal"
onClick={() => form.setValue("revealType", "delayed")}
/>
</Flex>
<div className="flex flex-col gap-3">
{form.watch("revealType") === "delayed" && (
<>
<Heading size="title.sm">Let&apos;s set a password</Heading>
<Alert status="warning" borderRadius="lg">
<Alert borderRadius="lg" status="warning">
<AlertIcon />
You&apos;ll need this password to reveal your NFTs. Please save it
somewhere safe.
@@ -343,10 +346,10 @@ const SelectReveal: React.FC<SelectRevealProps> = ({
gap={{ base: 4, md: 0 }}
>
<FormControl
isRequired
isInvalid={
!!form.getFieldState("password", form.formState).error
}
isRequired
mr={4}
>
<FormLabel>Password</FormLabel>
@@ -359,13 +362,13 @@ const SelectReveal: React.FC<SelectRevealProps> = ({
<InputRightElement cursor="pointer">
{show ? (
<EyeIcon
onClick={() => setShow(!show)}
className="size-3"
onClick={() => setShow(!show)}
/>
) : (
<EyeOffIcon
onClick={() => setShow(!show)}
className="size-3"
onClick={() => setShow(!show)}
/>
)}
</InputRightElement>
@@ -379,10 +382,10 @@ const SelectReveal: React.FC<SelectRevealProps> = ({
</FormErrorMessage>
</FormControl>
<FormControl
isRequired
isInvalid={
!!form.getFieldState("confirmPassword", form.formState).error
}
isRequired
>
<FormLabel>Confirm password</FormLabel>
<Input
@@ -410,12 +413,13 @@ const SelectReveal: React.FC<SelectRevealProps> = ({
<div className="w-auto md:w-[350px]">
<FileInput
accept={{ "image/*": [] }}
value={imageUrl}
showUploadButton
className="rounded border border-border transition-all duration-200"
client={client}
setValue={(file) =>
form.setValue("placeHolder.image", file)
}
className="rounded border border-border transition-all duration-200"
showUploadButton
value={imageUrl}
/>
</div>
<FormHelperText>
@@ -429,10 +433,10 @@ const SelectReveal: React.FC<SelectRevealProps> = ({
</FormErrorMessage>
</FormControl>
<FormControl
isRequired
isInvalid={
!!form.getFieldState("placeHolder.name", form.formState).error
}
isRequired
>
<FormLabel>Name</FormLabel>
<Input
@@ -1,12 +1,9 @@
import { CodeClient } from "@/components/ui/code/code.client";
import { ToolTipLabel } from "@/components/ui/tooltip";
/** biome-ignore-all lint/nursery/noNestedComponentDefinitions: FIXME */
import { FilePreview } from "@app/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/file-preview";
import {
Box,
type BoxProps,
Flex,
IconButton,
Image,
type ImageProps,
Portal,
Select,
Table,
@@ -17,8 +14,6 @@ import {
Thead,
Tr,
} from "@chakra-ui/react";
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
import { replaceIpfsUrl } from "lib/sdk";
import {
ChevronFirstIcon,
ChevronLastIcon,
@@ -27,84 +22,58 @@ import {
} from "lucide-react";
import { useMemo } from "react";
import { type Column, usePagination, useTable } from "react-table";
import type { ThirdwebClient } from "thirdweb";
import type { NFTInput } from "thirdweb/utils";
import { useThirdwebClient } from "../../@/constants/thirdweb.client";
import { CodeClient } from "@/components/ui/code/code.client";
import { ToolTipLabel } from "@/components/ui/tooltip";
const FileImage: React.FC<ImageProps> = ({ src, ...props }) => {
const client = useThirdwebClient();
const img = useImageFileOrUrl(
typeof src === "string" && src.startsWith("ipfs://")
? replaceIpfsUrl(src, client)
: src,
);
return <Image alt="" {...props} src={img} />;
};
const FileVideo: React.FC<
BoxProps &
Omit<React.ComponentProps<"video">, "ref" | "src"> & { src: string | File }
> = ({ src, ...props }) => {
const client = useThirdwebClient();
const video = useImageFileOrUrl(
typeof src === "string" && src.startsWith("ipfs://")
? replaceIpfsUrl(src, client)
: src,
);
return <Box as="video" {...props} src={video} />;
};
interface BatchTableProps {
data: NFTInput[];
portalRef: React.RefObject<HTMLDivElement | null>;
nextTokenIdToMint?: bigint;
client: ThirdwebClient;
}
export const BatchTable: React.FC<BatchTableProps> = ({
data,
portalRef,
nextTokenIdToMint,
client,
}) => {
const columns = useMemo(() => {
let cols: Column<NFTInput>[] = [];
if (nextTokenIdToMint !== undefined) {
cols = cols.concat({
Header: "Token ID",
accessor: (_row, index) => String(nextTokenIdToMint + BigInt(index)),
Header: "Token ID",
});
}
cols = cols.concat([
{
Header: "Image",
accessor: (row) => row.image,
Cell: ({ cell: { value } }: { cell: { value?: string } }) => (
<FileImage
flexShrink={0}
boxSize={24}
objectFit="contain"
src={value}
alt=""
<FilePreview
className="size-24 shrink-0 rounded-lg object-contain"
client={client}
srcOrFile={value}
/>
),
Header: "Image",
},
{
Header: "Animation Url",
accessor: (row) => row.animation_url,
Cell: ({ cell: { value } }: { cell: { value?: string } }) => (
<FileVideo
flexShrink={0}
boxSize={24}
objectFit="contain"
src={value || ""}
autoPlay
playsInline
muted
loop
<FilePreview
className="size-24 shrink-0 rounded-lg"
client={client}
srcOrFile={value}
/>
),
Header: "Animation Url",
},
{ Header: "Name", accessor: (row) => row.name },
{ accessor: (row) => row.name, Header: "Name" },
{
Header: "Description",
accessor: (row) => (
<ToolTipLabel label={row.description}>
<p className="line-clamp-6 whitespace-pre-wrap">
@@ -112,9 +81,9 @@ export const BatchTable: React.FC<BatchTableProps> = ({
</p>
</ToolTipLabel>
),
Header: "Description",
},
{
Header: "Attributes",
accessor: (row) => row.attributes || row.properties,
// biome-ignore lint/suspicious/noExplicitAny: FIXME
Cell: ({ cell }: { cell: any }) =>
@@ -125,12 +94,13 @@ export const BatchTable: React.FC<BatchTableProps> = ({
scrollableClassName="max-w-[300px]"
/>
) : null,
Header: "Attributes",
},
{ Header: "External URL", accessor: (row) => row.external_url },
{ Header: "Background Color", accessor: (row) => row.background_color },
{ accessor: (row) => row.external_url, Header: "External URL" },
{ accessor: (row) => row.background_color, Header: "Background Color" },
]);
return cols;
}, [nextTokenIdToMint]);
}, [nextTokenIdToMint, client]);
const {
getTableProps,
@@ -156,8 +126,8 @@ export const BatchTable: React.FC<BatchTableProps> = ({
columns,
data,
initialState: {
pageSize: 50,
pageIndex: 0,
pageSize: 50,
},
},
// will be fixed with @tanstack/react-table v8
@@ -168,7 +138,7 @@ export const BatchTable: React.FC<BatchTableProps> = ({
// Render the UI for your table
return (
<Flex flexGrow={1} overflow="auto">
<TableContainer maxW="100%">
<TableContainer className="w-full" maxW="100%">
<Table {...getTableProps()}>
<Thead>
{headerGroups.map((headerGroup, index) => (
@@ -191,8 +161,8 @@ export const BatchTable: React.FC<BatchTableProps> = ({
return (
<Tr
{...row.getRowProps()}
borderBottomWidth={1}
_last={{ borderBottomWidth: 0 }}
borderBottomWidth={1}
// biome-ignore lint/suspicious/noArrayIndexKey: FIXME
key={rowIndex}
>
@@ -219,15 +189,15 @@ export const BatchTable: React.FC<BatchTableProps> = ({
<div className="flex w-full items-center justify-center">
<div className="flex flex-row items-center gap-2">
<IconButton
isDisabled={!canPreviousPage}
aria-label="first page"
icon={<ChevronFirstIcon className="size-4" />}
isDisabled={!canPreviousPage}
onClick={() => gotoPage(0)}
/>
<IconButton
isDisabled={!canPreviousPage}
aria-label="previous page"
icon={<ChevronLeftIcon className="size-4" />}
isDisabled={!canPreviousPage}
onClick={() => previousPage()}
/>
<p className="whitespace-nowrap">
@@ -235,15 +205,15 @@ export const BatchTable: React.FC<BatchTableProps> = ({
<strong>{pageOptions.length}</strong>
</p>
<IconButton
isDisabled={!canNextPage}
aria-label="next page"
icon={<ChevronRightIcon className="size-4" />}
isDisabled={!canNextPage}
onClick={() => nextPage()}
/>
<IconButton
isDisabled={!canNextPage}
aria-label="last page"
icon={<ChevronLastIcon className="size-4" />}
isDisabled={!canNextPage}
onClick={() => gotoPage(pageCount - 1)}
/>
@@ -0,0 +1,85 @@
import { InfoIcon } from "lucide-react";
import type { JSX, MouseEventHandler } from "react";
import { Card } from "@/components/ui/card";
import { ToolTipLabel } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
interface SelectOptionProps extends React.HTMLAttributes<HTMLDivElement> {
name: string;
description?: string;
isActive?: boolean;
onClick: MouseEventHandler<HTMLDivElement>;
disabled?: boolean;
disabledText?: string;
infoText?: string | JSX.Element;
className?: string;
}
export const SelectOption: React.FC<SelectOptionProps> = ({
name,
description,
isActive = true,
onClick,
disabled,
disabledText,
infoText,
className,
...divProps
}) => {
return (
<ToolTipLabel
label={
disabled ? (
<Card className="bg-muted p-3">
<p className="text-sm">{disabledText}</p>
</Card>
) : undefined
}
>
<Card
className={cn(
"flex flex-col gap-2 rounded-md p-5 md:w-[350px]",
disabled
? "pointer-events-none cursor-not-allowed bg-muted"
: "cursor-pointer",
isActive && "border-primary",
className,
)}
onClick={onClick}
{...divProps}
>
<div className="flex flex-row justify-between">
<div className="flex flex-row items-start">
<div className="mt-0.5 mr-2.5 flex h-4 w-4 items-center justify-center rounded-full border border-inverted text-inverted">
{isActive && <div className="h-2 w-2 rounded-full bg-inverted" />}
</div>
<div className="ml-4 flex flex-col gap-2 self-start">
<h4
className={cn(
"font-semibold text-sm",
disabled && "text-gray-600",
)}
>
{name}
</h4>
{description && <p className="mt-1 text-sm">{description}</p>}
</div>
</div>
{infoText && (
<ToolTipLabel
label={
<Card className="bg-muted p-3">
<p className="text-sm">{infoText}</p>
</Card>
}
>
<div className="flex items-center">
<InfoIcon className="size-4" />
</div>
</ToolTipLabel>
)}
</div>
</Card>
</ToolTipLabel>
);
};
@@ -1,7 +1,7 @@
import { UnorderedList } from "@/components/ui/List/List";
import { InlineCode } from "@/components/ui/inline-code";
import { cn } from "@/lib/utils";
import { UploadIcon } from "lucide-react";
import { InlineCode } from "@/components/ui/inline-code";
import { UnorderedList } from "@/components/ui/List/List";
import { cn } from "@/lib/utils";
interface UploadStepProps {
// biome-ignore lint/suspicious/noExplicitAny: FIXME
@@ -61,16 +61,16 @@ export const UploadStep: React.FC<UploadStepProps> = ({
<li>
Files <em>must</em> contain one .csv or .json file with metadata. -{" "}
<a
download
className="text-link-foreground hover:text-foreground"
download
href="/assets/examples/example.csv"
>
Download example.csv
</a>
.{" "}
<a
download
className="text-link-foreground hover:text-foreground"
download
href="/assets/examples/example.json"
>
Download example.json
@@ -111,8 +111,8 @@ export const UploadStep: React.FC<UploadStepProps> = ({
<InlineCode code="animation_url" /> column and add the IPFS hashes
there.{" "}
<a
download
className="text-link-foreground hover:text-foreground"
download
href="/assets/examples/example-with-ipfs.csv"
>
Download example.csv
@@ -123,8 +123,8 @@ export const UploadStep: React.FC<UploadStepProps> = ({
the name of your files to the <InlineCode code="image" /> and
<InlineCode code="animation_url" /> column.{" "}
<a
download
className="text-link-foreground hover:text-foreground"
download
href="/assets/examples/example-with-maps.csv"
>
Download example.csv
@@ -1,7 +1,11 @@
"use client";
import { CircleXIcon, ExternalLinkIcon } from "lucide-react";
import Link from "next/link";
import { useState, useTransition } from "react";
import { toast } from "sonner";
import type { Team } from "@/api/team";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import {
Sheet,
SheetContent,
@@ -9,16 +13,12 @@ import {
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet";
import { PRO_CONTACT_US_URL } from "@/constants/pro";
import { useStripeRedirectEvent } from "@/hooks/stripe/redirect-event";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { CircleXIcon, ExternalLinkIcon } from "lucide-react";
import Link from "next/link";
import { useState, useTransition } from "react";
import { toast } from "sonner";
import { useStripeRedirectEvent } from "../../../../../app/(app)/(stripe)/stripe-redirect/stripeRedirectChannel";
import { buildCancelPlanUrl } from "../../../../../app/(app)/(stripe)/utils/build-url";
import { PRO_CONTACT_US_URL } from "../../../../../constants/pro";
import { pollWithTimeout } from "../../../../../utils/pollWithTimeout";
import { tryCatch } from "../../../../../utils/try-catch";
import { pollWithTimeout } from "@/utils/pollWithTimeout";
import { buildCancelPlanUrl } from "@/utils/stripe/build-url";
import { tryCatch } from "@/utils/try-catch";
export function CancelPlanButton(props: {
teamId: string;
@@ -26,13 +26,15 @@ export function CancelPlanButton(props: {
currentPlan: Team["billingPlan"];
billingStatus: Team["billingStatus"];
getTeam: () => Promise<Team>;
disabled?: boolean;
}) {
// shortcut the sheet in case the user is in the default state
if (props.billingStatus !== "invalidPayment" && props.currentPlan !== "pro") {
return (
<ImmediateCancelPlanButton
teamId={props.teamId}
disabled={props.disabled}
getTeam={props.getTeam}
teamId={props.teamId}
/>
);
}
@@ -40,7 +42,12 @@ export function CancelPlanButton(props: {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="outline" size="sm" className="gap-2 bg-background">
<Button
className="gap-2 bg-background"
disabled={props.disabled}
size="sm"
variant="outline"
>
<CircleXIcon className="size-4 text-muted-foreground" />
Cancel Plan
</Button>
@@ -73,9 +80,10 @@ function UnpaidInvoicesWarning({ teamSlug }: { teamSlug: string }) {
You have unpaid invoices. Please pay them before cancelling your plan.
</p>
<Button variant="outline" asChild className="w-full gap-2 bg-card">
<Button asChild className="w-full gap-2 bg-card" variant="outline">
<Link
href={`/team/${teamSlug}/~/settings/invoices?status=open`}
href={`/team/${teamSlug}/~/billing/invoices?status=open`}
rel="noopener noreferrer"
target="_blank"
>
See Invoices
@@ -95,7 +103,7 @@ function ProPlanCancelPlanSheetContent() {
Please contact us to cancel your Pro plan
</p>
<Button variant="outline" asChild className="w-full gap-2 bg-card">
<Button asChild className="w-full gap-2 bg-card" variant="outline">
<Link href={PRO_CONTACT_US_URL} target="_blank">
Contact Us <ExternalLinkIcon className="size-4" />
</Link>
@@ -107,6 +115,7 @@ function ProPlanCancelPlanSheetContent() {
function ImmediateCancelPlanButton(props: {
teamId: string;
getTeam: () => Promise<Team>;
disabled?: boolean;
}) {
const router = useDashboardRouter();
const [isRoutePending, startTransition] = useTransition();
@@ -141,11 +150,11 @@ function ImmediateCancelPlanButton(props: {
return (
<Button
variant="outline"
size="sm"
className="gap-2 bg-background"
disabled={showPlanSpinner}
asChild
className="gap-2 bg-background"
disabled={showPlanSpinner || props.disabled}
size="sm"
variant="outline"
>
<Link href={buildCancelPlanUrl({ teamId: props.teamId })} target="_blank">
{showPlanSpinner ? (
@@ -0,0 +1,85 @@
import { formatDistance } from "date-fns";
import Image from "next/image";
import type { BillingCredit } from "@/hooks/useApi";
import { formatToDollars } from "./formatToDollars";
interface CreditsItemProps {
credit?: BillingCredit;
}
export const CreditsItem: React.FC<CreditsItemProps> = ({ credit }) => {
const isTwCredit = credit?.name.startsWith("TW -");
const isStartupCredit = credit?.name.startsWith("SU -");
let creditTitle = credit?.name ?? "thirdweb credits";
if (isTwCredit) {
creditTitle = "thirdweb credits";
} else if (isStartupCredit) {
creditTitle = "Startup grant credits";
}
return (
<div className="rounded-lg border border-border bg-card">
<div className="flex flex-col gap-3 p-4 lg:p-6">
<div className="relative">
<div className="absolute top-0 right-0">
{isTwCredit ? (
<Image
alt="tw-credit"
className="size-6"
objectFit="contain"
src={require("../../../../public/brand/thirdweb-icon.svg")}
/>
) : isStartupCredit ? (
<Image
alt="tw-credit"
className="size-6"
objectFit="contain"
src={require("../../../../public/brand/thirdweb-icon.svg")}
/>
) : null}
</div>
<h3 className="font-semibold text-foreground text-xl tracking-tight">
{creditTitle}
</h3>
</div>
<div className="flex gap-6">
<div>
<h4 className="mb-0.5 text-muted-foreground text-sm">
Remaining Credits
</h4>
<p className="text-foreground">
{formatToDollars(credit?.remainingValueUsdCents || 0)}
</p>
</div>
{!isTwCredit && (
<div>
<h4 className="mb-0.5 text-muted-foreground text-sm">
Claimed Credits (All-Time)
</h4>
<p className="text-foreground">
{formatToDollars(credit?.originalGrantUsdCents || 0)}
</p>
</div>
)}
{credit?.expiresAt && (
<div>
<h4 className="mb-0.5 text-muted-foreground text-sm">Expires</h4>
<p className="text-foreground">
{credit?.expiresAt
? formatDistance(new Date(credit.expiresAt), Date.now(), {
addSuffix: true,
})
: "N/A"}
</p>
</div>
)}
</div>
</div>
</div>
);
};
@@ -0,0 +1,28 @@
"use client";
// TODO - convert to RSC
import { useAccountCredits } from "@/hooks/useApi";
import { CreditsItem } from "./CreditsItem";
export const CreditsInfoCard = () => {
const { data: credits } = useAccountCredits();
if (!credits) {
return null;
}
const restCredits = credits.filter((crd) => !crd.name.startsWith("OP -"));
if (restCredits.length === 0) {
return null;
}
return (
<section className="flex flex-col gap-4">
{restCredits.map((credit) => (
<CreditsItem credit={credit} key={credit.couponId} />
))}
</section>
);
};
@@ -1,28 +1,23 @@
"use client";
import { useTransition } from "react";
import type { Team } from "@/api/team";
import { PricingCard } from "@/components/blocks/pricing-card";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { Button } from "@/components/ui/button";
import { PRO_CONTACT_US_URL } from "@/constants/pro";
import { useStripeRedirectEvent } from "@/hooks/stripe/redirect-event";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { CheckIcon } from "lucide-react";
import Link from "next/link";
import { useTransition } from "react";
import { useStripeRedirectEvent } from "../../../../app/(app)/(stripe)/stripe-redirect/stripeRedirectChannel";
import { getValidTeamPlan } from "../../../../app/(app)/team/components/TeamHeader/getValidTeamPlan";
import { PRO_CONTACT_US_URL } from "../../../../constants/pro";
import { getValidTeamPlan } from "@/utils/getValidTeamPlan";
// this is used to determine whether to show "Upgrade" or "Downgrade" label based on tier level
const planToTierRecord: Record<Team["billingPlan"], number> = {
free: 0,
starter_legacy: 1,
starter: 2,
growth_legacy: 3,
growth: 4,
accelerate: 5,
scale: 6,
free: 0,
growth: 4,
growth_legacy: 3,
pro: 7,
scale: 6,
starter: 2,
};
interface BillingPricingProps {
@@ -74,21 +69,17 @@ export const BillingPricing: React.FC<BillingPricingProps> = ({
validTeamPlan === "starter" ||
validTeamPlan === "growth_legacy"));
const highlightStarterPlan =
highlightPlan === "starter" ||
(!highlightPlan &&
!isCurrentPlanScheduledToCancel &&
validTeamPlan === "starter_legacy");
const highlightAcceleratePlan =
highlightPlan === "accelerate" ||
(!highlightPlan &&
!isCurrentPlanScheduledToCancel &&
validTeamPlan === "growth");
const highlightStarterPlan = highlightPlan === "starter";
const highlightScalePlan =
highlightPlan === "scale" ||
(!highlightPlan &&
!isCurrentPlanScheduledToCancel &&
validTeamPlan === "accelerate");
(validTeamPlan === "accelerate" || validTeamPlan === "growth"));
const highlightProPlan =
highlightPlan === "pro" ||
(!highlightPlan &&
!isCurrentPlanScheduledToCancel &&
validTeamPlan === "pro");
return (
<div>
@@ -108,123 +99,79 @@ export const BillingPricing: React.FC<BillingPricingProps> = ({
<PricingCard
billingPlan="starter"
billingStatus={team.billingStatus}
current={validTeamPlan === "starter"}
cta={getPlanCta(
validTeamPlan,
"starter",
isCurrentPlanScheduledToCancel,
)}
teamSlug={team.slug}
teamId={team.id}
highlighted={highlightStarterPlan}
current={validTeamPlan === "starter"}
getTeam={getTeam}
highlighted={highlightStarterPlan}
teamId={team.id}
teamSlug={team.slug}
/>
{/* Growth */}
<PricingCard
billingPlan="growth"
billingStatus={team.billingStatus}
activeTrialEndsAt={
validTeamPlan === "growth" ? trialPeriodEndedAt : undefined
}
current={validTeamPlan === "growth"}
billingPlan="growth"
billingStatus={team.billingStatus}
cta={getPlanCta(
validTeamPlan,
"growth",
isCurrentPlanScheduledToCancel,
)}
current={validTeamPlan === "growth"}
getTeam={getTeam}
highlighted={highlightGrowthPlan}
teamSlug={team.slug}
teamId={team.id}
getTeam={getTeam}
/>
{/* Accelerate */}
<PricingCard
billingPlan="accelerate"
billingStatus={team.billingStatus}
teamSlug={team.slug}
teamId={team.id}
current={validTeamPlan === "accelerate"}
cta={getPlanCta(
validTeamPlan,
"accelerate",
isCurrentPlanScheduledToCancel,
)}
highlighted={highlightAcceleratePlan}
getTeam={getTeam}
/>
{/* Scale */}
<PricingCard
billingPlan="scale"
billingStatus={team.billingStatus}
teamSlug={team.slug}
teamId={team.id}
current={validTeamPlan === "scale"}
cta={getPlanCta(
validTeamPlan,
"scale",
isCurrentPlanScheduledToCancel,
)}
highlighted={highlightScalePlan}
current={validTeamPlan === "scale"}
getTeam={getTeam}
highlighted={highlightScalePlan}
teamId={team.id}
teamSlug={team.slug}
/>
{/* Pro */}
<PricingCard
billingPlan="pro"
billingStatus={team.billingStatus}
cta={getPlanCta(validTeamPlan, "pro", isCurrentPlanScheduledToCancel)}
current={validTeamPlan === "pro"}
getTeam={getTeam}
highlighted={highlightProPlan}
teamId={team.id}
teamSlug={team.slug}
/>
</div>
<div className="h-8" />
<ProCard />
</div>
);
};
const proFeatures = [
"Custom rate limits for APIs & Infra",
"Guaranteed support response time",
"Direct access to solutions & engineering teams",
"Enterprise grade SLAs",
];
function ProCard() {
return (
<div className="flex flex-col justify-between gap-6 rounded-lg border bg-card p-6 lg:flex-row">
<div>
<h2 className="mb-0.5 font-semibold text-xl tracking-tight">
Need more? Upgrade to Pro
</h2>
<p className="text-muted-foreground text-sm">
Ideal for teams that require more customization, SLAs, and support.
</p>
<ul className="mt-5 grid max-w-3xl grid-cols-1 gap-x-8 gap-y-2 text-muted-foreground text-sm lg:grid-cols-2">
{proFeatures.map((feature, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
<li key={i} className="flex items-center gap-2">
<CheckIcon className="size-4 text-success-text" />
{feature}
</li>
))}
</ul>
</div>
<Button variant="outline" asChild className="gap-2 bg-background">
<Link href={PRO_CONTACT_US_URL} target="_blank">
Contact Us
</Link>
</Button>
</div>
);
}
function getPlanCta(
currentPlan: Team["billingPlan"],
targetPlan: Team["billingPlan"],
isScheduledToCancel: boolean,
): CtaLink | undefined {
// if any of the plan is pro - show contact us
if (currentPlan === "pro" || targetPlan === "pro") {
// if the CURRENT plan is pro, show contact us link
if (currentPlan === "pro") {
return {
label: "Contact us",
href: PRO_CONTACT_US_URL,
label: "Contact us",
type: "link",
};
}
@@ -1,13 +1,13 @@
import type { Meta, StoryObj } from "@storybook/nextjs";
import { useId, useMemo, useState } from "react";
import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Switch } from "@/components/ui/switch";
import type { Meta, StoryObj } from "@storybook/react";
import { useMemo, useState } from "react";
import { type CouponData, CouponsUI } from "./CouponsUI";
const meta = {
title: "Billing/Coupons",
component: Story,
title: "Billing/Coupons",
} satisfies Meta<typeof CouponsUI>;
export default meta;
@@ -16,54 +16,54 @@ type Story = StoryObj<typeof CouponsUI>;
const couponStubs: CouponData[] = [
// Forever
{
id: "di_1QAE7jCQUO4TBFqFQgnS4Qj4",
start: 1729011691,
end: null,
coupon: {
id: "forever_active",
name: "Example 1",
duration: "forever",
duration_in_months: null,
id: "forever_active",
name: "Example 1",
},
end: null,
id: "di_1QAE7jCQUO4TBFqFQgnS4Qj4",
start: 1729011691,
},
// Once
{
id: "once",
start: 1733391052,
end: null,
coupon: {
id: "once_active",
name: "Example 2",
duration: "once",
duration_in_months: null,
id: "once_active",
name: "Example 2",
},
end: null,
id: "once",
start: 1733391052,
},
// Repeating - 3 months
{
id: "repeating-3",
start: 1733391629,
end: 1743391629, // Will end in the future
coupon: {
id: "repeating_active",
name: "Example 3",
duration: "repeating",
duration_in_months: 3,
id: "repeating_active",
name: "Example 3",
},
end: 1743391629,
id: "repeating-3", // Will end in the future
start: 1733391629,
},
// Repeating - 1 month
{
id: "repeating-1",
start: 1733391713,
end: 1736391713,
coupon: {
id: "repeating_single",
name: "Example 4",
duration: "repeating",
duration_in_months: 1,
id: "repeating_single",
name: "Example 4",
},
end: 1736391713,
id: "repeating-1",
start: 1733391713,
},
];
@@ -102,6 +102,9 @@ function Story() {
200 | 400 | 401 | 409 | 429 | 500
>(200);
const hasAccountCouponId = useId();
const paymentSetupId = useId();
return (
<div className="container max-w-[1100px] py-10">
<div className="mb-8 space-y-6">
@@ -109,22 +112,22 @@ function Story() {
<div className="space-y-3">
<h3 className="font-semibold text-lg">Status</h3>
<RadioGroup
value={status}
className="flex gap-4"
onValueChange={(value) =>
setStatus(value as "pending" | "error" | "success")
}
className="flex gap-4"
value={status}
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="pending" id="status-pending" />
<RadioGroupItem value="pending" />
<Label htmlFor="status-pending">Pending</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="error" id="status-error" />
<RadioGroupItem value="error" />
<Label htmlFor="status-error">Error</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="success" id="status-success" />
<RadioGroupItem value="success" />
<Label htmlFor="status-success">Success</Label>
</div>
</RadioGroup>
@@ -133,22 +136,22 @@ function Story() {
<div className="space-y-3">
<h3 className="font-semibold text-lg">Active Coupons</h3>
<RadioGroup
value={activeCouponsType}
className="flex gap-4"
onValueChange={(value) =>
setActiveCouponsType(value as "multiple" | "zero" | "one")
}
className="flex gap-4"
value={activeCouponsType}
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="multiple" id="coupons-multiple" />
<RadioGroupItem value="multiple" />
<Label htmlFor="coupons-multiple">Multiple</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="zero" id="coupons-zero" />
<RadioGroupItem value="zero" />
<Label htmlFor="coupons-zero">Zero</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="one" id="coupons-one" />
<RadioGroupItem value="one" />
<Label htmlFor="coupons-one">One</Label>
</div>
</RadioGroup>
@@ -157,19 +160,19 @@ function Story() {
<div className="space-y-3">
<h3 className="font-semibold text-lg">Apply Coupon Status</h3>
<RadioGroup
value={applyCouponStatus.toString()}
className="flex gap-4"
onValueChange={(value) =>
setApplyCouponStatus(
Number.parseInt(value) as 200 | 400 | 401 | 409 | 429 | 500,
)
}
value={applyCouponStatus.toString()}
>
{[200, 400, 401, 409, 429, 500].map((code) => (
<div key={code} className="flex items-center space-x-2">
<div className="flex items-center space-x-2" key={code}>
<RadioGroupItem
value={code.toString()}
id={`status-${code}`}
value={code.toString()}
/>
<Label htmlFor={`status-${code}`}>{code}</Label>
</div>
@@ -183,52 +186,52 @@ function Story() {
<div className="space-y-4">
<div className="flex items-center gap-4">
<Switch
id="has-account-coupon"
checked={hasAccountCoupon}
id={hasAccountCouponId}
onCheckedChange={setHasAccountCoupon}
/>
<Label htmlFor="has-account-coupon">Has Account Coupon</Label>
<Label htmlFor={hasAccountCouponId}>Has Account Coupon</Label>
</div>
<div className="flex items-center gap-4">
<Switch
id="payment-setup"
checked={isPaymentSetup}
id={paymentSetupId}
onCheckedChange={setIsPaymentSetup}
/>
<Label htmlFor="payment-setup">Payment Setup</Label>
<Label htmlFor={paymentSetupId}>Payment Setup</Label>
</div>
</div>
</div>
</div>
<CouponsUI
status={status}
activeCoupons={activeCoupons}
accountCouponId={hasAccountCoupon ? activeCoupons[0]?.id : undefined}
isPaymentSetup={isPaymentSetup}
activeCoupons={activeCoupons}
applyCoupon={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return {
status: applyCouponStatus,
data:
applyCouponStatus === 200
? {
id: "xyz",
start: 1727992716,
end: 1759528716,
coupon: {
id: "test",
name: "TEST COUPON",
duration: "repeating",
duration_in_months: 12,
id: "test",
name: "TEST COUPON",
},
end: 1759528716,
id: "xyz",
start: 1727992716,
}
: null,
status: applyCouponStatus,
};
}}
deleteCoupon={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
}}
isPaymentSetup={isPaymentSetup}
status={status}
/>
</div>
);
@@ -1,6 +1,6 @@
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { Suspense } from "react";
import { getAuthToken } from "../../../../../app/(app)/api/lib/getAuthToken";
import { getAuthToken } from "@/api/auth-token";
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
import { CouponsClient } from "./CouponsClient";
import type { CouponData } from "./CouponsUI";
@@ -39,10 +39,10 @@ async function AsyncCoupons(props: {
) {
return (
<CouponsClient
status="error"
activeCoupons={[]}
accountCouponId={undefined}
activeCoupons={[]}
isPaymentSetup={props.isPaymentSetup}
status="error"
teamId={props.teamId}
/>
);
@@ -58,34 +58,31 @@ async function AsyncCoupons(props: {
return (
<CouponsClient
status="success"
activeCoupons={allCouponsData.data}
accountCouponId={accountCouponData.data?.id}
activeCoupons={allCouponsData.data}
isPaymentSetup={props.isPaymentSetup}
status="success"
teamId={props.teamId}
/>
);
}
export function Coupons(props: {
teamId: string;
isPaymentSetup: boolean;
}) {
export function Coupons(props: { teamId: string; isPaymentSetup: boolean }) {
return (
<Suspense
fallback={
<CouponsClient
status="pending"
activeCoupons={[]}
accountCouponId={undefined}
activeCoupons={[]}
isPaymentSetup={true}
status="pending"
teamId={props.teamId}
/>
}
>
<AsyncCoupons
teamId={props.teamId}
isPaymentSetup={props.isPaymentSetup}
teamId={props.teamId}
/>
</Suspense>
);
@@ -16,6 +16,35 @@ export function CouponsClient(
return (
<CouponsUI
{...props}
applyCoupon={async (promoCode: string) => {
const res = await apiServerProxy<{ data: CouponData }>({
body: JSON.stringify({
promoCode,
teamId: props.teamId,
}),
headers: {
"Content-Type": "application/json",
},
method: "POST",
pathname: "/v1/coupons/redeem",
});
if (!res.ok) {
return {
data: null,
status: res.status,
};
}
const json = res.data;
router.refresh();
return {
data: json.data,
status: 200,
};
}}
deleteCoupon={async () => {
const res = await apiServerProxy({
method: "DELETE",
@@ -29,35 +58,6 @@ export function CouponsClient(
router.refresh();
}}
applyCoupon={async (promoCode: string) => {
const res = await apiServerProxy<{ data: CouponData }>({
method: "POST",
pathname: "/v1/coupons/redeem",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
promoCode,
teamId: props.teamId,
}),
});
if (!res.ok) {
return {
status: res.status,
data: null,
};
}
const json = res.data;
router.refresh();
return {
status: 200,
data: json.data,
};
}}
/>
);
}
@@ -1,17 +1,5 @@
"use client";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { ToolTipLabel } from "@/components/ui/tooltip";
import { useMutation } from "@tanstack/react-query";
import { format, fromUnixTime } from "date-fns";
import {
@@ -22,6 +10,18 @@ import {
Trash2Icon,
} from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { ToolTipLabel } from "@/components/ui/tooltip";
type Coupon = {
id: string;
@@ -211,17 +211,17 @@ function DeleteCouponButton(props: {
return (
<Button
variant="outline"
size="sm"
aria-label="Remove coupon"
disabled={props.disabled}
onClick={() => {
const promise = deleteCoupon.mutateAsync();
toast.promise(promise, {
success: "Coupon removed successfully",
error: "Failed to remove coupon",
success: "Coupon removed successfully",
});
}}
aria-label="Remove coupon"
size="sm"
variant="outline"
>
{deleteCoupon.isPending ? (
<Spinner className="size-4" />
@@ -1,14 +1,14 @@
"use client";
import { AlertTriangleIcon } from "lucide-react";
import Link from "next/link";
import type { Team } from "@/api/team";
import { Button, type ButtonProps } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { ProductSKU } from "@/types/billing";
import {
buildBillingPortalUrl,
buildCheckoutUrl,
} from "../../app/(app)/(stripe)/utils/build-url";
import type { Team } from "../api/team";
import type { ProductSKU } from "../lib/billing";
import { cn } from "../lib/utils";
import { Button, type ButtonProps } from "./ui/button";
} from "@/utils/stripe/build-url";
export function CheckoutButton(props: {
buttonProps?: Omit<ButtonProps, "children">;
@@ -38,11 +38,12 @@ export function CheckoutButton(props: {
}}
>
<Link
target="_blank"
href={buildCheckoutUrl({
teamSlug: props.teamSlug,
sku: props.sku,
teamSlug: props.teamSlug,
})}
rel="noopener noreferrer"
target="_blank"
>
{props.children}
</Link>
@@ -58,8 +59,8 @@ function BillingWarning({ teamSlug }: { teamSlug: string }) {
<p className="text-sm">
You have outstanding invoices. Please{" "}
<Link
href={`/team/${teamSlug}/~/settings/invoices?status=open`}
className="font-medium text-amber-700 underline transition-colors hover:text-amber-900 dark:text-amber-400 dark:hover:text-amber-300"
href={`/team/${teamSlug}/~/billing/invoices?status=open`}
>
pay them
</Link>{" "}
@@ -77,19 +78,20 @@ export function BillingPortalButton(props: {
return (
<Button
{...props.buttonProps}
asChild
className={cn(props.buttonProps?.className, "gap-2")}
disabled={props.buttonProps?.disabled}
asChild
onClick={async (e) => {
props.buttonProps?.onClick?.(e);
}}
>
<Link
<a
href={buildBillingPortalUrl({ teamSlug: props.teamSlug })}
rel="noopener noreferrer"
target="_blank"
>
{props.children}
</Link>
</a>
</Button>
);
}
@@ -1,7 +1,7 @@
export const formatToDollars = (cents: number) => {
const dollars = cents / 100;
return new Intl.NumberFormat(undefined, {
style: "currency",
currency: "USD",
style: "currency",
}).format(dollars);
};
@@ -1,20 +1,21 @@
"use client";
import { reSubscribePlan } from "@/actions/billing";
import type { Team } from "@/api/team";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { Button } from "@/components/ui/button";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { useMutation } from "@tanstack/react-query";
import { RefreshCwIcon } from "lucide-react";
import { useState, useTransition } from "react";
import { toast } from "sonner";
import { pollWithTimeout } from "../../../../../utils/pollWithTimeout";
import { tryCatch } from "../../../../../utils/try-catch";
import { reSubscribePlan } from "@/actions/billing";
import type { Team } from "@/api/team";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { pollWithTimeout } from "../../../utils/pollWithTimeout";
import { tryCatch } from "../../../utils/try-catch";
export function RenewSubscriptionButton(props: {
teamId: string;
getTeam: () => Promise<Team>;
disabled?: boolean;
}) {
const router = useDashboardRouter();
const [isRoutePending, setTransition] = useTransition();
@@ -67,11 +68,11 @@ export function RenewSubscriptionButton(props: {
return (
<Button
onClick={handleRenewSubscription}
variant="default"
size="sm"
className="gap-2"
disabled={showSpinner}
disabled={showSpinner || props.disabled}
onClick={handleRenewSubscription}
size="sm"
variant="default"
>
{showSpinner ? (
<Spinner className="size-4" />
@@ -1,7 +1,9 @@
/* eslint-disable no-restricted-syntax */
import { Input } from "@/components/ui/input";
import { PercentIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
type InputProps = React.ComponentProps<typeof Input>;
@@ -44,10 +46,13 @@ export const BasisPointsInput: React.FC<BasisPointsInputProps> = ({
return (
<div className="flex overflow-hidden rounded-lg border border-border ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2">
<Input
className="rounded-r-none border-none focus-visible:ring-0 focus-visible:ring-offset-0"
value={stringValue}
{...restInputProps}
onChange={(e) => setStringValue(e.target.value)}
className={cn(
"rounded-r-none border-none focus-visible:ring-0 focus-visible:ring-offset-0",
restInputProps.className,
)}
maxLength={5}
onBlur={(e) => {
const val = e.target.value;
const validValue = val.match(
@@ -59,7 +64,7 @@ export const BasisPointsInput: React.FC<BasisPointsInputProps> = ({
setStringValue("0.00");
}
}}
maxLength={5}
onChange={(e) => setStringValue(e.target.value)}
/>
<div className="flex items-center justify-center border-border border-l bg-card px-3 font-medium">
<PercentIcon className="size-4" />

Some files were not shown because too many files have changed in this diff Show More