From 6fbeb42feaff9bc66e75d4ccec839b31e95ce1ef Mon Sep 17 00:00:00 2001 From: Tarrence van As Date: Wed, 1 Apr 2026 19:50:46 -0400 Subject: [PATCH 1/3] feat(keychain): add advanced mode toggle to hide network details Introduces a user preference to toggle between simplified and advanced UI modes. When advanced mode is off, explorer links, Starknet icons, chain names, and network references are hidden throughout the keychain. Defaults to advanced (on) for now. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../keychain/src/components/ContractLink.tsx | 16 +++++++ .../src/components/DeployController.tsx | 18 +++++-- .../keychain/src/components/ErrorAlert.tsx | 28 +++++++---- .../keychain/src/components/ExplorerLink.tsx | 24 ++++++++++ .../keychain/src/components/Transaction.tsx | 20 ++++---- packages/keychain/src/components/activity.tsx | 47 ++++++++----------- .../collection/collectible-asset.tsx | 17 ++----- .../inventory/collection/collection-asset.tsx | 17 ++----- .../src/components/inventory/token/token.tsx | 19 ++------ .../src/components/provider/index.test.tsx | 1 + .../src/components/provider/index.tsx | 38 ++++++++------- .../src/components/session/AggregateCard.tsx | 36 ++++++++------ .../src/components/settings/Delegate.tsx | 7 ++- .../src/components/settings/Recovery.tsx | 7 ++- .../src/components/settings/index.tsx | 22 ++++++++- packages/keychain/src/context/advanced.tsx | 28 +++++++++++ packages/keychain/src/context/index.ts | 1 + .../keychain/src/test/mocks/providers.tsx | 17 ++++--- packages/keychain/src/utils/api/generated.ts | 13 +++++ 19 files changed, 246 insertions(+), 130 deletions(-) create mode 100644 packages/keychain/src/components/ExplorerLink.tsx create mode 100644 packages/keychain/src/context/advanced.tsx diff --git a/packages/keychain/src/components/ContractLink.tsx b/packages/keychain/src/components/ContractLink.tsx index bf3004ff07..9d4ae707f0 100644 --- a/packages/keychain/src/components/ContractLink.tsx +++ b/packages/keychain/src/components/ContractLink.tsx @@ -1,4 +1,5 @@ import { useConnection } from "@/hooks/connection"; +import { useAdvanced } from "@/context/advanced"; import { Address, cn } from "@cartridge/ui"; import { useExplorer } from "@starknet-react/core"; import { constants } from "starknet"; @@ -11,7 +12,22 @@ export function ContractLink({ className?: string; }) { const { controller } = useConnection(); + const { advanced } = useAdvanced(); const explorer = useExplorer(); + + if (!advanced) { + return ( + +
+ + ); + } + return ( (); @@ -203,11 +205,15 @@ export function DeployControllerView({ variant="expanded" icon={} title="Deploying Controller" - description={`Your controller is being deployed on ${chainName}`} + description={ + advanced + ? `Your controller is being deployed on ${chainName}` + : "Your controller is being deployed" + } hideIcon /> - {deployHash && controller && ( + {advanced && deployHash && controller && ( - {deployHash && controller && ( + {advanced && deployHash && controller && ( ["stack"]; }) { const explorer = useExplorer(); + const { advanced } = useAdvanced(); const getExplorerUrl = useCallback( (key: "address" | "class", value: string) => { switch (key) { @@ -448,15 +450,23 @@ function StackTraceDisplay({ {key} {key === "address" || key === "class" ? ( - - {formatAddress(value as string, { - size: "sm", - })} - + advanced ? ( + + {formatAddress(value as string, { + size: "sm", + })} + + ) : ( + + {formatAddress(value as string, { + size: "sm", + })} + + ) ) : key === "selector" ? (
{formatAddress(value as string, { diff --git a/packages/keychain/src/components/ExplorerLink.tsx b/packages/keychain/src/components/ExplorerLink.tsx new file mode 100644 index 0000000000..0923722291 --- /dev/null +++ b/packages/keychain/src/components/ExplorerLink.tsx @@ -0,0 +1,24 @@ +import { useAdvanced } from "@/context/advanced"; +import { useExplorer } from "@starknet-react/core"; +import { Link } from "react-router-dom"; + +export function ExplorerTransactionLink({ + transactionHash, + children, +}: { + transactionHash: string; + children: React.ReactNode; +}) { + const { advanced } = useAdvanced(); + const explorer = useExplorer(); + + if (!advanced) { + return <>{children}; + } + + return ( + + {children} + + ); +} diff --git a/packages/keychain/src/components/Transaction.tsx b/packages/keychain/src/components/Transaction.tsx index eb833b2800..991b5ab995 100644 --- a/packages/keychain/src/components/Transaction.tsx +++ b/packages/keychain/src/components/Transaction.tsx @@ -3,6 +3,7 @@ import { constants } from "starknet"; import { CheckIcon, ExternalIcon, Spinner, StarknetIcon } from "@cartridge/ui"; import { useController } from "@/hooks/controller"; import { useChainName } from "@/hooks/chain"; +import { useAdvanced } from "@/context/advanced"; import { useExplorer } from "@starknet-react/core"; import { Link } from "react-router-dom"; @@ -24,6 +25,7 @@ export function Transaction({ const [state, setState] = useState("pending"); const { icon } = useMemo(() => getColorIcon(state), [state]); const { controller } = useController(); + const { advanced } = useAdvanced(); const explorer = useExplorer(); useEffect(() => { @@ -56,15 +58,17 @@ export function Transaction({
{name}
-
-
- -
{chainName}
+ {advanced && ( +
+
+ +
{chainName}
+
+ + +
- - - -
+ )}
); } diff --git a/packages/keychain/src/components/activity.tsx b/packages/keychain/src/components/activity.tsx index 133a616c38..6dce62a357 100644 --- a/packages/keychain/src/components/activity.tsx +++ b/packages/keychain/src/components/activity.tsx @@ -1,5 +1,4 @@ -import { useCallback, useMemo, useState } from "react"; -import { Link } from "react-router-dom"; +import { useMemo, useState } from "react"; import { ActivityAchievementCard, ActivityCollectibleCard, @@ -12,25 +11,17 @@ import { Skeleton, } from "@cartridge/ui"; import { cn } from "@cartridge/ui/utils"; -import { useExplorer } from "@starknet-react/core"; import { useData } from "@/hooks/data"; +import { ExplorerTransactionLink } from "@/components/ExplorerLink"; import { CardProps } from "@/components/provider/data"; const OFFSET = 100; export function Activity() { const [cap, setCap] = useState(OFFSET); - const explorer = useExplorer(); const { events: data, status } = useData(); - const to = useCallback( - (transactionHash: string) => { - return explorer.transaction(transactionHash); - }, - [explorer], - ); - const { events, dates } = useMemo(() => { const filteredData = data.slice(0, cap); return { @@ -55,13 +46,17 @@ export function Activity() { {events .filter((event) => event.date === current) .map((props: CardProps, index: number) => { + const key = + props.variant === "token" + ? `${index}-${props.key}-${props.username}` + : `${index}-${props.key}`; + switch (props.variant) { case "token": return ( - - + ); case "collectible": return ( - - + ); case "game": return ( - - + ); case "achievement": return ( { - return explorer.transaction(transactionHash); - }, - [explorer], - ); - const handleUnlist = useCallback( async (orderId?: number) => { if (!contractAddress || !asset || !selfOrders) return; @@ -288,10 +280,9 @@ export function CollectibleAsset() { value="activity" > {events.map((props: CardProps, index: number) => ( - - + ))}