Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 22 additions & 5 deletions packages/nextjs/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ NEXT_PUBLIC_SEPOLIA_RPC_URL=
# --- Gas-drip faucet (OFF by default) ---
# Base URL of an HTTP faucet service (efs-project/devnet → faucet/). When set AND
# the wallet is on the faucet's chain (NEXT_PUBLIC_FAUCET_CHAIN_ID below), the app
# auto-drips a little gas on connect and shows a "Get test ETH" button in the
# wallet menu. Unset = disabled.
# can request gas after an explicit user action: the wallet-menu "Get test ETH"
# button, or the one-click editing wallet flow below. Loading the page or merely
# connecting a wallet does not drip. Unset = disabled.
#
# This is for the one network with NO unlocked account — live Sepolia (11155111).
# The fork chains (Local 31337 and the EFS Devnet 26001993) are funded instead by
Expand All @@ -80,10 +81,27 @@ NEXT_PUBLIC_SEPOLIA_RPC_URL=
# NEXT_PUBLIC_FAUCET_URL=https://<faucet-host>/faucet
NEXT_PUBLIC_FAUCET_URL=

# Chain the faucet funds — the drip only fires when the wallet is on it. Defaults
# to live Sepolia (11155111). Override only to point at another real testnet.
# Chain the faucet funds — faucet requests are allowed only when the wallet is on
# it. Defaults to live Sepolia (11155111). Override only to point at another real testnet.
NEXT_PUBLIC_FAUCET_CHAIN_ID=

# --- One-click editing wallet for live Sepolia ---
# When NEXT_PUBLIC_FAUCET_URL is set and the build defaults to that faucet chain,
# the debug UI shows a one-click "Enable promptless edits" affordance. Clicking it connects
# the existing Scaffold-ETH burner wallet with no popup; the faucet drip then funds
# that wallet. This is only a signer convenience: writes are authored by this wallet
# address, not by any durable EFS identity/account model. Real wallets still work
# and take precedence; disconnecting a real wallet falls back to the burner only
# after the visitor has explicitly enabled editing on the current page.
#
# Default: the one-click affordance is enabled whenever NEXT_PUBLIC_FAUCET_URL is
# configured. Set to false as a kill switch without removing the faucet service
# from the manual wallet menu. For a Sepolia buildathon deployment, set
# NEXT_PUBLIC_TARGET_CHAIN=sepolia; devnet/local-first builds intentionally do not
# show the one-click burner, even if a user later switches the header to Sepolia,
# because the bundled burner connector follows the configured default chain.
NEXT_PUBLIC_INSTANT_BURNER_SESSION=

# --- Devnet / VPS deployment (same-origin reverse-proxy config) ---
# When this app is served from a public host that reverse-proxies its own chain +
# IPFS + Arweave daemons (e.g. the EFS devnet at https://178.104.79.94.nip.io),
Expand Down Expand Up @@ -143,4 +161,3 @@ NEXT_PUBLIC_DEVNET_BANNER=
# a tarball has no .git dir; set NEXT_PUBLIC_GIT_SHA=<sha> explicitly).
NEXT_PUBLIC_GIT_SHA=
NEXT_PUBLIC_FORK_BLOCK=

9 changes: 5 additions & 4 deletions packages/nextjs/components/FaucetAutoDrip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import { useAutoFaucetDrip } from "~~/hooks/scaffold-eth";

/**
* Mounts the HTTP-faucet auto-drip. Renders nothing; no-op unless
* `NEXT_PUBLIC_FAUCET_URL` is set and the wallet is on the faucet's chain
* (`NEXT_PUBLIC_FAUCET_CHAIN_ID`). Sibling to `DevnetAutoFund`, which covers the
* local hardhat fork via the unlocked node account.
* Mounts the explicit editing-wallet faucet drip. Renders nothing; no-op unless
* the visitor clicked "Enable promptless edits", `NEXT_PUBLIC_FAUCET_URL` is set, and the
* burner wallet is on the faucet's chain (`NEXT_PUBLIC_FAUCET_CHAIN_ID`).
* Sibling to `DevnetAutoFund`, which covers the fork chains through the unlocked
* node account.
*/
export const FaucetAutoDrip = () => {
useAutoFaucetDrip();
Expand Down
25 changes: 18 additions & 7 deletions packages/nextjs/components/FaucetStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { useEffect, useRef } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useAccount, useBalance } from "wagmi";
import { useFaucetStatus } from "~~/utils/scaffold-eth";
import { FAUCET_CHAIN_ID, shouldMarkInstantBurnerReady, useFaucetStatus } from "~~/utils/scaffold-eth";

/**
* Persistent "Adding gas…" indicator next to the wallet while a faucet drip is in
Expand All @@ -14,10 +14,14 @@ import { useFaucetStatus } from "~~/utils/scaffold-eth";
* the balance has visibly increased — i.e. the ETH actually landed.
*/
export const FaucetStatus = () => {
const { pendingHash, setPending } = useFaucetStatus();
const { pendingHash, setPending, setReady } = useFaucetStatus();
const { address } = useAccount();
const queryClient = useQueryClient();
const { data, queryKey } = useBalance({ address, query: { enabled: !!address } });
const { data, queryKey } = useBalance({
address,
chainId: FAUCET_CHAIN_ID,
query: { enabled: !!address },
});
const baseline = useRef<bigint | undefined>(undefined);

// On a fresh drip: snapshot the pre-drip balance (the cached value, before any
Expand All @@ -38,12 +42,19 @@ export const FaucetStatus = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pendingHash]);

// Clear once the balance has increased past the baseline — the ETH is in.
// Clear once the dripped ETH is visibly in the wallet. If no baseline was
// cached before the drip, any positive balance is enough to avoid a stuck chip.
useEffect(() => {
if (pendingHash && baseline.current !== undefined && data?.value !== undefined && data.value > baseline.current) {
setPending(undefined);
Comment thread
JamesCarnley marked this conversation as resolved.
if (
shouldMarkInstantBurnerReady({
pendingHash,
baselineValue: baseline.current,
balanceValue: data?.value,
})
) {
setReady();
}
}, [data?.value, pendingHash, setPending]);
}, [data?.value, pendingHash, setReady]);

if (!pendingHash) return null;

Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/components/FeedbackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const FeedbackButton = ({ variant = "desktop" }: FeedbackButtonProps) =>
className="hidden xl:inline-flex btn btn-ghost btn-sm rounded-full font-normal gap-1.5 px-2"
>
{icon}
<span>Feedback</span>
<span className="hidden 2xl:inline">Feedback</span>
</a>
);
};
4 changes: 3 additions & 1 deletion packages/nextjs/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Bars3Icon, BugAntIcon, FolderIcon } from "@heroicons/react/24/outline";
import { DevWalletSwitcher } from "~~/components/DevWalletSwitcher";
import { FaucetStatus } from "~~/components/FaucetStatus";
import { FeedbackButton } from "~~/components/FeedbackButton";
import { InstantBurnerSession } from "~~/components/InstantBurnerSession";
import { NetworkSwitcher } from "~~/components/NetworkSwitcher";
import { SwitchTheme } from "~~/components/SwitchTheme";
import { RainbowKitCustomConnectButton } from "~~/components/scaffold-eth";
Expand Down Expand Up @@ -124,10 +125,11 @@ export const Header = () => {
</ul>
</div>
<div className="navbar-end flex-grow mr-4 gap-2">
<FaucetStatus />
<NetworkSwitcher />
<DevWalletSwitcher />
<FaucetStatus />
<RainbowKitCustomConnectButton />
<InstantBurnerSession />
<FeedbackButton />
<SwitchTheme />
</div>
Expand Down
Loading
Loading