Snapshot DAO Voting Integration in Mobile App

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
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.

Showing 1 of 1 servicesAll 1735 services
Snapshot DAO Voting Integration in Mobile App
Medium
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    760
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    640
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1056
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    449

Implementing Snapshot Integration for DAO Voting in Mobile Applications

Snapshot is an off-chain voting system where users sign an EIP-712 message with their wallet, and the result is stored in a decentralized IPFS/Snapshot Hub network. Voting costs nothing — no gas. Vote weight is determined by token balance on the blockchain at the proposal's snapshot block.

Integrating Snapshot into a mobile app is GraphQL API for reading data and REST API for submitting votes with signatures.

Reading Data: Snapshot GraphQL API

// Android — fetching proposals from Space via GraphQL
suspend fun getProposals(spaceId: String, first: Int = 20): List<SnapshotProposal> {
    val query = """
        {
          proposals(
            first: $first,
            skip: 0,
            where: { space: "$spaceId", state: "active" },
            orderBy: "created",
            orderDirection: desc
          ) {
            id
            title
            body
            choices
            start
            end
            snapshot
            state
            scores
            scores_total
            votes
            quorum
            author
          }
        }
    """.trimIndent()
    return snapshotApi.query(query).data?.proposals ?: emptyList()
}

Endpoint: https://hub.snapshot.org/graphql. Space ID is DAO's unique Snapshot identifier (e.g., uniswap.eth, aave.eth).

Voting: EIP-712 Signature

A vote is a signed message with typed data:

// iOS — forming and signing vote for Snapshot
func createVoteMessage(
    proposalId: String,
    choice: Int,
    spaceId: String,
    snapshotBlock: String
) -> TypedData {
    return TypedData(
        domain: TypedDataDomain(
            name: "snapshot",
            version: "0.1.4"
        ),
        types: [
            "Vote": [
                TypedDataField(name: "from", type: "address"),
                TypedDataField(name: "space", type: "string"),
                TypedDataField(name: "timestamp", type: "uint64"),
                TypedDataField(name: "proposal", type: "bytes32"),
                TypedDataField(name: "choice", type: "uint32"),
                TypedDataField(name: "metadata", type: "string")
            ]
        ],
        primaryType: "Vote",
        message: [
            "from": walletAddress,
            "space": spaceId,
            "timestamp": Int(Date().timeIntervalSince1970),
            "proposal": proposalId,
            "choice": choice,
            "metadata": "{}"
        ]
    )
}

After obtaining the signature from user — send to Snapshot API:

// iOS — submitting signed vote to Snapshot Hub
func submitVote(vote: VotePayload, sig: String) async throws {
    let body = SnapshotVoteRequest(
        address: walletAddress,
        msg: jsonEncode(vote),
        sig: sig
    )
    try await snapshotClient.post("/api/msg", body: body)
}

POST https://hub.snapshot.org/api/msg — endpoint for publishing. Response contains vote id (IPFS hash).

Voting Strategies

Snapshot supports custom strategies for determining vote weight:

  • erc20-balance-of — standard token balance
  • erc20-votes — delegated weight via getVotes()
  • delegation — including incoming delegations
  • quadratic — square root of balance
  • Can combine multiple strategies

Strategies are read from Space config via GET https://hub.snapshot.org/api/spaces/{spaceId}. Show users which strategy is used and their voting power.

Calculating Vote Weight Before Voting

// Android — fetching voting power via Snapshot Score API
suspend fun getVotingPower(
    voter: String,
    spaceId: String,
    proposal: SnapshotProposal
): BigDecimal {
    val response = snapshotScoreApi.getScores(
        space = spaceId,
        strategies = proposal.strategies,
        network = proposal.network,
        addresses = listOf(voter),
        snapshot = proposal.snapshot.toLong()
    )
    return response.result.scores.firstOrNull()?.get(voter) ?: BigDecimal.ZERO
}

Endpoint: https://score.snapshot.org/api/scores. Display voting power directly in voting form: "Your power: 1,250.4 UNI".

Snapshot Voting Types

Type Description
single-choice One option
approval Multiple options
ranked-choice Ranking (IRV)
quadratic Quadratic voting
weighted Distribute power across options

Each type requires its own UI form. weighted — sliders with percentages, sum = 100%. ranked-choice — drag-and-drop or numbered list.

Timeline: 3–5 days: GraphQL queries for proposal list and details, voting form with EIP-712 signature via WalletConnect, displaying voting power, supporting basic voting types (single-choice, approval).