Skip to content
Draft
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
1 change: 1 addition & 0 deletions apps/zerodev-signer-demo/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
45 changes: 44 additions & 1 deletion apps/zerodev-signer-demo/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { useQuery } from "@tanstack/react-query";
import { useAuthenticators } from "@zerodev/wallet-react";
import { SignatureRequest } from "@zerodev/wallet-react-ui";
import {
Check,
Copy,
Expand Down Expand Up @@ -107,6 +108,21 @@ export default function DashboardPage() {
const [isLoggingOut, setIsLoggingOut] = useState(false);
const [isBalanceRefreshing, setIsBalanceRefreshing] = useState(false);

// Toggle for whether SignatureRequest is mounted. When mounted, the kit
// gates signing calls on user confirmation; when not, calls go through
// silently (background mode). Default off; persisted in localStorage.
const [confirmationEnabled, setConfirmationEnabled] = useState<boolean>(() => {
if (typeof window === "undefined") return false;
return localStorage.getItem("zd:signingConfirmation") === "true";
});

useEffect(() => {
localStorage.setItem(
"zd:signingConfirmation",
String(confirmationEnabled),
);
}, [confirmationEnabled]);

// Wagmi hooks
const { address, status, chain, } = useAccount();
const publicClient = usePublicClient({ chainId: chain?.id });
Expand Down Expand Up @@ -241,6 +257,9 @@ export default function DashboardPage() {
return (
<>
<ExportWalletModal isOpen={showExportModal} onClose={() => setShowExportModal(false)} />
{confirmationEnabled && (
<SignatureRequest className='fixed inset-0 z-50 sm:absolute sm:inset-auto sm:right-2 sm:top-18 sm:w-[400px] sm:h-[600px]' />
)}
<div className="min-h-screen">
<AppHeader />

Expand All @@ -256,7 +275,7 @@ export default function DashboardPage() {
Created with {authMethodLabel}
</span>
</div>
<div className="flex items-center gap-2">
<div className="flex flex-wrap items-center gap-2">
<ChainSelector className="h-9 rounded-full px-3 text-xs" />
<button
onClick={() => setShowExportModal(true)}
Expand All @@ -266,6 +285,30 @@ export default function DashboardPage() {
<Key className="h-3.5 w-3.5" />
Export keys
</button>
<button
type="button"
role="switch"
aria-checked={confirmationEnabled}
onClick={() => setConfirmationEnabled((enabled) => !enabled)}
className="inline-flex h-9 cursor-pointer items-center justify-center gap-1.5 rounded-full border border-[var(--border-warm)] bg-white px-3 text-xs font-semibold text-[#423a32] transition-colors hover:bg-[var(--surface-warm)]"
title="Gate transactions on user confirmation"
>
<FileSignature className="h-3.5 w-3.5" />
Tx review
<span
className={cn(
"relative inline-block h-4 w-7 rounded-full transition-colors",
confirmationEnabled ? "bg-green-600" : "bg-gray-300"
)}
>
<span
className={cn(
"absolute left-0.5 top-0.5 h-3 w-3 rounded-full bg-white shadow-sm transition-transform",
confirmationEnabled && "translate-x-3"
)}
/>
</span>
</button>
<button
onClick={handleLogout}
className="inline-flex h-9 items-center justify-center gap-1.5 rounded-full border border-red-200 bg-white px-3 text-xs font-semibold text-red-700 transition-colors hover:bg-red-50 cursor-pointer"
Expand Down
Loading
Loading