Skip to content

Commit a5d6e76

Browse files
committed
Add webhook API functions for insight dashboard (#7171)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces functionality for managing webhooks in the application. It includes a temporary `WebhooksPage` for displaying webhook data and implements several API functions for creating, retrieving, deleting, and testing webhooks. ### Detailed summary - Added `WebhooksPage` component in `page.tsx` to display webhook data. - Implemented `getWebhooks` function to fetch webhooks from the API. - Created interfaces for webhook responses and payloads. - Added `createWebhook`, `deleteWebhook`, and `testWebhook` functions for managing webhooks. - Handled API errors with appropriate responses. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced the ability to create, view, delete, and test webhooks through the dashboard interface, allowing users to manage webhook integrations more easily. - Added a new dashboard page displaying webhook data for better visibility and management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 97b8926 commit a5d6e76

File tree

2 files changed

+210
-0
lines changed
  • apps/dashboard/src

2 files changed

+210
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
2+
"use server";
3+
4+
import { getAuthToken } from "app/(app)/api/lib/getAuthToken";
5+
import { THIRDWEB_INSIGHT_API_DOMAIN } from "constants/urls";
6+
7+
interface WebhookResponse {
8+
id: string;
9+
name: string;
10+
team_id: string;
11+
project_id: string;
12+
webhook_url: string;
13+
webhook_secret: string;
14+
filters: WebhookFilters;
15+
suspended_at: string | null;
16+
suspended_reason: string | null;
17+
disabled: boolean;
18+
created_at: string;
19+
updated_at: string | null;
20+
}
21+
22+
interface WebhookFilters {
23+
"v1.events"?: {
24+
chain_ids?: string[];
25+
addresses?: string[];
26+
signatures?: Array<{
27+
sig_hash: string;
28+
abi?: string;
29+
params?: Record<string, unknown>;
30+
}>;
31+
};
32+
"v1.transactions"?: {
33+
chain_ids?: string[];
34+
from_addresses?: string[];
35+
to_addresses?: string[];
36+
signatures?: Array<{
37+
sig_hash: string;
38+
abi?: string;
39+
params?: Record<string, unknown>;
40+
}>;
41+
};
42+
}
43+
44+
interface CreateWebhookPayload {
45+
name: string;
46+
webhook_url: string;
47+
filters: WebhookFilters;
48+
}
49+
50+
interface WebhooksListResponse {
51+
data: WebhookResponse[];
52+
error?: string;
53+
}
54+
55+
interface WebhookSingleResponse {
56+
data: WebhookResponse | null;
57+
error?: string;
58+
}
59+
60+
interface TestWebhookPayload {
61+
webhook_url: string;
62+
type?: "event" | "transaction";
63+
}
64+
65+
interface TestWebhookResponse {
66+
success: boolean;
67+
error?: string;
68+
}
69+
70+
// biome-ignore lint/correctness/noUnusedVariables: will be used in the next PR
71+
async function createWebhook(
72+
payload: CreateWebhookPayload,
73+
clientId: string,
74+
): Promise<WebhookSingleResponse> {
75+
try {
76+
const authToken = await getAuthToken();
77+
const response = await fetch(`${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks`, {
78+
method: "POST",
79+
headers: {
80+
"Content-Type": "application/json",
81+
"x-client-id": clientId,
82+
Authorization: `Bearer ${authToken}`,
83+
},
84+
body: JSON.stringify(payload),
85+
});
86+
87+
if (!response.ok) {
88+
const errorText = await response.text();
89+
return {
90+
data: null,
91+
error: `Failed to create webhook: ${errorText}`,
92+
};
93+
}
94+
95+
return (await response.json()) as WebhookSingleResponse;
96+
} catch (error) {
97+
return {
98+
data: null,
99+
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
100+
};
101+
}
102+
}
103+
104+
export async function getWebhooks(
105+
clientId: string,
106+
): Promise<WebhooksListResponse> {
107+
try {
108+
const authToken = await getAuthToken();
109+
const response = await fetch(`${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks`, {
110+
method: "GET",
111+
headers: {
112+
"x-client-id": clientId,
113+
Authorization: `Bearer ${authToken}`,
114+
},
115+
});
116+
117+
if (!response.ok) {
118+
const errorText = await response.text();
119+
return {
120+
data: [],
121+
error: `Failed to get webhooks: ${errorText}`,
122+
};
123+
}
124+
125+
return (await response.json()) as WebhooksListResponse;
126+
} catch (error) {
127+
return {
128+
data: [],
129+
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
130+
};
131+
}
132+
}
133+
// biome-ignore lint/correctness/noUnusedVariables: will be used in the next PR
134+
async function deleteWebhook(
135+
webhookId: string,
136+
clientId: string,
137+
): Promise<WebhookSingleResponse> {
138+
try {
139+
const authToken = await getAuthToken();
140+
const response = await fetch(
141+
`${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks/${encodeURIComponent(webhookId)}`,
142+
{
143+
method: "DELETE",
144+
headers: {
145+
"x-client-id": clientId,
146+
Authorization: `Bearer ${authToken}`,
147+
},
148+
},
149+
);
150+
151+
if (!response.ok) {
152+
const errorText = await response.text();
153+
return {
154+
data: null,
155+
error: `Failed to delete webhook: ${errorText}`,
156+
};
157+
}
158+
159+
return (await response.json()) as WebhookSingleResponse;
160+
} catch (error) {
161+
return {
162+
data: null,
163+
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
164+
};
165+
}
166+
}
167+
// biome-ignore lint/correctness/noUnusedVariables: will be used in the next PR
168+
async function testWebhook(
169+
payload: TestWebhookPayload,
170+
clientId: string,
171+
): Promise<TestWebhookResponse> {
172+
try {
173+
const authToken = await getAuthToken();
174+
const response = await fetch(
175+
`${THIRDWEB_INSIGHT_API_DOMAIN}/v1/webhooks/test`,
176+
{
177+
method: "POST",
178+
headers: {
179+
"Content-Type": "application/json",
180+
"x-client-id": clientId,
181+
Authorization: `Bearer ${authToken}`,
182+
},
183+
body: JSON.stringify(payload),
184+
},
185+
);
186+
187+
if (!response.ok) {
188+
const errorText = await response.text();
189+
return {
190+
success: false,
191+
error: `Failed to test webhook: ${errorText}`,
192+
};
193+
}
194+
195+
return (await response.json()) as TestWebhookResponse;
196+
} catch (error) {
197+
return {
198+
success: false,
199+
error: `Network or parsing error: ${error instanceof Error ? error.message : "Unknown error"}`,
200+
};
201+
}
202+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This is a temporary page to supress linting errors and will be implemented up in the stack
2+
import { getWebhooks } from "@/api/insight/webhooks";
3+
4+
export default async function WebhooksPage() {
5+
const { data: webhooks, error } = await getWebhooks("123");
6+
7+
return <div>{JSON.stringify({ webhooks, error })}</div>;
8+
}

0 commit comments

Comments
 (0)