Skip to content

Commit 8f59c2e

Browse files
authored
chore: Create contract subscription for existing webhook (#862)
* chore: Create contract subscription for existing webhook * make 400 * linter
1 parent e860bba commit 8f59c2e

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

src/server/routes/contract/subscriptions/add-contract-subscription.ts

+33-22
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { type Static, Type } from "@sinclair/typebox";
22
import type { FastifyInstance } from "fastify";
33
import { StatusCodes } from "http-status-codes";
44
import { getContract } from "thirdweb";
5-
import { isContractDeployed } from "thirdweb/utils";
5+
import { isContractDeployed, shortenAddress } from "thirdweb/utils";
66
import { upsertChainIndexer } from "../../../../shared/db/chain-indexers/upsert-chain-indexer";
77
import { createContractSubscription } from "../../../../shared/db/contract-subscriptions/create-contract-subscription";
88
import { getContractSubscriptionsUniqueChainIds } from "../../../../shared/db/contract-subscriptions/get-contract-subscriptions";
@@ -21,16 +21,26 @@ import {
2121
import { standardResponseSchema } from "../../../schemas/shared-api-schemas";
2222
import { getChainIdFromChain } from "../../../utils/chain";
2323
import { isValidWebhookUrl } from "../../../utils/validator";
24+
import { getWebhook } from "../../../../shared/db/webhooks/get-webhook";
25+
import type { Webhooks } from "@prisma/client";
2426

2527
const bodySchema = Type.Object({
2628
chain: chainIdOrSlugSchema,
2729
contractAddress: {
2830
...AddressSchema,
2931
description: "The address for the contract.",
3032
},
33+
webhookId: Type.Optional(
34+
Type.Number({
35+
description:
36+
"The ID of an existing webhook to use for this contract subscription. Either `webhookId` or `webhookUrl` must be provided.",
37+
examples: [1],
38+
}),
39+
),
3140
webhookUrl: Type.Optional(
3241
Type.String({
33-
description: "Webhook URL",
42+
description:
43+
"Creates a new webhook to call when new onchain data is detected. Either `webhookId` or `webhookUrl` must be provided.",
3444
examples: ["https://example.com/webhook"],
3545
}),
3646
),
@@ -91,6 +101,7 @@ export async function addContractSubscription(fastify: FastifyInstance) {
91101
const {
92102
chain,
93103
contractAddress,
104+
webhookId,
94105
webhookUrl,
95106
processEventLogs,
96107
filterEvents = [],
@@ -124,6 +135,25 @@ export async function addContractSubscription(fastify: FastifyInstance) {
124135
);
125136
}
126137

138+
// Get an existing webhook or create a new one.
139+
let webhook: Webhooks | null = null;
140+
if (webhookId) {
141+
webhook = await getWebhook(webhookId);
142+
} else if (webhookUrl && isValidWebhookUrl(webhookUrl)) {
143+
webhook = await insertWebhook({
144+
eventType: WebhooksEventTypes.CONTRACT_SUBSCRIPTION,
145+
name: `(Generated) Subscription for ${shortenAddress(contractAddress)}`,
146+
url: webhookUrl,
147+
});
148+
}
149+
if (!webhook) {
150+
throw createCustomError(
151+
'Failed to get or create webhook for contract subscription. Make sure you provide an valid "webhookId" or "webhookUrl".',
152+
StatusCodes.BAD_REQUEST,
153+
"INVALID_WEBHOOK",
154+
);
155+
}
156+
127157
// If not currently indexed, upsert the latest block number.
128158
const subscribedChainIds = await getContractSubscriptionsUniqueChainIds();
129159
if (!subscribedChainIds.includes(chainId)) {
@@ -137,30 +167,11 @@ export async function addContractSubscription(fastify: FastifyInstance) {
137167
}
138168
}
139169

140-
// Create the webhook (if provided).
141-
let webhookId: number | undefined;
142-
if (webhookUrl) {
143-
if (!isValidWebhookUrl(webhookUrl)) {
144-
throw createCustomError(
145-
"Invalid webhook URL. Make sure it starts with 'https://'.",
146-
StatusCodes.BAD_REQUEST,
147-
"BAD_REQUEST",
148-
);
149-
}
150-
151-
const webhook = await insertWebhook({
152-
eventType: WebhooksEventTypes.CONTRACT_SUBSCRIPTION,
153-
name: "(Auto-generated)",
154-
url: webhookUrl,
155-
});
156-
webhookId = webhook.id;
157-
}
158-
159170
// Create the contract subscription.
160171
const contractSubscription = await createContractSubscription({
161172
chainId,
162173
contractAddress: contractAddress.toLowerCase(),
163-
webhookId,
174+
webhookId: webhook.id,
164175
processEventLogs,
165176
filterEvents,
166177
processTransactionReceipts,

0 commit comments

Comments
 (0)