
Level Up Your Webhooks: Enhanced Signature Verification and Smarter Logging!
Level Up Your Webhooks: Enhanced Signature Verification and Smarter Logging!
Hey, code ninjas and blockchain buffs! 🚀 Exciting updates are rolling out for PayDirect’s crypto settlement platform on Base (yep, that's Ethereum L2 for you savvy developers). We've just pushed some snazzy changes to the main branch and they're all about making your webhooks slicker than ever. Hold onto your keyboards and let's dive into the nitty-gritty of what’s new!
What's the Buzz About?
Picture this: You're working on your latest dApp, leveraging PayDirect’s stellar webhook features. But ah, there’s a snag—those pesky signature verifications and timeout errors are cramping your style. Fear not, we've got you covered with an epic refactor that’ll have your webhooks running smoother than a buttered byte. 🧈💻
Improved CDP Signature Verification
First on the docket, we've revamped our CDP signature verification in route.ts. Why? Because we believe in robust security and a better developer experience. Dive into this beauty of a function, verifySignatureWithSecret, and see the magic unfold:
function verifySignatureWithSecret(
rawBody: string,
signatureHeader: string,
secret: string,
headers: Record<string, string>,
): boolean {
const keyMaterial = secret.trim();
if (!keyMaterial) return false;
try {
const elements = signatureHeader.split(",").map((p) => p.trim());
let timestamp = "";
let hField = "";
let providedSignature = "";
for (const el of elements) {
const eq = el.indexOf("=");
const key = el.slice(0, eq).trim();
const value = el.slice(eq + 1).trim();
if (key === "t") timestamp = value;
else if (key === "h") hField = value;
else if (key === "v1") providedSignature = value;
}
const ts = parseInt(timestamp, 10);
const ageSeconds = Math.floor(Date.now() / 1000) - ts;
if (ageSeconds > 300 || ageSeconds < -120) return false; // replay / skew
let signedPayload: string;
if (!hField) {
signedPayload = `${timestamp}.${rawBody}`;
} else {
const headerValues = hField
.split(" ")
.map((name) => headerValue(headers, name))
.join(".");
signedPayload = `${timestamp}.${hField}.${headerValues}.${rawBody}`;
}
const expectedSignature = crypto
.createHmac("sha256", keyMaterial)
.update(signedPayload, "utf8")
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(providedSignature), Buffer.from(expectedSignature));
} catch (err) {
return false;
}
}
This update makes the signature verification process more resilient, ensuring your webhook events are secure and legit. Say goodbye to those “Invalid signature” errors that were a tad too cryptic for comfort.
Logging Just Got Smarter
Let’s talk logs—those unsung heroes in the dev world. We've given our logging system a major glow-up in webhook-engine.ts. Check it out:
const TIMEOUT_MS = 30_000; // It's a slow world out there, let's be patient.
export class WebhookEngine {
// ...
async deliverPayload(attempt, url, webhookId) {
try {
// ...
} catch (err) {
const isAbort =
err instanceof Error &&
(err.name === "AbortError" || err.message === "This operation was aborted");
const errMsg = err instanceof Error ? err.message : "Unknown error";
if (isAbort) {
console.warn(
`[WEBHOOK] Delivery timeout after ${TIMEOUT_MS}ms (attempt ${attempt}/${MAX_RETRIES}): ${url}`
);
} else {
console.error(
`[WEBHOOK] Delivery error (attempt ${attempt}/${MAX_RETRIES}): ${url} -> ${errMsg}`
);
}
await this.logDelivery(
webhookId,
attempt,
`Delivery failed: ${errMsg}`
);
}
}
}
We’ve extended the timeout threshold, because hey, even servers need time to get their act together. Plus, our logs are now clearer—distinguishing between timeouts and other errors. No more guesswork!
Why It Matters
So why should you care about this update? Simple. It elevates your development experience by ensuring more reliable webhook delivery and gives you better insights when something goes awry. Your dApp deserves the best, and these improvements help you focus on building features, not debugging cryptic errors. 🌟
What’s Next?
Now that you’re in the know, it’s time to put these improvements to the test! Whether you’re into AI development or hardcore blockchain tinkering, leverage these changes to supercharge your project. 🚀🔥
Ready to dive deeper? Check out our documentation to get started, or reach out on our community forums if you’ve got questions. Remember, in the world of code, the possibilities are endless—and your webhooks deserve nothing less than awesome.
Catch you later, code warriors! ✌️💻
Don't stop coding—start exploring the new webhook capabilities today, and unleash the true potential of PayDirect on Base!
Tip the Author
Powered by PayDirect on Base
Enjoyed this post? Send a tip using crypto. We eat our own dog food.
More from PayDirect
Powered by ContentAgent




