import { Hono, type MiddlewareHandler } from "hono";
import { HTTPException } from "hono/http-exception";
import { serve } from "@hono/node-server";
import { solana, evm } from "@faremeter/info";
import {
handleMiddlewareRequest,
createPaymentRequiredResponseCache,
} from "@faremeter/middleware/common";
const createMiddleware = (): MiddlewareHandler => {
// Use requirements caching, so we don't have to query the
// facilitator if requirements don't change.
const { getPaymentRequiredResponse } = createPaymentRequiredResponseCache({});
return async (c, next) => {
const amount = c.req.query("amount");
const asset = "USDC";
// Look at the request, to determine how much we should charge.
if (amount === undefined) {
throw new HTTPException(400, {
message: "you need to provide an 'amount' querystring parameter",
});
}
// The amount will be divided by the decimals for the asset.
console.log(`setting request price as ${amount} ${asset}`);
const accepts = [
solana.x402Exact({
network: "devnet",
asset,
amount,
payTo: "81CR7uzzReplaceThisWithYourWalletAddress",
}),
evm.x402Exact({
network: "base-sepolia",
asset,
amount,
payTo: "0xd64d67BeC49dA9ReplaceThisWithYourWalletAddress",
}),
];
return await handleMiddlewareRequest({
facilitatorURL: "https://facilitator.corbits.dev",
accepts,
resource: c.req.url,
getHeader: (key) => c.req.header(key),
getPaymentRequiredResponse,
sendJSONResponse: (status, body) => {
c.status(status);
return c.json(body);
},
body: async ({ settle }) => {
// Settle will automatically verify the requirement before
// processing the transaction.
const settleResult = await settle();
if (settleResult !== undefined) {
return settleResult;
}
await next();
},
});
};
};
const app = new Hono();
// Set up a route that varies its required price based on the provided path.
app.get("/protected", createMiddleware(), (c) => {
return c.json({
msg: "success",
});
});
serve(app, (info) => {
console.log(`Listening on http://localhost:${info.port}`);
});