Skip to content

Commit ed81006

Browse files
Feature: New UB Components (#7354)
Co-authored-by: Joaquim Verges <joaquim.verges@gmail.com>
1 parent 3f74760 commit ed81006

File tree

119 files changed

+13948
-965
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+13948
-965
lines changed

.changeset/calm-suits-stare.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Adds new components BuyWidget, CheckoutWidget, and TransactionWidget
6+
7+
## BuyWidget
8+
A component that allows users to purchase tokens or NFTs directly within your application.
9+
10+
### Example:
11+
```tsx
12+
import { BuyWidget } from "thirdweb/react";
13+
14+
function App() {
15+
return (
16+
<BuyWidget
17+
client={client}
18+
chain={chain}
19+
tokenAddress="0x..." // Token or NFT contract address
20+
recipient="0x..." // Optional: recipient address
21+
theme="light" // Optional: "light" or "dark"
22+
/>
23+
);
24+
}
25+
```
26+
27+
## CheckoutWidget
28+
A comprehensive checkout experience for purchasing digital assets with multiple payment options.
29+
30+
### Example:
31+
```tsx
32+
import { CheckoutWidget } from "thirdweb/react";
33+
34+
function App() {
35+
return (
36+
<CheckoutWidget
37+
client={client}
38+
chain={chain}
39+
items={[
40+
{
41+
tokenAddress: "0x...",
42+
tokenId: "1", // For NFTs
43+
quantity: "1"
44+
}
45+
]}
46+
onSuccess={(result) => console.log("Purchase successful:", result)}
47+
theme="dark" // Optional: "light" or "dark"
48+
/>
49+
);
50+
}
51+
```
52+
53+
## TransactionWidget
54+
A widget for executing arbitrary blockchain transactions with a user-friendly interface.
55+
56+
### Example:
57+
```tsx
58+
import { TransactionWidget } from "thirdweb/react";
59+
import { prepareContractCall } from "thirdweb";
60+
61+
function App() {
62+
const transaction = prepareContractCall({
63+
contract: myContract,
64+
method: "transfer",
65+
params: [recipientAddress, amount]
66+
});
67+
68+
return (
69+
<TransactionWidget
70+
client={client}
71+
transaction={transaction}
72+
onSuccess={(result) => console.log("Transaction successful:", result)}
73+
onError={(error) => console.error("Transaction failed:", error)}
74+
theme="light" // Optional: "light" or "dark"
75+
/>
76+
);
77+
}
78+
```

AGENTS.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Welcome, AI copilots! This guide captures the coding standards, architectural de
2020
- Biome governs formatting and linting; its rules live in biome.json.
2121
- Run pnpm biome check --apply before committing.
2222
- Avoid editor‑specific configs; rely on the shared settings.
23+
- make sure everything builds after each file change by running `pnpm build`
2324

2425
2526

@@ -39,7 +40,8 @@ Welcome, AI copilots! This guide captures the coding standards, architectural de
3940
- Co‑locate tests: foo.ts ↔ foo.test.ts.
4041
- Use real function invocations with stub data; avoid brittle mocks.
4142
- For network interactions, use Mock Service Worker (MSW) to intercept fetch/HTTP calls, mocking only scenarios that are hard to reproduce.
42-
- Keep tests deterministic and side‑effect free; Jest is pre‑configured.
43+
- Keep tests deterministic and side‑effect free; Vitest is pre‑configured.
44+
- to run the tests: `cd packages thirdweb & pnpm test:dev <filename>`
4345

4446
4547

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/PayModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export function PayModalButton(props: {
4242
theme={getSDKTheme(theme === "dark" ? "dark" : "light")}
4343
className="!w-auto"
4444
payOptions={{
45-
onPurchaseSuccess(info) {
45+
// biome-ignore lint/suspicious/noExplicitAny: false positive
46+
onPurchaseSuccess(info: any) {
4647
if (
4748
info.type === "crypto" &&
4849
info.status.status !== "NOT_FOUND"

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/connect/universal-bridge/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function UBFooter() {
123123
href: "https://playground.thirdweb.com/connect/pay/fund-wallet",
124124
},
125125
{
126-
label: "Commerce",
126+
label: "Checkout",
127127
href: "https://playground.thirdweb.com/connect/pay/commerce",
128128
},
129129
{

apps/dashboard/src/app/pay/components/client/PayPageEmbed.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export function PayPageEmbed({
6363
onPurchaseSuccess: (result) => {
6464
if (!redirectUri) return;
6565
const url = new URL(redirectUri);
66-
switch (result.type) {
66+
switch (result?.type) {
6767
case "crypto": {
6868
url.searchParams.set("status", result.status.status);
6969
if (

apps/dashboard/src/components/buttons/MismatchButton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ export const MismatchButton = forwardRef<
293293
payOptions={{
294294
onPurchaseSuccess(info) {
295295
if (
296-
info.type === "crypto" &&
296+
info?.type === "crypto" &&
297297
info.status.status !== "NOT_FOUND"
298298
) {
299299
trackEvent({
@@ -308,7 +308,7 @@ export const MismatchButton = forwardRef<
308308
}
309309

310310
if (
311-
info.type === "fiat" &&
311+
info?.type === "fiat" &&
312312
info.status.status !== "NOT_FOUND"
313313
) {
314314
trackEvent({

apps/playground-web/src/app/connect/pay/commerce/page.tsx

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { Metadata } from "next";
77

88
export const metadata: Metadata = {
99
metadataBase,
10-
title: "Integrate Fiat & Cross-Chain Crypto Payments | thirdweb Pay",
10+
title: "Integrate Fiat & Cross-Chain Crypto Payments | Universal Bridge",
1111
description:
1212
"The easiest way for users to transact in your app. Onramp users in clicks and generate revenue for each user transaction. Integrate for free.",
1313
};
@@ -34,7 +34,7 @@ function BuyMerch() {
3434
return (
3535
<CodeExample
3636
header={{
37-
title: "Commerce",
37+
title: "Checkout",
3838
description: (
3939
<>
4040
Take payments from Fiat or Crypto directly to your seller wallet.
@@ -46,28 +46,22 @@ function BuyMerch() {
4646
),
4747
}}
4848
preview={<BuyMerchPreview />}
49-
code={`import { PayEmbed, getDefaultToken } from "thirdweb/react";
49+
code={`import { CheckoutWidget, getDefaultToken } from "thirdweb/react";
5050
import { base } from "thirdweb/chains";
5151
5252
function App() {
5353
return (
54-
<PayEmbed
55-
client={client}
56-
theme={"light"}
57-
payOptions={{
58-
mode: "direct_payment",
59-
paymentInfo: {
60-
amount: "35",
61-
chain: base,
62-
token: getDefaultToken(base, "USDC"),
63-
sellerAddress: "0xEb0effdFB4dC5b3d5d3aC6ce29F3ED213E95d675",
64-
},
65-
metadata: {
66-
name: "Black Hoodie (Size L)",
67-
image: "/drip-hoodie.png",
68-
},
69-
}}
70-
/>
54+
<CheckoutWidget
55+
client={THIRDWEB_CLIENT}
56+
theme="light"
57+
chain={base}
58+
amount={toUnits("2", 6)}
59+
tokenAddress="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
60+
seller="0xEb0effdFB4dC5b3d5d3aC6ce29F3ED213E95d675"
61+
feePayer="seller"
62+
name="Black Hoodie"
63+
description="Size L | Ships worldwide."
64+
/>
7165
);
7266
};`}
7367
lang="tsx"

0 commit comments

Comments
 (0)