From 578b3e07f6dab8d5d520c112238050f3690b557b Mon Sep 17 00:00:00 2001 From: Francesco Medas Date: Fri, 5 Jun 2026 12:56:04 +0400 Subject: [PATCH] Revert "fix(governance-api): normalize EVM (MetaMask) submitters to their Zilliqa address (#778)" This reverts commit f0339c68ad01e58dcba9f878efadbe480dff7969. --- products/governance-api/lib/routes/message.ts | 12 +---- .../lib/utils/verify-evm-signature.test.ts | 53 ------------------- .../lib/utils/verify-evm-signature.ts | 24 +-------- products/governance-api/package.json | 2 +- 4 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 products/governance-api/lib/utils/verify-evm-signature.test.ts diff --git a/products/governance-api/lib/routes/message.ts b/products/governance-api/lib/routes/message.ts index 7877be3fe..d18cb4f2c 100644 --- a/products/governance-api/lib/routes/message.ts +++ b/products/governance-api/lib/routes/message.ts @@ -2,7 +2,7 @@ import { Router } from "express"; import BN from "bn.js"; import spaces from "@snapshot-labs/snapshot-spaces"; import { verifySignature, pinJson } from "../utils"; -import { verifyEVMSignature, zilliqaAddressFromEVMSignature } from "../utils/verify-evm-signature"; +import { verifyEVMSignature } from "../utils/verify-evm-signature"; import { Message } from "../models"; import { blockchain } from "../zilliqa/custom-fetch"; @@ -226,16 +226,6 @@ message.post("/message", async (req, res) => { log.info({ address: body.address, sigType: body.sigType || "schnorr" }, "Signature verified"); - // EVM users sign with their 0x (Keccak) address, but their gZIL/ZRC2 balances and space - // membership are keyed by their Zilliqa (SHA256) address. Replace body.address with the - // canonical Zilliqa address recovered from the signature so the gZIL gate, the pinned - // voter-scoring snapshot, and the members/score checks all resolve against the user's real - // Zilliqa identity. Applies to both proposals and votes (same handler). - if (body.sigType === "evm") { - body.address = zilliqaAddressFromEVMSignature(body.sig.message, body.sig.signature); - log.info({ zilAddress: body.address }, "EVM identity normalized to Zilliqa address"); - } - proposal(res, msg); await vote(res, msg, ts, log); diff --git a/products/governance-api/lib/utils/verify-evm-signature.test.ts b/products/governance-api/lib/utils/verify-evm-signature.test.ts deleted file mode 100644 index a686c6bcb..000000000 --- a/products/governance-api/lib/utils/verify-evm-signature.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -// ABOUTME: Asserts zilliqaAddressFromEVMSignature recovers the signer's canonical Zilliqa address. -// ABOUTME: Run with `node --require ts-node/register lib/utils/verify-evm-signature.test.ts`. -import assert from "assert"; -import { Wallet, SigningKey } from "ethers"; -import { getAddressFromPublicKey } from "@zilliqa-js/crypto"; -import { - zilliqaAddressFromEVMSignature, - verifyEVMSignature, -} from "./verify-evm-signature"; - -// A MetaMask user signs with their EVM (Keccak) address, but their gZIL/ZRC2 balances and -// space membership live under their Zilliqa (SHA256) address. This proves we can recover the -// Zilliqa address from the EVM personal_sign signature alone. - -async function derivesCanonicalZilliqaAddress() { - const pk = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"; - const wallet = new Wallet(pk); - const message = JSON.stringify({ version: "0.1.2", type: "proposal", token: "duck" }); - const signature = await wallet.signMessage(message); // EIP-191 personal_sign - - // Ground truth derived straight from the private key (independent of the recovery path). - const expectedZil = getAddressFromPublicKey( - new SigningKey(pk).compressedPublicKey.replace(/^0x/, "") - ); - - const got = zilliqaAddressFromEVMSignature(message, signature); - - assert.strictEqual( - got.toLowerCase(), - expectedZil.toLowerCase(), - "derives the signer's canonical Zilliqa address from the EVM signature" - ); - assert.notStrictEqual( - got.toLowerCase(), - wallet.address.toLowerCase(), - "the Zilliqa address must differ from the EVM 0x address (the whole point)" - ); - // The same signature still verifies against the EVM address (unchanged behaviour). - assert.strictEqual( - verifyEVMSignature(message, signature, wallet.address), - true, - "EVM signature still verifies against the EVM address" - ); - console.log("OK derivesCanonicalZilliqaAddress:", got, "(EVM:", wallet.address + ")"); -} - -(async () => { - await derivesCanonicalZilliqaAddress(); - console.log("ALL PASS"); -})().catch((e) => { - console.error("FAIL:", e.message); - process.exit(1); -}); diff --git a/products/governance-api/lib/utils/verify-evm-signature.ts b/products/governance-api/lib/utils/verify-evm-signature.ts index cca54bdc1..866f67f39 100644 --- a/products/governance-api/lib/utils/verify-evm-signature.ts +++ b/products/governance-api/lib/utils/verify-evm-signature.ts @@ -1,5 +1,4 @@ -import { ethers, hashMessage, SigningKey } from 'ethers'; -import { getAddressFromPublicKey } from '@zilliqa-js/crypto'; +import { ethers } from 'ethers'; /** * Verifies an EIP-191 personal_sign signature. @@ -18,24 +17,3 @@ export function verifyEVMSignature( const normalised = address.startsWith('0x') ? address.slice(2) : address; return recovered.slice(2).toLowerCase() === normalised.toLowerCase(); } - -/** - * Derives the signer's canonical Zilliqa address (SHA256-based) from an EIP-191 personal_sign - * signature, by recovering the public key. This is the address ZilPay shows for the same key — - * i.e. where the user's gZIL/ZRC2 balances and space membership live. We use it to normalise an - * EVM (MetaMask) submitter to their Zilliqa identity so the gZIL gate, the pinned voter-scoring - * snapshot, and the members/score checks all resolve correctly. - * - * @param message - The raw string passed to personal_sign (msg.msg from the request). - * @param signature - The 0x-prefixed hex signature returned by personal_sign. - * @returns The checksummed Zilliqa base16 address ("0x…"). - */ -export function zilliqaAddressFromEVMSignature( - message: string, - signature: string -): string { - const digest = hashMessage(message); // EIP-191 digest, matching personal_sign - const uncompressed = SigningKey.recoverPublicKey(digest, signature); // "0x04…" - const compressed = SigningKey.computePublicKey(uncompressed, true); // "0x02/03…" - return getAddressFromPublicKey(compressed.replace(/^0x/, '')); -} diff --git a/products/governance-api/package.json b/products/governance-api/package.json index 3faea058e..3b084a4b0 100644 --- a/products/governance-api/package.json +++ b/products/governance-api/package.json @@ -8,7 +8,7 @@ "db:seed": "npx sequelize db:seed:all", "db:create": "npx sequelize db:create", "start": "node --require ts-node/register index.ts", - "test": "node --require ts-node/register lib/zilliqa/custom-fetch.test.ts && node --require ts-node/register lib/utils/verify-evm-signature.test.ts" + "test": "node --require ts-node/register lib/zilliqa/custom-fetch.test.ts" }, "author": "Hicaru", "license": "MIT",