Skip to content

Commit 282d9f2

Browse files
gregfromstlclaudegraphite-app[bot]
authored
[Dashboard] Fix: Use x-client-id + x-team-id for all UB requests (#6999)
Signed-off-by: greg <gregfromstl@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
1 parent e739de1 commit 282d9f2

File tree

12 files changed

+90
-51
lines changed

12 files changed

+90
-51
lines changed

apps/dashboard/src/@/api/universal-bridge/developer.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ type Webhook = {
1414
version?: number; // TODO (UB) make this mandatory after migration
1515
};
1616

17-
export async function getWebhooks() {
17+
export async function getWebhooks(props: {
18+
clientId: string;
19+
teamId: string;
20+
}) {
1821
const authToken = await getAuthToken();
1922
const res = await fetch(`${UB_BASE_URL}/v1/developer/webhooks`, {
2023
method: "GET",
2124
headers: {
2225
"Content-Type": "application/json",
26+
"x-client-id": props.clientId,
27+
"x-team-id": props.teamId,
2328
Authorization: `Bearer ${authToken}`,
2429
},
2530
});
@@ -35,12 +40,20 @@ export async function getWebhooks() {
3540

3641
export async function createWebhook(props: {
3742
clientId: string;
43+
teamId: string;
3844
version?: number;
3945
url: string;
4046
label: string;
4147
secret?: string;
4248
}) {
4349
const authToken = await getAuthToken();
50+
console.log(
51+
"UB_BASE_URL",
52+
UB_BASE_URL,
53+
props.clientId,
54+
props.teamId,
55+
authToken,
56+
);
4457
const res = await fetch(`${UB_BASE_URL}/v1/developer/webhooks`, {
4558
method: "POST",
4659
body: JSON.stringify({
@@ -51,6 +64,8 @@ export async function createWebhook(props: {
5164
}),
5265
headers: {
5366
"Content-Type": "application/json",
67+
"x-client-id": props.clientId,
68+
"x-team-id": props.teamId,
5469
Authorization: `Bearer ${authToken}`,
5570
},
5671
});
@@ -65,6 +80,7 @@ export async function createWebhook(props: {
6580

6681
export async function deleteWebhook(props: {
6782
clientId: string;
83+
teamId: string;
6884
webhookId: string;
6985
}) {
7086
const authToken = await getAuthToken();
@@ -74,7 +90,8 @@ export async function deleteWebhook(props: {
7490
method: "DELETE",
7591
headers: {
7692
"Content-Type": "application/json",
77-
"x-client-id-override": props.clientId,
93+
"x-client-id": props.clientId,
94+
"x-team-id": props.teamId,
7895
Authorization: `Bearer ${authToken}`,
7996
},
8097
},
@@ -105,6 +122,7 @@ export async function getFees(props: {
105122
headers: {
106123
"Content-Type": "application/json",
107124
"x-team-id": props.teamId,
125+
"x-client-id": props.clientId,
108126
Authorization: `Bearer ${authToken}`,
109127
},
110128
});
@@ -130,6 +148,7 @@ export async function updateFee(props: {
130148
headers: {
131149
"Content-Type": "application/json",
132150
"x-team-id": props.teamId,
151+
"x-client-id": props.clientId,
133152
Authorization: `Bearer ${authToken}`,
134153
},
135154
body: JSON.stringify({
@@ -187,6 +206,7 @@ export type Payment = {
187206

188207
export async function getPayments(props: {
189208
clientId: string;
209+
teamId: string;
190210
limit?: number;
191211
offset?: number;
192212
}) {
@@ -214,7 +234,8 @@ export async function getPayments(props: {
214234
method: "GET",
215235
headers: {
216236
"Content-Type": "application/json",
217-
"x-client-id-override": props.clientId,
237+
"x-client-id": props.clientId,
238+
"x-team-id": props.teamId,
218239
Authorization: `Bearer ${authToken}`,
219240
},
220241
});

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/connect/universal-bridge/webhooks/components/webhooks.client.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,17 @@ import { z } from "zod";
5858

5959
type PayWebhooksPageProps = {
6060
clientId: string;
61+
teamId: string;
6162
};
6263

6364
export function PayWebhooksPage(props: PayWebhooksPageProps) {
6465
const webhooksQuery = useQuery({
65-
queryKey: ["webhooks", props.clientId],
66+
queryKey: ["webhooks", props.clientId, props.teamId],
6667
queryFn: async () => {
67-
return await getWebhooks();
68+
return await getWebhooks({
69+
clientId: props.clientId,
70+
teamId: props.teamId,
71+
});
6872
},
6973
});
7074

@@ -76,7 +80,7 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
7680
return (
7781
<div className="flex flex-col items-center gap-8 rounded-lg border border-border p-8 text-center">
7882
<h2 className="font-semibold text-xl">No webhooks configured yet.</h2>
79-
<CreateWebhookButton clientId={props.clientId}>
83+
<CreateWebhookButton clientId={props.clientId} teamId={props.teamId}>
8084
<Button variant="primary" className="gap-1">
8185
<PlusIcon className="size-4" />
8286
<span>Create Webhook</span>
@@ -90,7 +94,7 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
9094
<div>
9195
<div className="flex items-center justify-between">
9296
<h2 className="font-semibold text-xl tracking-tight">Webhooks</h2>
93-
<CreateWebhookButton clientId={props.clientId}>
97+
<CreateWebhookButton clientId={props.clientId} teamId={props.teamId}>
9498
<Button size="sm" variant="default" className="gap-1">
9599
<PlusIcon className="size-4" />
96100
<span>Create Webhook</span>
@@ -123,6 +127,7 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
123127
<TableCell className="text-right">
124128
<DeleteWebhookButton
125129
clientId={props.clientId}
130+
teamId={props.teamId}
126131
webhookId={webhook.id}
127132
>
128133
<Button variant="ghost" size="icon">
@@ -167,6 +172,7 @@ function CreateWebhookButton(props: PropsWithChildren<PayWebhooksPageProps>) {
167172
mutationFn: async (values: z.infer<typeof formSchema>) => {
168173
await createWebhook({
169174
clientId: props.clientId,
175+
teamId: props.teamId,
170176
url: values.url,
171177
label: values.label,
172178
version: Number(values.version),
@@ -317,6 +323,7 @@ function DeleteWebhookButton(
317323
mutationFn: async (id: string) => {
318324
await deleteWebhook({
319325
clientId: props.clientId,
326+
teamId: props.teamId,
320327
webhookId: id,
321328
});
322329
return null;
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getProject } from "@/api/projects";
22
import { redirect } from "next/navigation";
3+
import { getTeamBySlug } from "../../../../../../../../@/api/team";
34
import { PayWebhooksPage } from "./components/webhooks.client";
45

56
export default async function Page(props: {
@@ -9,11 +10,14 @@ export default async function Page(props: {
910
}>;
1011
}) {
1112
const params = await props.params;
12-
const project = await getProject(params.team_slug, params.project_slug);
13+
const [project, team] = await Promise.all([
14+
getProject(params.team_slug, params.project_slug),
15+
getTeamBySlug(params.team_slug),
16+
]);
1317

14-
if (!project) {
18+
if (!project || !team) {
1519
redirect(`/team/${params.team_slug}`);
1620
}
1721

18-
return <PayWebhooksPage clientId={project.publishableKey} />;
22+
return <PayWebhooksPage clientId={project.publishableKey} teamId={team.id} />;
1923
}

apps/dashboard/src/app/checkout/components/client/CheckoutEmbed.client.tsx renamed to apps/dashboard/src/app/pay/components/client/PayPageEmbed.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { NATIVE_TOKEN_ADDRESS, createThirdwebClient, toTokens } from "thirdweb";
1717
import { AutoConnect, PayEmbed } from "thirdweb/react";
1818
import { setThirdwebDomains } from "thirdweb/utils";
1919

20-
export function CheckoutEmbed({
20+
export function PayPageEmbed({
2121
chainId,
2222
recipientAddress,
2323
amount,

apps/dashboard/src/app/checkout/components/client/CheckoutLinkForm.client.tsx renamed to apps/dashboard/src/app/pay/components/client/PaymentLinkForm.client.tsx

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useCallback, useMemo, useState } from "react";
1212
import { toast } from "sonner";
1313
import {
1414
type ThirdwebClient,
15+
createThirdwebClient,
1516
defineChain,
1617
getContract,
1718
toUnits,
@@ -21,7 +22,7 @@ import { resolveScheme, upload } from "thirdweb/storage";
2122
import { FileInput } from "../../../../components/shared/FileInput";
2223
import { resolveEns } from "../../../../lib/ens";
2324

24-
export function CheckoutLinkForm({ client }: { client: ThirdwebClient }) {
25+
export function PaymentLinkForm({ client }: { client: ThirdwebClient }) {
2526
const [chainId, setChainId] = useState<number>();
2627
const [recipientAddress, setRecipientAddress] = useState("");
2728
const [tokenAddressWithChain, setTokenAddressWithChain] = useState("");
@@ -38,35 +39,35 @@ export function CheckoutLinkForm({ client }: { client: ThirdwebClient }) {
3839
return chainId && recipientAddress && tokenAddressWithChain && amount;
3940
}, [chainId, recipientAddress, tokenAddressWithChain, amount]);
4041

41-
const handleImageUpload = useCallback(
42-
async (file: File) => {
43-
try {
44-
setImage(file);
45-
setUploadingImage(true);
42+
const handleImageUpload = useCallback(async (file: File) => {
43+
try {
44+
setImage(file);
45+
setUploadingImage(true);
4646

47-
const uri = await upload({
48-
client,
49-
files: [file],
50-
});
47+
const uploadClient = createThirdwebClient({
48+
clientId: "7ae789153cf9ecde8f35649f2d8a4333",
49+
});
50+
const uri = await upload({
51+
client: uploadClient,
52+
files: [file],
53+
});
5154

52-
// eslint-disable-next-line no-restricted-syntax
53-
const resolvedUrl = resolveScheme({
54-
uri,
55-
client,
56-
});
55+
// eslint-disable-next-line no-restricted-syntax
56+
const resolvedUrl = resolveScheme({
57+
uri,
58+
client: uploadClient,
59+
});
5760

58-
setImageUri(resolvedUrl);
59-
toast.success("Image uploaded successfully");
60-
} catch (error) {
61-
console.error("Error uploading image:", error);
62-
toast.error("Failed to upload image");
63-
setImage(null);
64-
} finally {
65-
setUploadingImage(false);
66-
}
67-
},
68-
[client],
69-
);
61+
setImageUri(resolvedUrl);
62+
toast.success("Image uploaded successfully");
63+
} catch (error) {
64+
console.error("Error uploading image:", error);
65+
toast.error("Failed to upload image");
66+
setImage(null);
67+
} finally {
68+
setUploadingImage(false);
69+
}
70+
}, []);
7071

7172
const handleSubmit = useCallback(
7273
async (e: React.FormEvent) => {

apps/dashboard/src/app/checkout/components/types.ts renamed to apps/dashboard/src/app/pay/components/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export type CheckoutParams = {
1+
export type PayParams = {
22
chainId: string;
33
recipientAddress: string;
44
tokenAddress: string;

apps/dashboard/src/app/checkout/page.tsx renamed to apps/dashboard/src/app/pay/page.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import { createThirdwebClient, defineChain, getContract } from "thirdweb";
55
import { getCurrencyMetadata } from "thirdweb/extensions/erc20";
66
import { checksumAddress } from "thirdweb/utils";
77
import { getClientThirdwebClient } from "../../@/constants/thirdweb-client.client";
8-
import { CheckoutEmbed } from "./components/client/CheckoutEmbed.client";
9-
import { CheckoutLinkForm } from "./components/client/CheckoutLinkForm.client";
10-
import type { CheckoutParams } from "./components/types";
8+
import { PayPageEmbed } from "./components/client/PayPageEmbed.client";
9+
import { PaymentLinkForm } from "./components/client/PaymentLinkForm.client";
10+
import type { PayParams } from "./components/types";
1111

12-
const title = "thirdweb Checkout";
12+
const title = "thirdweb Pay";
1313
const description = "Fast, secure, and simple payments.";
1414

1515
export const metadata: Metadata = {
@@ -23,7 +23,7 @@ export const metadata: Metadata = {
2323

2424
export default async function RoutesPage({
2525
searchParams,
26-
}: { searchParams: Promise<CheckoutParams> }) {
26+
}: { searchParams: Promise<PayParams> }) {
2727
const params = await searchParams;
2828

2929
// If no query parameters are provided, show the form
@@ -37,15 +37,15 @@ export default async function RoutesPage({
3737

3838
if (!authToken) {
3939
const searchParams = new URLSearchParams(params);
40-
return loginRedirect(`/checkout?${searchParams.toString()}`);
40+
return loginRedirect(`/pay?${searchParams.toString()}`);
4141
}
4242

4343
const client = getClientThirdwebClient({
4444
jwt: authToken,
4545
teamId: undefined,
4646
});
4747

48-
return <CheckoutLinkForm client={client} />;
48+
return <PaymentLinkForm client={client} />;
4949
}
5050

5151
// Validate query parameters
@@ -96,7 +96,7 @@ export default async function RoutesPage({
9696
};
9797

9898
return (
99-
<CheckoutEmbed
99+
<PayPageEmbed
100100
redirectUri={params.redirectUri}
101101
chainId={Number(params.chainId)}
102102
recipientAddress={params.recipientAddress}

0 commit comments

Comments
 (0)