ByAUJay
Summary: This is your ultimate guide for launching Web3-native APIs that real businesses can actually put to use. We're diving into reliable wallet authentication techniques like SIWE, account abstraction passkeys, and session keys. You’ll also get some handy tips on implementing rate limits to fend off those pesky bot attacks and manage RPC constraints. And let’s not overlook on-chain payments for subscriptions, streaming, and genuine pay-per-call options using stablecoins.
Creating API for Web3: Authentication, Rate Limits, and Onchain Payments
Decision-makers are excited to tap into the benefits of Web3 but want to avoid the headaches that come with it. In this post, we’ll walk you through what we do at 7Block Labs to help our clients develop APIs that are used by wallets, agents, or dapps. We’ll explore ways to authenticate users without relying on passwords, share some handy tips for fair rate-limiting (so you don’t eat up your RPC quotas), and discuss options for on-chain charging--whether you're looking at recurring payments, streaming fees, or charges per call.
Check out this handy collection of solid patterns, specific headers, message formats, and the latest best practices. You’ll also find some integration notes that you can easily drop into a spec or PR.
1) Authentication that fits Web3 (and Web2 SSO)
There are three solid ways to figure out “who” is calling your API:
- SIWE (Sign-In with Ethereum) makes it super easy to start off-chain sessions--just sign in with your wallet.
- Account Abstraction (AA, ERC-4337) simplifies the whole process with passkeys, so you can onboard without stressing over gas fees.
- Plus, there's an optional OIDC bridge that allows you to link wallets to enterprise SSO for a smooth integration experience.
1.1 SIWE: the baseline that works everywhere
SIWE is a straightforward, user-friendly message that individuals sign, and then your server verifies that signature to kick off a session (kind of like a cookie or JWT). The spec lists some essential fields you need to include, like domain, chainId, nonce, and issuedAt. Be sure that your nonce is at least 8 alphanumeric characters long, and it’s a good idea to link the session to both the domain and the chainId to help guard against replay attacks. And hey, don’t forget to include expirationTime for those short-lived assertions. If you want to dive deeper, check out the EIP documentation.
Key Server Rules You Should Enforce Right Away:
- No Spam: Let’s keep our discussions on point. Please steer clear of unwanted promotions or annoying spammy links that just end up cluttering our chats.
- Respect Privacy: It's super important to always keep everyone’s privacy in mind. Sharing someone’s personal info without their okay? Definitely not cool.
- Stay on Topic: Let’s try to keep our chats centered around what the server is all about. If you've got something different in mind, feel free to slide into DMs or hop over to another channel.
- Be Kind and Respectful: Kindness really matters. Always treat others with respect, even when you have differing opinions. Let’s keep things positive--harassment or hate speech won’t fly here.
- No NSFW Content: Let's keep things family-friendly! We want everyone to feel at home, so please avoid any adult content.
- Follow Discord's Guidelines: Just play nice and make sure you're sticking to Discord’s Community Guidelines. It’s a good idea to get to know them so you don’t accidentally trip up!
- Use Appropriate Channels: Every channel serves a specific purpose, so it's important to share your posts in the right place. Doing this helps keep everything organized and makes it easier for everyone to follow along.
- Report Issues: If you notice anything suspicious or out of the ordinary, please let us know! We’re all part of this community, and your feedback is super important for keeping things safe and sound.
Let’s turn our server into a friendly and fun space for everyone!
- First things first, make sure you check both EOA signatures and contract-account signatures with ERC‑1271. This way, smart contract wallets can join in on the signing action too. (eips.ethereum.org)
- Next up, make sure to align the SIWE “domain” with your HTTPS origin. It’s super crucial to reject any sneaky cross-origin tricks, just like the spec recommends. (eips.ethereum.org)
- And hey, don’t forget to use EIP‑712 hashing libraries whenever you can; they really help make sure that structured data gets signed the right way. (eips.ethereum.org)
Minimal Backend Flow (TypeScript with spruceid/siwe)
Quick Guide to Setting Up a Simple Backend Flow with TypeScript and spruceid/siwe
If you're looking to set up a straightforward backend flow using TypeScript along with spruceid/siwe, you're in the right place! Below, I’ve outlined a step-by-step guide to help you kick things off.
Prerequisites
Before diving in, make sure you have the following:
- Node.js (v12 or later)
- A package manager like npm or yarn
- Basic understanding of TypeScript and JavaScript
Step 1: Create a New Project
Let’s create a new folder for your project and initialize it:
mkdir my-siwe-backend
cd my-siwe-backend
npm init -y
Or, if you're using yarn:
mkdir my-siwe-backend
cd my-siwe-backend
yarn init -y
Step 2: Install Dependencies
Now, let’s grab the necessary packages. You’ll want to install TypeScript and the spruceid/siwe library:
npm install typescript @spruceid/siwe
Using yarn? Just run:
yarn add typescript @spruceid/siwe
Step 3: Set Up TypeScript
Next, set up TypeScript in your project by creating a tsconfig.json file. You can do this manually or by running:
npx tsc --init
Make sure to customize the tsconfig.json if needed. A basic config could look like this:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true
}
}
Step 4: Create Your Backend Logic
Now it’s time to write some actual code! Create a new file called index.ts:
import { SiweMessage } from '@spruceid/siwe';
const message = new SiweMessage({
domain: 'example.com',
address: '0xYourEthereumAddressHere',
statement: 'Sign in to access your account',
uri: 'http://localhost:3000',
version: '1',
chainId: 1,
nonce: 'random-nonce-value'
});
// You can now use `message` as needed
Step 5: Run Your Project
To compile and run your TypeScript code, just use the following commands:
npx tsc
node dist/index.js
Make sure your code is running smoothly!
Wrapping Up
And that’s it! You’ve set up a simple backend flow using TypeScript and spruceid/siwe. From here, you can expand your project with additional features and functionality as needed. Happy coding!
Step 1: Install Dependencies
To kick things off, you’ll need to install a few essential packages. Just run the following command:
npm install spruceid/siwe
Step 2: Create the Server
Next, let’s create a simple server. Express is a great choice for this. Here’s a quick example of a minimal setup:
import express from 'express';
import { SiweMessage } from 'siwe';
const app = express();
const PORT = process.env.PORT || 3000;
app.use(express.json());
app.post('/api/auth', async (req, res) => {
const { message, signature } = req.body;
const siweMessage = new SiweMessage(message);
try {
const validates = await siweMessage.verify(signature);
if (validates) {
// Handle successful authentication logic here
res.status(200).send('Authentication successful!');
} else {
res.status(401).send('Authentication failed.');
}
} catch (error) {
console.error(error);
res.status(500).send('Internal server error');
}
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Step 3: Testing the Endpoint
You can easily test out your new authentication endpoint using a tool like Postman or curl. Here’s a sample request you can try:
POST /api/auth
Content-Type: application/json
{
"message": "Your SIWE message goes here",
"signature": "Your SIWE signature goes here"
}
Step 4: Final Thoughts
And that’s a wrap! You’ve successfully created a minimal backend using TypeScript and spruceid/siwe. You can totally build on this solid foundation by adding more routes or even pulling in a database if you want. Happy coding!
import { SiweMessage } from 'siwe';
import { verifyTypedDataSig, verifyERC1271 } from './sig-helpers'; // your helpers
export async function siweLogin(req, res) {
const { message, signature } = req.body;
const siwe = new SiweMessage(message);
// 1) Basic spec checks
siwe.validate(message); // throws if malformed (version, chainId, etc.)
// 2) Signature: try EOA, then ERC-1271
const addr = siwe.address.toLowerCase();
const okEOA = await verifyTypedDataSig(addr, siwe.prepareMessage(), signature);
const ok1271 = okEOA ? true : await verifyERC1271(addr, siwe.prepareMessage(), signature);
if (!ok1271) return res.status(401).end();
// 3) Nonce & replay checks
await assertFreshNonce(req.sessionId, siwe.nonce);
// 4) Bind to domain+chain
if (siwe.domain !== new URL(process.env.PUBLIC_ORIGIN).host) return res.status(400).end();
// 5) Create session/JWT with address and plan entitlements
const token = await issueJwt({ sub: addr, chainId: siwe.chainId, plan: 'pro' });
res.json({ token });
}
Take a look at these useful libraries and documentation that might come in handy: the SIWE spec, EIP‑712, ERC‑1271, and Spruce’s implementations. You can dig deeper into the details at (eips.ethereum.org).
Advanced: SIWE over OIDC
If you’re thinking about getting Single Sign-On (SSO) going for your current SaaS or enterprise systems, you should definitely check out Spruce’s SIWE OIDC provider. You can set it up either as a standalone solution or run it as a Cloudflare Worker. Once that's done, you can easily federate using the standard OIDC flows, just like you would with Auth0, Okta, and other similar services. For all the nitty-gritty details, swing by the docs.login.xyz.
1.2 AA wallets, passkeys, and session keys
Understanding AA (ERC-4337) for Passkey-Based Onboarding
With AA (ERC-4337), you can create a smooth onboarding experience without the hassle of seeds or clunky passkeys. This sets the stage for easy passkey registration and gives users a gasless experience. Forget the usual transactions--you’ll be dealing with “UserOperation” objects and “paymasters” that can take care of those pesky gas fees. When thinking about APIs, here are a few important points to consider:
- Simplified User Experience:
With passkeys, users can get started without the hassle of memorizing complicated seeds or keys. It really streamlines the whole process, making it easy for everyone to dive in. - Cost Management:
With the introduction of paymasters, developers can now handle gas costs more efficiently. This means users won’t have to stress about gas fees right from the get-go, making it easier for everyone to jump in.
These changes really shake up how we view onboarding and user interactions in the blockchain world!
- Onboarding people who are new to crypto is a breeze with passkeys (WebAuthn), and you can conveniently link their sessions to a wallet address.
- You can also mint or validate “session keys” that come with specific scopes and time-to-live (TTLs). This is super handy for those frequent API calls from untrusted clients like mobile apps, browsers, or agents. Check it out here: (eips.ethereum.org)
Vendor Reality in 2025:
Looking toward 2025, it's clear that the vendor scene is going to change in some pretty significant ways compared to what we're used to now. Here’s what you can anticipate:
Increased Competition
As more players jump into the market, vendors are going to have to deal with tougher competition than ever. It's going to be super important to find ways to stand out and grab the attention of customers.
Emphasis on Sustainability
Sustainability isn't just a passing fad; it's rapidly turning into a must-have. Vendors are going to have to embrace eco-friendly practices and provide greener products if they want to keep up with what consumers expect.
Tech Integration
Technology is set to take an even bigger stage, with vendors tapping into AI, IoT, and blockchain to smooth out operations and really amp up customer experiences.
Changing Consumer Preferences
Consumers are on the hunt for more personalized experiences these days. This means vendors will really need to step up their game and adapt to what customers want, using data insights to customize their products and services.
Global Supply Chains
Global supply chains are going to stay complex and might run into some challenges ahead. Vendors will have to be flexible and prepared to adapt to changing market conditions.
Collaboration Over Competition
In 2025, we might start seeing a real change in how vendors work together. By teaming up, they can combine their resources, share what they know, and face common challenges as a united front.
Conclusion
To wrap it up, vendors in 2025 will need to be flexible, creative, and really pay attention to sustainability. The ones who can roll with the punches and embrace change will be the most likely to succeed in a market that's constantly shifting.
- Coinbase Smart Wallet: This wallet offers some seriously cool features, including passkeys, support for ERC‑4337, and a paymaster to ease those pesky gas fees. It’s definitely worth a look! Check it out here.
- ZeroDev and similar SDKs: These handy tools allow you to generate short-lived session keys tailored for specific contract methods or API actions. If you want to dive deeper, check out this link.
Tip: When you're checking signatures on your API, remember to back both EOA (using ecrecover) and 1271 for those contract wallets in the signature field of your requests. Oh, and there's some cool stuff happening with ERC‑4337 that focuses on signature aggregation (take a peek at ERC‑7766), which could really help save money as you grow. (eips.ethereum.org)
2) Rate limits that actually work for wallets, bots, and RPC ceilings
Classical IP-based throttling falls flat when you've got tons of users chilling behind a shared gateway or if you're facing a botnet situation. What's really effective are those layered rate limits:
- Edge limits: Keep your origin safe and deal with any heavy-duty traffic right off the bat.
- Identity limits: These are applied for each wallet address, every SIWE session, and according to your NFT plan.
- Upstream limits: Don't forget to stick to the limits established by your RPC provider.
2.1 Standardize your limit headers and 429s
Return 429 Too Many Requests with Retry-After
When you find yourself reaching those request limits, it’s important to respond with a 429 status code. This way, users will understand they need to take a breather. And don’t skip the Retry-After header--it lets them know when it’s okay to try again.
To make everything run smoothly and keep it user-friendly, we recommend checking out the new IETF “RateLimit” fields. These will help SDKs automatically tweak and control requests as needed. Here’s what we think you should do:
- When things are running without a hitch, you’ll notice:
RateLimit-Policy,RateLimit(or if you're using the older setup, keep an eye out forRateLimit-Limit,RateLimit-Remaining,RateLimit-Reset). - If you find yourself running into a speed limit, be sure to check for
Retry-After(in seconds). (developer.mozilla.org)
Sure! Please share the text you want me to rewrite, and I'll take care of it for you.
HTTP/1.1 200 OK
RateLimit-Policy: "burst";q=120;w=60, "day";q=100000;w=86400
RateLimit: "burst";r=40;t=18, "day";r=82950;t=43200
These headers show you how much of your remaining quota (r) is left and when it resets (t) for each policy window, so you won't have to guess anymore. Platforms like Cloudflare are catching up with these trends, and you'll see them pop up pretty frequently in the drafts. (developers.cloudflare.com)
2.2 Identity‑aware limits
Choose at least one stable key:
- SIWE address (this one’s usually the go-to option).
- Contract account address (1271) for teams or organizations.
- Token/NFT gate: Consider using a subscription NFT (ERC‑5643) or something like an Unlock membership; you can tailor different per-minute quotas for various tiers. (eips.ethereum.org)
Practical: Rather than relying on just the IP, try storing your counters with the key format address:window. Don’t forget to include the address and plan in your JWT. This way, edge workers can enforce the rules without needing to ping the database for every single request!
2.3 Don’t shock your RPC providers
Your API's reliability really depends on your upstream Web3 setup--like services such as Infura, Cloudflare, Alchemy, and others. These providers come with some pretty strict limits on throughput and daily credits. Check out these examples:
- Infura’s “Core/Free” plan has some daily credit caps and limits on the number of requests you can send each second. If you exceed those limits, you’ll be greeted with 402/429 errors, and your WebSockets might get disconnected until the limits reset. For more details, you can check out the info here.
- When using the Cloudflare Ethereum Gateway, each plan has its own request quotas, so it’s a good idea to keep those in mind while you’re working with the gateway. You can find more info here.
- Alchemy recommends trying to keep your requests under 100 KB and responses around ~10 MB. And don’t forget about the batch limits--like the cap of 20 requests you can throw in a single WebSocket batch. If you want to dig deeper into their suggestions, head over here.
Mitigations We Ship by Default:
- Content Security Policy (CSP): This is a handy tool that helps keep your site safe from cross-site scripting attacks. It does so by specifying which resources are allowed to load on your website.
- HttpOnly and Secure Cookies: These cookie flags are your allies in protecting against cross-site scripting and man-in-the-middle attacks.
- SameSite Cookie Attribute: This cool feature limits how cookies are shared during cross-site requests, which boosts web security.
- Strict Transport Security (HSTS): This is a web security policy that plays a crucial role in safeguarding websites from man-in-the-middle attacks. It does this by enforcing the use of HTTPS, ensuring that all communications between the browser and the site are secure.
- X-Content-Type-Options: This setting helps keep your site safe by stopping browsers from guessing a file's MIME type. It ensures that files are only treated as the type you say they are, which lowers the chances of attacks.
- X-Frame-Options: This header helps keep your site safe from clickjacking by managing whether it can be displayed inside a frame.
- X-XSS-Protection: This header helps prevent pages from loading if they catch wind of any reflected cross-site scripting attacks.
- Referrer-Policy: This setting gives you the power to decide how much referrer info is shared when users head from your site to other sites.
- Feature-Policy (now Permissions-Policy): This handy tool helps you manage which browser features can be accessed, giving your applications an extra boost of security.
By including these mitigations by default, we're ensuring that your experience is not just seamless but also safe right from the start!
- Cache those popular JSON-RPC responses--like the latest block and ERC-20 metadata--right at the edge. If you’ve got high-fan-out subscriptions, WebSockets are the way to go. Use HTTP when you need to deal with bursty reads.
- When you bump into a 429 error or notice any
RateLimit*headers from upstream, implement a token-bucket with a jittered backoff strategy. - Keep concurrency limits in check for each tenant to steer clear of those annoying “thundering herds” that can pop up after resets.
3) Onchain payments: recurring, streaming, and true pay‑per‑call
In the Web2 scene, it’s super easy to just say, “Pay me for this API call”--you can pull out your card and toss a couple of cents at it. But when you switch to on-chain transactions, there are a few important things to keep in mind: you want stability (like using USDC), a smooth user experience (think low fees), and the ability to verify what’s been settled (those handy receipts come in clutch). So, let’s take a closer look at what’s really working in the space right now.
3.1 Accept stablecoins with enterprise rails
- Stripe: Exciting news! The “Pay with Crypto” option now lets you use USDC across platforms like Base, Ethereum, Solana, and Polygon. The coolest part? It settles right into your Stripe balance as fiat with a simple 1.5% fee. Plus, they’re rolling out subscriptions using stablecoins (currently in private preview) that leverage a wallet-save smart contract. This means you won’t have to worry about those annoying re-prompts every billing cycle. It’s a fast and easy way to bring on-chain capabilities into your operations without the hassle of managing new treasury tasks. Get all the details here.
- Coinbase Onchain Payment Protocol (Commerce): In 2024, merchants hopped on board with a fresh protocol that instantly settles payments in USDC--or USD if you're a managed merchant. It plays nice with budget-friendly Layer 2 options like Base, too! Plus, you'll get user-friendly webhooks and on-chain receipts with the APIs. If you’re curious to dive deeper, check out this link.
If you're mainly dealing with the US and don't mind shelling out a little extra for processing fees, both Stripe and Coinbase have some great tools to help you manage disputes, process refunds, and keep everything organized with their dashboards. But if you want to stick strictly with on-chain solutions, take a look at the setups below.
3.2 Onchain recurring subscriptions (two robust patterns)
- Subscription NFTs (ERC‑5643): This nifty feature lets you mint an NFT that will expire after a designated time. On the backend, just check access with the condition
expiresAt(tokenId) > now. It’s a handy way to standardize how we deal with renewals, cancellations, and expirations. Interestingly, ENS seems to do something similar in their operations. And the best part? You can set up renewals to happen automatically, either through your agents or even directly by users themselves. (ercs.ethereum.org)
Unlock Protocol Memberships
So, let’s dive into Unlock Protocol memberships! You basically create a “Lock,” which is like an ERC‑721 membership card that comes with an expiration date and the option to renew it whenever you want. The auto-renewal process is super easy and works through ERC‑20 approvals. Plus, if you prefer, you can even make recurring payments in fiat to keep your keys alive on-chain.
You’ve got some cool options here: tweak the duration, set prices in USDC, and even burn time for transfers as part of your secondary market strategy. Want to dig deeper? Check out more details here: (docs.unlock-protocol.com)
When to Choose Which:
Making decisions can be tough, especially when you're juggling a million things at once. Here’s a handy guide to help you sift through options and find the best path forward in various situations.
1. Time Sensitivity
- When you're in a hurry, it’s best to grab those quick solutions. They might not be flawless, but hey, they help you get things done.
- On the other hand, if you've got some time to spare, consider stepping back and exploring your choices. Taking a thoughtful approach can really pay off in the long run.
2. Resources Available
- If you've got a lot of resources at your fingertips, that's fantastic! You can dive into more complex options and maybe even take some calculated risks.
- But if resources are looking a bit slim, it’s probably smarter to keep things simple and stick to the basics.
3. Risk Tolerance
- If you're up for an adventure, go ahead and grab those high-risk, high-reward opportunities.
- If you'd rather take it easy, stick with choices that keep the risks to a minimum.
4. Personal Impact
- Think about how a decision affects you on a personal level. If it's something that really matters to you, it’s worth putting in the time and effort to find the best option out there.
- But if it’s not that big of a deal, going with a decent choice might be all you need.
5. Long-Term vs. Short-Term Goals
- When you're thinking about your long-term goals, it's super important to really take your time and make thoughtful decisions that connect with your overall vision.
- On the flip side, for those urgent needs, going for quick fixes is totally okay!
6. Advice from Others
- You know, getting a second opinion can really make a difference! Don’t hesitate to reach out to friends, family, or mentors to see what they think.
- And hey, don’t forget to listen to your gut; it usually has a good sense of what you truly want.
Conclusion
Every situation is one-of-a-kind, so think of these tips as friendly advice instead of strict rules. Consider your options carefully and go with what feels best for you!
- If you're on the hunt for a reliable subscription model packed with some fantastic tools and a user-friendly dashboard, you should definitely check out Unlock.
- Want a stylish and lightweight ERC‑721 interface that you can control entirely? Try out ERC‑5643!
3.3 Streaming (per‑second) payments that double as entitlements
Streams let you keep charging as value flows in. If the stream dips to zero, you can automatically reduce or completely halt your API calls.
- Superfluid: This awesome platform keeps your token flows going without a hitch thanks to something called “Super Tokens.” You can easily use
getNetFlowRateto see if your payment is currently active. It’s a great fit for usage-based pricing, like charging “$0.001/sec while the job’s running.” If you want to dive deeper, check out the Superfluid docs. - Sablier: This platform comes with some solid lockup and flow features. Each stream functions as an ERC‑721, making it usable as collateral, and it provides various curve options, such as linear and cliffs. You can think of an active stream NFT like a “paid seat.” For more details, swing by Sablier's site!
Implementation note: Make sure to manage on-chain verification (flow > 0) on the server side. It’s a good idea to cache the results for around 30-60 seconds. Don’t stress too much about some temporary lapses; it's better to prevent flapping.
3.4 Real pay‑per‑call with USDC and signatures (no user gas)
If you're aiming for that exact rate of “$0.001 per API hit” but don't want your users to deal with submitting a transaction every time they make a call, here’s a helpful solution:
- EIP-3009, or as it's sometimes called, “TransferWithAuthorization/ReceiveWithAuthorization,” is a pretty nifty feature that lets users sign off-chain EIP-712 authorizations for USDC. What’s great about this is that your server or relayer can handle just one on-chain transaction to pull USDC using the user’s signature. You can even bundle multiple authorizations into a single batch, which can help you save on gas fees. For an extra layer of security and to dodge front-running issues, it’s a smart move to use
receiveWithAuthorization. Want to dive deeper? Check it out here: (eips.ethereum.org)
Concrete Shape of a Per-Call Flow:
When we dive into the per-call flow, it's really useful to picture how everything connects. Here’s a quick overview of what that looks like:
- Initiation: The call starts when someone dials a number. And this is where the fun really gets rolling!
- Signal Processing: The system kicks in and gets to work on the signals. It makes sure everything's in place for the call to connect without a hitch.
- Call Setup: This part is where you get everything ready for the call. You can think of it like picking the ideal spot for two people to have a good conversation.
- Call Maintenance: The call is in full swing now! In this stage, we're keeping the connection alive and making any necessary tweaks to ensure everything runs smoothly.
- Call Termination: When it's time to wrap up the chat, we move into the termination phase. Here, we tie up any loose ends, ensuring that the call is properly closed and all the relevant data is taken care of.
And that’s the general flow of a per-call process! Every single step plays an important role in ensuring that conversations flow smoothly.
- The client kicks things off by sending a quick EIP-3009 authorization in the API request body, which includes how much USDC is involved in this call.
- The server takes a moment to check the signature and then queues up the authorization.
- Once we hit either the batch size or the time limit (like when we get 200 calls or 30 seconds roll by), the server goes ahead and sends out a transaction using
receiveWithAuthorizationfor each item. - If the on-chain settlement goes through without a hitch, we mark those calls as paid; if something goes wrong, we’ll hit them back with a 402 Payment Required.
Caveats: Don’t forget to check for chain coverage! There have been some hiccups with Polygon's bridged USDC, especially around the 3009 support, so be sure to double-check those token contract features. Also, keep in mind that Circle has recommended some 1271-compatible extensions for contract wallets. You can find more details here.
3.5 Using “permit” for prepaid credits
If you’re into prepaid balances:
- Issue “API Credits” as an ERC‑20 token. Users can easily grant permission to your billing contract using the EIP‑2612 permit, which lets them skip gas fees for approvals. With each API receipt, your contract will burn credits. This method is simple, easy to track, and keeps everything transparent on the blockchain. Take a look at the details here: (eips.ethereum.org)
3.6 Attested entitlements (tamper‑evident off‑chain)
Store your metering info off-chain, but when it’s time to attest things like your plan, limits, or settled usage, make sure to keep it on-chain using the EAS (Ethereum Attestation Service). Here’s a quick schema to keep in mind: “plan:pro, rpm:600, expires:timestamp.” Your API is designed to trust your signer, so your customers can easily check the attestation on EAS Scan. It’s neat, portable, and works across various chains. Take a look here: (attest.org).
4) Reference architecture: glue it together
Take a look at these three solid blueprints you can choose from or even mix and match!
4.1 SIWE + JWT + Stripe/Coinbase subscriptions (fastest enterprise path)
- Auth: We're rolling with SIWE for login. Just a quick heads-up, though--there are a few server hiccups with the JWT tied to the address and chainId. We make sure to keep the address saved in the tenant record.
- Limits: Every address gets its own little token bucket right at the edge. We’ll be sharing
RateLimit*headers, and if things start to get crazy, we’ll kick back a 429 status along with a Retry-After header. - Payments: You’ve got a choice! Go with either Stripe’s “Pay with Crypto” or Coinbase Commerce for your payments. We’ve set up webhooks to keep track of entitlements in the database. Plus, if you’re into it, we can mint an EAS attestation for some extra auditability. Want more info? Check it out here: (docs.stripe.com)
Why:
- Operations that suit enterprises
- Limited exposure for smart contracts
- Fast setup time
4.2 Unlock membership or ERC‑5643 subscription (pure onchain access)
- Auth: With SIWE, your edge worker can check whether the calling address holds a valid membership NFT (Unlock) or an ERC‑5643 token that’s still active (
expiresAt > now) for every request. - Limits: You can set up SKU tiers (like Starter or Pro) linked to the token ID or lock address, and edge rates will be associated with each address.
- Payments: It’s all on-chain! Users can easily renew their memberships right from their wallets, and your API will reflect any changes after just a 1-block delay. For more info, take a look here: (docs.unlock-protocol.com)
Why This Matters
- No Web2 Processor: We're ditching the old-school web models.
- Global Reach: Our approach brings people together from every corner of the globe.
- Transparent Onchain Entitlements: Everything is straightforward and accessible right on the blockchain.
4.3 USDC pay‑per‑call + batching (true micropayments)
- Auth: We're rolling with AA passkeys or SIWE to manage the session, and yeah, the session includes the public address too.
- Payment: Each API call comes with a 3009 authorization for, say, 0.001 USDC. The server takes all those N authorizations and mashes them together into a single
receiveWithAuthorizationtransaction every T seconds. - Limits: We’ve set up a light pre-limit and some post-settlement reconciliation. If any batches bite the dust, those calls will be flagged as unpaid (you'll get a 402 error if you try to retry). (For more info, check out the details here.)
Why
We're diving into accurate metering for agentic/AI oracles and HPC endpoints--no more worrying about pre-funding or those monthly cycles.
5) Practical implementation details you can copy
- Nonce Management (SIWE): Let's keep it straightforward--set a 10-minute TTL for your nonces and ensure that each one is a one-time wonder. You should store these nonces in Redis, using the session as the key, and don't allow any attempts to reuse them. And hey, don’t forget that the spec requires nonces to be a minimum of 8 alphanumeric characters long. (eips.ethereum.org)
- Contract Signatures: When
isContract(address)comes back as true, make sure to check the ERC‑1271isValidSignatureusing your EIP‑712 hash. And hey, don’t forget to stash those positive results for 60 seconds! (eips.ethereum.org) - Rate Limiting Headers: Let's stick to the IETF draft naming conventions. Be sure to add both the
RateLimit-Policyand aRateLimititem list that clearly shows how many requests you have left (r) and when the limit will reset (t). And remember, when you hit a 429 error, always include aRetry-Afterheader. (ietf.org) - RPC Hygiene: Make sure to monitor your RPC calls by setting a limit on how many each tenant can make. It’s generally a smart move to keep your request and response sizes well below your provider's soft limits--try to stay under 100 KB for requests. (alchemy.com)
- Streaming Checks: It's a good idea to cache the state for Superfluid/Sablier, but don’t forget to double-check when mutation events come up. Giving it a short grace period--say about 30 seconds--before you cut off access can really help smooth things over. (docs.superfluid.org)
- Unlock Auto-Renew: If you're dealing with ERC-20 priced locks, make sure a keeper calls
renewMembershipForwheneverisRenewableis set to true. Just a quick tip: users will need to pre-approve an allowance for everything to run without a hitch. (docs.unlock-protocol.com) - EIP‑3009 Batching: You can use
receiveWithAuthorizationin your billing contract to manage batch settlements in one go. It’s best to steer clear oftransferWithAuthorizationfrom other contracts since it comes with the risk of a mempool replay. Check it out here: (eips.ethereum.org) - Attestations: Set up a compact EAS schema and share it with the public. Make sure your verifier checks that "issuer == your signer" and "expiration > now" to ensure everything's in order. (github.com)
6) Compliance signals for U.S. businesses (non‑legal)
If you’re dealing with customer funds--whether you’re managing them, handling them, or sending them--it's super important that your model meets U.S. standards:
- OFAC: Make sure your sanctions screening matches the level of risk you're dealing with. Their newest guidance for the virtual currency world highlights the need for things like IP geofencing, address screening, and having strong training and testing programs set up. Check it out here: (ofac.treasury.gov)
- FinCEN: Generally, most non-custodial API providers aren’t considered money transmitters. But, if you're dealing with customer funds, it’s a good idea to look at the 2019 CVC guidance to figure out when MSB rules might apply. Check it out here: (fincen.gov)
Stripe and Coinbase processors help out by handling some of this workload. That said, on-chain models should still have solid screening and transparency measures in place.
7) What to ship this quarter (a clean checklist)
- Auth
- First things first, let's get SIWE integrated with ERC‑1271 support, and to boost security, we'll set a 10-minute nonce TTL.
- If we have some crypto newcomers on board, we might also want to think about enabling AA passkeys through Coinbase Smart Wallet or ZeroDev. You can find all the info here.
- Limits
- It's a smart move to edge-enforce token buckets that are linked to wallet addresses. Remember to publish those
RateLimit*headers and include aRetry-Afterresponse when it's appropriate. You can check out some useful details here. - Let’s also make sure we keep the upstream RPC concurrency for each tenant around 70-80% of your plan ceilings. You can find more information on that here.
- It's a smart move to edge-enforce token buckets that are linked to wallet addresses. Remember to publish those
- Payments (pick one to start)
- If you're looking to process USDC subscriptions, you might want to kick things off with Stripe or Coinbase. Check out this handy guide here.
- Another cool option is Unlock/5643, which is great for managing on-chain memberships. You can dive into more details here.
- Or, if you're leaning towards per-call payments, take a peek at EIP‑3009. With the right batching, we can keep gas costs under $0.01 per call on Base. Find all the details here.
- Auditability
- Finally, it’s important to generate EAS attestations for both plan and limits snapshots. If you’re curious to dive deeper, you can check it out here.
8) Emerging practices to watch
- ERC‑4337 is shaking things up with signature aggregation (ERC‑7766) to simplify the whole validation process for multi-user batches. You can check it out here: (eips.ethereum.org).
- EIP‑712 is getting a nice upgrade with EIP‑7713, which rolls out a “box” type for nested typed-data. This is super useful if you’re looking to bundle multiple rich payment authorizations into a single message. Learn more about it here: (eips.ethereum.org).
- There are some exciting contract-wallet-friendly extensions coming from EIP‑3009 (like 1271 validation) that are starting to make their way into production tokens. Get all the details here: (ethereum-magicians.org).
9) A concrete, end‑to‑end example (put it in your spec)
- Login: We're rolling with SIWE v1, connected to
api.example.comon chainId 8453 (Base). - Session: We manage sessions using a JWT that has
sub=,plan,rpm, and an expiration time set atexp=24h. - Limits: The Edge Worker keeps an eye on the JWT and controls the
rpmvia a token bucket. You’ll find some handy headers in the response:RateLimit-Policy: "rpm";q=600;w=60RateLimit: "rpm";r=120;t=12
- Payment: To get your membership rolling on Base, you'll need to dish out some USDC (ERC‑20). Plus, we’ve got auto-renewal sorted through
renewMembershipFor, and the server holds onto a cache ofkeyExpirationTimestampFor(address)for 30 seconds. You can dive deeper into that here. - RPC: All our reads go through Cloudflare Gateway, which features a shared cache for
eth_blockNumberand some metadata. We’ve also capped concurrency per tenant at 15 req/s, well within the plan limits. For all the details, check it out here.
Result: password-free access, straightforward limits, and an on-chain subscription that anyone, whether an auditor or a customer, can easily verify for themselves.
How we help
7Block Labs: Tailored Solutions for Startups and Enterprises
At 7Block Labs, we're all about creating and delivering patterns that fit your startup or enterprise like a glove. Whether you're diving into SIWE/AA authentication, tackling edge-rate-limit stacks, or looking for billing solutions, we’ve got all the bases covered.
You can choose from popular services like Stripe, Coinbase, Unlock, Superfluid/Sablier, or even EIP-3009.
We also make sure you have all the observability, alerts, and compliance signals that your stakeholders are counting on. And if you're after a reference implementation on Base with passkeys and USDC, don’t worry--we can whip that up for you in just a few weeks, not months!
References (selected):
- If you're into SIWE (EIP‑4361), EIP‑712, and ERC‑1271, you can find all the details here.
- Want to know more about ERC‑4337 AA, session keys/providers, and passkeys? Big shoutout to Coinbase for the info--dive in here.
- Curious about rate-limit headers (IETF drafts) and the ins and outs of 429 semantics? Check it all out here.
- Got some burning questions about RPC limits and best practices? Infura, Cloudflare, and Alchemy have some solid guides you can browse here.
- For insights on payments, don’t miss the Stripe crypto docs and subscription preview, plus the Coinbase Onchain Payment Protocol/Commerce--find it all here.
- If subscriptions/streaming pique your interest, check out ERC‑5643, Unlock, Superfluid, and Sablier here.
- And don’t forget about EIP‑3009 for the scoop on pay‑per‑call details and any caveats--check it out here.
- Last but not least, if you’re curious about attestations, swing by EAS at attest.org.
If you’re after a deeper dive or need a fully coded starter, don’t hesitate to get in touch. That’s what we do best!
Like what you're reading? Let's build together.
Get a free 30-minute consultation with our engineering team.
Related Posts
ByAUJay
Building 'Private Social Networks' with Onchain Keys
Creating Private Social Networks with Onchain Keys
ByAUJay
Tokenizing Intellectual Property for AI Models: A Simple Guide
## How to Tokenize “Intellectual Property” for AI Models ### Summary: A lot of AI teams struggle to show what their models have been trained on or what licenses they comply with. With the EU AI Act set to kick in by 2026 and new publisher standards like RSL 1.0 making things more transparent, it's becoming more crucial than ever to get this right.
ByAUJay
Creating 'Meme-Utility' Hybrids on Solana: A Simple Guide
## How to Create “Meme‑Utility” Hybrids on Solana Dive into this handy guide on how to blend Solana’s Token‑2022 extensions, Actions/Blinks, Jito bundles, and ZK compression. We’ll show you how to launch a meme coin that’s not just fun but also packs a punch with real utility, slashes distribution costs, and gets you a solid go-to-market strategy.

