Реалізація підключення Snapshot для голосування DAO у мобільному додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація підключення Snapshot для голосування DAO у мобільному додатку
Середній
~3-5 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Впровадження інтеграції Snapshot для голосування DAO в мобільних додатках

Snapshot — це off-chain система голосування, де користувач підписує повідомлення EIP-712 своїм гаманцем, а результат зберігається в децентралізованій мережі IPFS/Snapshot Hub. Голосування нічого не коштує — немає газу. Вага голосу визначається балансом токенів у блокчейні на моменту снапшоту пропозиції.

Інтеграція Snapshot у мобільний додаток — це GraphQL API для читання даних та REST API для відправки голосів з підписом.

Читання даних: Snapshot GraphQL API

// Android — отримання списку пропозицій Space через 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 — унікальний ідентифікатор DAO у Snapshot (наприклад, uniswap.eth, aave.eth).

Голосування: Підпис EIP-712

Голос — це підписане повідомлення з типізованими даними:

// iOS — формування та підпис голосу для 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": "{}"
        ]
    )
}

Після отримання підпису від користувача — відправте в Snapshot API:

// iOS — відправка підписаного голосу в 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 для публікації. У відповіді — id голосу (IPFS хеш).

Стратегії голосування

Snapshot підтримує кастомні стратегії визначення ваги голосу:

  • erc20-balance-of — стандартний баланс токена
  • erc20-votes — делегована вага через getVotes()
  • delegation — з урахуванням вхідних делегацій
  • quadratic — квадратний корінь від балансу
  • Можна комбінувати кілька стратегій

Стратегії читаються з конфігурації Space через GET https://hub.snapshot.org/api/spaces/{spaceId}. Показуйте користувачам, яка стратегія використовується та їх голосуюча сила.

Розрахунок ваги голосу перед голосуванням

// Android — отримання голосуючої сили через 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. Показуйте голосуючу силу прямо у формі голосування: «Ваша сила: 1250,4 UNI».

Типи голосування Snapshot

Тип Описання
single-choice Один варіант
approval Кілька варіантів
ranked-choice Ранжування (IRV)
quadratic Квадратичне голосування
weighted Розподіл сили по варіантам

Кожен тип потребує своєї UI форми. weighted — слайдери з відсотками, сума = 100%. ranked-choice — drag-and-drop або нумерований список.

Часова шкала: 3–5 днів: GraphQL запити для списку пропозицій та деталей, форма голосування з EIP-712 підписом через WalletConnect, відображення голосуючої сили, підтримка базових типів голосування (single-choice, approval).