Implementing Token Balance Display on a Website

If a website's token balance diverges from the network, users lose trust in the service. We design and implement correct balance display turnkey: from design to delivery. You get accurate real-time data and reduced support load.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1359
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113
  • Website development for SBH Partners
    Website development for SBH Partners
    1201
  • Website development for Red Pear
    Website development for Red Pear
    619

Why the token balance on a website is displayed incorrectly

Most often, the displayed token balance diverges from the network not because of an error in the contract, but because of how the website receives and stores data.

The classic scenario: a user sends a transaction, the interface shows the deduction immediately after sending, while the network confirms it a few blocks later — or does not confirm it at all when the gas is replaced.

The result is an incorrect token balance on the website, repeated transfer attempts, and manual investigations on the support side.

The second most common cause is stale cache. The node's response is cached for minutes, while the state changes every few seconds; with multiple addresses or networks, the cache key is not fully differentiated, and one wallet's data leaks into another.

Incorrect addressing is adjacent to this: the wrong address format, the wrong network, tokens with their own decimals not taken into account — and the amount on screen differs from the real one by orders of magnitude.

The third source of discrepancies is the absence of a re-check of the transaction. The website trusts the response to the send and no longer re-reads the state, so a stuck or canceled operation remains in the interface forever as successful.

Incoming transfers deserve separate mention: without subscribing to network events, the token balance on the website is updated only when the page is reloaded.

All three causes are addressed at the architecture level: reading state directly from the network, a short cache with explicit invalidation on an event, and transaction confirmation based on actual inclusion in a block. Let's break down how this is structured and what it delivers in practice.

How correct token balance display works

Balance is not a single number, but the result of reconciling several sources: a blockchain indexer, a node, and internal accounting records.

If you pull the value directly from the node on every page render, the interface becomes dependent on its availability: when the response is delayed, the user sees "0" instead of the real amount.

That is why correct token balance display is built on separating reads and writes: writes go through the node, reads go through an index with confirmed states.

Data source and its boundaries

The indexer returns the balance for an address with a delay of one or two blocks — this is the price of consistency. A direct request to the node is faster, but returns intermediate states and provides no history.

In practice, the source is chosen for the task: an index is sufficient for a wallet showcase, while a node is needed to confirm an operation before debiting.

Balance caching

The cache holds the last confirmed value and a timestamp, not a "raw" number. When the source is unavailable, the cached balance is returned with a staleness marker — the interface does not show a false zero. Invalidation is tied to a transfer event, not to a timer.

Balance updates

Balance updates go through two channels: event subscription for instant reaction and periodic polling as a safeguard against missed messages. This eliminates desynchronization after large transactions.

Option When it fits Limitations
Direct request to the node Verification before debiting Dependency on availability, no history
Indexer Showcase, history, multi-address Delay of one or two blocks
Cache with staleness marker High load, offline mode Explicit invalidation required

Our engineers build such a layer on The Graph and proprietary indexers — with an explicit data staleness policy.

Stages of implementing correct balance display

A correct balance is not a single network request but a coordinated scheme: the data source, the moment of update, the behavior when there is a discrepancy. An error in any link produces "stuck" amounts that the user sees before the transaction is confirmed.

That is why we approach the implementation of balance display as an engineering process with a verifiable result at every step.

  1. Integration audit. We analyze the current scheme: where the balance comes from, how often it is polled, what is shown when the response is delayed. We identify bottlenecks — usually the absence of a cache for the intermediate state and requests on every page render.
  2. Choosing the source and update mode. We determine what we consider the truth: an indexer, a node, or an aggregator, and how we update — by event or on a schedule. For active scenarios we set up a subscription; for the rest, a background update at a reasonable interval.
  3. Setting up updates and caching. We introduce an intermediate layer: the last confirmed value plus an "updating" marker. This way the interface does not flash a zero on reload and does not show a stale amount as current.
  4. Handling discrepancies and failures. We define the behavior when the source is unavailable: we show the last known value with an explicit status rather than an empty screen. Separately, we cover the case when a transaction is in progress — the balance is marked as pending confirmation.
  5. Correctness verification. We compare the readings against an independent source on a set of control addresses, including edge cases: zero balance, large amounts, multiple assets. We run scenarios with network delays and repeated requests.
  6. Monitoring and documentation handover. We set up alerts for discrepancies and growth in update latency, and we describe the data flow scheme and the incident response procedure.

After handover, the team is left with a working scheme with clear control points rather than a "black box" that cannot be fixed without its author. Describe your task — we will come back with an estimate and a plan for each stage.

How does a balance from cache differ from a balance from the network?

Cache is the last known value stored on our side: in process memory, in a key-value store, or in a database. It is served instantly, does not depend on the availability of a network node, and does not block the interface.

The price of speed is possible staleness: if a transaction occurred between requests, the cache will show the old balance until it is overwritten.

Network is a request to a node or to our indexer, which reads the state at the current block height. Here it is important to distinguish two numbers: the balance by the latest block and the confirmed balance, where the required number of confirmations has already been reached.

The first can change during a chain reorganization, the second cannot. For withdrawals and transaction accounting, we rely only on the confirmed value.

