HomeCase studiesA Multi-Chain Digital Collectibles Social Platform

Case study · Gothenburg, Sweden

A Multi-Chain Digital Collectibles Social Platform

Web3 and digital collectibles — social discovery rather than trading

Ownership of digital collectibles is public and verifiable, and almost entirely unreadable as a social experience. Our team built a platform that turns a wallet into a profile: it links public addresses to user accounts, continuously indexes what those wallets hold across six blockchain networks, mirrors the artwork from decentralised storage into a CDN so it renders instantly, and wraps the result in a full social layer — feed, likes, comments, following, blocking, search, direct messaging and moderation. The architecture is strictly non-custodial and read-only. Delivered as a native iOS application over a Node.js API with an administrative back office.

Industry
Web3 and digital collectibles — social discovery rather than trading
Solution
A consumer social platform: a REST API with an administrative back office, plus a native mobile application, built on top of a continuous multi-chain ownership indexing pipeline.
Platforms
iOS · Web & API
Stack
Node.js · Express · PostgreSQL · Swift · Firebase · AWS
Location
Gothenburg, Sweden · delivered remotely
Role
Engineering, with the team behind for mobile and QA

Delivered remotely for a business based in Gothenburg, Sweden. Names withheld by agreement.

Project Overview

Industry: Web3 and digital collectibles — social discovery rather than trading.

Type of solution: A consumer social platform: a REST API with an administrative back office, plus a native mobile application, built on top of a continuous multi-chain ownership indexing pipeline.

Business context: Collectors hold items across several wallets and several blockchains. That ownership is publicly verifiable, but there is no natural place to experience it socially. Marketplaces optimise for buying, and a wallet address is not a profile. A collector who wants to show a collection, follow other collectors, react to what they hold or simply talk about it has no venue designed for that. The product treats ownership as identity: a collection becomes a profile, an item becomes a post, and every post is backed by verified on-chain ownership rather than an upload.

General users: Collectors as the primary and effectively only end-user role, supported by platform administrators and permission-scoped sub-administrators in the back office.

General purpose: To make verified digital collectible ownership legible, browsable and social — without the platform ever taking custody of an asset or brokering a transaction.

The Business Challenge

The platform does not own its own source of truth. Ownership lives on public blockchains and changes without notifying anyone. Every record in the application database is a lagging replica of external state, and keeping that replica honest is not a background concern — it is the product's central reliability problem.

Collections are fragmented. A single collector may hold items across several addresses and several networks. Presenting one coherent collection means traversing all of them, continuously.

Collectible media is chaotic. Artwork is referenced through decentralised storage URIs in more than one syntax, through inline encoded data, or through arbitrary web hosts. File extensions are unreliable. Formats span still images, animated images, vector graphics, video and audio. Individual files run to tens of megabytes. All of it has to appear in a scrolling mobile feed without hesitation.

Decentralised storage gateways are slow and frequently unavailable. Building a consumer feed whose runtime dependency is a public gateway is not a viable design.

Engagement history must survive ownership changes. Items transfer. Likes, comments and reports attached to them cannot simply vanish each time the underlying ownership is refreshed, or the social layer resets itself continuously.

Users expect their collection immediately. Someone who has just linked a wallet will not wait for a nightly job. But the indexing work is heavy and rate-limited, which pulls in exactly the opposite direction.

Ownership claims have to be trustworthy. If two accounts can assert the same wallet, verified ownership — the entire premise of the product — becomes worthless.

Nothing about this justified holding user assets. A social product has no business custodying collectibles or handling signing material, and every architectural decision had to reflect that.

Our Approach

Treat ownership reconciliation as the core system, not a background job. We built a synchronisation pipeline that walks every user's linked addresses across six EVM-compatible networks using cursor-paginated retrieval, with deliberate pacing between calls to stay within the indexing provider's rate limits. It runs on a nightly schedule and is also invoked directly whenever a user adds, removes or changes an address, so wallet linking produces an immediate result while steady-state drift is corrected on a cycle.

Reconcile in two phases so the social graph survives. Rather than reloading the dataset each run, the pipeline inserts newly held items and detaches ownership from items no longer held. The collectible record — and every like, comment and report attached to it — persists across transfers. This is the difference between a social platform and a periodically-reset gallery.

Key identity correctly from the start. Items are identified by contract address plus token identifier, the only composite key that holds up across collections and across chains.

Take ownership of the media. Every referenced asset is fetched once at ingest, its true type detected from the downloaded bytes rather than its extension, then transformed to suit a mobile feed: resized against a maximum canvas with aspect ratio preserved, quality mapped according to source file size, vector content rasterised, video frame-extracted for preview, and a small thumbnail generated. The results are stored in cloud object storage and served through a CDN. The feed never depends on a gateway we do not control, and the expensive work happens once per item rather than once per view.

Make ownership exclusive. An address can be attached to exactly one account. Claiming an address detaches it from any other, so the platform's verified-ownership claim cannot be diluted by duplicate assertions.

Stay non-custodial and read-only, deliberately. The platform holds no signing material and never submits a transaction. It reads public chain state through a hosted indexer and links out to an external marketplace for anyone who wants to transact. This removes an entire category of risk that the product had no reason to accept.

Delegate realtime messaging. Chat is delivered through a hosted realtime database consumed directly by the mobile client, with the backend contributing push notification dispatch and private-bucket handling for attachments. No socket infrastructure to operate.

Distinguish public content from private content in storage. Collectible media is public by nature and served openly from the CDN. Message attachments are not, and are stored in a private bucket served through short-lived signed URLs.

Build moderation in, not on. Reporting, administrative review, item-level blocking and soft deletion across the data model were part of the design rather than a later addition — because a feed populated automatically from external sources will surface content nobody chose to publish.

The Solution

Wallet linking with exclusivity. Users attach one or more public addresses to their account. The platform validates the claim, detaches the address from any other account holding it, and triggers an immediate indexing pass.

Continuous multi-chain ownership indexing. A scheduled pipeline traverses every linked address across six EVM-compatible networks with paginated, rate-limit-aware retrieval, reconciling results against the application database in two phases so that engagement history is preserved through transfers.

Media normalisation and CDN delivery. Assets are resolved from decentralised storage or arbitrary hosts, type-detected from their bytes, transformed by format, thumbnailed, and mirrored into cloud object storage behind a CDN.

Social feed with four modes. Latest, engagement-weighted trending, randomised discovery, and following-only — with blocking relationships enforced inside the queries themselves rather than filtered afterwards.

Full engagement layer. Likes on items, threaded comments with editing and deletion, and likes on individual comments, all with live counts.

Social graph. Follow and unfollow, follower and following lists for both the current user and others, and blocking with a managed blocked-user list.

Profiles as collections. Each profile presents avatar, biography, follower and following counts, post count and the user's verified holdings as a grid.

Search. Discovery across both users and collectibles.

Appraisal view. A per-item view combining listing price with a live fiat conversion rate drawn from a public price feed, alongside a rarity tier, artist attribution and an outbound link for anyone who wants to purchase.

Direct messaging. One-to-one chat with unread counts and recent-conversation state, delivered through a hosted realtime database, with image attachments handled server-side into private storage and served through expiring signed URLs.

Push notifications and transactional email. Device token registry and push dispatch, plus templated email for verification, password reset and administrative alerts.

Deep-link sharing. Individual items can be shared as links that open directly to the item inside the app.

Reporting and moderation. Users report a collectible; the report is persisted and simultaneously emailed to administrators with full context. Administrators review a report queue and can block an individual item.

Administrative back office. Role and permission management mapped to individual API routes, permission-scoped sub-administrator accounts, user and collectible management, the report queue, CMS static pages, email templates, newsletter subscribers, and a dashboard with date-windowed breakdowns.

Multiple sign-in paths. Email with verification codes, plus federated identity through the major mobile social and platform providers.

Internationalisation from day one. Two locale bundles wired through the API's response layer rather than retrofitted later.

Key Features

