Skip to content

feat: route gasless voting through governance vote-relay, drop gelato#3077

Open
JoaquinBattilana wants to merge 12 commits into
mainfrom
feat/gasless-vote-relay
Open

feat: route gasless voting through governance vote-relay, drop gelato#3077
JoaquinBattilana wants to merge 12 commits into
mainfrom
feat/gasless-vote-relay

Conversation

@JoaquinBattilana

Copy link
Copy Markdown
Member

Summary

Routes gasless governance voting through the new governance vote-relay (governance-v3-cache PR #126) and removes the Gelato relayer, whose sponsor flow required calldata built in the browser and a key managed outside our infra.

The relay now encodes submitVoteBySignature server-side, so the browser only sends the raw voting-balance proofs plus the EIP-712 signature. The browser never holds the relay API key — it calls a same-origin Next.js proxy that attaches the server-side key, mirroring pages/api/rpc-proxy.ts.

browser ──sign + POST──> /api/governance/vote-relay/* ──x-api-key──> vote-relay ──> VotingMachine

Changes

  • New pages/api/governance/vote-relay/[...path].ts — same-origin proxy. Attaches server-side x-api-key, forwards the caller IP as x-forwarded-for (relay's per-IP rate limiter keys on it), and passes the relay's status/body straight through. Allowlists only the relay's vote routes (incl. /v1/votes/representative) so it can't be used as an open proxy.
  • New src/components/transactions/GovVote/temporary/voteRelayClient.tssubmitRelayVote (POST raw proofs + signature) and pollVoteStatus (polls until MINED/CONFIRMED; fails on FAILED|EXPIRED|CANCELLED|DROPPED; keeps waiting on PENDING|INMEMPOOL|REPLACED), plus a typed RelayError { code, retryable }.
  • Edit GovVoteActions.tsx — the gasless branch now signs (unchanged EIP-712) → POSTs to the proxy → polls status. On RELAYER_UNAVAILABLE it falls back to the self-paid submitVote; any other relay error (bad signature, already voted, simulation reverted, vote in flight) surfaces to the user.
  • Edit VotingMachineService.ts — dropped the now-unused generateSubmitVoteBySignatureTxData (the relay encodes calldata itself).
  • Removed pages/api/gelato/relay.ts and the GELATO_SPONSOR_KEY env var.
  • Env — added VOTE_RELAY_URL + VOTE_RELAY_API_KEY (server-side only) to .env.example.

The NEXT_PUBLIC_ENABLE_GASLESS_VOTING gate is unchanged. When the relay is unconfigured, the proxy returns RELAYER_UNAVAILABLE and voting falls back to self-paid, so nothing breaks before the relay is live.

Notes / out of scope

  • Representative voting UI is not included. The proxy forwards /v1/votes/representative, but there is no client logic for SubmitVoteAsRepresentative signing / proofOfRepresentation / represented-voter selection yet — a separate follow-up.
  • Not verified end-to-end against a live relay (needs a staging VOTE_RELAY_API_KEY and an in-window proposal). Verified by typecheck + lint; happy path is logic/types only.
  • Depends on governance-v3-cache PR feat: staking page #126 being deployed. Stacked on feat/governance-cache-sdk (the branch that introduced the Gelato flow this replaces).

Testing

  • tsc --noEmit clean.
  • ESLint + prettier clean on all touched files.

@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
interface Ready Ready Preview, Comment Jul 22, 2026 3:34am

Request Review

sammdec
sammdec previously approved these changes Jul 22, 2026
// The browser never holds the relay's api key: it calls this route, which attaches
// the server-side `x-api-key` and forwards to the relay, mirroring `rpc-proxy.ts`.
// See governance-v3-cache PR #126 for the relay contract.
const VOTE_RELAY_URL = process.env.VOTE_RELAY_URL; // e.g. https://governance-cache-api.aave.com/relay

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoaquinBattilana Do we need to add this to vercel?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we should add typed env vars as we have in v4 (in a separated PR)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agreed

// the server-side `x-api-key` and forwards to the relay, mirroring `rpc-proxy.ts`.
// See governance-v3-cache PR #126 for the relay contract.
const VOTE_RELAY_URL = process.env.VOTE_RELAY_URL; // e.g. https://governance-cache-api.aave.com/relay
const VOTE_RELAY_API_KEY = process.env.VOTE_RELAY_API_KEY;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoaquinBattilana Add to vercel?

@linear-code

linear-code Bot commented Jul 22, 2026

Copy link
Copy Markdown

AAVEV3-156

Base automatically changed from feat/governance-cache-sdk to main July 22, 2026 14:19
@JoaquinBattilana
JoaquinBattilana dismissed sammdec’s stale review July 22, 2026 14:19

The base branch was changed.

Comment on lines +78 to +80
const text = await relayResponse.text();
res.status(relayResponse.status);
res.setHeader('Content-Type', 'application/json');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how we handle 4xxs

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.

3 participants