Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2bceb82
fix(dashboard): make the RPC proxy URL absolute for WalletConnect
brunod-e Aug 11, 2026
d5b43a6
Merge pull request #2112 from blockful/hotfix/walletconnect-absolute-…
pikonha Aug 11, 2026
f7943f8
Merge branch 'main' into dev
pikonha Aug 13, 2026
4bf577e
chore: version packages
github-actions[bot] Aug 13, 2026
dbd2f4f
Merge pull request #2120 from blockful/changeset-release/dev
pikonha Aug 13, 2026
4a410fe
feat(relayer): add POST /relay/queue and /relay/execute proposal endp…
LeonardoVieira1630 Aug 13, 2026
245beb6
refactor(relayer): make ANTICAPTURE_API_URL required
LeonardoVieira1630 Aug 13, 2026
72509df
refactor: unnecessary comments
LeonardoVieira1630 Aug 13, 2026
50109a9
refactor(relayer): mock proposal-source tests with msw instead of inj…
LeonardoVieira1630 Aug 13, 2026
7cdb079
refactor: source to call anticapture via sdk
LeonardoVieira1630 Aug 13, 2026
5f974d6
refactor: rename class
LeonardoVieira1630 Aug 13, 2026
028d2be
refactor(relayer): house stub-factory pattern in enactment tests
LeonardoVieira1630 Aug 13, 2026
c24a289
feat(dashboard): add the services row to the panel
brunod-e Aug 13, 2026
d5f8ac9
refactor(relayer): extract GovernorGateway domain interface
LeonardoVieira1630 Aug 13, 2026
75f1051
ci(relayer): add changeset and run client codegen in the Docker build
LeonardoVieira1630 Aug 13, 2026
5fc5286
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 13, 2026
c12e7b7
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 13, 2026
42e23df
fix(dashboard): draw the services badge icon in the dimmed colour
brunod-e Aug 13, 2026
feefc70
fix(dashboard): space the panel sections the way the design draws them
brunod-e Aug 14, 2026
cc11b48
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 14, 2026
d8eed0f
fix(relayer): harden /relay endpoints per review findings
LeonardoVieira1630 Aug 14, 2026
3616fd6
fix(relayer): fetch the codegen spec over gateful's public domain
LeonardoVieira1630 Aug 14, 2026
add355c
fix(relayer): address Codex review on PR #2122
LeonardoVieira1630 Aug 14, 2026
fdbbcde
Merge pull request #2122 from blockful/feat/relayer-queue-execute-end…
LeonardoVieira1630 Aug 14, 2026
d2e152f
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 14, 2026
dd33254
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 14, 2026
ba5d1cd
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 17, 2026
881dd44
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 17, 2026
9a5948f
fix(dashboard): keep service dividers off wrapped line boundaries
brunod-e Aug 17, 2026
5db013d
Merge branch 'feat/panel-v2.1-use-it-now' into feat/panel-v2.1-servic…
brunod-e Aug 17, 2026
9ddac26
feat(dashboard): enable the Gitcoin whitelabel with full governance
brunod-e Aug 18, 2026
fd3891a
Merge pull request #2134 from blockful/feat/gitcoin-whitelabel
pikonha Aug 19, 2026
e388432
Merge remote-tracking branch 'origin/dev' into feat/panel-v2.1-servic…
brunod-e Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .changeset/common-wombats-cheat.md

This file was deleted.

7 changes: 7 additions & 0 deletions .changeset/gateful-relay-enactment-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@anticapture/gateful": minor
---

The public API surface gains POST /{dao}/relay/queue and
POST /{dao}/relay/execute, proxied to the relayer's new proposal enactment
endpoints and merged into the Gateful OpenAPI spec.
5 changes: 5 additions & 0 deletions .changeset/gitcoin-whitelabel-governance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@anticapture/dashboard": minor
---

Enable the Gitcoin whitelabel with full governance (create, vote, queue and execute proposals).
5 changes: 5 additions & 0 deletions .changeset/panel-v21-services-row.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@anticapture/dashboard": minor
---

Add the Blockful services row at the foot of the panel, listing the service lines with a link to the contact page.
8 changes: 8 additions & 0 deletions .changeset/relayer-proposal-enactment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@anticapture/relayer": minor
---

Add POST /relay/queue and /relay/execute endpoints that sponsor the
permissionless Governor lifecycle transactions. Proposal args are fetched from
the Anticapture API by proposal id and verified trustlessly against the
governor's hashProposal before anything is signed.
6 changes: 6 additions & 0 deletions apps/dashboard/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @anticapture/dashboard

## 2.14.1

### Patch Changes

- [#2112](https://github.com/blockful/anticapture/pull/2112) [`2bceb82`](https://github.com/blockful/anticapture/commit/2bceb8236d85654972fdfbba9167e2c0fd3c319e) Thanks [@brunod-e](https://github.com/brunod-e)! - Fix WalletConnect pairing by giving the provider an absolute RPC proxy URL.

## 2.14.0

### Minor Changes
Expand Down
11 changes: 10 additions & 1 deletion apps/dashboard/features/create-proposal/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export const BODY_CHAR_LIMIT = 100_000;
export const BODY_WARNING_THRESHOLD = 95_000;

export const canCreateProposalForDao = (daoId: DaoIdEnum | null | undefined) =>
daoId === DaoIdEnum.ENS || daoId === DaoIdEnum.SHU;
daoId === DaoIdEnum.ENS ||
daoId === DaoIdEnum.SHU ||
daoId === DaoIdEnum.GITCOIN;

export interface SuggestedTransferToken {
symbol: string;
Expand Down Expand Up @@ -36,6 +38,13 @@ export const SUGGESTED_TRANSFER_TOKENS: Partial<
trustWalletToken("WETH", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
trustWalletToken("ENS", "0xc18360217d8f7ab5e7c516566761ea12ce7f9d72"),
],
[DaoIdEnum.GITCOIN]: [
trustWalletToken("USDT", "0xdac17f958d2ee523a2206206994597c13d831ec7"),
trustWalletToken("USDC", "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
trustWalletToken("DAI", "0x6b175474e89094c44da98b954eedeac495271d0f"),
trustWalletToken("WETH", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
trustWalletToken("GTC", "0xde30da39c46104798bb5aa3fe8b9e0e1f348163f"),
],
};

export const PROPOSAL_JSON_PLACEHOLDER = `{
Expand Down
36 changes: 23 additions & 13 deletions apps/dashboard/features/panel/PanelSection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LatestFindingTicker } from "@/features/panel/components/LatestFindingTicker";
import { PanelHero } from "@/features/panel/components/PanelHero";
import { PanelTable } from "@/features/panel/components/PanelTable";
import { ServicesRow } from "@/features/panel/components/ServicesRow";
import { TrackRecordSection } from "@/features/panel/components/TrackRecordSection";
import { UseItNowSection } from "@/features/panel/components/UseItNowSection";
import {
Expand All @@ -10,24 +11,33 @@ import {

export const PanelSection = () => {
return (
<div className="mt-12 flex w-full flex-col gap-5 px-4 py-5 lg:mt-0 lg:gap-2 lg:p-5">
<PanelHero />
// Figma spaces the three blocks 32px apart and everything inside them 8px
// apart, so the inner wrappers hold the tight gap while the page holds the
// section rhythm.
<div className="mt-12 flex w-full flex-col gap-5 px-4 py-5 lg:mt-0 lg:gap-8 lg:p-5">
<div className="flex flex-col gap-5 lg:gap-2">
<PanelHero />

<LatestFindingTicker />
<LatestFindingTicker />

<SubSectionsContainer className="gap-3">
<SubSection
className="gap-0"
subsectionTitle={"Monitored DAOs"}
dateRange=""
>
<PanelTable />
</SubSection>
</SubSectionsContainer>
<SubSectionsContainer className="gap-3">
<SubSection
className="gap-0"
subsectionTitle={"Monitored DAOs"}
dateRange=""
>
<PanelTable />
</SubSection>
</SubSectionsContainer>
</div>

<TrackRecordSection />

<UseItNowSection />
<div className="flex flex-col gap-5 lg:gap-2">
<UseItNowSection />

<ServicesRow />
</div>
</div>
);
};
54 changes: 54 additions & 0 deletions apps/dashboard/features/panel/components/ServicesRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { ChevronRight, ShieldCheck } from "lucide-react";

import { BadgeIcon } from "@/shared/components/design-system/badges/badge-icon/BadgeIcon";
import { DefaultLink } from "@/shared/components/design-system/links/default-link/DefaultLink";
import { BulletDivider } from "@/shared/components/design-system/section/bullet-divider/BulletDivider";

const SERVICES = [
"Security audits",
"Calldata review",
"Front-end package",
"Consulting & research",
];

export const ServicesRow = () => {
return (
<div className="bg-surface-default flex flex-col gap-2 p-3 lg:flex-row lg:items-center lg:justify-between lg:gap-4">
<div className="flex flex-col gap-2 lg:flex-row lg:items-center lg:gap-4">
<div className="flex items-center gap-1.5">
<BadgeIcon icon={ShieldCheck} variant="dimmed" iconVariant="dimmed" />
<h2 className="text-primary text-alternative-xs font-mono font-medium uppercase leading-4 tracking-wider">
Services by Blockful
</h2>
</div>

{/* Every label carries a leading bullet and the list is pulled left by
* exactly that lead-in (4px bullet + 7px gap) inside an overflow-hidden
* wrapper, so a bullet landing at a wrapped line start is clipped away
* instead of reading as a list marker. */}
<div className="overflow-hidden">
<div className="-ml-[11px] flex flex-wrap items-center gap-x-[7px] gap-y-1">
{SERVICES.map((service) => (
<div key={service} className="flex items-center gap-x-[7px]">
<BulletDivider />
<span className="text-secondary text-sm font-normal leading-5">
{service}
</span>
</div>
))}
</div>
</div>
</div>

<DefaultLink
href="/contact"
variant="highlight"
size="sm"
openInNewTab={false}
>
Talk to us
<ChevronRight className="size-4" />
</DefaultLink>
</div>
);
};
1 change: 1 addition & 0 deletions apps/dashboard/features/panel/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from "@/features/panel/components/PanelHero";
export * from "@/features/panel/components/LatestFindingTicker";
export * from "@/features/panel/components/TrackRecordSection";
export * from "@/features/panel/components/UseItNowSection";
export * from "@/features/panel/components/ServicesRow";
export * from "@/features/panel/components/DaoProtectionLevels";
export * from "@/features/panel/components/TooltipCell";
2 changes: 1 addition & 1 deletion apps/dashboard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@anticapture/dashboard",
"version": "2.14.0",
"version": "2.14.1",
"private": true,
"scripts": {
"dev": "next dev --turbo",
Expand Down
7 changes: 5 additions & 2 deletions apps/dashboard/shared/dao-config/gtc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { QUORUM_CALCULATION_TYPES } from "@/shared/constants/labels";
import { RECOMMENDED_SETTINGS } from "@/shared/constants/recommended-settings";
import type { DaoConfiguration } from "@/shared/dao-config/types";
import { GitcoinOgIcon } from "@/shared/og/dao-og-icons";
import { toAbsoluteUrl } from "@/shared/seo/site";
import {
RiskLevel,
GovernanceImplementationEnum,
Expand All @@ -23,6 +24,8 @@ export const GTC: DaoConfiguration = {
forumLink: "https://gov.gitcoin.co/",
icon: GitcoinIcon,
ogIcon: GitcoinOgIcon,
hostnames: ["gitcoin.gov.blockful.io"],
whitelabel: {},
daoOverview: {
token: "ERC20",
chain: { ...mainnet, icon: MainnetIcon },
Expand All @@ -33,8 +36,8 @@ export const GTC: DaoConfiguration = {
timelock: "0x57a8865cfB1eCEf7253c27da6B4BC3dAEE5Be518",
},
govPlatform: {
name: "Tally",
url: "https://tally.xyz/gov/gitcoin/proposal/",
name: "Anticapture",
url: toAbsoluteUrl("/gtc/proposals/"),
},
cancelFunction:
"https://etherscan.io/address/0x57a8865cfB1eCEf7253c27da6B4BC3dAEE5Be518#writeContract#F2",
Expand Down
9 changes: 8 additions & 1 deletion apps/dashboard/shared/services/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import { createWalletClient } from "viem";
import { createConfig, http } from "wagmi";
import { mainnet, optimism, scroll } from "wagmi/chains";

const rpcTransport = (chainId: number) => http(`/api/rpc/${chainId}`);
// The RPC proxy path must be absolute in the browser: wagmi hands these
// transport URLs to the WalletConnect provider's rpcMap, whose HTTP
// connection rejects relative URLs (breaking every WalletConnect pairing
// right after session approval). During SSR the transports are never
// called, so the relative path is fine there.
const origin = typeof window === "undefined" ? "" : window.location.origin;

const rpcTransport = (chainId: number) => http(`${origin}/api/rpc/${chainId}`);

export const walletClient = createWalletClient({
chain: mainnet,
Expand Down
3 changes: 3 additions & 0 deletions apps/relayer/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ MAX_DELEGATIONS_PER_ADDRESS_PER_MONTH=3

# Server
PORT=3002

ANTICAPTURE_API_URL=https://dev-gateful.up.railway.app
ANTICAPTURE_API_KEY=...
24 changes: 24 additions & 0 deletions apps/relayer/e2e/fixtures/executed-proposal.ts

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion apps/relayer/e2e/helpers/anvil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export async function startAnvil(options?: {
port?: number;
logs?: boolean;
forkUrl?: string;
/** Overrides the shared FORK_BLOCK for suites pinned to specific state. */
forkBlockNumber?: number;
}): Promise<string> {
const forkUrl = options?.forkUrl ?? process.env["RPC_URL"];
if (!forkUrl) {
Expand All @@ -29,7 +31,7 @@ export async function startAnvil(options?: {
anvilInstance = Instance.anvil(
{
forkUrl,
forkBlockNumber: FORK_BLOCK,
forkBlockNumber: options?.forkBlockNumber ?? FORK_BLOCK,
...(options?.port !== undefined ? { port: options.port } : {}),
},
{ timeout: 30_000 },
Expand Down
Loading
Loading