Development of a vote delegation module in a mobile DAO app

In a mobile DAO, votes are lost when delegation requires dozens of manual actions and does not account for chains. We develop a turnkey vote delegation module: from accounting logic to the interface. The client gets a transparent mechanism that reduces voting time and relieves the team's workload.

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a mobile application for FEEDME
    Development of a mobile application for FEEDME
    971
  • Development of a mobile application for XOOMER
    Development of a mobile application for XOOMER
    869
  • Development of a mobile application for RHL
    Development of a mobile application for RHL
    1289
  • Development of a mobile application for ZIPPY
    Development of a mobile application for ZIPPY
    1143
  • Development of a mobile application for Affhome
    Development of a mobile application for Affhome
    1076
  • Development of a mobile application for the FLAVORS company
    Development of a mobile application for the FLAVORS company
    677

Why vote delegation breaks in a mobile DAO

Vote delegation in a mobile DAO app breaks not at the level of tally logic, but at the level of delivering state to the device. The user signs a transaction, the interface shows a new vote weight, but the network has not yet confirmed the operation at that moment.

From there, any action — re-delegation, changing the delegate, revoking — is built on an incorrect picture, and the app confidently leads the person into a dead end.

The most common cause is state desynchronization between the local cache and the chain. The mobile client keeps the last known snapshot of vote distribution so the delegate list opens instantly, and updates it based on events.

If the app went to the background, lost connection, or missed a block, the snapshot silently goes stale: the interface draws old weights, while the transaction goes out with parameters that are no longer current. The user sees one thing, the network executes another.

The second group of failures is duplicates and stuck transactions. A double tap on the delegation button, a resend after a timeout, an app restart while waiting for confirmation — and two operations with the same intent end up in the mempool.

One goes through, the second hangs or is rejected, and the vote balance in the interface diverges from the real one.

Separately, there is the stuck transaction with an underestimated fee: it is not confirmed, but it does not disappear either, blocking the queue of subsequent operations for the same account.

The third source is the mismatch between the moment of signing and the moment of execution. Between them, the voting epoch changes, the delegate's term of authority expires, or a rule restricting the delegation chain takes effect. The transaction is formally valid, but it is applied to a state that no longer exists.

Let's break down how this is closed: idempotent operations, explicit waiting states instead of optimistic interface updates, and rebuilding the vote snapshot from confirmed events rather than from local guesses.

What a correct delegation implementation delivers

A correct implementation of vote delegation comes down to three things: how the app calculates voting weight at the moment of the blockchain snapshot, how it shows the user to whom and for how long they are transferring their voting right, and how it cancels delegation without losing already-counted votes.

If even one layer is implemented "by eye," the user sees one thing, the network accounts for another — and the first to notice this is not the developer, but support.

The speed at which an operation is confirmed is determined not by the transaction itself, but by what happens before it.

When the app preloads the current list of delegates in advance, caches the snapshot state, and doesn't drag the user through three screens for a single signature, confirmation fits into a single network wait instead of several sequential ones.

The difference is especially noticeable on a weak mobile connection, where every extra synchronization means minutes and an abandoned operation.

The share of successful operations grows when the app validates delegation before sending: it checks that the delegate's address is correct, that the term hasn't expired, that the user has enough funds for the fee, and that re-signing won't create a duplicate.

A transaction rejected by the network costs the user time and trust, and costs us a support request, which is more expensive than any pre-check on the client.

Reducing the number of support requests is a direct consequence of transparency. The user should be able to see how many votes they have delegated, for how long, and how to return them, without reading documentation.

When the delegation state is displayed honestly and updates itself, the questions "why wasn't my vote counted" and "how do I cancel" simply stop arising.

That is precisely why delegation support is not a single button, but a combination of weight calculation, state display, and rollback. Let's break down how this is structured in the mobile app and what we check before release.

Voting Accounting Methods: Comparing Approaches

Vote accounting in a mobile DAO is not a single mechanic but a fork in the road between several models, and the choice among them determines how the app will behave as the number of participants grows. Below are the working options we have implemented, with the honest limitations of each.

Accounting option When it fits Limitations
Direct delegation by address Small community, stable voting base, simplicity matters As the number of delegates grows, weight recalculation becomes more expensive; manual reassignment when the wallet changes
Delegation by campaigns Votes come in waves, each with its own set of participants Requires separate snapshot logic for each campaign; history auditing is harder
Sub-delegation (chains) Large structures with representatives and sub-representatives Risk of chain looping; depth control and loop protection are needed
Hybrid: direct + pool Some votes are held personally, some are contributed to a shared pool Double counting with a sloppy snapshot; transparency requires a separate screen

Direct delegation by address is the most predictable option: the user appoints a delegate, and the weight is recalculated on every vote.

