
Research
/Security News
GlassWASM: WebAssembly Malware Found in Trojanized Open VSX Extensions
The trojanized extensions use TinyGo-compiled WebAssembly and Solana transaction memos to resolve command-and-control infrastructure.
Payment processing SDK for DERO — Accept DERO payments with invoices, payment monitoring, webhooks, and a merchant dashboard.
Payment processing SDK for DERO — Accept DERO payments with invoices, payment monitoring, webhooks, and a merchant dashboard.
No actively maintained payment processor exists for current DERO (HE/Stargate). dero-pay fills that gap.
<PayWithDero>, <InvoiceView>, <PaymentStatus> componentsbun add dero-pay
import { InvoiceEngine } from "dero-pay/server";
import { deroToAtomic } from "dero-pay";
const engine = new InvoiceEngine({
walletRpcUrl: "http://127.0.0.1:10103/json_rpc",
daemonRpcUrl: "http://127.0.0.1:10102/json_rpc",
webhookUrl: "https://mystore.com/webhooks/dero",
webhookSecret: process.env.WEBHOOK_SECRET!,
});
await engine.start();
// Create an invoice
const invoice = await engine.createInvoice({
name: "Widget Pro",
description: "Premium widget subscription",
amount: deroToAtomic("5.0"), // 5 DERO
});
console.log(invoice.integratedAddress); // Send DERO here
console.log(invoice.id); // Track status with this
// Listen for events
engine.on("invoiceStatusChanged", (invoice, previousStatus) => {
console.log(`Invoice ${invoice.id}: ${previousStatus} → ${invoice.status}`);
});
// app/api/pay/create/route.ts
import { createPaymentHandlers } from "dero-pay/next";
const { createInvoiceHandler, statusHandler } = createPaymentHandlers({
walletRpcUrl: "http://127.0.0.1:10103/json_rpc",
daemonRpcUrl: "http://127.0.0.1:10102/json_rpc",
});
export const POST = createInvoiceHandler;
// app/api/pay/status/route.ts
export const GET = statusHandler;
// lib/deropay.ts
import { createPaymentHandlers, createX402RouteGuard } from "dero-pay/next";
import { deroToAtomic } from "dero-pay";
export const paymentHandlers = createPaymentHandlers({
walletRpcUrl: "http://127.0.0.1:10103/json_rpc",
daemonRpcUrl: "http://127.0.0.1:10102/json_rpc",
receiptSecret: process.env.DEROPAY_RECEIPT_SECRET!,
});
export const x402Guard = createX402RouteGuard({
getEngine: paymentHandlers.getEngine,
receiptSecret: process.env.DEROPAY_RECEIPT_SECRET!,
policy: {
name: "Premium API Access",
amountAtomic: deroToAtomic("0.10"),
requiredConfirmations: 3,
maxReceiptsPerDay: 500,
maxAtomicPerWindow: {
amountAtomic: deroToAtomic("10"),
windowSeconds: 3600,
},
metadata: { plan: "premium" },
},
});
// app/api/protected/report/route.ts
import { x402Guard } from "@/lib/deropay";
export const GET = x402Guard(async () => {
return Response.json({
report: "paid content",
});
});
When a valid X-DeroPay-Receipt is not provided, this route responds with:
HTTP 402 Payment RequiredYou can retry using either header:
X-DeroPay-Receipt: <token>Authorization: X402 proof="<token>"402 Payment Required plus invoice details (amount, integrated address, expiry, confirmations).Receipt verification is local and fast (signature + policy checks), so protected routes do not need per-request chain proof verification.
Default receipt TTL is 600 seconds when issuing via issueReceiptHandler, and can be customized with ttlSeconds.
Optional quota controls are available directly on X402PaymentPolicy:
maxReceiptsPerDaymaxAtomicPerWindow: { amountAtomic, windowSeconds }maxReceiptsPerDay and maxAtomicPerWindow are enforced via store-backed usage reservations.
For correct quota enforcement across multiple API instances:
SqliteInvoiceStore on shared disk, or a custom central store implementation)If quota reservation support is missing in the configured store, guarded routes will reject usage with a server error so limits are not silently bypassed.
// app/api/pay/receipts/issue/route.ts
import { paymentHandlers } from "@/lib/deropay";
export const POST = paymentHandlers.issueReceiptHandler;
// app/api/pay/receipts/verify/route.ts
import { paymentHandlers } from "@/lib/deropay";
export const POST = paymentHandlers.verifyReceiptHandler;
Issue a receipt after invoice completion:
curl -X POST http://localhost:3000/api/pay/receipts/issue \
-H "Content-Type: application/json" \
-d '{
"invoiceId":"inv_123",
"resource":"/api/protected/report",
"ttlSeconds":600
}'
Verify and use the receipt:
curl -X POST http://localhost:3000/api/pay/receipts/verify \
-H "Content-Type: application/json" \
-d '{
"receipt":"<token>",
"resource":"/api/protected/report",
"minAmountAtomic":"100000000000"
}'
curl http://localhost:3000/api/protected/report \
-H "X-DeroPay-Receipt: <token>"
curl http://localhost:3000/api/protected/report \
-H 'Authorization: X402 proof="<token>"'
Build the authorization header programmatically:
import { formatX402AuthorizationHeader } from "dero-pay";
const headerValue = formatX402AuthorizationHeader(receiptToken);
// => X402 proof="<token>"
A full runnable Next.js example is available at:
apps/x402-exampleX402PolicyResolverimport { createX402RouteGuard } from "dero-pay/next";
import { deroToAtomic } from "dero-pay";
export const meteredGuard = createX402RouteGuard({
getEngine: paymentHandlers.getEngine,
receiptSecret: process.env.DEROPAY_RECEIPT_SECRET!,
policy: async (request) => {
const url = new URL(request.url);
const tokens = Number(url.searchParams.get("tokens") ?? "1000");
const amountAtomic = deroToAtomic((tokens / 100_000).toFixed(5));
return {
name: "Metered inference request",
amountAtomic,
resource: "/api/protected/inference",
metadata: { tokens },
};
},
});
import { InvoiceEngine } from "dero-pay/server";
const engine = new InvoiceEngine({
walletRpcUrl: "http://127.0.0.1:10103/json_rpc",
daemonRpcUrl: "http://127.0.0.1:10102/json_rpc",
});
engine.on("x402Audit", (event) => {
console.log("[x402-audit]", event.type, event.resource, event.invoiceId, event.reason);
});
import { DeroPayProvider, InvoiceView, PayWithDero } from "dero-pay/react";
function PaymentPage({ invoiceId }: { invoiceId: string }) {
return (
<DeroPayProvider appName="My Store" statusEndpoint="/api/pay/status">
<InvoiceView
invoiceId={invoiceId}
onCompleted={() => console.log("Paid!")}
/>
<PayWithDero invoiceId={invoiceId} />
</DeroPayProvider>
);
}
dero-pay/
├── src/
│ ├── core/ # Types, payment ID generation, pricing utilities
│ ├── rpc/ # Wallet & Daemon RPC clients (HTTP JSON-RPC)
│ ├── monitor/ # Payment polling engine with confirmation tracking
│ ├── webhook/ # HMAC-signed webhook dispatcher with retry
│ ├── store/ # Pluggable storage (memory, SQLite)
│ ├── server/ # Invoice engine orchestrator
│ ├── client/ # Browser XSWD client + payment session
│ ├── react/ # React components (Provider, PayWithDero, InvoiceView)
│ └── next/ # Next.js API handlers + middleware
└── dashboard/ # Self-hosted admin dashboard (Next.js app)
| Import Path | Description |
|---|---|
dero-pay | Core types, payment ID generation, pricing utilities |
dero-pay/rpc | Wallet and Daemon RPC clients |
dero-pay/server | Invoice engine, storage, monitor, webhooks |
dero-pay/client | Browser-side XSWD payment client |
dero-pay/react | React components and provider |
dero-pay/next | Next.js API route handlers and middleware |
created → pending → confirming → completed
↘ expired
↘ partial (underpaid, still waiting)
The dashboard is a Next.js app that provides an admin UI:
cd dashboard
cp .env.example .env.local # Edit with your wallet RPC settings
bun install
bun dev
Open http://localhost:3100 to access the dashboard.
--rpc-server flag# Mainnet
dero-wallet-cli --wallet-file wallet.db --rpc-server --rpc-bind=127.0.0.1:10103
# Testnet
dero-wallet-cli --wallet-file wallet.db --rpc-server --rpc-bind=127.0.0.1:40403 --testnet
DeroPay signs webhooks with HMAC-SHA256. Verify them on your end:
import { verifyWebhookSignature } from "dero-pay/server";
const isValid = verifyWebhookSignature(
requestBody,
request.headers.get("X-DeroPay-Signature")!,
process.env.WEBHOOK_SECRET!
);
MIT — see LICENSE
DHEBP is not affiliated with or endorsed by the DERO Project or its core developers.
FAQs
Payment processing SDK for DERO — Accept DERO payments with invoices, payment monitoring, webhooks, and a merchant dashboard.
We found that dero-pay demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
The trojanized extensions use TinyGo-compiled WebAssembly and Solana transaction memos to resolve command-and-control infrastructure.

Security News
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.

Security News
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.