Continuous multi-chain ownership indexing Every linked address is traversed across six EVM-compatible networks on a schedule and on demand, with cursor pagination and deliberate pacing to respect third-party rate limits.

Two-phase reconciliation that preserves engagement New holdings are inserted and departed holdings are detached rather than deleted, so likes, comments and reports attached to a collectible survive its transfer to another owner.

Media mirroring pipeline Assets are fetched from decentralised storage or arbitrary hosts, type-detected from their bytes, format-specifically transformed, thumbnailed and served from a CDN — so the feed never waits on a public gateway.

Non-custodial, read-only architecture The platform holds no signing material and submits no transactions. It reads public chain state and links out for anything transactional.

Address exclusivity One address belongs to one account, and claiming it detaches it elsewhere — the control that makes verified ownership meaningful.

Four-mode social feed with blocking enforced in-query Latest, trending, randomised discovery and following-only, all with block relationships applied at the database level.

Full engagement and social graph layer Item likes, comments with edit and delete, comment likes, follow/unfollow with both-direction lists, and user blocking.

Realtime messaging with private attachments One-to-one chat through a hosted realtime database, with images stored in a private bucket and delivered through short-lived signed URLs — separated deliberately from public collectible media.

Reporting and administrative moderation User reporting with immediate administrative notification, a report queue, item-level blocking, and soft deletion throughout so actions remain auditable and reversible.

Route-mapped permission model Sub-administrator access is configured as data against individual API routes rather than hard-coded, so scopes change without a release.

Technical Architecture

Mobile client. A native iOS application organised as feature modules — authentication, feed, discovery, profile, messaging, settings — each with its own controllers, models and interface files, over a single networking layer with environment-switched base paths. Media-heavy rendering is handled explicitly: cached image loading, a dedicated animated-image renderer, and a purpose-built player controller managing video autoplay within reusable scrolling cells. Chat runs directly against a hosted realtime database; push, deep links, crash reporting and federated sign-in are integrated through the platform's mobile services SDK.

API layer. An Express application split into two route trees — a versioned mobile API and an administrative API — each with its own authentication middleware and controller set. The administrative side adds a permission matrix resolved per request against the caller's role and the route being invoked.

Ownership synchronisation pipeline. The system's centre of gravity. A scheduled job, also callable on demand, that walks users and their linked addresses, queries a hosted multi-chain indexing API per address per network with cursor pagination and rate-limit pacing, and reconciles results in two phases against the local dataset.

Media processing pipeline. URI resolution across decentralised-storage and inline-data forms, byte-level content-type detection, format-specific transformation with size-driven quality mapping and aspect-preserving downscaling, thumbnail generation, video frame extraction, then upload to object storage with delivery rewritten to a CDN host.

Data layer. A relational database accessed through a query builder and ORM with soft-delete, uniqueness and field-visibility behaviour applied at the model level, covering users, collectibles, the social graph, engagement, reports, roles and permissions, and administrative content.

Realtime layer. Messaging delegated entirely to a hosted realtime database consumed by the client, with the backend contributing only push dispatch and attachment handling.

Supporting services. Public and private object storage with pre-signed URL issuance, push messaging, templated transactional email, and localisation.

Flow: Native mobile app → JWT-authenticated REST API → Scheduled and on-demand ownership synchronisation → Hosted multi-chain indexing API across six networks → Two-phase reconciliation into the relational database → Media pipeline into object storage and CDN → Social feed, realtime messaging and push notifications

Technology Stack

