Skip to content

Add support for chain filtering in webhook creation #7209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions apps/dashboard/src/@/api/insight/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ interface TestWebhookResponse {
error?: string;
}

type SupportedWebhookChainsResponse =
| { chains: Array<number> }
| { error: string };

export async function createWebhook(
payload: CreateWebhookPayload,
clientId: string,
Expand Down Expand Up @@ -205,3 +209,31 @@ export async function testWebhook(
};
}
}

export async function getSupportedWebhookChains(): Promise<SupportedWebhookChainsResponse> {
try {
const response = await fetch(
`https://${THIRDWEB_INSIGHT_API_DOMAIN}/service/chains`,
{
method: "GET",
headers: {
"x-service-api-key": process.env.INSIGHT_SERVICE_API_KEY || "",
},
},
);

if (!response.ok) {
const errorText = await response.json();
return { error: `Failed to fetch supported chains: ${errorText.error}` };
}

const data = await response.json();
if (Array.isArray(data.data)) {
return { chains: data.data };
}
return { error: "Unexpected response format" };
} catch (error) {
console.error("Error fetching supported chains:", error);
return { error: `Failed to fetch supported chains: ${error}` };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ export function MultiNetworkSelector(props: {
side?: "left" | "right" | "top" | "bottom";
showSelectedValuesInModal?: boolean;
client: ThirdwebClient;
chainIds?: number[];
}) {
const { allChains, idToChain } = useAllChainsData();
let { allChains, idToChain } = useAllChainsData();

if (props.chainIds && props.chainIds.length > 0) {
allChains = allChains.filter((chain) =>
props.chainIds?.includes(chain.chainId),
);
}

const options = useMemo(() => {
let sortedChains = allChains;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ import {

interface CreateWebhookModalProps {
clientId: string;
supportedChainIds: Array<number>;
}

export function CreateWebhookModal({ clientId }: CreateWebhookModalProps) {
export function CreateWebhookModal({
clientId,
supportedChainIds,
}: CreateWebhookModalProps) {
const router = useDashboardRouter();
const thirdwebClient = useThirdwebClient();
const [isOpen, setIsOpen] = useState(false);
Expand Down Expand Up @@ -270,6 +274,7 @@ export function CreateWebhookModal({ clientId }: CreateWebhookModalProps) {
goToNextStep={goToNextStep}
goToPreviousStep={goToPreviousStep}
isLoading={isLoading}
supportedChainIds={supportedChainIds}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import { MultiNetworkSelector } from "@/components/blocks/NetworkSelectors";
import { Spinner } from "@/components/ui/Spinner/Spinner";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
Expand All @@ -24,6 +23,7 @@ import { useThirdwebClient } from "@/constants/thirdweb.client";
import { useQueryClient } from "@tanstack/react-query";
import type { UseFormReturn } from "react-hook-form";

import { MultiNetworkSelector } from "@/components/blocks/NetworkSelectors";
import { truncateMiddle } from "../utils/abiUtils";
import type {
AbiData,
Expand All @@ -45,6 +45,7 @@ interface FilterDetailsStepProps {
goToNextStep: () => void;
goToPreviousStep: () => void;
isLoading: boolean;
supportedChainIds: Array<number>;
}

export function FilterDetailsStep({
Expand All @@ -60,6 +61,7 @@ export function FilterDetailsStep({
goToNextStep,
goToPreviousStep,
isLoading,
supportedChainIds,
}: FilterDetailsStepProps) {
const thirdwebClient = useThirdwebClient();
const queryClient = useQueryClient();
Expand Down Expand Up @@ -106,6 +108,7 @@ export function FilterDetailsStep({
}
onChange={(chainIds) => field.onChange(chainIds.map(String))}
client={thirdwebClient}
chainIds={supportedChainIds}
/>
</FormControl>
<FormMessage />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ function getEventType(filters: WebhookFilters): string {
interface WebhooksTableProps {
webhooks: WebhookResponse[];
clientId: string;
supportedChainIds: number[];
}

export function WebhooksTable({ webhooks, clientId }: WebhooksTableProps) {
export function WebhooksTable({
webhooks,
clientId,
supportedChainIds,
}: WebhooksTableProps) {
const [isDeleting, setIsDeleting] = useState<Record<string, boolean>>({});
const { testWebhookEndpoint, isTestingMap } = useTestWebhook(clientId);
const router = useDashboardRouter();
Expand Down Expand Up @@ -210,7 +215,10 @@ export function WebhooksTable({ webhooks, clientId }: WebhooksTableProps) {
return (
<div className="w-full">
<div className="mb-4 flex items-center justify-end">
<CreateWebhookModal clientId={clientId} />
<CreateWebhookModal
clientId={clientId}
supportedChainIds={supportedChainIds}
/>
</div>
<TWTable
data={sortedWebhooks}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { type WebhookResponse, getWebhooks } from "@/api/insight/webhooks";
import {
type WebhookResponse,
getSupportedWebhookChains,
getWebhooks,
} from "@/api/insight/webhooks";
import { getProject } from "@/api/projects";
import { TrackedUnderlineLink } from "@/components/ui/tracked-link";
import { notFound } from "next/navigation";
Expand All @@ -11,6 +15,7 @@ export default async function WebhooksPage({
let webhooks: WebhookResponse[] = [];
let clientId = "";
let errorMessage = "";
let supportedChainIds: number[] = [];

try {
// Await params before accessing properties
Expand All @@ -32,6 +37,13 @@ export default async function WebhooksPage({
} else if (webhooksRes.data) {
webhooks = webhooksRes.data;
}

const supportedChainsRes = await getSupportedWebhookChains();
if ("chains" in supportedChainsRes) {
supportedChainIds = supportedChainsRes.chains;
} else {
errorMessage = supportedChainsRes.error;
}
} catch (error) {
errorMessage = "Failed to load webhooks. Please try again later.";
console.error("Error loading project or webhooks", error);
Expand Down Expand Up @@ -71,7 +83,11 @@ export default async function WebhooksPage({
</div>
</div>
) : webhooks.length > 0 ? (
<WebhooksTable webhooks={webhooks} clientId={clientId} />
<WebhooksTable
webhooks={webhooks}
clientId={clientId}
supportedChainIds={supportedChainIds}
/>
) : (
<div className="flex flex-col items-center justify-center gap-4 rounded-lg border border-border p-12 text-center">
<div>
Expand All @@ -80,7 +96,10 @@ export default async function WebhooksPage({
Create a webhook to get started.
</p>
</div>
<CreateWebhookModal clientId={clientId} />
<CreateWebhookModal
clientId={clientId}
supportedChainIds={supportedChainIds}
/>
</div>
)}
</div>
Expand Down
Loading