Skip to content

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

Merged
JoaquinBattilana merged 14 commits into
mainfrom
feat/gasless-vote-relay
Aug 13, 2026
Merged

feat: route gasless voting through governance vote-relay, drop gelato#3077
JoaquinBattilana merged 14 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 Aug 13, 2026 2:28pm

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

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.

no need to be env var this one i think

// 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?

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.

added to staging, prod not available yet

@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

# Conflicts:
#	.env.example
#	src/components/transactions/GovVote/GovVoteActions.tsx
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

@mgrabina

mgrabina commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

note
image

sammdec
sammdec previously approved these changes Aug 11, 2026
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

⚠️ Global Bundle Size Increased

Page Size (compressed)
global 1.32 MB (🟡 +10 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

Six Pages Changed Size

The following pages changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/ 96.01 KB (🟡 +2 B) 1.42 MB
/dashboard 85.59 KB (🟡 +2 B) 1.41 MB
/markets 54.89 KB (🟡 +2 B) 1.38 MB
/safety-module 56.45 KB (🟡 +2 B) 1.38 MB
/sgho 92.99 KB (🟡 +2 B) 1.41 MB
/v3-migration 52.64 KB (🟡 +2 B) 1.37 MB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

@JoaquinBattilana
JoaquinBattilana merged commit 7e1c978 into main Aug 13, 2026
20 of 21 checks passed
@JoaquinBattilana
JoaquinBattilana deleted the feat/gasless-vote-relay branch August 13, 2026 15:44
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