Category Technology
Backend runtime Node.js with Express
Database PostgreSQL
Data access Query builder with an ORM layer providing soft-delete, uniqueness and field-visibility behaviour
API authentication JWT, with separate schemes for the mobile and administrative surfaces; bcrypt password hashing
Blockchain data Hosted multi-chain NFT indexing API (read-only); on-chain unit conversion via a standard blockchain utility library
Decentralised storage IPFS gateway resolution at ingest
Object storage & delivery AWS S3 with public and private buckets, pre-signed URLs, CDN-fronted delivery
Media processing Server-side image transformation, buffer-based file-type detection, dimension inspection, ffmpeg-backed video frame extraction and thumbnailing
Scheduling Cron-driven synchronisation jobs, plus a standalone one-shot sync entry point
Push & identity services Firebase (Authentication, Realtime Database, Cloud Messaging, Dynamic Links, Crashlytics, Analytics)
Email SMTP relay with templated transactional messages
Localisation Server-side internationalisation with multiple locale bundles
Mobile platform Native iOS — Swift and UIKit, storyboard-driven, feature-module structure
Mobile networking HTTP client with environment-switched base paths and typed endpoint definitions, JSON mapping layer
Mobile media Cached image loading, animated-image rendering, custom video-player controller for autoplay in scrolling lists, image cropping and lightbox viewing
Mobile authentication Federated sign-in through the major mobile social and platform providers, with Keychain-backed credential storage
Delivery Multi-stage container build with a process manager runtime; CI pipeline definitions for build and deploy

Technical Challenges & Solutions

Challenge Our Approach
The application does not own its source of truth — ownership changes on-chain without notification A synchronisation pipeline that runs nightly and on demand, traversing every linked address across six EVM-compatible networks with cursor pagination, and reconciling results against the local dataset every pass.
Refreshing ownership must not destroy engagement history Two-phase reconciliation: insert newly held items, detach ownership from departed ones rather than deleting the record. Likes, comments and reports attached to a collectible survive its transfer.
Collectible media arrives in incompatible forms from unreliable hosts, with untrustworthy extensions A dedicated ingest pipeline resolving decentralised-storage and inline-data URIs, detecting content type from the downloaded bytes, and applying format-specific transformation — rasterising vectors, frame-extracting video, quality-mapping by file size and downscaling with aspect ratio preserved.
Public gateways are too slow and too unreliable to sit in a consumer feed's request path All media is mirrored once at ingest into cloud object storage and served through a CDN. The feed depends only on infrastructure the platform controls, and transformation cost is paid once per item rather than once per view.
A rate-limited third-party API fanned out across users × addresses × networks × pages Batched, scheduled execution with cursor pagination and deliberate pacing between calls — accepting a slower job in exchange for staying inside provider limits and never letting that latency touch a user request.
Users expect their collection instantly, but indexing is heavy The same synchronisation routine is both scheduled and directly invocable, triggered whenever an address is added, removed or changed, so linking a wallet returns results immediately while the nightly cycle corrects drift.
Verified ownership is worthless if it can be claimed twice Address exclusivity enforced at the point of linking: claiming an address detaches it from any other account, so a wallet backs exactly one profile.
A feed populated automatically from external sources will surface unwanted content Reporting built in from the start, with immediate administrative notification carrying full context, a review queue, item-level blocking, and soft deletion across the data model so every moderation action is auditable and reversible.
Public collectible media and private user-to-user attachments need different handling Separate storage treatment: collectible derivatives served openly from the CDN, message attachments held in a private bucket and released only through short-lived signed URLs.

Security & Reliability

Non-custodial by architecture. The platform holds no signing material and submits no transactions. It reads public chain state and links out for anything transactional. The most effective security control in a Web3 product is not handling what you do not need to handle.

Token-based authentication with surface separation. The mobile API and the administrative API authenticate independently, with distinct token handling, so a credential for one surface is not a credential for the other. Passwords are hashed with a modern adaptive algorithm.

Route-mapped authorisation. Administrative permissions are resolved per request against the caller's role and the specific route invoked, with sub-administrator scopes configured as data rather than compiled in.

Storage separation by sensitivity. Public collectible derivatives and private user-to-user attachments are stored and served under different rules, with private content released only through short-lived signed URLs.

Verified ownership. Every item in a profile is present because it was read from a public chain against an exclusively-claimed address, not because a user uploaded it.

Moderation with an audit trail. Reports are persisted and escalated with context, administrative actions are recorded, and soft deletion throughout the data model means removals are reversible and reviewable rather than destructive.

