Skip to content

Deliver EVM integration for governance portal#773

Merged
lukozill merged 3 commits intomainfrom
users/lukasz/adding_evm_support_to_governance_portal
Apr 17, 2026
Merged

Deliver EVM integration for governance portal#773
lukozill merged 3 commits intomainfrom
users/lukasz/adding_evm_support_to_governance_portal

Conversation

@lukozill
Copy link
Copy Markdown
Contributor

Summary

Adds EVM wallet support (MetaMask, Ledger Live, Brave Wallet, Coinbase Wallet, and any
window.ethereum-injecting extension) as an alternative to the existing ZilPay connector in
the Governance Portal.

No new frontend dependencies — all EVM wallet interaction goes through the
browser-injected window.ethereum provider. @web3modal/standalone + @wagmi/core were
considered but rejected: wagmi v2 and viem are ESM-only and conflict with Vue CLI 4 /
Webpack 4, requiring invasive config changes not worth taking on in a legacy project. The
trade-off is that WalletConnect QR-code flow is not supported, which is acceptable because
the target users connect hardware Ledgers via MetaMask or Ledger Live.

Phase 1 — Decouple blockchain reads from ZilPay (governance-snapshot)

  • Added src/helpers/zilliqa.ts — shared @zilliqa-js/zilliqa singleton pointed at
    https://api.zilliqa.com/
  • Rewrote getBlockNumber and getTotalSupply in src/helpers/web3.ts to use the RPC
    singleton directly instead of the ZilPay provider object
  • Rewrote the zrc2-balance-of strategy in src/helpers/get-scores.ts to use the RPC
    singleton
  • Updated all callers in src/store/modules/app.ts and src/views/Create.vue — ZilPay is
    no longer involved in any read path

Phase 2 — EVM connector and store wiring (governance-snapshot)

  • Added "evm" entry to src/helpers/connectors.json
  • Added EVMConnector class to src/helpers/plugins/LockPlugin.ts — connects via
    eth_requestAccounts, session-checks via eth_accounts (no prompt), logout clears
    localStorage only
  • Registered EVMConnector in src/auth.ts
  • Updated loadProvider in src/store/modules/web3.ts: EVM path derives base16/bech32
    from the connected address using toBech32Address from @zilliqa-js/crypto; subscribes to
    accountsChanged events
  • Updated signMessage in src/helpers/web3.ts: EVM path signs via personal_sign
    (EIP-191), returning { message, signature }; ZilPay Schnorr path unchanged
  • Updated send() in src/store/modules/app.ts to include sigType: 'evm' | 'schnorr' in
    the API request body
  • Fixed connector icon in src/components/Modal/Account.vue to show a generic wallet icon
    for non-ZilPay connectors

Phase 3 — Backend EVM signature verification (governance-api)

  • Added ethers dependency
  • Created lib/utils/verify-evm-signature.ts — verifies EIP-191 personal_sign signatures
    using ethers.utils.verifyMessage + ecrecover
  • Updated lib/routes/message.ts: routes signature verification by sigType'evm' uses
    ECDSA recovery, default uses existing Schnorr path; all existing ZilPay and legacy
    submissions continue to work unchanged

Key design decisions

  • EVM addresses are stored in the same format as ZilPay addresses (lowercase hex, no 0x
    prefix). The existing validation.isBech32 guard in message.ts already handles this
    correctly.
  • All balances (including EVM wallet users') live on the Scilla side of Zilliqa, keyed by
    base16 address — no changes needed to balance retrieval or the 30 gZIL proposal minimum
    check.
  • The Vuex web3 state shape ({ base16, bech32 }) is unchanged; bech32 is derived from
    the EVM address via toBech32Address.
  • Session persistence follows the same _lock.connector localStorage pattern as ZilPay.

Test plan

  • Locally ran the governance portal with governance docker compose
  • Created a new vote in GZIL space
  • Voted with ZilPay wallet (Schnorr path — regression)
  • Voted with EVM wallet (MetaMask / window.ethereum — new path)

@lukozill lukozill merged commit 8571b9f into main Apr 17, 2026
1 of 3 checks passed
@lukozill lukozill deleted the users/lukasz/adding_evm_support_to_governance_portal branch April 17, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants