Compare commits

...
Author SHA1 Message Date
Joaquim VergesGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
7defce7264 Version Packages (#8303)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-26 00:46:21 -07:00
Joaquim VergesandGitHub ae3a122cf1 [X402] Fix network comparison in decodePaymentRequest (#8313) 2025-10-26 00:44:27 -07:00
Jonas DanielsandGitHub 2412a6958c Handle null metadata in ERC721 and ERC1155 getNFT functions (#8312) 2025-10-24 15:22:14 -07:00
Jonas DanielsandGitHub bfd3be764c Filter out null-ish values from ERC721 and ERC1155 getNFTs() arrays (#8311) 2025-10-24 14:39:31 -07:00
Joaquim VergesandGitHub 46b9d2dd82 [Playground] Use production API URL (#8307) 2025-10-24 11:38:11 -07:00
MananTank 3e9eb49787 [MNY-289] SDK: Fix token selection UI loading state when wallet is connected to a chain that is not supported by tw bridge (#8304)
<!--

## 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 addresses an issue with the `Select Token` UI being stuck in a loading state when the wallet is connected to an unsupported chain by the `thirdweb Bridge`. It modifies the logic for selecting the default chain in various widgets.

### Detailed summary
- Updated the function from `getDefaultSelectedChain` to `findChain` for clarity.
- Improved logic to handle cases where `activeChainId` is undefined.
- Adjusted the selection of `selectedChain` to use the new `findChain` function, ensuring proper fallback options.

> ✨ 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 Select Token components from remaining in loading state when the connected wallet chain is not supported by thirdweb Bridge. This affects BuyWidget, SwapWidget, and BridgeWidget.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-23 23:39:57 +00:00
MananTank 630edadcec Dashboard: Fix horizontal overflow in /bridge page (#8302)
<!--

## 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 styling of the `bridge-page` component by adding an `overflow-hidden` class to a `div`, which likely improves the layout and prevents overflow issues.

### Detailed summary

- Added `overflow-hidden` class to the `div` in the `bridge-page` component to manage overflow behavior.

> ✨ 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 the bridge page container to refine content display behavior and ensure consistent visual presentation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-23 23:30:50 +00:00
MananTank f757e60846 [MNY-237] SDK: Update theme colors, minor UI tweaks (#8305)
<!--

## 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 theme colors and making minor UI tweaks across various React components in the `thirdweb` package.

### Detailed summary

- Updated `weight` from `600` to `500` in multiple components' `Text`.
- Adjusted `border` styles in `Container` components.
- Modified padding and margin in several layout elements.
- Enhanced UI elements with consistent `letterSpacing` and `fontSize`.
- Added new theme stories for `darkThemeObj` and `lightThemeObj`.

> ✨ 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 Storybook theme showcase displaying color tokens and design system palette
- **Bug Fixes**
    - Improved loading skeleton UI with better scrollable layout and visual consistency
- **Style**
    - Refactored theme system with explicit color objects
    - Updated button styling with adjusted border radius and padding
    - Refined typography (font weights) across UI components
    - Adjusted layout spacing and padding throughout Bridge and wallet components
    - Increased QR code size for improved visibility
- **Chores**
    - Added changeset documentation for patch release

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-23 23:21:57 +00:00
kumaryash90 d5d593956e Update factory (#8301)
<!--

## 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 patch for the `thirdweb` package, adding a new factory address for the `create2` deployment on the Neura testnet.

### Detailed summary
- Added a new factory address for `267`: `0x4e59b44847b379578588920cA78FbF26c0B4956C` to the `FACTORIES` record in `create-2-factory.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 Neura testnet in Create2 factory deployments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-23 17:05:22 +00:00
26 changed files with 481 additions and 332 deletions
@@ -20,7 +20,7 @@ export function BridgePageUI(props: {
<div className="grow flex flex-col">
<BridgePageHeader />
<div className="flex grow items-center justify-center px-4 relative pt-12 pb-20 lg:py-28 min-h-[calc(100dvh-60px)]">
<div className="flex grow items-center justify-center px-4 relative pt-12 pb-20 lg:py-28 min-h-[calc(100dvh-60px)] overflow-hidden">
<DotsBackgroundPattern />
<UniversalBridgeEmbed buyTab={props.buyTab} swapTab={props.swapTab} />
</div>
@@ -18,8 +18,7 @@ export async function GET(request: NextRequest) {
// const BACKEND_WALLET_ADDRESS = process.env.ENGINE_BACKEND_SMART_WALLET as string;
const ENGINE_VAULT_ACCESS_TOKEN = process.env
.ENGINE_VAULT_ACCESS_TOKEN as string;
// const API_URL = `https://${process.env.NEXT_PUBLIC_API_URL || "api.thirdweb.com"}`;
const API_URL = "http://localhost:3030";
const API_URL = `https://${process.env.NEXT_PUBLIC_API_URL || "api.thirdweb.com"}`;
const twFacilitator = facilitator({
baseUrl: `${API_URL}/v1/payments/x402`,
+8
View File
@@ -1,5 +1,13 @@
# wagmi-inapp
## 0.0.15
### Patch Changes
- Updated dependencies [[`3e9eb49`](https://github.com/thirdweb-dev/js/commit/3e9eb49787e00c09c3286aeb4ad73826a2856e65), [`bfd3be7`](https://github.com/thirdweb-dev/js/commit/bfd3be764c461c420f1f8520fe4d5d2cc83e42f7), [`ae3a122`](https://github.com/thirdweb-dev/js/commit/ae3a122cf1628f0fc997dd240d4b23842ac30f66), [`d5d5939`](https://github.com/thirdweb-dev/js/commit/d5d593956e12b2a15393ed32d1d742bc43575bdd), [`f757e60`](https://github.com/thirdweb-dev/js/commit/f757e6084648b6b6e5879abeab30954753a1020d)]:
- thirdweb@5.110.2
- @thirdweb-dev/wagmi-adapter@0.2.170
## 0.0.14
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "wagmi-inapp",
"private": true,
"version": "0.0.14",
"version": "0.0.15",
"type": "module",
"scripts": {
"dev": "vite",
+7
View File
@@ -1,5 +1,12 @@
# @thirdweb-dev/nebula
## 0.2.73
### Patch Changes
- Updated dependencies [[`3e9eb49`](https://github.com/thirdweb-dev/js/commit/3e9eb49787e00c09c3286aeb4ad73826a2856e65), [`bfd3be7`](https://github.com/thirdweb-dev/js/commit/bfd3be764c461c420f1f8520fe4d5d2cc83e42f7), [`ae3a122`](https://github.com/thirdweb-dev/js/commit/ae3a122cf1628f0fc997dd240d4b23842ac30f66), [`d5d5939`](https://github.com/thirdweb-dev/js/commit/d5d593956e12b2a15393ed32d1d742bc43575bdd), [`f757e60`](https://github.com/thirdweb-dev/js/commit/f757e6084648b6b6e5879abeab30954753a1020d)]:
- thirdweb@5.110.2
## 0.2.72
### Patch Changes
+1 -1
View File
@@ -57,5 +57,5 @@
"type": "module",
"types": "./dist/types/exports/thirdweb.d.ts",
"typings": "./dist/types/exports/thirdweb.d.ts",
"version": "0.2.72"
"version": "0.2.73"
}
+14
View File
@@ -1,5 +1,19 @@
# thirdweb
## 5.110.2
### Patch Changes
- [#8304](https://github.com/thirdweb-dev/js/pull/8304) [`3e9eb49`](https://github.com/thirdweb-dev/js/commit/3e9eb49787e00c09c3286aeb4ad73826a2856e65) Thanks [@MananTank](https://github.com/MananTank)! - Fix Select Token UI stuck in loading state if wallet is connected to a chain that is not supported by thirdweb Bridge in BuyWidget, SwapWidget and BridgeWidget
- [#8311](https://github.com/thirdweb-dev/js/pull/8311) [`bfd3be7`](https://github.com/thirdweb-dev/js/commit/bfd3be764c461c420f1f8520fe4d5d2cc83e42f7) Thanks [@jnsdls](https://github.com/jnsdls)! - filter out null-ish values from `ERC721.getNFTs()` and `ERC1155.getNFTs()` arrays
- [#8313](https://github.com/thirdweb-dev/js/pull/8313) [`ae3a122`](https://github.com/thirdweb-dev/js/commit/ae3a122cf1628f0fc997dd240d4b23842ac30f66) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix network comparison when using diff libraries
- [#8301](https://github.com/thirdweb-dev/js/pull/8301) [`d5d5939`](https://github.com/thirdweb-dev/js/commit/d5d593956e12b2a15393ed32d1d742bc43575bdd) Thanks [@kumaryash90](https://github.com/kumaryash90)! - create2 factory for neura testnet
- [#8305](https://github.com/thirdweb-dev/js/pull/8305) [`f757e60`](https://github.com/thirdweb-dev/js/commit/f757e6084648b6b6e5879abeab30954753a1020d) Thanks [@MananTank](https://github.com/MananTank)! - Update theme colors and minor UI tweaks in React Components
## 5.110.1
### Patch Changes
+1 -1
View File
@@ -430,5 +430,5 @@
}
},
"typings": "./dist/types/exports/thirdweb.d.ts",
"version": "5.110.1"
"version": "5.110.2"
}
@@ -321,6 +321,7 @@ const CUSTOM_GAS_FOR_CHAIN: Record<string, CustomChain> = {
const FACTORIES: Record<string, string> = {
"88888": "0xc501b9abf5540de1dd24f66633b1ecf35ff7101f",
"267": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"420120000": COMMON_FACTORY_ADDRESS,
"420120001": COMMON_FACTORY_ADDRESS, // EIP155 is enforced, but the check fails, hence we hardcode the address here instead of computing dynamically
};
@@ -83,11 +83,23 @@ async function getNFTFromRPC(
client: options.contract.client,
tokenId: options.tokenId,
tokenUri,
}).catch(() => ({
id: options.tokenId,
type: "ERC1155",
uri: tokenUri,
})),
})
.then((metadata) => {
// if the metadata is null-ish, return a default metadata object
if (!metadata) {
return {
id: options.tokenId,
type: "ERC1155",
uri: tokenUri,
};
}
return metadata;
})
.catch(() => ({
id: options.tokenId,
type: "ERC1155",
uri: tokenUri,
})),
{
chainId: options.contract.chain.id,
owner: null,
@@ -139,11 +139,23 @@ async function getNFTFromRPC(
client: options.contract.client,
tokenId,
tokenUri: uri,
}).catch(() => ({
id: tokenId,
type: "ERC721",
uri,
})),
})
.then((metadata) => {
// if the metadata is null-ish, return a default metadata object
if (!metadata) {
return {
id: tokenId,
type: "ERC721",
uri,
};
}
return metadata;
})
.catch(() => ({
id: tokenId,
type: "ERC721",
uri,
})),
{
chainId: options.contract.chain.id,
owner,
@@ -1,48 +1,3 @@
type ThemeColors = {
base1: string;
base2: string;
base3: string;
base4: string;
primaryText: string;
secondaryText: string;
danger: string;
success: string;
overlay: string;
accentText: string;
accentBg: string;
textOnAccent: string;
};
const darkColors = {
accentBg: "hsl(216 100% 50%)",
accentText: "#3385FF",
base1: "hsl(230 11.63% 8.43%)",
base2: "hsl(230 11.63% 12%)",
base3: "hsl(230 11.63% 15%)",
base4: "hsl(230 11.63% 17%)",
danger: "#e5484D",
overlay: "rgba(0, 0, 0, 0.7)",
primaryText: "#eeeef0",
secondaryText: "#7c7a85",
success: "#30A46C",
textOnAccent: "#eeeef0",
} as const satisfies ThemeColors;
const lightColors = {
accentBg: "hsl(216 100% 50%)",
accentText: "#3385FF",
base1: "#fdfcfd",
base2: "#f2eff3",
base3: "#e3dfe6",
base4: "#dbd8e0",
danger: "#e5484D",
overlay: "rgba(0, 0, 0, 0.7)",
primaryText: "#211f26",
secondaryText: "#6f6d78",
success: "#30A46C",
textOnAccent: "#fdfcfd",
} as const satisfies ThemeColors;
/**
* @theme
*/
@@ -95,64 +50,77 @@ export type Theme = {
fontFamily: string;
};
/**
* @internal
*/
function createThemeObj(type: "dark" | "light", colors: ThemeColors): Theme {
return {
colors: {
accentButtonBg: colors.accentBg,
accentButtonText: colors.textOnAccent,
accentText: colors.accentText,
export const darkThemeObj: Theme = {
type: "dark",
colors: {
accentButtonBg: "hsl(221 83% 54%)",
accentButtonText: "hsl(0 0% 100%)",
accentText: "hsl(209.61deg 100% 65.31%)",
borderColor: "hsl(0 0% 15%)",
connectedButtonBg: "hsl(0 0% 3.92%)",
connectedButtonBgHover: "hsl(0 0% 11%)",
danger: "hsl(360 72% 55%)",
inputAutofillBg: "hsl(0 0% 11%)",
modalBg: "hsl(0 0% 3.92%)",
primaryButtonBg: "hsl(0 0% 100%)",
primaryButtonText: "hsl(0 0% 0%)",
primaryText: "hsl(0 0% 98%)",
scrollbarBg: "hsl(0 0% 11%)",
secondaryButtonBg: "hsl(0 0% 9%)",
modalOverlayBg: "rgba(0, 0, 0, 0.7)",
secondaryButtonHoverBg: "hsl(0 0% 9%/80%)",
secondaryButtonText: "hsl(0 0% 98%)",
secondaryIconColor: "hsl(0 0% 63%)",
secondaryIconHoverBg: "hsl(0 0% 11%)",
secondaryIconHoverColor: "hsl(0 0% 98%)",
secondaryText: "hsl(0 0% 63%)",
selectedTextBg: "hsl(0 0% 100%)",
selectedTextColor: "hsl(0 0% 0%)",
separatorLine: "hsl(0 0% 15%)",
skeletonBg: "hsl(0 0% 12%)",
success: "hsl(142 75% 50%)",
tertiaryBg: "hsl(0 0% 11%/50%)",
tooltipBg: "hsl(0 0% 11%)",
tooltipText: "hsl(0 0% 98%)",
},
fontFamily: "inherit",
};
borderColor: colors.base4,
connectedButtonBg: colors.base1,
connectedButtonBgHover: colors.base2,
danger: colors.danger,
inputAutofillBg: colors.base1,
modalBg: colors.base1,
modalOverlayBg: colors.overlay,
primaryButtonBg: colors.primaryText,
primaryButtonText: colors.base1,
primaryText: colors.primaryText,
scrollbarBg: colors.base2,
secondaryButtonBg: colors.base3,
secondaryButtonHoverBg: colors.base4,
secondaryButtonText: colors.primaryText,
secondaryIconColor: colors.secondaryText,
secondaryIconHoverBg: colors.base3,
secondaryIconHoverColor: colors.primaryText,
secondaryText: colors.secondaryText,
selectedTextBg: colors.primaryText,
selectedTextColor: colors.base1,
separatorLine: colors.base4,
skeletonBg: colors.base4,
success: colors.success,
tertiaryBg: colors.base2,
tooltipBg: colors.primaryText,
tooltipText: colors.base1,
},
fontFamily: "inherit",
type,
};
}
export const darkThemeObj = /* @__PURE__ */ createThemeObj("dark", darkColors);
export const lightThemeObj = /* @__PURE__ */ createThemeObj(
"light",
lightColors,
);
export const lightThemeObj: Theme = {
type: "light",
colors: {
accentButtonBg: "hsl(221 83% 54%)",
accentButtonText: "hsl(0 0% 100%)",
accentText: "hsl(211.23deg 100% 44.47%)",
borderColor: "hsl(0 0% 85%)",
connectedButtonBg: "hsl(0 0% 100%)",
connectedButtonBgHover: "hsl(0 0% 93%)",
danger: "hsl(360 72% 60%)",
inputAutofillBg: "hsl(0 0% 93%)",
modalBg: "hsl(0 0% 100%)",
primaryButtonBg: "hsl(0 0% 4%)",
primaryButtonText: "hsl(0 0% 100%)",
primaryText: "hsl(0 0% 4%)",
scrollbarBg: "hsl(0 0% 93%)",
secondaryButtonBg: "hsl(0 0% 93%)",
modalOverlayBg: "rgba(0, 0, 0, 0.7)",
secondaryButtonHoverBg: "hsl(0 0% 93%/80%)",
secondaryButtonText: "hsl(0 0% 4%)",
secondaryIconColor: "hsl(0 0% 40%)",
secondaryIconHoverBg: "hsl(0 0% 93%)",
secondaryIconHoverColor: "hsl(0 0% 4%)",
secondaryText: "hsl(0 0% 40%)",
selectedTextBg: "hsl(0 0% 4%)",
selectedTextColor: "hsl(0 0% 100%)",
separatorLine: "hsl(0 0% 85%)",
skeletonBg: "hsl(0 0% 85%)",
success: "hsl(142.09 70.56% 35.29%)",
tertiaryBg: "hsl(0 0% 93%/70%)",
tooltipBg: "hsl(0 0% 100%)",
tooltipText: "hsl(0 0% 4%)",
},
fontFamily: "inherit",
};
/**
* @theme
@@ -5,7 +5,6 @@ import type { SupportedFiatCurrency } from "../../../../../pay/convert/type.js";
import { checksumAddress } from "../../../../../utils/address.js";
import { formatNumber } from "../../../../../utils/formatNumber.js";
import { toTokens } from "../../../../../utils/units.js";
import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
import {
iconSize,
radius,
@@ -62,8 +61,6 @@ export function FiatProviderSelection({
currency,
country,
}: FiatProviderSelectionProps) {
const theme = useCustomTheme();
// Fetch quotes for all providers
const quoteQueries = useBuyWithFiatQuotesForProviders({
amount: toAmount || "0",
@@ -122,9 +119,9 @@ export function FiatProviderSelection({
fullWidth
onClick={() => onProviderSelected(provider.id)}
style={{
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
borderRadius: radius.lg,
textAlign: "left",
padding: `${spacing.md}`,
}}
variant="secondary"
>
@@ -269,7 +269,7 @@ export function PaymentSelection({
}
return (
<Container flex="column" px="md" pb="md" pt="md+">
<Container flex="column" px="md" pt="md+">
<ModalHeader onBack={getBackHandler()} title={getStepTitle()} />
<Spacer y="lg" />
@@ -61,10 +61,8 @@ function PaymentMethodTokenRow({
onClick={() => onPaymentMethodSelected(paymentMethod)}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
opacity: hasEnoughBalance ? 1 : 0.5,
padding: `${spacing.sm} ${spacing.md}`,
borderRadius: radius.lg,
padding: `${spacing.md} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
@@ -134,71 +132,74 @@ export function TokenSelection({
if (paymentMethodsLoading) {
return (
<>
<Text color="primaryText" size="md">
Loading your tokens
</Text>
<Spacer y="sm" />
<Container flex="column" gap="sm">
{/* Skeleton rows matching PaymentMethodTokenRow structure */}
{[1, 2, 3].map((i) => (
<Container
flex="column"
gap="xs"
pb="lg"
style={{
maxHeight: "400px",
overflowY: "auto",
scrollbarWidth: "none",
}}
>
{/* Skeleton rows matching PaymentMethodTokenRow structure */}
{new Array(10).fill(0).map((_, i) => (
<Container
// biome-ignore lint/suspicious/noArrayIndexKey: ok
key={i}
style={{
backgroundColor: theme.colors.tertiaryBg,
borderRadius: radius.lg,
padding: `${spacing.md} ${spacing.md}`,
}}
>
<Container
key={i}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
padding: `${spacing.sm} ${spacing.md}`,
}}
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
>
{/* Left side: Token icon and name skeleton */}
<Container
center="y"
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
gap="sm"
style={{ maxWidth: "50%" }}
>
{/* Left side: Token icon and name skeleton */}
<Container
center="y"
flex="row"
gap="sm"
style={{ maxWidth: "50%" }}
>
{/* Token icon skeleton */}
<div
style={{
backgroundColor: theme.colors.skeletonBg,
borderRadius: "50%",
height: "32px",
width: "32px",
}}
/>
<Container flex="column" gap="3xs">
{/* Token name skeleton */}
<Skeleton height="14px" width="60px" />
{/* Chain name skeleton */}
<Skeleton height="12px" width="40px" />
</Container>
{/* Token icon skeleton */}
<div
style={{
backgroundColor: theme.colors.skeletonBg,
borderRadius: "50%",
height: "32px",
width: "32px",
}}
/>
<Container flex="column" gap="3xs">
{/* Token name skeleton */}
<Skeleton height="14px" width="60px" />
{/* Chain name skeleton */}
<Skeleton height="12px" width="40px" />
</Container>
</Container>
{/* Right side: Price and balance skeleton */}
<Container
flex="column"
gap="3xs"
style={{ alignItems: "flex-end", flex: 1 }}
>
{/* Price amount skeleton */}
<Skeleton height="16px" width="80px" />
{/* Balance skeleton */}
<Container flex="row" gap="3xs">
<Skeleton height="12px" width="50px" />
<Skeleton height="12px" width="40px" />
</Container>
{/* Right side: Price and balance skeleton */}
<Container
flex="column"
gap="3xs"
style={{ alignItems: "flex-end", flex: 1 }}
>
{/* Price amount skeleton */}
<Skeleton height="16px" width="80px" />
{/* Balance skeleton */}
<Container flex="row" gap="3xs">
<Skeleton height="12px" width="50px" />
<Skeleton height="12px" width="40px" />
</Container>
</Container>
</Container>
))}
</Container>
</>
</Container>
))}
</Container>
);
}
@@ -221,35 +222,30 @@ export function TokenSelection({
}
return (
<>
<Text color="primaryText" size="md">
Your token balances
</Text>
<Spacer y="sm" />
<Container
flex="column"
gap="sm"
style={{
maxHeight: "400px",
overflowY: "auto",
scrollbarWidth: "none",
}}
>
{paymentMethods
.filter((method) => method.type === "wallet")
.map((method) => (
<PaymentMethodTokenRow
client={client}
destinationAmount={destinationAmount}
destinationToken={destinationToken}
feePayer={feePayer}
key={`${method.originToken.address}-${method.originToken.chainId}`}
onPaymentMethodSelected={onPaymentMethodSelected}
paymentMethod={method}
currency={currency}
/>
))}
</Container>
</>
<Container
flex="column"
gap="xs"
pb="lg"
style={{
maxHeight: "400px",
overflowY: "auto",
scrollbarWidth: "none",
}}
>
{paymentMethods
.filter((method) => method.type === "wallet")
.map((method) => (
<PaymentMethodTokenRow
client={client}
destinationAmount={destinationAmount}
destinationToken={destinationToken}
feePayer={feePayer}
key={`${method.originToken.address}-${method.originToken.chainId}`}
onPaymentMethodSelected={onPaymentMethodSelected}
paymentMethod={method}
currency={currency}
/>
))}
</Container>
);
}
@@ -1,5 +1,5 @@
"use client";
import { ChevronRightIcon, PlusIcon } from "@radix-ui/react-icons";
import { PlusIcon } from "@radix-ui/react-icons";
import type { ThirdwebClient } from "../../../../../client/client.js";
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
@@ -12,7 +12,6 @@ import { CreditCardIcon } from "../../ConnectWallet/icons/CreditCardIcon.js";
import { WalletRow } from "../../ConnectWallet/screens/Buy/swap/WalletRow.js";
import { Container } from "../../components/basic.js";
import { Button } from "../../components/buttons.js";
import { Spacer } from "../../components/Spacer.js";
import { Text } from "../../components/text.js";
interface WalletFiatSelectionProps {
@@ -35,56 +34,39 @@ export function WalletFiatSelection({
const theme = useCustomTheme();
return (
<>
<Container flex="column" gap="xs">
{paymentMethods.includes("crypto") && (
<>
{paymentMethods.length > 1 && (
<>
<Text color="primaryText" size="sm" weight={500}>
Pay with Crypto
</Text>
<Spacer y="sm" />
</>
)}
{/* Connected Wallets */}
{connectedWallets.length > 0 && (
<>
<Container flex="column" gap="sm">
{connectedWallets.map((wallet) => {
const account = wallet.getAccount();
if (!account?.address) {
return null;
}
return (
<Button
fullWidth
key={wallet.id}
onClick={() => onWalletSelected(wallet)}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
justifyContent: "space-between",
padding: `${spacing.sm} ${spacing.md}`,
}}
variant="secondary"
>
<WalletRow
address={account?.address}
client={client}
iconSize="lg"
textSize="sm"
/>
<ChevronRightIcon
style={{ height: iconSize.md, width: iconSize.md }}
/>
</Button>
);
})}
</Container>
<Spacer y="sm" />
</>
<Container flex="column" gap="sm">
{connectedWallets.map((wallet) => {
const account = wallet.getAccount();
if (!account?.address) {
return null;
}
return (
<Button
fullWidth
key={`${wallet.id}-${account.address}`}
onClick={() => onWalletSelected(wallet)}
style={{
borderRadius: radius.md,
justifyContent: "space-between",
padding: `${spacing.md} ${spacing.md}`,
}}
variant="secondary"
>
<WalletRow
address={account?.address}
client={client}
iconSize="lg"
textSize="sm"
/>
</Button>
);
})}
</Container>
)}
{/* Connect Another Wallet */}
@@ -92,11 +74,9 @@ export function WalletFiatSelection({
fullWidth
onClick={onConnectWallet}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
height: "auto",
padding: `${spacing.sm} ${spacing.md}`,
padding: `${spacing.md} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
@@ -109,23 +89,22 @@ export function WalletFiatSelection({
<Container
style={{
alignItems: "center",
border: `1px dashed ${theme.colors.secondaryIconColor}`,
borderRadius: radius.sm,
border: `1px dashed ${theme.colors.secondaryText}`,
borderRadius: radius.full,
display: "flex",
height: iconSize.lg,
height: `${iconSize.lg}px`,
justifyContent: "center",
padding: spacing["4xs"],
width: iconSize.lg,
width: `${iconSize.lg}px`,
}}
>
<PlusIcon
color={theme.colors.secondaryText}
height={iconSize.md}
width={iconSize.md}
height={iconSize["sm+"]}
width={iconSize["sm+"]}
/>
</Container>
<Container flex="column" gap="3xs" style={{ flex: 1 }}>
<Text color="primaryText" size="sm" style={{ fontWeight: 600 }}>
<Text color="primaryText" size="sm">
Connect a Wallet
</Text>
<Text color="secondaryText" size="xs">
@@ -138,49 +117,37 @@ export function WalletFiatSelection({
)}
{paymentMethods.includes("card") && (
<>
<Spacer y="lg" />
<Text color="primaryText" size="sm" weight={500}>
Pay with Card
</Text>
<Spacer y="sm" />
<Button
fullWidth
onClick={onFiatSelected}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
height: "auto",
padding: `${spacing.sm} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
<Button
fullWidth
onClick={onFiatSelected}
style={{
borderRadius: radius.md,
height: "auto",
padding: `${spacing.md} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
>
<Container
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
>
<Container
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
>
<CreditCardIcon
color={theme.colors.secondaryIconColor}
size={iconSize.lg}
/>
<Container flex="column" gap="3xs" style={{ flex: 1 }}>
<Text color="primaryText" size="sm" style={{ fontWeight: 600 }}>
Pay with Card
</Text>
<Text color="secondaryText" size="xs">
Onramp and pay in one step
</Text>
</Container>
<CreditCardIcon
color={theme.colors.secondaryText}
size={iconSize.lg}
/>
<Container flex="column" gap="3xs" style={{ flex: 1 }}>
<Text color="primaryText" size="sm">
Pay with Card
</Text>
<Text color="secondaryText" size="xs">
Onramp and pay in one step
</Text>
</Container>
</Button>
</>
</Container>
</Button>
)}
</>
</Container>
);
}
@@ -45,11 +45,11 @@ type SelectTokenUIProps = {
activeWalletInfo: ActiveWalletInfo | undefined;
};
function getDefaultSelectedChain(
chains: BridgeChain[],
activeChainId: number | undefined,
) {
return chains.find((chain) => chain.chainId === (activeChainId || 1));
function findChain(chains: BridgeChain[], activeChainId: number | undefined) {
if (!activeChainId) {
return undefined;
}
return chains.find((chain) => chain.chainId === activeChainId);
}
/**
@@ -67,11 +67,9 @@ export function SelectToken(props: SelectTokenUIProps) {
const selectedChain =
_selectedChain ||
(chainQuery.data
? getDefaultSelectedChain(
chainQuery.data,
props.selectedToken?.chainId ||
props.activeWalletInfo?.activeChain.id,
)
? findChain(chainQuery.data, props.selectedToken?.chainId) ||
findChain(chainQuery.data, props.activeWalletInfo?.activeChain.id) ||
findChain(chainQuery.data, 1)
: undefined);
// all tokens
@@ -76,7 +76,7 @@ export function WalletEntryButton(props: {
<Container expand flex="column" gap="xxs">
{nameOverride ? (
<Text color="primaryText" weight={600}>
<Text color="primaryText" weight={500}>
{nameOverride}
</Text>
) : (
@@ -320,7 +320,7 @@ const WalletSelectorInner: React.FC<WalletSelectorProps> = (props) => {
bottomSection = (
<>
<Line />
<Container flex="column" gap="md" p="md">
<Container flex="column" gap="md" px="lg" py="md+">
{newToWallets}
{continueAsGuest}
</Container>
@@ -705,7 +705,7 @@ const ShowAllWalletsIcon = /* @__PURE__ */ StyledDiv(() => {
},
alignItems: "center",
backgroundColor: theme.colors.tertiaryBg,
border: `2px solid ${theme.colors.borderColor}`,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
display: "grid",
gap: spacing["4xs"],
@@ -52,7 +52,7 @@ export function ReceiveFunds(props: {
)
}
qrCodeUri={address}
size={310}
size={350}
/>
</Container>
<Spacer y="xl" />
@@ -62,7 +62,7 @@ export function ReceiveFunds(props: {
className="tw-copy-address-button"
>
<Text color="primaryText" size="md">
{shortenString(address || "")}
{shortenString(address || "", false)}
</Text>
<CopyIcon
hasCopied={hasCopied}
@@ -76,6 +76,7 @@ export function ReceiveFunds(props: {
<Text
balance
center
size="sm"
className="receive_fund_screen_instruction"
multiline
>
@@ -10,9 +10,10 @@ export const ModalTitle = /* @__PURE__ */ StyledH2((_) => {
return {
color: theme.colors.primaryText,
fontSize: fontSize.lg,
fontWeight: 600,
fontWeight: 500,
lineHeight: 1.3,
margin: 0,
letterSpacing: "-0.025em",
textAlign: "left",
};
});
@@ -74,7 +74,7 @@ export const ConnectingScreen: React.FC<{
center
color="primaryText"
size="lg"
weight={600}
weight={500}
className="tw-screen-title"
data-status={props.errorConnecting ? "failed" : "in-progress"}
>
@@ -0,0 +1,165 @@
import type { Meta } from "@storybook/react-vite";
import {
darkThemeObj,
lightThemeObj,
type Theme,
} from "../react/core/design-system/index.js";
import { StyledDiv } from "../react/web/ui/design-system/elements.js";
const meta: Meta = {
title: "theme",
};
export default meta;
export function Dark() {
return <Variant theme={darkThemeObj} />;
}
export function Light() {
return <Variant theme={lightThemeObj} />;
}
function Variant(props: { theme: Theme }) {
return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "10px",
maxWidth: "700px",
margin: "0 auto",
backgroundColor: props.theme.colors.modalBg,
padding: "14px",
lineHeight: "1.5",
borderRadius: "8px",
}}
>
<ColorPairTest theme={props.theme} text="primaryText" />
<ColorPairTest theme={props.theme} text="secondaryText" />
<ColorPairTest theme={props.theme} text="accentText" />
<ColorPairTest theme={props.theme} text="danger" />
<ColorPairTest theme={props.theme} text="success" />
<ColorPairTest theme={props.theme} bg="tooltipBg" text="tooltipText" />
<ColorPairTest
theme={props.theme}
bg="accentButtonBg"
text="accentButtonText"
/>
<ColorPairTest
theme={props.theme}
bg="primaryButtonBg"
text="primaryButtonText"
/>
<ColorPairTest
theme={props.theme}
bg="selectedTextBg"
text="selectedTextColor"
/>
<ColorPairTest theme={props.theme} bg="skeletonBg" text="primaryText" />
<ColorPairTest theme={props.theme} bg="scrollbarBg" text="primaryText" />
<ColorPairTest
theme={props.theme}
bg="inputAutofillBg"
text="primaryText"
/>
<ColorPairTest
theme={props.theme}
bg="tertiaryBg"
hoverBg="secondaryButtonHoverBg"
text="primaryText"
/>
<ColorPairTest
theme={props.theme}
bg="secondaryButtonBg"
hoverBg="secondaryButtonHoverBg"
text="secondaryButtonText"
/>
<ColorPairTest
theme={props.theme}
hoverBg="secondaryIconHoverBg"
text="secondaryIconColor"
hoverText="secondaryIconHoverColor"
/>
<ColorPairTest
theme={props.theme}
bg="connectedButtonBg"
text="primaryText"
hoverBg="connectedButtonBgHover"
/>
<div
style={{
border: `1px solid ${props.theme.colors.borderColor}`,
padding: "20px",
borderRadius: "8px",
color: props.theme.colors.primaryText,
}}
>
border
</div>
<div
style={{
border: `1px solid ${props.theme.colors.separatorLine}`,
padding: "20px",
borderRadius: "8px",
color: props.theme.colors.primaryText,
}}
>
separatorLine
</div>
</div>
);
}
function ColorPairTest(props: {
theme: Theme;
bg?: keyof Theme["colors"];
text: keyof Theme["colors"];
hoverBg?: keyof Theme["colors"];
hoverText?: keyof Theme["colors"];
}) {
return (
<HoverBg
style={{ display: "flex", flexDirection: "column", gap: "10px" }}
bg={props.bg ? props.theme.colors[props.bg] : undefined}
hoverBg={props.hoverBg ? props.theme.colors[props.hoverBg] : undefined}
text={props.theme.colors[props.text]}
>
{[props.bg, props.hoverBg, props.text].filter(Boolean).join(", ")}
</HoverBg>
);
}
const HoverBg = StyledDiv(
(props: {
bg?: string;
hoverBg?: string;
text: string;
hoverText?: string;
}) => {
return {
backgroundColor: props.bg ?? "transparent",
padding: "20px",
borderRadius: "8px",
fontSize: "16px",
fontWeight: 400,
color: props.text,
"&:hover": props.hoverBg
? {
backgroundColor: props.hoverBg,
}
: undefined,
};
},
);
+2 -1
View File
@@ -162,7 +162,8 @@ export async function decodePaymentRequest(
const selectedPaymentRequirements = paymentRequirements.find(
(value) =>
value.scheme === decodedPayment.scheme &&
value.network === decodedPayment.network,
networkToChainId(value.network) ===
networkToChainId(decodedPayment.network),
);
if (!selectedPaymentRequirements) {
return {
+2
View File
@@ -1,5 +1,7 @@
# @thirdweb-dev/wagmi-adapter
## 0.2.170
## 0.2.169
## 0.2.168
+1 -1
View File
@@ -56,5 +56,5 @@
"type": "module",
"types": "./dist/types/exports/thirdweb.d.ts",
"typings": "./dist/types/exports/thirdweb.d.ts",
"version": "0.2.169"
"version": "0.2.170"
}