How to use Sponsorship Policy webhooks
Webhooks allow you to receive real-time notifications when sponsorship-related events occur. You can use webhooks to approve or reject sponsorship requests and receive notifications about finalized sponsorships. Start by going to the sponsorship policies page on the Pimlico dashboard, clicking on the existing policy and clicking on the "Edit button".
Webhook Types
UserOperation Sponsorship
These webhooks are triggered when using the pm_sponsorUserOperation endpoint.
Request for Sponsorship
const body = {
type: "sponsorshipPolicy.webhook", // Will become "user_operation.sponsorship.requested"
data: {
object: {
userOperation,
entryPoint,
chainId,
sponsorshipPolicyId,
apiKey
}
}
}
The webhook must return a response with the following structure:
{
"sponsor": true // Boolean - whether to approve the sponsorship
}
Sponsorship Finalized
Sent when a UserOperation sponsorship is approved and finalized:
const body = {
type: "user_operation.sponsorship.finalized",
data: {
object: {
userOperation,
entryPoint,
chainId,
sponsorshipPolicyId,
apiKey
}
}
}
MagicSpend Withdrawal
These webhooks are triggered when using the pimlico_sponsorMagicSpendWithdrawal endpoint.
Request for Withdrawal
Sent when a MagicSpend withdrawal sponsorship is requested:
const body = {
type: "magic_spend.sponsorship.requested",
data: {
object: {
recipient,
token,
amount,
signature,
chainId,
apiKey,
sponsorshipPolicyId
}
}
}
The webhook must return a response with the following structure:
{
"sponsor": true // Boolean - whether to approve the withdrawal
}
Withdrawal Finalized
Sent when a MagicSpend withdrawal is approved and finalized:
const body = {
type: "magic_spend.sponsorship.finalized",
data: {
object: {
withdrawal,
hash,
signature,
chainId,
apiKey,
sponsorshipPolicyId
}
}
}
How to verify the webhook
To verify the webhook, you can use the @pimlico/webhook
package. You will need to provide the webhook secret, which you can find in the sponsorship policy settings.
Installation
pnpm install @pimlico/webhook
Usage
import { pimlicoWebhookVerifier } from "@pimlico/webhook"
import type { VercelRequest, VercelResponse } from "@vercel/node"
const webhookSecret = process.env.PIMLICO_WEBHOOK_SECRET as string
const verifyWebhook = pimlicoWebhookVerifier(webhookSecret)
export default async function handler(req: VercelRequest, res: VercelResponse) {
const webhookEvent = verifyWebhook(
req.headers as Record<string, string>,
JSON.stringify(req.body)
)
// Handle different webhook types
switch(webhookEvent.type) {
case "sponsorshipPolicy.webhook":
case "user_operation.sponsorship.requested":
case "magic_spend.sponsorship.requested":
return res.status(200).json({
sponsor: true
})
case "user_operation.sponsorship.finalized":
case "magic_spend.sponsorship.finalized":
// Handle notification - no response needed
return res.status(200).end()
default:
return res.status(400).json({ error: "Unknown webhook type" })
}
}