Update latency is not just the node's response time. It includes the polling interval, indexing delay, and the time it takes for the frontend to redraw the value. If we poll the node on every page render, as traffic grows we hit the provider's limits and get request queues. That is why we hit the network on a schedule and on an event, and serve cache in between.

Choosing a mode is a trade-off between freshness and responsiveness, and it is decided not globally but locally. A showcase, transaction history, reference screens — cache with background refresh.

The transfer confirmation screen, limits, available remainder — network with an explicit "checking" indicator. The user must see which value is in front of them: one marked as confirmed or one still updating.

A practical technique is two-layer delivery: we show the cache immediately, launch a network request in parallel, and swap the number when the confirmed response arrives. This way the interface does not "blink" with emptiness, and the discrepancy is closed within seconds. Next, we break down how this maps onto a specific scenario.

Case Study: How We Eliminated a Balance Discrepancy on the Website

Before the implementation, the balance on the website was pulled from a single source — a public network node polled on a schedule. Under peak load, the response did not arrive within the allotted interval, and the front end displayed zero instead of the actual amount.

The user saw an empty wallet, wrote to support, and the balance "appeared" on its own a few minutes later — reputationally, this is more costly than any delay.

What Exactly Broke the Display

The root cause was not in the interface, but in the data retrieval model: a single polling point with no retries, a cache with a short time-to-live, and no cross-checking between sources.

If the node responded slower than usual, a zero result ended up in the cache, which was then served to all requests until the TTL expired.

What We Changed

  • Introduced multiple independent data sources with cross-verification: a discrepancy above the threshold flags the value as unreliable and it is not served to the interface.
  • Switched to event-driven updates: the balance is recalculated upon the transaction, not on a timer.
  • Separated the states of "no data" and "zero balance" — the interface no longer shows zero where a response has not yet been received.
  • Added a discrepancy log: every mismatch between sources is recorded with context for investigation.

Metrics Before and After

Metric Before After
Share of requests with zero balance when the actual balance is non-zero up to 4% isolated cases, all in the log
Update delay after a transaction tens of seconds comparable to network response time
Support requests on the topic of balance a regular stream decreased by a multiple

We also addressed user support separately: the operator now has access to the discrepancy log, and the question "why is my balance zero" is resolved without escalation to development.

The verification scheme was built on Ethereum — taking block confirmations into account, so as not to show a balance for a transaction that has not yet been finalized.

Integration concerns: compatibility, migration, rollback

Token balance display is almost always embedded into an already running site, so the main question is not "will it work" but "what will happen to the current frontend, cache, and accounting data during an update." In practice, the balance is read through a separate service layer: it queries a blockchain node or provider, normalizes the response, and delivers a ready value to the frontend.

Existing pages, authentication, and markup are not rewritten — the new module is connected as an independent component with its own config.

What if a rollback or migration is needed without taking the site down?

Updates are rolled out in stages: first the balance module runs in parallel with the current display, then traffic is switched over by a share, and only after metrics are verified is the old path disabled.

The rollback plan is a pre-defined scenario: restore the previous configuration, switch the data source to the backup, and confirm that balances match the accounting system.

Migration without downtime is achieved because the switch happens at the configuration level, not by rebuilding the site.

What if we have a non-standard stack? Integration compatibility is checked at the design stage: the module communicates with the frontend through a standard interface, so it does not depend on a specific framework or CMS.

Constraints are documented in advance — for example, requirements for balance refresh frequency and external provider availability.

What about data discrepancies? Balance is a sensitive value, so we add reconciliation with the accounting system and logging of every response. If there is a discrepancy, we show the last confirmed value rather than a random number.

The client receives:

  • a data flow diagram between the site, the service layer, and the balance source;
  • connection configurations with refresh parameters and a backup source;
  • an error handling policy and interface behavior when the provider is unavailable;
  • balance documentation: response formats, fields, rounding rules, and limits;
  • a rollback plan with a step-by-step scenario for reverting to the previous version;
  • a procedure for reconciling balances with the accounting system and a process for resolving discrepancies.

Describe your task and current stack — we will come back with a compatibility assessment, migration plan, and documentation scope.

Timeline for Implementing Token Balance Display

The timeline depends not on the volume of code, but on how many balance sources need to be consolidated and how strict the requirements for freshness are.

Token balance display is always a chain of "data source → caching layer → interface," and each part adds its own stage to the schedule. Below are approximate stages of work without tying them to specific dates: duration is measured in business days and is refined after an audit.

The stages proceed sequentially, but the interface and the data layer are partially handled in parallel — this shortens the overall schedule.

If there are multiple sources, a stage for reconciling them with each other is added: a discrepancy of a couple of blocks between the node and the indexer has to be resolved with an explicit priority rule, otherwise the user sees a "jumping" balance.

What affects the timeline the most? The number of sources, the requirements for update latency, and the availability of ready access to the node or API. What if there is no access yet?

Then the audit starts with setting up access, and this adds a separate stage to the schedule — usually 1-3 days.

Describe the task: which tokens, where the balance comes from, and how often it should update — we will get back to you with an estimate and a stage-by-stage plan.