Skip to content

Instantly share code, notes, and snippets.

@ryangoree
Last active February 23, 2025 23:49
Show Gist options
  • Save ryangoree/94d0bd54508974a7b311a916d5101ccf to your computer and use it in GitHub Desktop.
Save ryangoree/94d0bd54508974a7b311a916d5101ccf to your computer and use it in GitHub Desktop.
Reverse proxy for monitoring RPC requests to a local anvil server
import { createWriteStream, writeFileSync } from 'node:fs';
import { createServer, request } from 'node:http';
// Settings //
const TARGET_HOST = '127.0.0.1';
const TARGET_PORT = 8545;
const PROXY_PORT = 8546;
// Server //
const server = createServer((req, res) => {
let body = '';
req.on('data', (chunk) => (body += chunk));
req.on('end', async () => {
// Log the request
log('RPC Request:', JSON.parse(body));
// Forward the request to Anvil
const proxyReq = request(
{
hostname: TARGET_HOST,
port: TARGET_PORT,
path: req.url,
method: req.method,
headers: req.headers,
},
(proxyRes) => {
// Log the response
let body = '';
proxyRes.on('data', (chunk) => (body += chunk));
proxyRes.on('end', () => log('RPC Response:', JSON.parse(body)));
// Send response back to client
res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);
proxyRes.pipe(res);
}
);
proxyReq.on('error', (err) => {
log('Proxy Error:', err);
res.writeHead(500);
res.end('Proxy error');
});
proxyReq.write(body);
proxyReq.end();
});
});
// Start server
server.listen(PROXY_PORT, () =>
console.log(
`Proxy server running at: ${`http://127.0.0.1:${PROXY_PORT}`}`
)
);
// Logger //
const timestamp = new Date().toISOString();
const logFileName = `requests-${timestamp}.log`;
// Reset log file
writeFileSync(logFileName, '');
// Create a write stream to log file
const logStream = createWriteStream(logFileName, {
flags: 'a', // Append mode
});
// Log to the log file and console
function log(...args: any[]) {
const timestamp = new Date().toISOString();
const message = formatArgs(...args);
const logLine = `[${timestamp}] ${message}\n`;
logStream.write(logLine);
console.log(logLine);
}
function formatArgs(...args: any[]) {
return args.map(formatArg).join(' ');
}
function formatArg(arg: any) {
if (typeof arg === 'object') {
return JSON.stringify(arg, bigintReplacer, 2);
}
return arg;
}
function bigintReplacer(_: string, value: any) {
if (typeof value === 'bigint') {
return value.toString();
}
return value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment