Skip to content

Commit ad4ec1a

Browse files
committed
Merge remote-tracking branch 'origin/main' into ph/sliding-rate-limit
2 parents 6309f8a + 185d2f3 commit ad4ec1a

File tree

334 files changed

+18169
-14206
lines changed

Some content is hidden

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

334 files changed

+18169
-14206
lines changed

.changeset/blue-geese-refuse.md

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

.changeset/quick-bugs-remain.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
"@thirdweb-dev/insight": major
3+
---
4+
5+
Initial release of dedicated insight TS sdk
6+
7+
This package is a thin openAPI wrapper for insight, our in-house indexer.
8+
9+
## Configuration
10+
11+
```ts
12+
import { configure } from "@thirdweb-dev/insight";
13+
14+
// call this once at the startup of your application
15+
configure({
16+
clientId: "<YOUR_CLIENT_ID>",
17+
});
18+
```
19+
20+
## Example Usage
21+
22+
```ts
23+
import { getV1Events } from "@thirdweb-dev/insight";
24+
25+
const events = await getV1Events({
26+
query: {
27+
chain: [1, 137],
28+
filter_address: "0x1234567890123456789012345678901234567890",
29+
},
30+
});
31+
```

.changeset/wicked-pianos-carry.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Expose getOwnedTokens, getOwnedNFTs and getTransaction functions
6+
7+
You can now use Insight, our in-house indexer directly from the SDK with a simple API:
8+
9+
## Get Owned ERC20 tokens
10+
11+
```ts
12+
import { Insight } from "thirdweb";
13+
14+
const tokens = await Insight.getOwnedTokens({
15+
client,
16+
ownerAddress,
17+
chains: [base, polygon, arbitrum],
18+
});
19+
```
20+
21+
## Get Owned NFTs (ERC721 and ERC1155)
22+
23+
```ts
24+
import { Insight } from "thirdweb";
25+
26+
const nfts = await Insight.getOwnedNFTs({
27+
client,
28+
ownerAddress,
29+
chains: [sepolia],
30+
});
31+
```
32+
33+
## Get Transactions for a given wallet address
34+
35+
```ts
36+
import { Insight } from "thirdweb";
37+
38+
const transactions = await Insight.getTransactions({
39+
client,
40+
walletAddress,
41+
chains: [sepolia],
42+
});
43+
```
44+
45+
All functions come with extra query filters for more granular queries, refer to the documentation for more details.

.github/workflows/CI.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ jobs:
102102
runs-on: ubuntu-latest-8
103103
strategy:
104104
matrix:
105-
package_manager: [npm, yarn, pnpm, bun]
105+
package_manager: [pnpm] # TODO, reenable [npm, yarn, pnpm, bun]
106106
bundler: [vite, webpack, esbuild]
107107
steps:
108108
- name: Check out the code
@@ -123,7 +123,14 @@ jobs:
123123
mkdir test-project
124124
cd test-project
125125
npm init -y
126-
${{ matrix.package_manager }} add react react-dom ../packages/thirdweb
126+
127+
# Handle different package managers
128+
if [ "${{ matrix.package_manager }}" = "pnpm" ]; then
129+
# Create pnpm workspace
130+
echo '{"name": "test-project", "private": true, "workspaces": ["."]}' > package.json
131+
echo '{"packages": ["../packages/*"]}' > pnpm-workspace.yaml
132+
pnpm add react react-dom ../packages/thirdweb -w
133+
fi
127134
- name: Create test file
128135
run: |
129136
cd test-project
@@ -133,23 +140,23 @@ jobs:
133140
if: matrix.bundler == 'vite'
134141
run: |
135142
cd test-project
136-
${{matrix.package_manager}} add vite
143+
${{matrix.package_manager}} add vite -w
137144
echo 'import { defineConfig } from "vite"; import {resolve} from "path"; export default defineConfig({ build: { lib: { entry: resolve(__dirname, "index.js"), name: "e2e_test" }, outDir: "dist" }});' > vite.config.js
138145
npx vite build
139146
140147
- name: Bundle with webpack
141148
if: matrix.bundler == 'webpack'
142149
run: |
143150
cd test-project
144-
${{matrix.package_manager}} add webpack webpack-cli
151+
${{matrix.package_manager}} add webpack webpack-cli -w
145152
echo 'const path = require("path"); module.exports = { mode: "production", entry: "./index.js", output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js" }};' > webpack.config.js
146153
npx webpack
147154
148155
- name: Bundle with esbuild
149156
if: matrix.bundler == 'esbuild'
150157
run: |
151158
cd test-project
152-
${{matrix.package_manager}} add esbuild
159+
${{matrix.package_manager}} add esbuild -w
153160
npx esbuild index.js --bundle --outdir=dist
154161
155162
- name: Verify bundle
@@ -177,6 +184,9 @@ jobs:
177184
- name: Setup & Install
178185
uses: ./.github/composite-actions/install
179186

187+
- name: Build Packages
188+
run: pnpm build
189+
180190
- name: Report bundle size
181191
uses: andresz1/size-limit-action@94bc357df29c36c8f8d50ea497c3e225c3c95d1d # v1.8.0
182192
with:

.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
public-hoist-pattern[]=*import-in-the-middle*
2+
public-hoist-pattern[]=*require-in-the-middle*

apps/dashboard/next.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ function getConfig(): NextConfig {
203203
type: "memory",
204204
});
205205
}
206-
config.externals.push("pino-pretty");
207206
config.module = {
208207
...config.module,
209208
exprContextCritical: false,

apps/dashboard/package.json

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,29 +29,29 @@
2929
"@emotion/styled": "11.14.0",
3030
"@hookform/resolvers": "^3.9.1",
3131
"@marsidev/react-turnstile": "^1.1.0",
32-
"@radix-ui/react-accordion": "^1.2.3",
33-
"@radix-ui/react-alert-dialog": "^1.1.6",
34-
"@radix-ui/react-avatar": "^1.1.3",
35-
"@radix-ui/react-checkbox": "^1.1.4",
36-
"@radix-ui/react-dialog": "1.1.6",
37-
"@radix-ui/react-dropdown-menu": "^2.1.6",
38-
"@radix-ui/react-hover-card": "^1.1.6",
39-
"@radix-ui/react-label": "^2.1.2",
40-
"@radix-ui/react-popover": "^1.1.6",
41-
"@radix-ui/react-progress": "^1.1.2",
42-
"@radix-ui/react-radio-group": "^1.2.3",
43-
"@radix-ui/react-select": "^2.1.6",
44-
"@radix-ui/react-separator": "^1.1.2",
45-
"@radix-ui/react-slot": "^1.1.2",
46-
"@radix-ui/react-switch": "^1.1.3",
47-
"@radix-ui/react-tooltip": "1.1.8",
48-
"@sentry/nextjs": "9.5.0",
49-
"@shazow/whatsabi": "0.20.0",
50-
"@tanstack/react-query": "5.67.3",
32+
"@radix-ui/react-accordion": "^1.2.4",
33+
"@radix-ui/react-alert-dialog": "^1.1.7",
34+
"@radix-ui/react-avatar": "^1.1.4",
35+
"@radix-ui/react-checkbox": "^1.1.5",
36+
"@radix-ui/react-dialog": "1.1.7",
37+
"@radix-ui/react-dropdown-menu": "^2.1.7",
38+
"@radix-ui/react-hover-card": "^1.1.7",
39+
"@radix-ui/react-label": "^2.1.3",
40+
"@radix-ui/react-popover": "^1.1.7",
41+
"@radix-ui/react-progress": "^1.1.3",
42+
"@radix-ui/react-radio-group": "^1.2.4",
43+
"@radix-ui/react-select": "^2.1.7",
44+
"@radix-ui/react-separator": "^1.1.3",
45+
"@radix-ui/react-slot": "^1.2.0",
46+
"@radix-ui/react-switch": "^1.1.4",
47+
"@radix-ui/react-tooltip": "1.2.0",
48+
"@sentry/nextjs": "9.12.0",
49+
"@shazow/whatsabi": "0.21.0",
50+
"@tanstack/react-query": "5.72.1",
5151
"@tanstack/react-table": "^8.21.2",
5252
"@thirdweb-dev/service-utils": "workspace:*",
5353
"@vercel/functions": "2.0.0",
54-
"@vercel/og": "^0.6.5",
54+
"@vercel/og": "^0.6.8",
5555
"abitype": "1.0.8",
5656
"chakra-react-select": "^4.7.6",
5757
"class-variance-authority": "^0.7.1",
@@ -68,7 +68,7 @@
6868
"input-otp": "^1.4.1",
6969
"ioredis": "^5.6.0",
7070
"ipaddr.js": "^2.2.0",
71-
"lucide-react": "0.483.0",
71+
"lucide-react": "0.487.0",
7272
"next": "15.2.4",
7373
"next-plausible": "^3.12.4",
7474
"next-themes": "^0.4.6",
@@ -78,25 +78,26 @@
7878
"papaparse": "^5.5.2",
7979
"pluralize": "^8.0.0",
8080
"posthog-js": "1.67.1",
81+
"prettier": "3.5.3",
8182
"qrcode": "^1.5.3",
82-
"react": "19.0.0",
83+
"react": "19.1.0",
8384
"react-children-utilities": "^2.10.0",
8485
"react-day-picker": "^8.10.1",
85-
"react-dom": "19.0.0",
86+
"react-dom": "19.1.0",
8687
"react-dropzone": "^14.3.8",
8788
"react-error-boundary": "^5.0.0",
88-
"react-hook-form": "7.54.2",
89+
"react-hook-form": "7.55.0",
8990
"react-markdown": "^9.0.1",
9091
"react-table": "^7.8.0",
91-
"recharts": "2.15.1",
92+
"recharts": "2.15.2",
9293
"remark-gfm": "4.0.1",
9394
"responsive-rsc": "0.0.7",
9495
"server-only": "^0.0.1",
9596
"shiki": "1.27.0",
96-
"sonner": "2.0.1",
97+
"sonner": "2.0.3",
9798
"spdx-correct": "^3.2.0",
9899
"stripe": "17.7.0",
99-
"swagger-ui-react": "^5.20.1",
100+
"swagger-ui-react": "^5.20.7",
100101
"tailwind-merge": "^2.6.0",
101102
"tailwindcss-animate": "^1.0.7",
102103
"thirdweb": "workspace:*",
@@ -110,38 +111,38 @@
110111
"@next/bundle-analyzer": "15.2.4",
111112
"@next/eslint-plugin-next": "15.2.4",
112113
"@playwright/test": "1.51.1",
113-
"@storybook/addon-essentials": "8.6.4",
114-
"@storybook/addon-interactions": "8.6.4",
115-
"@storybook/addon-links": "8.6.4",
116-
"@storybook/addon-onboarding": "8.6.4",
117-
"@storybook/addon-viewport": "8.6.4",
118-
"@storybook/blocks": "8.6.4",
119-
"@storybook/nextjs": "8.6.4",
120-
"@storybook/react": "8.6.4",
121-
"@storybook/test": "8.6.4",
114+
"@storybook/addon-essentials": "8.6.12",
115+
"@storybook/addon-interactions": "8.6.12",
116+
"@storybook/addon-links": "8.6.12",
117+
"@storybook/addon-onboarding": "8.6.12",
118+
"@storybook/addon-viewport": "8.6.12",
119+
"@storybook/blocks": "8.6.12",
120+
"@storybook/nextjs": "8.6.12",
121+
"@storybook/react": "8.6.12",
122+
"@storybook/test": "8.6.12",
122123
"@types/color": "4.2.0",
123-
"@types/node": "22.13.10",
124+
"@types/node": "22.14.0",
124125
"@types/papaparse": "^5.3.15",
125126
"@types/pluralize": "^0.0.33",
126127
"@types/qrcode": "^1.5.5",
127-
"@types/react": "19.0.10",
128-
"@types/react-dom": "19.0.4",
128+
"@types/react": "19.1.0",
129+
"@types/react-dom": "19.1.1",
129130
"@types/react-table": "^7.7.20",
130131
"@types/spdx-correct": "^3.1.3",
131132
"@types/swagger-ui-react": "^4.19.0",
132133
"@typescript-eslint/eslint-plugin": "7.14.1",
133134
"@typescript-eslint/parser": "7.14.1",
134135
"autoprefixer": "^10.4.21",
135-
"checkly": "5.0.1",
136+
"checkly": "5.2.0",
136137
"eslint": "8.57.0",
137138
"eslint-config-biome": "1.9.4",
138-
"eslint-plugin-react-compiler": "19.0.0-beta-40c6c23-20250301",
139+
"eslint-plugin-react-compiler": "19.0.0-beta-e993439-20250405",
139140
"eslint-plugin-storybook": "0.12.0",
140-
"knip": "5.46.0",
141+
"knip": "5.47.0",
141142
"next-sitemap": "^4.2.3",
142143
"postcss": "8.5.3",
143-
"storybook": "8.6.4",
144+
"storybook": "8.6.12",
144145
"tailwindcss": "3.4.17",
145-
"typescript": "5.8.2"
146+
"typescript": "5.8.3"
146147
}
147148
}

apps/dashboard/src/@/actions/stripe-actions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function getStripe() {
2323

2424
export async function getTeamInvoices(
2525
team: Team,
26-
options?: { cursor?: string },
26+
options?: { cursor?: string; status?: "open" },
2727
) {
2828
try {
2929
const customerId = team.stripeCustomerId;
@@ -37,6 +37,8 @@ export async function getTeamInvoices(
3737
customer: customerId,
3838
limit: 10,
3939
starting_after: options?.cursor,
40+
// Only return open invoices if the status is open
41+
status: options?.status,
4042
});
4143

4244
return invoices;

apps/dashboard/src/@/api/analytics.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ export async function getEcosystemWalletUsage(args: {
346346
searchParams.append("period", period);
347347
}
348348
const res = await fetchAnalytics(
349-
`v2/wallets/connects/${ecosystemSlug}?${searchParams.toString()}`,
349+
`v2/wallet/connects?${searchParams.toString()}`,
350350
{
351351
method: "GET",
352352
headers: {
@@ -356,7 +356,10 @@ export async function getEcosystemWalletUsage(args: {
356356
);
357357

358358
if (res?.status !== 200) {
359-
console.error("Failed to fetch ecosystem wallet stats");
359+
const reason = await res?.text();
360+
console.error(
361+
`Failed to fetch ecosystem wallet stats: ${res?.status} - ${res.statusText} - ${reason}`,
362+
);
360363
return null;
361364
}
362365

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import "server-only";
2+
import { unstable_cache } from "next/cache";
3+
4+
export type RPCUsageDataItem = {
5+
date: string;
6+
usageType: "included" | "overage" | "rate-limit";
7+
count: string;
8+
};
9+
10+
export const fetchRPCUsage = unstable_cache(
11+
async (params: {
12+
teamId: string;
13+
projectId?: string;
14+
authToken: string;
15+
from: string;
16+
to: string;
17+
period: "day" | "week" | "month" | "year" | "all";
18+
}) => {
19+
const analyticsEndpoint = process.env.ANALYTICS_SERVICE_URL as string;
20+
const url = new URL(`${analyticsEndpoint}/v2/rpc/usage-types`);
21+
url.searchParams.set("teamId", params.teamId);
22+
if (params.projectId) {
23+
url.searchParams.set("projectId", params.projectId);
24+
}
25+
url.searchParams.set("from", params.from);
26+
url.searchParams.set("to", params.to);
27+
url.searchParams.set("period", params.period);
28+
29+
const res = await fetch(url, {
30+
headers: {
31+
Authorization: `Bearer ${params.authToken}`,
32+
},
33+
});
34+
35+
if (!res.ok) {
36+
const error = await res.text();
37+
return {
38+
ok: false as const,
39+
error: error,
40+
};
41+
}
42+
43+
const resData = await res.json();
44+
45+
return {
46+
ok: true as const,
47+
data: resData.data as RPCUsageDataItem[],
48+
};
49+
},
50+
["nebula-analytics"],
51+
{
52+
revalidate: 60 * 60, // 1 hour
53+
},
54+
);

0 commit comments

Comments
 (0)