Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save 0xCardinalError/3f2ab21612c10c038cdc127d242ced08 to your computer and use it in GitHub Desktop.
Save 0xCardinalError/3f2ab21612c10c038cdc127d242ced08 to your computer and use it in GitHub Desktop.
Swarm endpoint server
const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
const {
keccak256,
encodeAbiParameters,
parseAbiParameters,
getAddress,
createPublicClient,
http,
verifyMessage,
} = require("viem");
const { gnosis } = require("viem/chains");
const POSTAGE_STAMP_ABI = [
{
name: "batchOwner",
type: "function",
stateMutability: "view",
inputs: [{ type: "bytes32", name: "batchId" }],
outputs: [{ type: "address" }],
},
];
const POSTAGE_STAMP_ADDRESS = "0x45a1502382541Cd610CC9068e88727426b696293";
const app = express();
app.options("*", (req, res) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
res.header("Access-Control-Allow-Headers", "*");
res.sendStatus(200);
});
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
next();
});
const gnosisPublicClient = createPublicClient({
chain: gnosis,
transport: http(),
});
const verifySignature = async (req, res, next) => {
if (req.path === "/bzz") {
const signature = req.headers["x-upload-signature"];
const uploaderAddress = req.headers["x-uploader-address"];
const fileName = req.headers["x-file-name"];
const batchId = req.headers["swarm-postage-batch-id"];
if (!signature || !uploaderAddress || !fileName || !batchId) {
return res.status(401).json({
error: "Missing required headers",
missing: { signature, uploaderAddress, fileName, batchId },
});
}
try {
const messageHash = keccak256(
encodeAbiParameters(parseAbiParameters(["string", "bytes32"]), [
fileName,
`0x${batchId}`,
])
);
const recoveredAddress = await gnosisPublicClient.verifyMessage({
address: uploaderAddress,
message: { raw: messageHash },
signature,
});
if (!recoveredAddress) {
return res.status(401).json({
error: "Invalid signature",
recovered: recoveredAddress,
provided: uploaderAddress,
});
}
next();
} catch (error) {
console.error("\x1b[31m%s\x1b[0m", "Verification Error:", error);
return res.status(401).json({
error: "Verification failed",
details: error.message,
stack: error.stack,
});
}
} else {
next();
}
};
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
console.log("Headers:", JSON.stringify(req.headers, null, 2));
next();
});
const proxy = createProxyMiddleware({
target: "http://localhost:1633",
changeOrigin: true,
pathRewrite: null,
secure: false,
});
app.use("/", verifySignature, proxy);
app.listen(3333, () => console.log("Proxy server running on port 3333"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment