C-DAC Noida · 2026 · Backend engineer
A platform backend with queue-backed workers
The backend for a web3 gaming platform: wallet sign-in, player profiles, social content, a marketplace, leaderboards and referrals, in one modular service.
- MongoDB
- Redis-compatible queues
- EVM signatures
- JWT
- OpenAPI
- Docker
At a glance
- Sign-In with Ethereum using one-time, server-issued nonces
- Third-party and on-chain work moved off the request path onto queue workers
- Referral abuse checks without storing raw IP addresses
Built at C-DAC. Client, product and infrastructure details are withheld; code is not public.
Shape
One service with a module per domain: players, content, marketplace orders, leaderboards, referrals, uploads and agents. Each module follows controller → service → repository, and the API is described with OpenAPI.
Keeping requests fast
Anything that waits on someone else runs in the background. Scraping social posts from a third-party provider, recording activity on-chain, migrating stored media and evaluating referrals all go onto Redis-compatible queues with dedicated background workers, so request latency does not depend on an external API. Storage migrations have a dead-letter queue, and every worker listens for a shutdown signal so a deploy drains cleanly.
Abuse controls
- A referral reward is granted at most once per signup IP per hour, using
SET NXwith a TTL on a SHA-256 hash of the IP. A blocked reward fails silently instead of telling an abuser what tripped. - Referral clicks are counted with a daily-salted IP hash, which allows daily unique counts without storing raw addresses.
- Per-client rate limiting sits in front of the router.
Sign-in
Players sign in with Sign-In with Ethereum (EIP-4361). The server issues a one-time nonce, the wallet signs a message containing it, and the backend recovers the signer from the signature, consumes the nonce so it cannot be replayed, and only then issues a JWT. Wallet addresses are stored exactly as the wallet presented them, because lowercasing a checksummed address breaks lookups and integrations.
How I'd build it in Spring Boot
- Modules: package-by-feature (
player,marketplace,referral, …), each with a@RestController, a service and a Spring Data MongoDB repository; springdoc-openapi generates the API description. - Sign-in: the nonce stored in MongoDB with a TTL index; the signer recovered with web3j's
Sign.signedPrefixedMessageToKey; the nonce consumed with a singleMongoTemplate.removewhose deleted count must be 1, so a replay fails; then a JWT validated by Spring Security's resource server on every later request. - Background work: Kafka or RabbitMQ listeners with retries and a dead-letter destination, or Redis-backed queues drained by worker beans implementing
SmartLifecycle;server.shutdown=gracefullets in-flight work finish on deploy. - Referral abuse check:
setIfAbsent("referral:signup-ip:" + hash, "1", Duration.ofHours(1)), with the IP hashed throughMessageDigest(SHA-256) so raw addresses are never stored. - Rate limiting: a Bucket4j servlet filter keyed by client.