chore: sync all changes to Gitea
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled

- Config, docs, scripts, and backup manifests
- Submodule refs unchanged (m = modified content in submodules)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-02 11:37:34 -08:00
parent ed85135249
commit b3a8fe4496
883 changed files with 73580 additions and 4796 deletions

131
x402-api/src/index.js Normal file
View File

@@ -0,0 +1,131 @@
/**
* Minimal x402-enabled Express API using thirdweb settlePayment.
* Supports custom Chain 138; default payment chain is Arbitrum Sepolia (USDC) for testing
* until a Chain 138 token supports ERC-2612/ERC-3009. See docs/04-configuration/CHAIN138_X402_TOKEN_SUPPORT.md.
*/
import "dotenv/config";
import express from "express";
import { createThirdwebClient, defineChain } from "thirdweb";
import { facilitator, settlePayment } from "thirdweb/x402";
import { arbitrumSepolia } from "thirdweb/chains";
const app = express();
app.use(express.json());
const PORT = process.env.PORT || 4020;
const secretKey = process.env.THIRDWEB_SECRET_KEY;
const serverWalletAddress = process.env.SERVER_WALLET_ADDRESS;
const useChain138 = process.env.X402_USE_CHAIN_138 === "true";
const rpcUrl138 = process.env.RPC_URL_138 || "https://rpc-http-pub.d-bis.org";
/** Custom Chain 138 for thirdweb (DeFi Oracle Meta Mainnet) */
const chain138 = defineChain({
id: 138,
name: "DeFi Oracle Meta Mainnet",
rpc: rpcUrl138,
nativeCurrency: {
name: "Ether",
symbol: "ETH",
decimals: 18,
},
});
const client = secretKey
? createThirdwebClient({ secretKey })
: null;
const thirdwebFacilitator =
client && serverWalletAddress
? facilitator({
client,
serverWalletAddress,
})
: null;
/** Resolve network: Chain 138 if enabled and token supports permit, else Arbitrum Sepolia for USDC. */
function getNetwork() {
if (useChain138 && thirdwebFacilitator) {
return chain138;
}
return arbitrumSepolia;
}
/** Price: USD string (default USDC on chain) or token object for Chain 138 when permit is available. */
function getPrice() {
if (useChain138) {
// When a Chain 138 token has permit, use e.g. cUSDC: 0xf22258f57794CC8E06237084b353Ab30fFfa640b, 6 decimals
const cusdc138 = "0xf22258f57794CC8E06237084b353Ab30fFfa640b";
return {
amount: "10000",
asset: { address: cusdc138, decimals: 6 },
};
}
return "$0.01";
}
/** Shared handler for paid routes (PAYMENT-SIGNATURE or X-PAYMENT header). */
async function handlePaidRoute(req, res) {
const paymentData =
req.headers["payment-signature"] ||
req.headers["PAYMENT-SIGNATURE"] ||
req.headers["x-payment"] ||
req.headers["X-PAYMENT"];
if (!thirdwebFacilitator || !serverWalletAddress) {
return res.status(503).json({
error: "x402 not configured",
hint: "Set THIRDWEB_SECRET_KEY and SERVER_WALLET_ADDRESS in .env",
});
}
const resourceUrl =
(req.protocol + "://" + req.get("host") + req.originalUrl) || "";
const method = req.method;
const result = await settlePayment({
resourceUrl,
method,
paymentData: paymentData || undefined,
payTo: serverWalletAddress,
network: getNetwork(),
price: getPrice(),
facilitator: thirdwebFacilitator,
routeConfig: {
description: "Access to paid API content",
mimeType: "application/json",
maxTimeoutSeconds: 60 * 60,
},
});
if (result.status === 200) {
return res.json({
data: "paid content",
message: "Payment settled successfully",
});
}
res
.status(result.status)
.set(result.responseHeaders || {})
.json(result.responseBody ?? { error: "Payment required" });
}
/** Protected routes: require x402 payment (PAYMENT-SIGNATURE or X-PAYMENT header). */
app.get("/api/premium", handlePaidRoute);
app.get("/api/paid", handlePaidRoute);
/** Health: no payment required. */
app.get("/health", (req, res) => {
res.json({
ok: true,
x402: !!thirdwebFacilitator,
chain: useChain138 ? "chain138" : "arbitrumSepolia",
});
});
app.listen(PORT, () => {
console.log(`x402-api listening on port ${PORT}`);
if (!thirdwebFacilitator) {
console.warn("THIRDWEB_SECRET_KEY or SERVER_WALLET_ADDRESS not set; /api/premium will return 503.");
} else {
console.log(`Payment chain: ${useChain138 ? "Chain 138" : "Arbitrum Sepolia (default USDC)"}`);
}
});