Device-side credential handling. Mobile credentials are held in the platform Keychain rather than in application storage.

Content-type verification at ingest. Files fetched from untrusted hosts are identified from their bytes rather than their declared extension before any processing occurs.

Scalability & Performance

Expensive work moved off the request path. Ownership indexing and media transformation both run as scheduled batch processes. Third-party latency, gateway timeouts and transformation cost never appear in a user-facing response.

Transform once, serve many. Every asset is normalised a single time at ingest and served thereafter from a CDN. In a media-heavy feed, this is the single largest determinant of perceived performance.

Rate-limit-aware retrieval. Cursor pagination with deliberate pacing keeps the synchronisation job inside provider limits, trading job duration for reliability — the correct trade for a batch process.

Filtering pushed into the database. Feed ordering and blocking semantics are expressed in SQL with pagination applied at the query level, keeping result sets bounded rather than filtering in application code.

Stateless, containerised application tier. Token authentication and externalised storage keep instances free of local state, with a multi-stage container build and process-managed runtime for horizontal deployment.

Realtime load carried outside the API. Messaging traffic goes to a hosted realtime service and never reaches the application tier.

Client-side media discipline. Cached image loading, a dedicated renderer for animated content, and a managed player controller for video autoplay in reusable cells keep scrolling smooth in a feed that is almost entirely media.

Push over polling. Notifications are delivered by push rather than by client polling.

Business Outcomes

  • A wallet became a profile. Fragmented holdings across multiple addresses and multiple networks present as one coherent, browsable collection.
  • Ownership displayed is verified rather than claimed, backed by continuous reconciliation against public chain state and enforced address exclusivity.
  • Collectible artwork renders immediately, because the platform serves its own normalised copies from a CDN instead of waiting on public decentralised-storage gateways.
  • Engagement history persists through ownership changes, so the social layer accumulates rather than resetting every time an item transfers.
  • Linking a wallet produces an immediate result, because indexing is invocable on demand as well as on a schedule.
  • The platform never takes custody, removing an entire category of operational and regulatory risk from a product whose value is social rather than transactional.
  • Content that arrives automatically can still be governed, through user reporting, administrative review, item-level blocking and reversible deletion.
  • Administrative access is configurable rather than hard-coded, with permission scopes changed as data instead of as a release.

Why it worked

Web3 products fail in a specific and predictable way: the blockchain integration gets the attention, and the boring infrastructure around it — data reconciliation, media handling, moderation — is treated as plumbing. Then the product ships, and users find that their collection is out of date, half the artwork does not load, and the feed shows items their owner sold last week. The chain integration was never the hard part.

We built this one the other way round. The reconciliation strategy came first, and it was designed so that engagement history survives ownership changes, because a social platform that resets its own social graph on every sync is not a social platform. The media pipeline came second, and it was built on the assumption that every external host will eventually be slow, wrong about its own file types, or simply down — so the platform serves its own copies. Only then did the social features go on top. And the whole thing was kept non-custodial, because a product that connects collectors socially has no reason to hold their assets, and taking on that risk for no product benefit is a decision worth not making.

Our teams work across Node.js and relational data modelling, blockchain data integration and multi-chain state reconciliation, high-volume media processing and CDN delivery, native iOS development, and the trust-and-safety layer that any user-generated or automatically-populated feed eventually requires — along with the judgement to know which part of a Web3 product is actually the difficult one.

Final Summary

Digital collectible ownership is public, verifiable and almost impossible to experience socially. Collections are split across wallets and across chains, the artwork lives behind decentralised gateways that are slow when they work at all, and a wallet address makes a poor profile. Marketplaces solve buying. Nothing solved belonging.

Our team built a platform that turns verified ownership into a social feed. Users link public addresses; a synchronisation pipeline traverses every one of them across six EVM-compatible networks on a schedule and on demand, with paginated, rate-limit-aware retrieval, reconciling results in two phases so that likes, comments and reports attached to an item survive its transfer to a new owner. Every referenced asset is fetched once, identified from its actual bytes, transformed by format — vectors rasterised, video frame-extracted, images quality-mapped and downscaled, thumbnails generated — and mirrored into cloud storage behind a CDN, so the feed depends on nothing the platform does not control.