The limitation shows up at scale — the more connections there are, the more expensive and slower the recalculation, and changing the wallet requires manual reassignment.

Delegation by campaigns removes part of that load: votes are tied to a specific poll rather than to an account forever.

In exchange, it imposes a requirement on snapshots — weight state must be fixed at the moment the campaign starts, otherwise the results will "drift" with late delegations.

Sub-delegation gives flexibility to large structures but requires protection against loop chains and a depth limit.

The hybrid model is convenient for mixed communities, but double counting is the most common mistake: without a clear separation of direct and pool votes at the snapshot stage, the results diverge from expectations.

In practice, the choice comes down to three questions: how many delegates are expected, how often their composition changes, and whether a history is needed for auditing.

The answers to these determine which vote accounting option will form the foundation of the app without rework at the next stage of growth.

How we implement the vote delegation module

Implementing the vote delegation module starts with an audit: we look at how accounts are structured in the application, where signing keys are stored, and which networks and contracts are already connected.

At this stage, it is important to understand whether the user votes themselves or delegates the right to another address, and how this is reflected in the history. Without such a check, the module can easily be designed in a way that conflicts with the existing wallet logic.

Next, we build the delegation scheme: who can be a delegate, for what term, whether the right can be revoked early, and what happens upon re-delegation.

We separately work through scenarios where the delegate loses access or refuses the votes themselves — such cases most often break voting in real communities.

  1. Audit of the current application — we analyze accounts, key storage, connected networks and contracts, and record the limitations.
  2. Designing the delegation scheme — we define roles, terms, revocation rules, and rules for re-transferring votes.
  3. Configuring the module — we connect the logic to the wallet and contracts, and configure the signing of delegation operations.
  4. Scenario verification — we run through transfer, revocation, re-delegation, and voting on behalf of the delegate.
  5. Testing on a test network — we check the module's behavior without risk to real votes and assets.
  6. Handover and documentation — we describe the scheme, rules, and procedure for the support team.

Each stage ends with a check: if the revocation or re-delegation scenario behaves incorrectly, we return to the scheme rather than patching the behavior at the interface level.

This way the module remains predictable both as the number of participants grows and when delegates change.

As a result, the client receives a working vote delegation module, a scheme for how it interacts with the wallet and contracts, as well as documentation for support. Describe your task — we will get back to you with an estimate and a stage plan.

What the client receives

We hand over not "working code" but a package that lets the vote delegation module live and evolve without us. Each artifact addresses its own class of questions: how it is built, how to verify it, how to change it, and what to do in case of failure.

  • Delegation module configurations — network parameters, contract addresses, vote weight thresholds, and recalculation rules when a delegate changes. Moved into separate environment files so that switching between the test and production environments does not require code changes.
  • Vote flow diagrams — how a vote travels from the owner to the delegate, where the snapshot is recorded, at what point the weight stops being counted upon revocation. The diagram eliminates half the questions in calls with lawyers and auditors.
  • Access and role policies — which administrators can change delegation parameters, who has read-only access, how rights are granted and revoked. With a role matrix and an action log.
  • Integration documentation — description of methods, request and response formats, error codes. Enough for a third-party team to connect the module without reading the source code.
  • Operational procedures — what to do when vote weight diverges, how to roll back an unsuccessful parameter change, where to look first. With a checklist for the on-call engineer.
  • A set of checks — tests for delegation and revocation scenarios, including edge cases: the delegate left, the weight changed between votings, double delegation.
  • Handover recording — a walkthrough of architectural decisions and open questions so that the context does not remain only in the chat history.

The package is assembled so that a new engineer gets up to speed with the module through documentation rather than verbal explanations. Describe your task — we will come back with an estimate and a plan for your environment.

Case study: accelerating delegation in a mobile wallet

The client — a mobile DAO wallet team on NEAR — came with a complaint: vote delegation worked, but users rarely got to it.

The operation took 6 screens and 4 confirmations, the average completion time was 3 minutes 40 seconds, and the share of attempts abandoned midway held at 38%.

Support was receiving 40-60 requests per week, and almost all of them were "I don't understand who I'm delegating to" and "the vote went to the wrong place."

What was changed

The flow was rewritten into a single screen: delegate selection, share size, and confirmation — in one view with live recalculation of vote weight.

A preview of consequences before signing was added, along with a cached delegate list with background refresh and an explicit operation status after submission — instead of a waiting screen with an indeterminate result.

Separately, the class of errors that generated the most noise was closed off: a mismatch between the selected delegate and the actually signed transaction.

Now the delegation parameters are assembled in one place and validated before signing, rather than along the way through several screens.

What the result was

The average operation time dropped to 50 seconds, and the share of abandoned attempts fell to 9%.

