Skip to content

Commit c37aff8

Browse files
authored
Merge branch 'main' into yash/stylus-cli-update
2 parents c9dfa00 + 9f88b5c commit c37aff8

File tree

79 files changed

+2008
-282
lines changed

Some content is hidden

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

79 files changed

+2008
-282
lines changed

.changeset/crazy-regions-send.md

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

.changeset/fresh-words-learn.md renamed to .changeset/orange-files-admire.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"thirdweb": patch
33
---
44

5-
Add Somnia Testnet
5+
properly type purchaseData

apps/dashboard/framer-rewrites.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = [
1616
// -- end build category
1717

1818
// -- scale category
19-
"/rpc-edge",
19+
"/rpc",
2020
"/insight",
2121
"/storage",
2222
// -- end scale category

apps/dashboard/redirects.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,11 @@ async function redirects() {
435435
permanent: false,
436436
source: "/engine",
437437
},
438+
{
439+
destination: "/rpc",
440+
permanent: false,
441+
source: "/rpc-edge",
442+
},
438443
...legacyDashboardToTeamRedirects,
439444
...projectPageRedirects,
440445
...teamPageRedirects,

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import posthog from "posthog-js";
22

33
import type { Team } from "@/api/team";
4+
import type { ProductSKU } from "../types/billing";
45

56
// ----------------------------
67
// CONTRACTS
@@ -380,3 +381,31 @@ export function reportAssetCreationFailed(
380381
step: properties.step,
381382
});
382383
}
384+
385+
type UpsellParams = {
386+
content: "storage-limit";
387+
campaign: "create-coin" | "create-nft";
388+
sku: Exclude<ProductSKU, null>;
389+
};
390+
391+
/**
392+
* ### Why do we need to report this event?
393+
* - To track how effective the upsells are in driving users to upgrade
394+
*
395+
* ### Who is responsible for this event?
396+
* @MananTank
397+
*/
398+
export function reportUpsellShown(properties: UpsellParams) {
399+
posthog.capture("upsell shown", properties);
400+
}
401+
402+
/**
403+
* ### Why do we need to report this event?
404+
* - To track how effective the upsells are in driving users to upgrade
405+
*
406+
* ### Who is responsible for this event?
407+
* @MananTank
408+
*/
409+
export function reportUpsellClicked(properties: UpsellParams) {
410+
posthog.capture("upsell clicked", properties);
411+
}

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

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type {
66
EcosystemWalletStats,
77
EngineCloudStats,
88
InAppWalletStats,
9-
RpcMethodStats,
109
TransactionStats,
1110
UniversalBridgeStats,
1211
UniversalBridgeWalletStats,
@@ -17,6 +16,41 @@ import type {
1716
import { getAuthToken } from "./auth-token";
1817
import { getChains } from "./chain";
1918

19+
export interface InsightChainStats {
20+
date: string;
21+
chainId: string;
22+
totalRequests: number;
23+
}
24+
25+
export interface InsightStatusCodeStats {
26+
date: string;
27+
httpStatusCode: number;
28+
totalRequests: number;
29+
}
30+
31+
export interface InsightEndpointStats {
32+
date: string;
33+
endpoint: string;
34+
totalRequests: number;
35+
}
36+
37+
interface InsightUsageStats {
38+
date: string;
39+
totalRequests: number;
40+
}
41+
42+
export interface RpcMethodStats {
43+
date: string;
44+
evmMethod: string;
45+
count: number;
46+
}
47+
48+
export interface RpcUsageTypeStats {
49+
date: string;
50+
usageType: string;
51+
count: number;
52+
}
53+
2054
async function fetchAnalytics(
2155
input: string | URL,
2256
init?: RequestInit,
@@ -76,6 +110,9 @@ function buildSearchParams(params: AnalyticsQueryParams): URLSearchParams {
76110
if (params.period) {
77111
searchParams.append("period", params.period);
78112
}
113+
if (params.limit) {
114+
searchParams.append("limit", params.limit.toString());
115+
}
79116
return searchParams;
80117
}
81118

@@ -225,6 +262,26 @@ export async function getRpcMethodUsage(
225262
return json.data as RpcMethodStats[];
226263
}
227264

265+
export async function getRpcUsageByType(
266+
params: AnalyticsQueryParams,
267+
): Promise<RpcUsageTypeStats[]> {
268+
const searchParams = buildSearchParams(params);
269+
const res = await fetchAnalytics(
270+
`v2/rpc/usage-types?${searchParams.toString()}`,
271+
{
272+
method: "GET",
273+
},
274+
);
275+
276+
if (res?.status !== 200) {
277+
console.error("Failed to fetch RPC usage");
278+
return [];
279+
}
280+
281+
const json = await res.json();
282+
return json.data as RpcUsageTypeStats[];
283+
}
284+
228285
export async function getWalletUsers(
229286
params: AnalyticsQueryParams,
230287
): Promise<WalletUserStats[]> {
@@ -424,3 +481,91 @@ export async function getEngineCloudMethodUsage(
424481
const json = await res.json();
425482
return json.data as EngineCloudStats[];
426483
}
484+
485+
export async function getInsightChainUsage(
486+
params: AnalyticsQueryParams,
487+
): Promise<{ data: InsightChainStats[] } | { errorMessage: string }> {
488+
const searchParams = buildSearchParams(params);
489+
const res = await fetchAnalytics(
490+
`v2/insight/usage/by-chain?${searchParams.toString()}`,
491+
{
492+
method: "GET",
493+
},
494+
);
495+
496+
if (res?.status !== 200) {
497+
const reason = await res?.text();
498+
const errMsg = `Failed to fetch Insight chain usage: ${res?.status} - ${res.statusText} - ${reason}`;
499+
console.error(errMsg);
500+
return { errorMessage: errMsg };
501+
}
502+
503+
const json = await res.json();
504+
return { data: json.data as InsightChainStats[] };
505+
}
506+
507+
export async function getInsightStatusCodeUsage(
508+
params: AnalyticsQueryParams,
509+
): Promise<{ data: InsightStatusCodeStats[] } | { errorMessage: string }> {
510+
const searchParams = buildSearchParams(params);
511+
const res = await fetchAnalytics(
512+
`v2/insight/usage/by-status-code?${searchParams.toString()}`,
513+
{
514+
method: "GET",
515+
},
516+
);
517+
518+
if (res?.status !== 200) {
519+
const reason = await res?.text();
520+
const errMsg = `Failed to fetch Insight status code usage: ${res?.status} - ${res.statusText} - ${reason}`;
521+
console.error(errMsg);
522+
return { errorMessage: errMsg };
523+
}
524+
525+
const json = await res.json();
526+
return { data: json.data as InsightStatusCodeStats[] };
527+
}
528+
529+
export async function getInsightEndpointUsage(
530+
params: AnalyticsQueryParams,
531+
): Promise<{ data: InsightEndpointStats[] } | { errorMessage: string }> {
532+
const searchParams = buildSearchParams(params);
533+
const res = await fetchAnalytics(
534+
`v2/insight/usage/by-endpoint?${searchParams.toString()}`,
535+
{
536+
method: "GET",
537+
},
538+
);
539+
540+
if (res?.status !== 200) {
541+
const reason = await res?.text();
542+
const errMsg = `Failed to fetch Insight endpoint usage: ${res?.status} - ${res.statusText} - ${reason}`;
543+
console.error(errMsg);
544+
return { errorMessage: errMsg };
545+
}
546+
547+
const json = await res.json();
548+
return { data: json.data as InsightEndpointStats[] };
549+
}
550+
551+
export async function getInsightUsage(
552+
params: AnalyticsQueryParams,
553+
): Promise<{ data: InsightUsageStats[] } | { errorMessage: string }> {
554+
const searchParams = buildSearchParams(params);
555+
const res = await fetchAnalytics(
556+
`v2/insight/usage?${searchParams.toString()}`,
557+
{
558+
method: "GET",
559+
},
560+
);
561+
562+
if (res?.status !== 200) {
563+
const reason = await res?.text();
564+
const errMsg = `Failed to fetch Insight usage: ${res?.status} - ${res.statusText} - ${reason}`;
565+
console.error(errMsg);
566+
return { errorMessage: errMsg };
567+
}
568+
569+
const json = await res.json();
570+
return { data: json.data as InsightUsageStats[] };
571+
}

apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export type MultiStepState<T extends string> = {
1818
}
1919
| {
2020
type: "error";
21-
message: React.ReactNode;
21+
message: string;
2222
};
2323
label: string;
2424
description?: string;
@@ -27,6 +27,10 @@ export type MultiStepState<T extends string> = {
2727
export function MultiStepStatus<T extends string>(props: {
2828
steps: MultiStepState<T>[];
2929
onRetry: (step: MultiStepState<T>) => void;
30+
renderError?: (
31+
step: MultiStepState<T>,
32+
errorMessage: string,
33+
) => React.ReactNode;
3034
}) {
3135
return (
3236
<DynamicHeight>
@@ -66,22 +70,24 @@ export function MultiStepStatus<T extends string>(props: {
6670
</p>
6771
)}
6872

69-
{step.status.type === "error" && (
70-
<div className="mt-1 space-y-2">
71-
<p className="mb-1 text-red-500 text-sm">
72-
{step.status.message}
73-
</p>
74-
<Button
75-
className="gap-2"
76-
onClick={() => props.onRetry(step)}
77-
size="sm"
78-
variant="destructive"
79-
>
80-
<RefreshCwIcon className="size-4" />
81-
Retry
82-
</Button>
83-
</div>
84-
)}
73+
{step.status.type === "error"
74+
? props.renderError?.(step, step.status.message) || (
75+
<div className="mt-1 space-y-2">
76+
<p className="mb-1 text-red-500 text-sm">
77+
{step.status.message}
78+
</p>
79+
<Button
80+
className="gap-2"
81+
onClick={() => props.onRetry(step)}
82+
size="sm"
83+
variant="destructive"
84+
>
85+
<RefreshCwIcon className="size-4" />
86+
Retry
87+
</Button>
88+
</div>
89+
)
90+
: null}
8591
</div>
8692
</div>
8793
))}

apps/dashboard/src/@/components/blocks/wallet-address.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ export function WalletAddress(props: {
5959

6060
// special case for zero address
6161
if (address === ZERO_ADDRESS) {
62-
return <span className="cursor-pointer font-mono">{shortenedAddress}</span>;
62+
return (
63+
<span className={cn("cursor-pointer font-mono", props.className)}>
64+
{shortenedAddress}
65+
</span>
66+
);
6367
}
6468

6569
return (

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ export interface TransactionStats {
3939
count: number;
4040
}
4141

42-
export interface RpcMethodStats {
43-
date: string;
44-
evmMethod: string;
45-
count: number;
46-
}
47-
4842
export interface EngineCloudStats {
4943
date: string;
5044
chainId: string;
@@ -78,4 +72,5 @@ export interface AnalyticsQueryParams {
7872
from?: Date;
7973
to?: Date;
8074
period?: "day" | "week" | "month" | "year" | "all";
75+
limit?: number;
8176
}

apps/dashboard/src/@/utils/pricing.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export const TEAM_PLANS: Record<
2323
features: [
2424
"Email Support",
2525
"48hr Guaranteed Response",
26-
"Invite Team Members",
2726
"Custom In-App Wallet Auth",
2827
],
2928
price: 99,

0 commit comments

Comments
 (0)