Skip to content

Commit 5e42136

Browse files
authored
Merge branch 'main' into gi/portal-knowledge-base
2 parents 9ad67aa + 6cf92c6 commit 5e42136

File tree

262 files changed

+3984
-3063
lines changed

Some content is hidden

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

262 files changed

+3984
-3063
lines changed

.changeset/open-readers-do.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Faster useSendTransaction execution

.changeset/shiny-olives-pay.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/six-dryers-sing.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/stale-yaks-bathe.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Adds Bridge.Transfer module for direct token transfers:
6+
7+
```typescript
8+
import { Bridge, NATIVE_TOKEN_ADDRESS } from "thirdweb";
9+
10+
const quote = await Bridge.Transfer.prepare({
11+
chainId: 1,
12+
tokenAddress: NATIVE_TOKEN_ADDRESS,
13+
amount: toWei("0.01"),
14+
sender: "0x...",
15+
receiver: "0x...",
16+
client: thirdwebClient,
17+
});
18+
```
19+
20+
This will return a quote that might look like:
21+
```typescript
22+
{
23+
originAmount: 10000026098875381n,
24+
destinationAmount: 10000000000000000n,
25+
blockNumber: 22026509n,
26+
timestamp: 1741730936680,
27+
estimatedExecutionTimeMs: 1000
28+
steps: [
29+
{
30+
originToken: {
31+
chainId: 1,
32+
address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
33+
symbol: "ETH",
34+
name: "Ethereum",
35+
decimals: 18,
36+
priceUsd: 2000,
37+
iconUri: "https://..."
38+
},
39+
destinationToken: {
40+
chainId: 1,
41+
address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
42+
symbol: "ETH",
43+
name: "Ethereum",
44+
decimals: 18,
45+
priceUsd: 2000,
46+
iconUri: "https://..."
47+
},
48+
originAmount: 10000026098875381n,
49+
destinationAmount: 10000000000000000n,
50+
estimatedExecutionTimeMs: 1000
51+
transactions: [
52+
{
53+
action: "approval",
54+
id: "0x",
55+
to: "0x...",
56+
data: "0x...",
57+
chainId: 1,
58+
type: "eip1559"
59+
},
60+
{
61+
action: "transfer",
62+
to: "0x...",
63+
value: 10000026098875381n,
64+
data: "0x...",
65+
chainId: 1,
66+
type: "eip1559"
67+
}
68+
]
69+
}
70+
],
71+
expiration: 1741730936680,
72+
intent: {
73+
chainId: 1,
74+
tokenAddress: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
75+
amount: 10000000000000000n,
76+
sender: "0x...",
77+
receiver: "0x..."
78+
}
79+
}
80+
```
81+
82+
## Sending the transactions
83+
The `transactions` array is a series of [ox](https://oxlib.sh) EIP-1559 transactions that must be executed one after the other in order to fulfill the complete route. There are a few things to keep in mind when executing these transactions:
84+
- Approvals will have the `approval` action specified. You can perform approvals with `sendAndConfirmTransaction`, then proceed to the next transaction.
85+
- All transactions are assumed to be executed by the `sender` address, regardless of which chain they are on. The final transaction will use the `receiver` as the recipient address.
86+
- If an `expiration` timestamp is provided, all transactions must be executed before that time to guarantee successful execution at the specified price.
87+
88+
NOTE: To get the status of each non-approval transaction, use `Bridge.status` rather than checking for transaction inclusion. This function will ensure full completion of the transfer.
89+
90+
You can include arbitrary data to be included on any webhooks and status responses with the `purchaseData` option:
91+
92+
```ts
93+
const quote = await Bridge.Transfer.prepare({
94+
chainId: 1,
95+
tokenAddress: NATIVE_TOKEN_ADDRESS,
96+
amount: toWei("0.01"),
97+
sender: "0x...",
98+
receiver: "0x...",
99+
purchaseData: {
100+
reference: "payment-123",
101+
metadata: {
102+
note: "Transfer to Alice"
103+
}
104+
},
105+
client: thirdwebClient,
106+
});
107+
```
108+
109+
## Fees
110+
There may be fees associated with the transfer. These fees are paid by the `feePayer` address, which defaults to the `sender` address. You can specify a different address with the `feePayer` option. If you do not specify an option or explicitly specify `sender`, the fees will be added to the input amount. If you specify the `receiver` as the fee payer the fees will be subtracted from the destination amount.
111+
112+
For example, if you were to request a transfer with `feePayer` set to `receiver`:
113+
```typescript
114+
const quote = await Bridge.Transfer.prepare({
115+
chainId: 1,
116+
tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
117+
amount: 100_000_000n, // 100 USDC
118+
sender: "0x...",
119+
receiver: "0x...",
120+
feePayer: "receiver",
121+
client: thirdwebClient,
122+
});
123+
```
124+
125+
The returned quote might look like:
126+
```typescript
127+
{
128+
originAmount: 100_000_000n, // 100 USDC
129+
destinationAmount: 99_970_000n, // 99.97 USDC
130+
...
131+
}
132+
```
133+
134+
If you were to request a transfer with `feePayer` set to `sender`:
135+
```typescript
136+
const quote = await Bridge.Transfer.prepare({
137+
chainId: 1,
138+
tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
139+
amount: 100_000_000n, // 100 USDC
140+
sender: "0x...",
141+
receiver: "0x...",
142+
feePayer: "sender",
143+
client: thirdwebClient,
144+
});
145+
```
146+
147+
The returned quote might look like:
148+
```typescript
149+
{
150+
originAmount: 100_030_000n, // 100.03 USDC
151+
destinationAmount: 100_000_000n, // 100 USDC
152+
...
153+
}
154+
```

.changeset/tidy-seas-sing.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Added Bridge.Onramp.prepare and Bridge.Onramp.status functions
6+
7+
## Bridge.Onramp.prepare
8+
9+
Prepares an onramp transaction, returning a link from the specified provider to onramp to the specified token.
10+
11+
```typescript
12+
import { Bridge } from "thirdweb";
13+
import { ethereum } from "thirdweb/chains";
14+
import { NATIVE_TOKEN_ADDRESS, toWei } from "thirdweb/utils";
15+
16+
const preparedOnramp = await Bridge.Onramp.prepare({
17+
client: thirdwebClient,
18+
onramp: "stripe",
19+
chainId: ethereum.id,
20+
tokenAddress: NATIVE_TOKEN_ADDRESS,
21+
receiver: "0x...", // receiver's address
22+
amount: toWei("10"), // 10 of the destination token
23+
// Optional params:
24+
// sender: "0x...", // sender's address
25+
// onrampTokenAddress: NATIVE_TOKEN_ADDRESS, // token to initially onramp to
26+
// onrampChainId: 1, // chain to initially onramp to
27+
// currency: "USD",
28+
// maxSteps: 2,
29+
// purchaseData: { customId: "123" }
30+
});
31+
32+
console.log(preparedOnramp.link); // URL to redirect the user to
33+
console.log(preparedOnramp.currencyAmount); // Price in fiat currency
34+
```
35+
36+
## Bridge.Onramp.status
37+
38+
Retrieves the status of an Onramp session created via Bridge.Onramp.prepare.
39+
40+
```typescript
41+
import { Bridge } from "thirdweb";
42+
43+
const onrampStatus = await Bridge.Onramp.status({
44+
id: "022218cc-96af-4291-b90c-dadcb47571ec",
45+
client: thirdwebClient,
46+
});
47+
48+
// Possible results:
49+
// {
50+
// status: "CREATED",
51+
// transactions: [],
52+
// purchaseData: {
53+
// orderId: "abc-123",
54+
// },
55+
// }
56+
//
57+
// or
58+
// {
59+
// status: "PENDING",
60+
// transactions: [],
61+
// purchaseData: {
62+
// orderId: "abc-123",
63+
// },
64+
// }
65+
//
66+
// or
67+
// {
68+
// status: "COMPLETED",
69+
// transactions: [
70+
// {
71+
// chainId: 1,
72+
// transactionHash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
73+
// },
74+
// ],
75+
// purchaseData: {
76+
// orderId: "abc-123",
77+
// },
78+
// }
79+
```

.github/contributing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ We use [Turborepo](https://turbo.build/repo/docs) to manage the repository, and
1414

1515
We use [pnpm](https://pnpm.io) for package management across the repo. `pnpm` is similar to `npm` or `yarn` but with more efficient disk space usage.
1616

17-
**With the v5 SDK, we've consolidated everything into a single project at [/packages/thirdweb](./packages/thirdweb). You can still find the legacy packages at [/legacy_packages](./legacy_packages).**
17+
**With the v5 SDK, we've consolidated everything into a single project at [/packages/thirdweb](../packages/thirdweb). You can still find the legacy packages at [/legacy_packages](../legacy_packages).**
1818

1919
This single package provides a performant & lightweight SDK to interact with any EVM chain across Node, React, and React Native. Learn more about how to use the thirdweb SDK in our [documentation](https://portal.thirdweb.com/typescript/v5).
2020

AGENTS.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
🤖 Codex Agent Guidelines for thirdweb-dev/js
2+
3+
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.
4+
5+
6+
7+
1. GitHub Workflow & Etiquette
8+
9+
- Pull‑request titles must start with the affected workspace in brackets (e.g. [SDK], [Dashboard], [Portal], [Playground]).
10+
- Begin the PR description with a one‑sentence summary, then add a checklist of changes and reference issues with Fixes #123.
11+
- Keep commits small and topical – one logical change per commit.
12+
- Branch names should follow area/brief-topic (e.g. sdk/fix-gas-estimate). Avoid personal names.
13+
- Request at least one core maintainer review. Do not self‑merge unless you are the sole owner of that package.
14+
- All CI checks (type‑check, Biome, tests) must pass before merging.
15+
16+
17+
18+
2. Formatting & Linting
19+
20+
- Biome governs formatting and linting; its rules live in biome.json.
21+
- Run pnpm biome check --apply before committing.
22+
- Avoid editor‑specific configs; rely on the shared settings.
23+
24+
25+
26+
3. TypeScript Style Guide
27+
28+
- Write idiomatic TypeScript: explicit function declarations and return types.
29+
- Limit each file to one stateless, single‑responsibility function for clarity and testability.
30+
- Re‑use shared types from @/types or local types.ts barrels.
31+
- Prefer type aliases over interface except for nominal shapes.
32+
- Avoid any and unknown unless unavoidable; narrow generics whenever possible.
33+
- Choose composition over inheritance; leverage utility types (Partial, Pick, etc.).
34+
35+
36+
37+
4. Testing Strategy
38+
39+
- Co‑locate tests: foo.ts ↔ foo.test.ts.
40+
- Use real function invocations with stub data; avoid brittle mocks.
41+
- 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+
44+
45+
46+
5. packages/thirdweb
47+
48+
5.1 Public API Surface
49+
50+
- Export everything via the exports/ directory, grouped by feature.
51+
- Every public symbol must have comprehensive TSDoc:
52+
- Include at least one @example block that compiles.
53+
- Tag with one custom annotation (@beta, @internal, @experimental, etc.).
54+
- Comment only ambiguous logic; avoid restating TypeScript in prose.
55+
56+
5.2 Performance
57+
58+
- Lazy‑load heavy dependencies inside async paths to keep the initial bundle lean:
59+
60+
`const { jsPDF } = await import("jspdf");`
61+
62+
63+
64+
6. apps/dashboard & apps/playground
65+
66+
6.1 Core UI Toolkit
67+
68+
- Import primitives from @/components/ui/\_ (e.g. Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator).
69+
- Use NavLink for internal navigation so active states are handled automatically.
70+
- Group feature‑specific components under feature/components/\_ and expose a barrel index.ts when necessary.
71+
72+
6.2 Styling Conventions
73+
74+
- Tailwind CSS is the styling system – no inline styles or CSS modules.
75+
- Merge class names with cn() from @/lib/utils to keep conditional logic readable.
76+
- Stick to design tokens: backgrounds (bg-card), borders (border-border), muted text (text-muted-foreground), etc.
77+
- Expose a className prop on the root element of every component for overrides.
78+
79+
6.3 Component Patterns
80+
81+
- Server Components (run on the Node edge):
82+
-- Read cookies/headers with next/headers.
83+
-- Access server‑only environment variables or secrets.
84+
-- Perform heavy data fetching that should not ship to the client.
85+
-- Implement redirect logic with redirect() from next/navigation.
86+
-- Start files with import "server-only"; to prevent client bundling.
87+
- Client Components (run in the browser):
88+
-- Begin files with 'use client'; before imports.
89+
-- Handle interactive UI relying on React hooks (useState, useEffect, React Query, wallet hooks).
90+
-- Access browser APIs (localStorage, window, IntersectionObserver, etc.).
91+
-- Support fast transitions where data is prefetched on the client.
92+
93+
6.4 Data Fetching Guidelines
94+
95+
- Server Side
96+
-- Always call getAuthToken() to retrieve the JWT from cookies.
97+
-- Inject the token as an Authorization: Bearer header – never embed it in the URL.
98+
-- Return typed results (Project[], User[], …) – avoid any.
99+
- Client Side
100+
-- Wrap calls in React Query (@tanstack/react-query).
101+
-- Use descriptive, stable queryKeys for cache hits.
102+
-- Configure staleTime / cacheTime based on freshness requirements (default ≥ 60 s).
103+
-- Keep tokens secret by calling internal API routes or server actions.
104+
105+
106+
107+
7. Performance & Bundle Size
108+
109+
- Track bundle budgets via package.json#size-limit.
110+
- Lazy‑import optional features; avoid top‑level side‑effects.
111+
- De‑duplicate dependencies across packages through pnpm workspace hoisting.
112+
113+
114+
115+
8. Documentation & Developer Experience
116+
117+
- Each change in packages/\* should contain a changeset for the appropriate package, with the appropriate version bump
118+
119+
- patch for changes that don't impact the public API
120+
- minor for any new/modified public API
121+
122+
- Surface breaking changes prominently in PR descriptions.
123+
- For new UI components, add Storybook stories (\*.stories.tsx) alongside the code.

0 commit comments

Comments
 (0)