passnode
v1.0.2
Published
PassNode: Core NPM package for Web3 wallet-based access control middleware for Node.js APIs. Enable monetization, usage credits, and temporary passes for microservices. #Web3Middleware #NodejsAPI #AccessControl #BlockchainMonetization
Readme
PassNode — Wallet-Aware Middleware for Node.js
npm package:
passnode
PassNode is a lightweight middleware that lets you gate Express/Fastify endpoints using Web3 wallets. Pair it with a simple JSON rules file to sell usage credits, time-based passes, or direct pay-per-call access in minutes.
- 🔒 Wallet-native auth – verify requests with ECDSA signatures (MetaMask, Rainbow, etc.).
- ⚙️ Config-driven plans – manage pricing and access in
passnode.rules.jsongenerated by the PassNode builder. - 🧱 Drop-in middleware – wrap any route without restructuring your service.
- 🔁 Upgradeable – keep everything off-chain or plug in
passnode-onchainfor tamper-proof settlement.
Installation
npm install passnode
# or
yarn add passnodeRequires Node.js 18+.
Quick Start
Generate a rules file by running the client server and opening the builder:
cd client-server npm install npm run build npm startVisit
http://localhost:4300/builder, configure plans, then downloadpassnode.rules.json.Add the middleware to your API:
const { createPassNode } = require('passnode'); const gate = createPassNode({ rulesPath: './passnode.rules.json', statePath: './passnode.state.json', planType: 'usage' }); app.post('/generate-report', gate, (req, res) => { res.json({ ok: true, wallet: req.passnode.wallet }); });On the frontend, request a signature and send it with the request:
const nonce = `PassNode access ${Date.now()}`; const signature = await signer.signMessage(nonce); await fetch('/generate-report', { method: 'POST', headers: { 'x-wallet-address': walletAddress, 'x-wallet-signature': signature, 'x-wallet-nonce': nonce } });
PassNode validates the signature, checks the appropriate plan, and raises 401/402 responses when balances run out.
Plan Types
Declare the enforcement strategy per route:
usage– decrements credits from the rules entry.pass– validates active passes and expiry windows.pay-per-use– charges a per-request amount immediately.
You can override planType when creating the middleware or when decorating individual routes: createPassNode({ planType: 'usage' }), app.get('/download', gate.withPlan('pay-per-use'), handler).
Custom State Storage
By default PassNode persists balances to passnode.state.json. Bring your own storage by implementing:
const gate = createPassNode({
rulesPath: './passnode.rules.json',
planType: 'usage',
stateAdapter: {
async load() {
return redis.get('passnode:state');
},
async save(state) {
await redis.set('passnode:state', JSON.stringify(state));
}
}
});Error Handling
Catch PassNode errors with your normal Express error middleware:
app.use((err, _req, res, next) => {
if (err?.isPassNodeError) {
return res.status(err.statusCode).json({ error: err.message, detail: err.detail });
}
return next(err);
});Upgrading to PassNode Chain
Need tamper-proof settlement and shared revenue? Install passnode-onchain alongside this package:
npm install passnode passnode-onchainThen create a chain adapter and pass it into the middleware:
const { createPassNode } = require('passnode');
const { createPassNodeChain } = require('passnode-onchain');
const chain = createPassNodeChain({
rpcUrl: process.env.RPC_URL,
signerKey: process.env.SERVICE_SIGNER_KEY,
network: 'sepolia',
contracts: {
ledger: process.env.LEDGER_ADDRESS
}
});
const gate = createPassNode({
rulesPath: './passnode.rules.json',
planType: 'usage',
chain
});See passnode-chain for deployment and settlement details.
Example Apps
Clone and run the client server to inspect practical examples under /examples (e.g. Express starter, Next.js starter). Each boilerplate can be downloaded as a zip to bootstrap your own project.
Documentation & Support
- Getting Started Guide
- PassNode Standard Deep Dive
- Frontend Integration Tips
- Open an issue if you need help or want to request features.
PassNode is maintained by Leumas Tech. Contributions, feedback, and coffee donations are welcome — see the /coffee page in the client server for MetaMask-powered support.
