Skip to content

Commit a3bfdbb

Browse files
committed
Merge remote-tracking branch 'origin/main' into ph/testWebhook
2 parents b020439 + 46ef3e6 commit a3bfdbb

File tree

122 files changed

+2579
-797
lines changed

Some content is hidden

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

122 files changed

+2579
-797
lines changed

.changeset/clever-carrots-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Add headless components: ChainProvider, ChainIcon & ChainName

.github/workflows/issue.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Linked Issue
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited]
6+
7+
env:
8+
VALID_ISSUE_PREFIXES: "CNCT|DASH"
9+
10+
jobs:
11+
linear:
12+
name: Linear
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Check for linked issue
16+
uses: actions/github-script@v7
17+
with:
18+
script: |
19+
const pr = await github.rest.pulls.get({
20+
owner: context.repo.owner,
21+
repo: context.repo.repo,
22+
pull_number: context.issue.number
23+
});
24+
25+
const body = pr.data.body || '';
26+
const issueRegex = new RegExp(`(${process.env.VALID_ISSUE_PREFIXES})-\\d+`, 'i');
27+
28+
if (!issueRegex.test(body)) {
29+
core.setFailed(
30+
`No valid issue reference found. PR body must contain an issue ID with one of these prefixes: ${process.env.VALID_ISSUE_PREFIXES}`
31+
);
32+
return;
33+
}
34+
35+
const matches = body.match(issueRegex);
36+
console.log(`Found issue reference: ${matches[0]}`);

.github/workflows/linear.yml

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

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

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,12 @@
11
import { fetchAnalytics } from "data/analytics/fetch-analytics";
2-
3-
export interface WalletStats {
4-
date: string;
5-
uniqueWalletsConnected: number;
6-
totalConnections: number;
7-
walletType: string;
8-
}
9-
10-
export interface WalletUserStats {
11-
date: string;
12-
newUsers: number;
13-
returningUsers: number;
14-
totalUsers: number;
15-
}
16-
17-
export interface InAppWalletStats {
18-
date: string;
19-
authenticationMethod: string;
20-
uniqueWalletsConnected: number;
21-
}
22-
23-
export interface EcosystemWalletStats extends InAppWalletStats {}
24-
25-
export interface UserOpStats {
26-
date: string;
27-
successful: number;
28-
failed: number;
29-
sponsoredUsd: number;
30-
chainId?: string;
31-
}
32-
33-
interface AnalyticsQueryParams {
34-
clientId?: string;
35-
accountId?: string;
36-
from?: Date;
37-
to?: Date;
38-
period?: "day" | "week" | "month" | "year" | "all";
39-
}
2+
import type {
3+
AnalyticsQueryParams,
4+
InAppWalletStats,
5+
RpcMethodStats,
6+
UserOpStats,
7+
WalletStats,
8+
WalletUserStats,
9+
} from "types/analytics";
4010