Support requests about delegation were cut by four times, while repeat delegations (changing the delegate) grew threefold — people started using the feature rather than trying it once.

Network load did not increase: the number of transactions per user stayed the same, only how many of them reach signing changed.

How does direct delegation differ from a chain?

Direct delegation is a single link: a token holder appoints a delegate, and the full weight of their vote goes to that address. A chain arises when a delegate themselves delegates their aggregate weight to someone else, and the vote continues moving further along the graph.

The difference is not cosmetic: it determines how the application calculates the final weight at the moment of voting and what happens upon revocation.

In the direct variant, vote accounting is trivial — the voter's weight equals the sum of tokens delegated to them plus their own balance. The recalculation is local, the state converges in a single pass, and revoking the delegation instantly returns the weight to the owner.

A chain requires traversing the graph down to the terminal addresses: it is necessary to find everyone who actually votes and sum up the weight along the paths.

Here two engineering risks emerge — looping (A delegates to B, B delegates to A) and "stuck" weight, when an intermediate node revoked its delegation after voting had already begun.

In practice, this affects three things. The first is the moment of weight fixation: a state snapshot before voting begins eliminates manipulation by shuffling votes along the chain.

The second is the depth limit: a cap of 3-5 hops protects against infinite traversal and makes the calculation predictable. The third is cycle handling: a node caught in a loop is excluded from the count, otherwise the voting transaction will not complete.

For the client, the choice comes down to the governance model.

Direct delegation is simpler to audit and clearer to participants, but it does not support a "delegate of delegates." A chain gives flexibility to large holders and community representatives, but it requires explicit traversal logic, protection against cycles, and transparent display in the interface — who stands behind whom and where the weight went.

In both cases, vote accounting must be deterministic: the same result when recalculated on any node in the network.

Common technical concerns

Vote delegation is a mechanic where a mistake in access rights costs the most: a compromised delegate key drains voting weight, and an irreversible transaction on the mainnet cannot be rolled back.

That is why we address security, compatibility, and rollback questions before development starts, not after the first incident.

How are keys and signatures protected during delegation?

The private key never leaves the secure perimeter of the device: the signature is generated in hardware storage (Secure Enclave / Keystore), and the application only receives the result.

The delegate is specified by address, and limits on weight and duration are written into the contract call itself — even if the session is compromised, an attacker cannot withdraw more than allowed. Additionally, we log every action and send a push notification when the delegate changes.

Is it compatible with already deployed contracts and wallets?

Yes, if the contract supports the standard delegation interface. We verify method signatures, return value types, and behavior on repeated calls, then run scenarios on a testnet with real addresses.

For wallets without native support, we add an adapter layer — the user sees a familiar confirmation screen.

What happens when a transaction is rolled back?

On the blockchain, a rollback is not a "cancellation" but a new transaction with the reverse action. We design delegation to be idempotent: a repeated call with the same parameters does not duplicate weight, and a revocation returns the votes to the owner.

If a transaction fails due to gas or a revert, the state does not change, and the application shows a clear reason and offers to retry.

How do we verify correctness before release?

We cover the contract and client with automated tests for the scenarios: delegation, revocation, re-delegation, boundary values of weight and duration. Separately, we check for key leakage and behavior during network interruptions. The release goes through a contract audit and gradual rollout to a share of users.

Let's discuss your vote delegation task

Vote delegation is a mechanic where a configuration error costs more than on an ordinary screen: an incorrectly calculated vote weight or a lost delegate state distorts the voting result, and it cannot be rolled back after the fact.

That is why before starting we break down the delegation model down to the details — who delegates a vote to whom, how chains are calculated, what happens on revocation, and how the interface behaves when out of sync with the network.

To come back with an estimate and a plan rather than generalities, we need to understand your vote delegation task specifically. Describe the scenarios and constraints — that is enough to estimate the scope and propose an architecture.

  • Current delegation model: direct vote transfer, delegate chains, or a hybrid with partial weight.
  • Network and standard: where the vote accounting lives, how the application reads state and confirms transactions.
  • Wallet and signatures: which connection methods are supported, whether hardware wallet support is needed.
  • Revocation and redistribution scenarios: how a vote returns to the delegator and what the user sees at that moment.
  • Offline behavior: what we show when the connection is lost and how we synchronize state when it returns.
  • Existing code: whether there is a prototype or an application that needs to be improved rather than written from scratch.
  • Constraints on timelines and platforms: iOS, Android, or both, and whether synchronized releases are needed.

Based on the breakdown, we come back with a timeline estimate, a phased plan, and a list of risks — what we do first, where we build in a buffer for network integration, and how we verify the correctness of vote counting before release.

Describe your task — we will discuss the details and propose a solution for your delegation scenario.