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) {
@@ -435,6 +437,10 @@ function StackTraceDisplay({
[explorer],
);
+ if (!advanced) {
+ return null;
+ }
+
return (
{stackTrace.map((trace, i, arr) => (
@@ -448,15 +454,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 && (
+
-
-
-
-
+ )}
);
}
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 (
) : undefined
}
diff --git a/packages/keychain/src/components/inventory/collection/collectible-asset.tsx b/packages/keychain/src/components/inventory/collection/collectible-asset.tsx
index 546533edcc..b4400cc89e 100644
--- a/packages/keychain/src/components/inventory/collection/collectible-asset.tsx
+++ b/packages/keychain/src/components/inventory/collection/collectible-asset.tsx
@@ -35,10 +35,11 @@ import {
getChecksumAddress,
} from "starknet";
import { useConnection, useControllerTheme } from "@/hooks/connection";
+import { useAdvanced } from "@/context/advanced";
+import { ExplorerTransactionLink } from "@/components/ExplorerLink";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { CollectionHeader } from "./header";
import placeholder from "/placeholder.svg?url";
-import { useExplorer } from "@starknet-react/core";
import { CardProps, useTraceabilities } from "@/hooks/traceabilities";
import { OrderModel } from "@cartridge/arcade";
import { useMarketplace } from "@/hooks/marketplace";
@@ -56,7 +57,7 @@ export function CollectibleAsset() {
const account = useAccount();
const address = account?.address || "";
const { chainId } = useConnection();
- const explorer = useExplorer();
+ const { advanced } = useAdvanced();
const location = useLocation();
const [searchParams] = useSearchParams();
const [cap, setCap] = useState(OFFSET);
@@ -147,13 +148,6 @@ export function CollectibleAsset() {
return { orderAmount: amount, orderImage: token.logo_url };
}, [mainOrder]);
- const to = useCallback(
- (transactionHash: string) => {
- return explorer.transaction(transactionHash);
- },
- [explorer],
- );
-
const handleUnlist = useCallback(
async (orderId?: number) => {
if (!contractAddress || !asset || !selfOrders) return;
@@ -247,13 +241,15 @@ export function CollectibleAsset() {
{properties.length > 0 && (
)}
-
+ {advanced && (
+
+ )}
{events.map((props: CardProps, index: number) => (
-
-
+
))}
{
- return explorer.transaction(transactionHash);
- },
- [explorer],
- );
-
const status = useMemo(() => {
if (collectionStatus === "error" || traceabilitiesStatus === "error")
return "error";
@@ -239,26 +233,27 @@ export function CollectionAsset() {
{properties.length > 0 && (
)}
-
+ {advanced && (
+
+ )}
{events.map((props: CardProps, index: number) => (
-
-
+
))}
{
- return explorer.transaction(transactionHash);
- },
- [explorer],
- );
-
if (!token) {
return null;
}
@@ -199,11 +193,13 @@ function ERC20() {
-
+ {advanced && (
+
+ )}
{status === "loading" ? (
@@ -230,10 +226,9 @@ function ERC20() {
{date}
{transactions.map((item) => (
-
-
+
))}
))}
diff --git a/packages/keychain/src/components/provider/index.test.tsx b/packages/keychain/src/components/provider/index.test.tsx
index cff85d4f14..27f48b5890 100644
--- a/packages/keychain/src/components/provider/index.test.tsx
+++ b/packages/keychain/src/components/provider/index.test.tsx
@@ -82,6 +82,7 @@ vi.mock("@/components/provider/data", () => ({
}));
vi.mock("@/context", () => ({
+ AdvancedProvider: ({ children }: PropsWithChildren) => <>{children}>,
ToastProvider: ({ children }: PropsWithChildren) => <>{children}>,
StarterpackProviders: ({ children }: PropsWithChildren) => <>{children}>,
}));
diff --git a/packages/keychain/src/components/provider/index.tsx b/packages/keychain/src/components/provider/index.tsx
index ce6ad72858..2d6d4b4ebe 100644
--- a/packages/keychain/src/components/provider/index.tsx
+++ b/packages/keychain/src/components/provider/index.tsx
@@ -20,7 +20,11 @@ import { UIProvider } from "./ui";
import { FeatureProvider } from "@/hooks/features";
import { ArcadeProvider as ProfileArcadeProvider } from "@/components/provider/arcade";
import { DataProvider as ProfileDataProvider } from "@/components/provider/data";
-import { ToastProvider, StarterpackProviders } from "@/context";
+import {
+ AdvancedProvider,
+ ToastProvider,
+ StarterpackProviders,
+} from "@/context";
import { IndexerAPIProvider } from "@cartridge/ui/utils/api/indexer";
import { CartridgeAPIProvider } from "@cartridge/ui/utils/api/cartridge";
import { ErrorBoundary } from "../ErrorBoundary";
@@ -86,21 +90,23 @@ export function Provider({ children }: PropsWithChildren) {
defaultChainId={defaultChainId}
provider={jsonRpcProvider({ rpc })}
>
-
-
-
-
-
-
- {children}
-
-
-
-
-
-
+
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+
+
diff --git a/packages/keychain/src/components/session/AggregateCard.tsx b/packages/keychain/src/components/session/AggregateCard.tsx
index 3aed4215b6..ebf857855c 100644
--- a/packages/keychain/src/components/session/AggregateCard.tsx
+++ b/packages/keychain/src/components/session/AggregateCard.tsx
@@ -5,6 +5,7 @@ import {
} from "@/hooks/session";
import { useConnection } from "@/hooks/connection";
+import { useAdvanced } from "@/context/advanced";
import {
Accordion,
AccordionContent,
@@ -46,6 +47,7 @@ export function AggregateCard({
}: AggregateCardProps) {
const [isOpened, setisOpened] = useState(isExpanded);
const { controller } = useConnection();
+ const { advanced } = useAdvanced();
const explorer = useExplorer();
const { onToggleMethod, isEditable } = useCreateSession();
@@ -85,20 +87,22 @@ export function AggregateCard({
{name}
-
- {formatAddress(address, { first: 5, last: 5 })}
-
+ {advanced && (
+
+ {formatAddress(address, { first: 5, last: 5 })}
+
+ )}
diff --git a/packages/keychain/src/components/settings/Delegate.tsx b/packages/keychain/src/components/settings/Delegate.tsx
index eafb8d601c..4f98430b4e 100644
--- a/packages/keychain/src/components/settings/Delegate.tsx
+++ b/packages/keychain/src/components/settings/Delegate.tsx
@@ -7,6 +7,7 @@ import {
HeaderInner,
} from "@cartridge/ui";
import { useConnection } from "@/hooks/connection";
+import { useAdvanced } from "@/context/advanced";
import { useCallback, useEffect, useState } from "react";
import { CallData, num } from "starknet";
import { createExecuteUrl } from "@/utils/connection/execute";
@@ -14,6 +15,7 @@ import { useNavigate } from "react-router-dom";
export function Delegate() {
const { controller } = useConnection();
+ const { advanced } = useAdvanced();
const navigate = useNavigate();
const [delegateAddress, setDelegateAddress] = useState("");
const [isValid, setIsValid] = useState(true);
@@ -48,8 +50,9 @@ export function Delegate() {
- Your controller can be owned by an existing Starknet wallet which
- can receive the rewards you earn while playing.
+ Your controller can be owned by an existing{" "}
+ {advanced ? "Starknet " : ""}wallet which can receive the rewards
+ you earn while playing.
(This can be updated later)
diff --git a/packages/keychain/src/components/settings/Recovery.tsx b/packages/keychain/src/components/settings/Recovery.tsx
index 98526a2634..1afaea9de0 100644
--- a/packages/keychain/src/components/settings/Recovery.tsx
+++ b/packages/keychain/src/components/settings/Recovery.tsx
@@ -7,6 +7,7 @@ import {
HeaderInner,
} from "@cartridge/ui";
import { useConnection } from "@/hooks/connection";
+import { useAdvanced } from "@/context/advanced";
import { useCallback, useEffect, useState } from "react";
import { CallData, num } from "starknet";
import { createExecuteUrl } from "@/utils/connection/execute";
@@ -14,6 +15,7 @@ import { useNavigate } from "react-router-dom";
export function Recovery() {
const { controller } = useConnection();
+ const { advanced } = useAdvanced();
const navigate = useNavigate();
const [externalOwnerAddress, setExternalOwnerAddress] = useState("");
const [isValid, setIsValid] = useState(true);
@@ -49,8 +51,9 @@ export function Recovery() {
{/* TODO: Get rid of this div once Content is updated with TW */}
- Recovery accounts are Starknet wallets that can be used to recover
- your Controller if you lose access to your signers.
+ Recovery accounts are {advanced ? "Starknet wallets" : "wallets"}{" "}
+ that can be used to recover your Controller if you lose access to
+ your signers.
+
+
+
+
+ Show advanced details
+
+
+
+
+
@@ -179,13 +199,15 @@ export function Settings() {
{controller.username()}
-
-
-
+ {advanced && (
+
+
+
+ )}
)}
diff --git a/packages/keychain/src/components/settings/registered-account-card.tsx b/packages/keychain/src/components/settings/registered-account-card.tsx
index 3b4c559c6e..fe6dfc0f3d 100644
--- a/packages/keychain/src/components/settings/registered-account-card.tsx
+++ b/packages/keychain/src/components/settings/registered-account-card.tsx
@@ -12,8 +12,8 @@ import {
ArgentIcon,
CopyAddress,
} from "@cartridge/ui";
-import { cn } from "@cartridge/ui/utils";
-import { formatAddress } from "@cartridge/ui/utils";
+import { cn, formatAddress } from "@cartridge/ui/utils";
+import { useAdvanced } from "@/context/advanced";
export interface RegisteredAccount {
accountName: string;
@@ -28,6 +28,8 @@ export const RegisteredAccountCard = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes
& SignerCardProps
>(({ className, accountName, accountAddress, onDelete, ...props }, ref) => {
+ const { advanced } = useAdvanced();
+
return (
{accountName}
-
- {formatAddress(accountAddress, { first: 4, last: 4 })}
-
+ {advanced && (
+
+ {formatAddress(accountAddress, { first: 4, last: 4 })}
+
+ )}
@@ -73,13 +77,15 @@ export const RegisteredAccountCard = React.forwardRef<
{accountName}
-
-
-
+ {advanced && (
+
+
+
+ )}
diff --git a/packages/keychain/src/components/transaction/CallCard.tsx b/packages/keychain/src/components/transaction/CallCard.tsx
index f141734ff9..2b8579dd38 100644
--- a/packages/keychain/src/components/transaction/CallCard.tsx
+++ b/packages/keychain/src/components/transaction/CallCard.tsx
@@ -12,6 +12,7 @@ import {
cn,
} from "@cartridge/ui";
import { humanizeString } from "@cartridge/controller";
+import { useAdvanced } from "@/context/advanced";
import { ContractLink } from "@/components/ContractLink";
interface CallCardProps {
@@ -271,6 +272,12 @@ export function CallCardContents({
call: Call;
className?: string;
}) {
+ const { advanced } = useAdvanced();
+
+ if (!advanced) {
+ return null;
+ }
+
return (
void;
+}
+
+const AdvancedContext = createContext
(
+ undefined,
+);
+
+export function AdvancedProvider({ children }: { children: React.ReactNode }) {
+ const [advanced, setAdvanced] = useState(true);
+
+ return (
+
+ {children}
+
+ );
+}
+
+export function useAdvanced() {
+ const ctx = useContext(AdvancedContext);
+ if (!ctx) {
+ throw new Error("useAdvanced must be used within an AdvancedProvider");
+ }
+ return ctx;
+}
diff --git a/packages/keychain/src/context/index.ts b/packages/keychain/src/context/index.ts
index 65604fcfc1..90e8781bb1 100644
--- a/packages/keychain/src/context/index.ts
+++ b/packages/keychain/src/context/index.ts
@@ -1,3 +1,4 @@
+export { AdvancedProvider, useAdvanced } from "./advanced";
export { NavigationProvider, useNavigation } from "./navigation";
export { ToastProvider, useToast } from "./toast";
diff --git a/packages/keychain/src/test/mocks/providers.tsx b/packages/keychain/src/test/mocks/providers.tsx
index 836339bd30..b95b25e5d6 100644
--- a/packages/keychain/src/test/mocks/providers.tsx
+++ b/packages/keychain/src/test/mocks/providers.tsx
@@ -9,6 +9,7 @@ import { withConnection } from "./connection";
import { withPostHog } from "./posthog";
import { withStarknet } from "./starknet";
import { FeatureProvider } from "@/hooks/features";
+import { AdvancedProvider } from "@/context/advanced";
import { NavigationProvider } from "@/context/navigation";
import { QueryClient, QueryClientProvider } from "react-query";
@@ -35,13 +36,15 @@ export function renderWithProviders(
const RouterComponent = (
-
-
-
- {withStarknet(withPostHog(ui), config.starknet)}
-
-
-
+
+
+
+
+ {withStarknet(withPostHog(ui), config.starknet)}
+
+
+
+
);
diff --git a/packages/keychain/src/utils/api/generated.ts b/packages/keychain/src/utils/api/generated.ts
index 0c0e2b4338..e89035d221 100644
--- a/packages/keychain/src/utils/api/generated.ts
+++ b/packages/keychain/src/utils/api/generated.ts
@@ -378,6 +378,8 @@ export type Activity = Node & {
actualFee?: Maybe;
controller?: Maybe;
controllerID?: Maybe;
+ /** Recalculated credit fee using native USDC oracle price */
+ correctedCreditFee?: Maybe;
createdAt: Scalars["Time"];
/** Credits fee for the activity */
creditsFee?: Maybe;
@@ -556,6 +558,17 @@ export type ActivityWhereInput = {
controllerIDNEQ?: InputMaybe;
controllerIDNotIn?: InputMaybe>;
controllerIDNotNil?: InputMaybe;
+ /** corrected_credit_fee field predicates */
+ correctedCreditFee?: InputMaybe;
+ correctedCreditFeeGT?: InputMaybe;
+ correctedCreditFeeGTE?: InputMaybe;
+ correctedCreditFeeIn?: InputMaybe>;
+ correctedCreditFeeIsNil?: InputMaybe;
+ correctedCreditFeeLT?: InputMaybe;
+ correctedCreditFeeLTE?: InputMaybe;
+ correctedCreditFeeNEQ?: InputMaybe;
+ correctedCreditFeeNotIn?: InputMaybe>;
+ correctedCreditFeeNotNil?: InputMaybe;
/** created_at field predicates */
createdAt?: InputMaybe;
createdAtGT?: InputMaybe;
@@ -5051,6 +5064,8 @@ export type RpcLog = Node & {
method?: Maybe;
/** Starknet network used */
network: RpcLogNetwork;
+ /** Origin header from the request */
+ origin?: Maybe;
/** When billing was processed. NULL indicates not yet processed. */
processedAt?: Maybe;
/** Referer header from the request */
@@ -5200,6 +5215,22 @@ export type RpcLogWhereInput = {
networkNotIn?: InputMaybe>;
not?: InputMaybe;
or?: InputMaybe>;
+ /** origin field predicates */
+ origin?: InputMaybe;
+ originContains?: InputMaybe;
+ originContainsFold?: InputMaybe;
+ originEqualFold?: InputMaybe;
+ originGT?: InputMaybe;
+ originGTE?: InputMaybe;
+ originHasPrefix?: InputMaybe;
+ originHasSuffix?: InputMaybe;
+ originIn?: InputMaybe>;
+ originIsNil?: InputMaybe;
+ originLT?: InputMaybe;
+ originLTE?: InputMaybe;
+ originNEQ?: InputMaybe;
+ originNotIn?: InputMaybe>;
+ originNotNil?: InputMaybe;
/** processed_at field predicates */
processedAt?: InputMaybe;
processedAtGT?: InputMaybe;