On top of that sits the product users actually see: a feed with latest, trending, discovery and following modes; likes, comments and comment likes; following, blocking and search; profiles that present a collection; an appraisal view; direct messaging with private attachments; deep-link sharing; push notifications; and a moderation stack with user reporting, administrative review, item-level blocking and reversible deletion. The architecture is non-custodial and read-only throughout — no signing material, no transactions, no assets held. Delivered as a native iOS application over a Node.js API and administrative back office, it makes a fragmented, chaotic, externally-owned dataset behave like a social network, which is the only thing that makes any of it worth looking at.

01 — Questions

asked about this kind of project

How do you keep an application database in sync with on-chain ownership?

With a reconciliation pipeline rather than an import. Chains do not notify your application when an item transfers, so the database is always a lagging replica and must be re-checked on a cycle. The critical design decision is what happens to items that are no longer held: detach ownership rather than delete the record, so everything attached to that item — engagement, reports, history — survives. Reload-from-scratch is simpler to write and destroys your product every time it runs.

Why mirror NFT media instead of loading it from IPFS directly?

Because a consumer feed cannot have a public gateway in its request path. Gateways are slow, intermittently unavailable, and entirely outside your control. Fetching each asset once at ingest, normalising it, and serving it from your own CDN converts an unpredictable per-view dependency into a one-time per-item cost. It also gives you the ability to moderate imagery you serve, which you do not have when hotlinking.

What does a robust NFT media pipeline actually need to handle?

More than people expect. URIs arrive in several decentralised-storage syntaxes, as inline encoded data, and as arbitrary web URLs. File extensions are frequently wrong, so type detection must read the actual bytes. Formats span still images, animated images, vector graphics, video and audio, each needing different treatment — vectors rasterised, video frame-extracted for preview, large files quality-mapped and downscaled. And thumbnails matter enormously, because the feed is mostly grids.

Should a Web3 social product be custodial?

Almost never. If the product's value is social rather than transactional, holding assets or signing material adds significant operational and regulatory risk for no product benefit. Reading public chain state through an indexer and linking out for anything transactional delivers the same user experience with a dramatically smaller attack surface. The strongest security control available is not handling what you do not need to handle.

How do you make ownership claims trustworthy?

Enforce exclusivity at the point of linking. If two accounts can assert the same wallet, verified ownership stops meaning anything, and the platform's core claim collapses. Claiming an address should detach it from every other account that holds it. It is a small piece of logic that carries the entire trust model.

How do you handle a rate-limited third-party API across a growing user base?

Batch it, schedule it, paginate it with cursors, and pace it deliberately. Accept a slower job in exchange for staying inside provider limits. The important architectural rule is that this work never sits on a user request — but pair it with an on-demand invocation path for the moments where a user genuinely is waiting, such as immediately after linking a wallet, so responsiveness and batch efficiency are not in conflict.

Should realtime chat be built or integrated?

Integrated, in most cases. A hosted realtime service provides delivery, presence and scale without your team operating socket infrastructure or staffing its failure modes. Building in-house is justified only when messaging is the product. Keep the backend involved where it should be — push notification dispatch and private handling of attachments — and let the hosted service carry the message traffic.

What does moderation need to look like in an automatically-populated feed?

Stronger than in a feed users curate themselves. When content arrives through indexing rather than upload, nobody chose to publish it, so reporting, administrative review and item-level blocking need to exist from day one rather than after the first incident. Soft deletion throughout matters too: moderation decisions get appealed, and a destructive delete leaves you with nothing to review.

03 — Similar project?

describe what is different about yours

Build yours.

Tell me what exists, what you need and the deadline. Fixed price for a defined scope, or hourly from $10 with a written estimate first.

Ahmedabad, India · IST (UTC+5:30) · --:-- IST · Mon–Fri 09:00–18:00 IST · US & EU overlap daily

No newsletter, no CRM. Just a reply.