4111
function buildSearchParams(params: AnalyticsQueryParams): URLSearchParams {
4212
const searchParams = new URLSearchParams();
@@ -115,6 +85,27 @@ export async function getUserOpUsage(
11585
return json.data as UserOpStats[];
11686
}
11787

88+
export async function getRpcMethodUsage(
89+
params: AnalyticsQueryParams,
90+
): Promise<RpcMethodStats[]> {
91+
const searchParams = buildSearchParams(params);
92+
const res = await fetchAnalytics(
93+
`v1/rpc/evm-methods?${searchParams.toString()}`,
94+
{
95+
method: "GET",
96+
headers: { "Content-Type": "application/json" },
97+
},
98+
);
99+
100+
if (res?.status !== 200) {
101+
console.error("Failed to fetch RPC method usage");
102+
return [];
103+
}
104+
105+
const json = await res.json();
106+
return json.data as RpcMethodStats[];
107+
}
108+
118109
export async function getWalletUsers(
119110
params: AnalyticsQueryParams,
120111
): Promise<WalletUserStats[]> {
@@ -135,3 +126,21 @@ export async function getWalletUsers(
135126
const json = await res.json();
136127
return json.data as WalletUserStats[];
137128
}
129+
130+
export async function isProjectActive(
131+
params: AnalyticsQueryParams,
132+
): Promise<boolean> {
133+
const searchParams = buildSearchParams(params);
134+
const res = await fetchAnalytics(`v1/active?${searchParams.toString()}`, {
135+
method: "GET",
136+
headers: { "Content-Type": "application/json" },
137+
});
138+
139+
if (res?.status !== 200) {
140+
console.error("Failed to fetch project active status");
141+
return false;
142+
}
143+
144+
const json = await res.json();
145+
return json.data.isActive as boolean;
146+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { cn } from "@/lib/utils";
2+
3+
export function TextDivider(props: {
4+
text: string;
5+
className?: string;
6+
}) {
7+
return (
8+
<div
9+
className={cn(
10+
"flex items-center text-muted-foreground text-sm",
11+
props.className,
12+
)}
13+
>
14+
<span className="h-[1px] flex-1 bg-border" />
15+
<span className="mx-4">{props.text}</span>
16+
<span className="h-[1px] flex-1 bg-border" />
17+
</div>
18+
);
19+
}

apps/dashboard/src/components/homepage/sections/PricingCard.tsx renamed to apps/dashboard/src/@/components/blocks/pricing-card.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { Team } from "@/api/team";
2+
import { CheckoutButton } from "@/components/billing";
23
import { Badge } from "@/components/ui/badge";
34
import { Button } from "@/components/ui/button";
5+
import { ToolTipLabel } from "@/components/ui/tooltip";
46
import { TrackedLinkTW } from "@/components/ui/tracked-link";
57
import { cn } from "@/lib/utils";
8+
import { CheckIcon, CircleDollarSignIcon } from "lucide-react";
69
import type React from "react";
710
import { TEAM_PLANS } from "utils/pricing";
8-
import { CheckoutButton } from "../../../@/components/billing";
911
import { remainingDays } from "../../../utils/date-utils";
10-
import { FeatureItem } from "./FeatureItem";
1112

1213
type ButtonProps = React.ComponentProps<typeof Button>;
1314

@@ -31,6 +32,7 @@ type PricingCardProps = {
3132
current?: boolean;
3233
canTrialGrowth?: boolean;
3334
activeTrialEndsAt?: string;
35+
redirectPath: string;
3436
};
3537

3638
export const PricingCard: React.FC<PricingCardProps> = ({
@@ -41,6 +43,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
4143
current = false,
4244
canTrialGrowth = false,
4345
activeTrialEndsAt,
46+
redirectPath,
4447
}) => {
4548
const plan = TEAM_PLANS[billingPlan];
4649
const isCustomPrice = typeof plan.price === "string";
@@ -128,6 +131,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
128131
variant={cta.variant || "outline"}
129132
teamSlug={teamSlug}
130133
sku={billingPlan === "starter" ? "plan:starter" : "plan:growth"}
134+
redirectPath={redirectPath}
131135
>
132136
{cta.title}
133137
</CheckoutButton>
@@ -154,3 +158,30 @@ export const PricingCard: React.FC<PricingCardProps> = ({
154158
</div>
155159
);
156160
};
161+
162+
type FeatureItemProps = {
163+
text: string | string[];
164+
};
165+
166+
function FeatureItem({ text }: FeatureItemProps) {
167+
const titleStr = Array.isArray(text) ? text[0] : text;
168+
169+
return (
170+
<div className="flex items-center gap-2">
171+
<CheckIcon className="size-4 shrink-0 text-green-500" />
172+
{Array.isArray(text) ? (
173+
<div className="flex items-center gap-2">
174+
<p className="text-muted-foreground">
175+
{titleStr}{" "}
176+
<span className="text-muted-foreground md:hidden">{text[1]}</span>
177+
</p>
178+
<ToolTipLabel label={text[1]}>
179+
<CircleDollarSignIcon className="hidden size-4 text-muted-foreground md:block" />
180+
</ToolTipLabel>
181+
</div>
182+
) : (
183+
<p className="text-muted-foreground">{titleStr}</p>
184+
)}
185+
</div>
186+
);
187+
}

apps/dashboard/src/@/components/ui/inline-code.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export function InlineCode({
77
return (
88
<code
99
className={cn(
10-
"inline-block rounded bg-muted px-2 font-mono text-sm",
10+
"mx-0.5 inline rounded-lg border border-border px-1.5 py-[3px] font-mono text-[0.85em] text-foreground",
1111
className,
1212
)}
1313
>

apps/dashboard/src/@/constants/env.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export const THIRDWEB_ACCESS_TOKEN = process.env.THIRDWEB_ACCESS_TOKEN;
3434
// Comma-separated list of chain IDs to disable faucet for.
3535
export const DISABLE_FAUCET_CHAIN_IDS = process.env.DISABLE_FAUCET_CHAIN_IDS;
3636

37+
export const BASE_URL = isProd
38+
? "https://thirdweb.com"
39+
: (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL
40+
? `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`
41+
: "http://localhost:3000") || "https://thirdweb-dev.com";
42+
3743
export function getAbsoluteUrlFromPath(path: string) {
38-
const url = new URL(
39-
isProd
40-
? "https://thirdweb.com"
41-
: (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL
42-
? `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`
43-
: "http://localhost:3000") || "https://thirdweb-dev.com",
44-
);
44+
const url = new URL(BASE_URL);
4545

4646
url.pathname = path;
4747
return url;

apps/dashboard/src/@3rdweb-sdk/react/cache-keys.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ export const engineKeys = {
111111
] as const,
112112
health: (instance: string) =>
113113
[...engineKeys.all, instance, "health"] as const,
114-
latestVersion: () => [...engineKeys.all, "latestVersion"] as const,
114+
deploymentPublicConfiguration: () =>
115+
[...engineKeys.all, "deploymentPublicConfiguration"] as const,
115116
systemMetrics: (engineId: string) =>
116117
[...engineKeys.all, engineId, "systemMetrics"] as const,
117118
queueMetrics: (engineId: string) =>

apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
useConnectModal,
2222
} from "thirdweb/react";
2323
import { useFavoriteChainIds } from "../../../../app/(dashboard)/(chain)/components/client/star-button";
24+
import { doLogout } from "../../../../app/login/auth-actions";
2425
import { LazyConfigureNetworkModal } from "../../../../components/configure-networks/LazyConfigureNetworkModal";
2526
import { useAllChainsData } from "../../../../hooks/chains/allChains";
2627
import {
@@ -174,10 +175,7 @@ export const CustomConnectWallet = (props: {
174175
}}
175176
onDisconnect={async () => {
176177
try {
177-
// log out the user
178-
await fetch("/api/auth/logout", {
179-
method: "POST",
180-
});
178+
await doLogout();
181179
} catch (err) {
182180
console.error("Failed to log out", err);
183181
}

0 commit comments

Comments
 (0)