Skip to content

Commit dd65506

Browse files
[Playground] Refactor Universal Bridge sidebar links and update order (#6543)
1 parent 26cfd1b commit dd65506

File tree

13 files changed

+231
-28
lines changed

13 files changed

+231
-28
lines changed

apps/playground-web/public/ub.png

54.4 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type React from "react";
2+
import { APIHeader } from "../../../../components/blocks/APIHeader";
3+
4+
export default function Layout(props: {
5+
children: React.ReactNode;
6+
}) {
7+
return (
8+
<div>
9+
<APIHeader
10+
title="Universal Bridge API"
11+
description={
12+
<>HTTP API to bridge, swap and onramp to and from any currency</>
13+
}
14+
docsLink="https://portal.thirdweb.com/connect/pay/overview"
15+
heroLink="/ub.png"
16+
/>
17+
18+
{props.children}
19+
</div>
20+
);
21+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table";
2+
import Link from "next/link";
3+
import { getBridgePaths } from "./utils";
4+
5+
export default async function Page() {
6+
try {
7+
const paths = await getBridgePaths();
8+
return (
9+
<div className="pb-20">
10+
<h2 className="mb-2 font-semibold text-2xl tracking-tight">
11+
Universal Bridge REST API
12+
</h2>
13+
<p className="mb-5 text-muted-foreground">
14+
Directly interact with the Universal Bridge API from your backend,
15+
using standard REST api.
16+
</p>
17+
18+
<div className="flex flex-col gap-8">
19+
<BlueprintSection
20+
title="Available endpoints"
21+
blueprints={paths.map(([pathName, pathObj]) => {
22+
if (!pathObj) {
23+
throw new Error(`Path not found: ${pathName}`);
24+
}
25+
return {
26+
name: pathName,
27+
description: pathObj.get?.description || "",
28+
link: `/connect/pay/backend/reference?route=${pathName}`,
29+
};
30+
})}
31+
/>
32+
</div>
33+
</div>
34+
);
35+
} catch (error) {
36+
console.error(error);
37+
return <div>Error fetching API spec</div>;
38+
}
39+
}
40+
41+
function BlueprintSection(props: {
42+
title: string;
43+
blueprints: { name: string; description: string; link: string }[];
44+
}) {
45+
return (
46+
<div className="overflow-hidden rounded-lg border bg-card">
47+
<div className="flex items-center gap-2 border-b bg-accent/20 px-6 py-4">
48+
<h2 className="font-semibold text-lg tracking-tight">{props.title}</h2>
49+
</div>
50+
<Table>
51+
<TableBody>
52+
{props.blueprints.map((item) => (
53+
<TableRow
54+
key={item.link}
55+
className="group hover:bg-accent/50"
56+
linkBox
57+
>
58+
<TableCell>
59+
<span className="flex items-center gap-3">
60+
<Link
61+
href={item.link}
62+
className="before:absolute before:inset-0"
63+
>
64+
<div className="flex flex-col">
65+
<p className="font-semibold text-md">{item.name}</p>
66+
<p className="text-muted-foreground text-sm">
67+
{item.description}
68+
</p>
69+
</div>
70+
</Link>
71+
</span>
72+
</TableCell>
73+
</TableRow>
74+
))}
75+
</TableBody>
76+
</Table>
77+
</div>
78+
);
79+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
Breadcrumb,
3+
BreadcrumbItem,
4+
BreadcrumbLink,
5+
BreadcrumbList,
6+
BreadcrumbSeparator,
7+
} from "@/components/ui/breadcrumb";
8+
import { redirect } from "next/navigation";
9+
import { THIRDWEB_CLIENT } from "../../../../../lib/client";
10+
import { isProd } from "../../../../../lib/env";
11+
import { BlueprintPlayground } from "../../../../insight/[blueprint_slug]/blueprint-playground.client";
12+
import { getBridgePaths } from "../utils";
13+
14+
export default async function Page(props: {
15+
searchParams: Promise<{
16+
route: string;
17+
}>;
18+
}) {
19+
const params = await props.searchParams;
20+
21+
// invalid url
22+
if (!params.route) {
23+
redirect("/connect/pay/backend");
24+
}
25+
26+
const thirdwebDomain = !isProd ? "thirdweb-dev" : "thirdweb";
27+
const domain = `https://bridge.${thirdwebDomain}.com`;
28+
29+
const paths = await getBridgePaths();
30+
const pathMetadata = paths.find(([path]) => path === params.route)?.[1]?.get;
31+
32+
// invalid url
33+
if (!pathMetadata) {
34+
redirect("/connect/pay/backend");
35+
}
36+
37+
const title = pathMetadata.summary || "";
38+
return (
39+
<div>
40+
<Breadcrumbs />
41+
<h1 className="mt-3 mb-6 font-semibold text-2xl tracking-tight lg:text-3xl">
42+
{title}
43+
</h1>
44+
<BlueprintPlayground
45+
key={params.route}
46+
metadata={pathMetadata}
47+
backLink={"/connect/pay/backend"}
48+
clientId={THIRDWEB_CLIENT.clientId}
49+
path={params.route}
50+
supportedChainIds={[]}
51+
domain={domain}
52+
/>
53+
</div>
54+
);
55+
}
56+
57+
function Breadcrumbs() {
58+
return (
59+
<Breadcrumb>
60+
<BreadcrumbList>
61+
<BreadcrumbItem>
62+
<BreadcrumbLink href="/connect/pay/backend">
63+
Universal Bridge API
64+
</BreadcrumbLink>
65+
</BreadcrumbItem>
66+
<BreadcrumbSeparator />
67+
</BreadcrumbList>
68+
</Breadcrumb>
69+
);
70+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { OpenAPIV3 } from "openapi-types";
2+
import { isProd } from "../../../../lib/env";
3+
4+
export async function getBridgePaths() {
5+
const thirdwebDomain = !isProd ? "thirdweb-dev" : "thirdweb";
6+
const res = await fetch(`https://bridge.${thirdwebDomain}.com/openapi.json`);
7+
const openapiJson = (await res.json()) as OpenAPIV3.Document;
8+
return Object.entries(openapiJson.paths).filter(
9+
([, pathObj]) =>
10+
pathObj?.get?.deprecated === undefined ||
11+
pathObj?.get?.deprecated === false,
12+
);
13+
}

apps/playground-web/src/app/insight/[blueprint_slug]/blueprint-playground.client.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import {
3535
useForm,
3636
} from "react-hook-form";
3737
import { z } from "zod";
38-
import { isProd } from "../../../lib/env";
3938
import type { BlueprintParameter, BlueprintPathMetadata } from "../utils";
4039

4140
export function BlueprintPlayground(props: {
@@ -44,6 +43,7 @@ export function BlueprintPlayground(props: {
4443
clientId: string;
4544
path: string;
4645
supportedChainIds: number[];
46+
domain: string;
4747
}) {
4848
const [abortController, setAbortController] =
4949
useState<AbortController | null>(null);
@@ -56,6 +56,9 @@ export function BlueprintPlayground(props: {
5656
try {
5757
const res = await fetch(url, {
5858
signal: controller.signal,
59+
headers: {
60+
"x-client-id": props.clientId,
61+
},
5962
});
6063
return {
6164
status: res.status,
@@ -78,8 +81,6 @@ export function BlueprintPlayground(props: {
7881
},
7982
});
8083

81-
const thirdwebDomain = !isProd ? "thirdweb-dev" : "thirdweb";
82-
8384
return (
8485
<BlueprintPlaygroundUI
8586
backLink={props.backLink}
@@ -98,7 +99,7 @@ export function BlueprintPlayground(props: {
9899
abortController.abort();
99100
}
100101
}}
101-
domain={`https://insight.${thirdwebDomain}.com`}
102+
domain={props.domain}
102103
path={props.path}
103104
supportedChainIds={props.supportedChainIds}
104105
/>

apps/playground-web/src/app/insight/[blueprint_slug]/page.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from "@/components/ui/breadcrumb";
88
import { redirect } from "next/navigation";
99
import { THIRDWEB_CLIENT } from "../../../lib/client";
10+
import { isProd } from "../../../lib/env";
1011
import { fetchBlueprintSpec } from "../utils";
1112
import { BlueprintPlayground } from "./blueprint-playground.client";
1213

@@ -26,6 +27,9 @@ export default async function Page(props: {
2627
redirect("/insight");
2728
}
2829

30+
const thirdwebDomain = !isProd ? "thirdweb-dev" : "thirdweb";
31+
const domain = `https://insight.${thirdwebDomain}.com`;
32+
2933
const [blueprintSpec] = await Promise.all([
3034
fetchBlueprintSpec({
3135
blueprintId: params.blueprint_slug,
@@ -58,6 +62,7 @@ export default async function Page(props: {
5862
clientId={THIRDWEB_CLIENT.clientId}
5963
path={searchParams.path}
6064
supportedChainIds={supportedChainIds}
65+
domain={domain}
6166
/>
6267
</div>
6368
);

apps/playground-web/src/app/navLinks.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,6 @@ export const staticSidebarLinks: SidebarLink[] = [
6060
},
6161
],
6262
},
63-
{
64-
name: "Universal Bridge",
65-
expanded: false,
66-
links: [
67-
{
68-
name: "UI Component",
69-
href: "/connect/pay",
70-
},
71-
{
72-
name: "Fund Wallet",
73-
href: "/connect/pay/fund-wallet",
74-
},
75-
{
76-
name: "Commerce",
77-
href: "/connect/pay/commerce",
78-
},
79-
{
80-
name: "Transactions",
81-
href: "/connect/pay/transactions",
82-
},
83-
],
84-
},
8563
{
8664
name: "Auth",
8765
href: "/connect/auth",
@@ -124,6 +102,34 @@ export const staticSidebarLinks: SidebarLink[] = [
124102
},
125103
];
126104

105+
const universalBridgeSidebarLinks: SidebarLink = {
106+
name: "Universal Bridge",
107+
isCollapsible: false,
108+
expanded: false,
109+
links: [
110+
{
111+
name: "UI Component",
112+
href: "/connect/pay",
113+
},
114+
{
115+
name: "Fund Wallet",
116+
href: "/connect/pay/fund-wallet",
117+
},
118+
{
119+
name: "Commerce",
120+
href: "/connect/pay/commerce",
121+
},
122+
{
123+
name: "Transactions",
124+
href: "/connect/pay/transactions",
125+
},
126+
{
127+
name: "Backend API",
128+
href: "/connect/pay/backend",
129+
},
130+
],
131+
};
132+
127133
const engineSidebarLinks: SidebarLink = {
128134
name: "Engine",
129135
isCollapsible: false,
@@ -167,13 +173,14 @@ export async function getSidebarLinks() {
167173

168174
const sidebarLinks: SidebarLink[] = [
169175
...staticSidebarLinks,
176+
universalBridgeSidebarLinks,
177+
engineSidebarLinks,
170178
{
171179
name: "Insight",
172180
isCollapsible: false,
173181
expanded: false,
174182
links: insightLinks,
175183
},
176-
engineSidebarLinks,
177184
];
178185

179186
return sidebarLinks;

apps/playground-web/src/lib/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const THIRDWEB_CLIENT = createThirdwebClient(
1919
process.env.THIRDWEB_SECRET_KEY
2020
? {
2121
secretKey: process.env.THIRDWEB_SECRET_KEY,
22+
clientId: process.env.NEXT_PUBLIC_THIRDWEB_CLIENT_ID as string,
2223
config: {
2324
storage: isDev
2425
? {

apps/portal/src/app/references/components/TDoc/utils/getSidebarLinkgroups.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const tagsToGroup = {
3535
"@extension": "Extensions",
3636
"@rpc": "RPC",
3737
"@transaction": "Transactions",
38+
"@bridge": "Universal Bridge",
3839
"@buyCrypto": "Buy Crypto",
3940
"@utils": "Utils",
4041
"@chain": "Chain",
@@ -60,6 +61,7 @@ const sidebarGroupOrder: TagKey[] = [
6061
"@account",
6162
"@contract",
6263
"@transaction",
64+
"@bridge",
6365
"@nebula",
6466
"@social",
6567
"@auth",

0 commit comments

Comments
 (0)