From 9894920168311e40233a7f6243739d6a95feb639 Mon Sep 17 00:00:00 2001 From: RM3 Date: Mon, 9 Feb 2026 13:09:13 -0300 Subject: [PATCH 1/7] fix: fixed activity query params --- packages/keychain/src/components/provider/data.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/keychain/src/components/provider/data.tsx b/packages/keychain/src/components/provider/data.tsx index 7df8e8e3b..4234e5b33 100644 --- a/packages/keychain/src/components/provider/data.tsx +++ b/packages/keychain/src/components/provider/data.tsx @@ -39,16 +39,20 @@ export function DataProvider({ children }: { children: ReactNode }) { ); const account = useAccount(); - const address = account?.address || ""; + const address = useMemo( + () => (account ? addAddressPadding(account.address) : ""), + [account], + ); const { project } = useConnection(); const projects = useMemo(() => { const projects = project ? [project] : []; - return projects.map((proejct) => { + return projects.map((project) => { return { - project: proejct, + project, address, limit: 0, + date: "", }; }); }, [project, address]); @@ -61,7 +65,7 @@ export function DataProvider({ children }: { children: ReactNode }) { refetch: refetchTransfers, } = useTransfersQuery( { - projects: projects.map((p) => ({ ...p, date: "" })), + projects, }, { queryKey: ["transfers", address, project], From 8c4b1d68f0b51e6034b8626c2c1a5b0f342f408f Mon Sep 17 00:00:00 2001 From: RM3 Date: Mon, 9 Feb 2026 13:06:34 -0300 Subject: [PATCH 2/7] fix: empty activities on partial error --- packages/keychain/src/components/provider/data.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/keychain/src/components/provider/data.tsx b/packages/keychain/src/components/provider/data.tsx index 4234e5b33..4447db3f7 100644 --- a/packages/keychain/src/components/provider/data.tsx +++ b/packages/keychain/src/components/provider/data.tsx @@ -90,9 +90,9 @@ export function DataProvider({ children }: { children: ReactNode }) { ); const status = useMemo(() => { - return transfersStatus === "loading" && activitiesStatus === "loading" + return transfersStatus === "loading" || activitiesStatus === "loading" ? "loading" - : transfersStatus === "error" || activitiesStatus === "error" + : transfersStatus === "error" && activitiesStatus === "error" ? "error" : "success"; }, [transfersStatus, activitiesStatus]); From 45640eeecde648dcb8e2ea34e728c129fc5ba333 Mon Sep 17 00:00:00 2001 From: RM3 Date: Fri, 13 Feb 2026 14:34:26 -0300 Subject: [PATCH 3/7] chore: updated activity cards --- packages/keychain/src/components/activity.tsx | 50 +++---- .../src/components/inventory/token/token.tsx | 41 +++++- .../keychain/src/components/provider/data.tsx | 131 +++++++++++++----- 3 files changed, 156 insertions(+), 66 deletions(-) diff --git a/packages/keychain/src/components/activity.tsx b/packages/keychain/src/components/activity.tsx index b65969766..81d2d51fc 100644 --- a/packages/keychain/src/components/activity.tsx +++ b/packages/keychain/src/components/activity.tsx @@ -1,3 +1,5 @@ +import { useCallback, useMemo, useState } from "react"; +import { Link } from "react-router-dom"; import { ActivityAchievementCard, ActivityCollectibleCard, @@ -12,30 +14,10 @@ import { import { cn } from "@cartridge/ui/utils"; import { useExplorer } from "@starknet-react/core"; import { useData } from "@/hooks/data"; -import { useCallback, useMemo, useState } from "react"; -import { Link } from "react-router-dom"; +import { CardProps } from "@/components/provider/data"; const OFFSET = 100; -interface CardProps { - variant: "token" | "collectible" | "game" | "achievement"; - key: string; - transactionHash: string; - amount: string; - address: string; - value: string; - name: string; - collection: string; - image: string; - title: string; - website: string; - certified: boolean; - action: "send" | "receive" | "mint"; - timestamp: number; - date: string; - points?: number; -} - export function Activity() { const [cap, setCap] = useState(OFFSET); const explorer = useExplorer(); @@ -66,25 +48,30 @@ export function Activity() { {dates.map((current) => { return (
-

{current}

-
+

+ {current} +

+
{events .filter((event) => event.date === current) .map((props: CardProps, index: number) => { + console.log(`EVENT [USERNAME]:`, props.username); switch (props.variant) { case "token": return ( ); @@ -99,8 +86,10 @@ export function Activity() { name={props.name} collection={props.collection} address={props.address} + username={props.username} image={props.image} action={props.action} + timestamp={props.timestamp * 1000} /> ); @@ -112,10 +101,13 @@ export function Activity() { target="_blank" > ); @@ -125,10 +117,12 @@ export function Activity() { key={`${index}-${props.key}`} title={"Achievement"} topic={props.title} - website={props.website} image={props.image} - certified={props.certified} points={props.points || 0} + themeColor={props.color} + website={props.website} + certified={props.certified} + timestamp={props.timestamp * 1000} /> ); } diff --git a/packages/keychain/src/components/inventory/token/token.tsx b/packages/keychain/src/components/inventory/token/token.tsx index 726c0be7c..94fcafab2 100644 --- a/packages/keychain/src/components/inventory/token/token.tsx +++ b/packages/keychain/src/components/inventory/token/token.tsx @@ -16,7 +16,7 @@ import { useData } from "@/hooks/data"; import { getDate, isPublicChain, useCreditBalance } from "@cartridge/ui/utils"; import { useExplorer } from "@starknet-react/core"; import { constants, getChecksumAddress } from "starknet"; -import { useAccount } from "@/hooks/account"; +import { useAccount, useUsernames } from "@/hooks/account"; import { useToken } from "@/hooks/token"; import { useCallback, useMemo } from "react"; import { useConnection } from "@/hooks/connection"; @@ -127,6 +127,22 @@ function ERC20() { return isControllerGte("0.5.6"); }, [isControllerGte]); + const addresses = useMemo(() => { + const accounts = + transfers?.transfers?.items.flatMap((item) => + item.transfers.reduce( + (acc, item) => [ + ...acc, + `0x${BigInt(item.fromAddress).toString(16)}`, + `0x${BigInt(item.toAddress).toString(16)}`, + ], + [] as string[], + ), + ) ?? []; + return Array.from(new Set(accounts)); + }, [transfers]); + const { usernames } = useUsernames({ addresses }); + const txs = useMemo(() => { if (!transfers || !token?.metadata?.image) { return []; @@ -142,16 +158,27 @@ function ERC20() { const timestamp = new Date(transfer.executedAt).getTime(); const date = getDate(timestamp); const image = token.metadata.image; + const toUsername = usernames.find( + (user) => + BigInt(user.address ?? "0x0") === BigInt(transfer.toAddress), + )?.username; + const fromUsername = usernames.find( + (user) => + BigInt(user.address ?? "0x0") === BigInt(transfer.fromAddress), + )?.username; return { key: `${transfer.transactionHash}-${transfer.eventId}-${i}`, transactionHash: transfer.transactionHash, amount: value, to: transfer.toAddress, + toUsername, from: transfer.fromAddress, + fromUsername, contractAddress: transfer.contractAddress, symbol: transfer.symbol, eventId: transfer.eventId, date: date, + timestamp, image, action: getChecksumAddress(transfer.fromAddress) === @@ -161,7 +188,7 @@ function ERC20() { }; }); }); - }, [transfers, accountAddress, token?.metadata?.image]); + }, [transfers, accountAddress, usernames, token?.metadata?.image]); const to = useCallback( (transactionHash: string) => { @@ -200,8 +227,8 @@ function ERC20() { {} as Record, ), ).map(([date, transactions]) => ( -
-

+

+

{date}

{transactions.map((item) => ( @@ -215,8 +242,14 @@ function ERC20() { // no price available from the oracle for $PAPER value="" address={item.action === "send" ? item.to : item.from} + username={ + item.action === "send" + ? item.toUsername + : item.fromUsername + } image={token.metadata.image!} action={item.action} + timestamp={item.timestamp} /> ))} diff --git a/packages/keychain/src/components/provider/data.tsx b/packages/keychain/src/components/provider/data.tsx index 4447db3f7..f19079663 100644 --- a/packages/keychain/src/components/provider/data.tsx +++ b/packages/keychain/src/components/provider/data.tsx @@ -5,7 +5,7 @@ import { useActivitiesQuery, useTransfersQuery, } from "@cartridge/ui/utils/api/cartridge"; -import { useAccount } from "@/hooks/account"; +import { useAccount, useUsernames } from "@/hooks/account"; import { useConnection, useControllerTheme } from "@/hooks/connection"; import { addAddressPadding, getChecksumAddress } from "starknet"; import { erc20Metadata } from "@cartridge/presets"; @@ -19,11 +19,13 @@ export interface CardProps { transactionHash: string; amount: string; address: string; + username: string; value: string; name: string; collection: string; image: string; title: string; + color: string; website: string; certified: boolean; action: "send" | "receive" | "mint"; @@ -33,7 +35,19 @@ export interface CardProps { } export function DataProvider({ children }: { children: ReactNode }) { - const theme = useControllerTheme(); + const controllerTheme = useControllerTheme(); + const theme = useMemo( + () => ({ + color: + typeof controllerTheme?.colors?.primary == "string" + ? (controllerTheme?.colors?.primary as string) + : "#ffffff", + icon: controllerTheme?.icon ?? "", + certified: controllerTheme?.verified ?? false, + }), + [controllerTheme], + ); + const [accountAddress, setAccountAddress] = useState( undefined, ); @@ -80,7 +94,7 @@ export function DataProvider({ children }: { children: ReactNode }) { refetch: refetchTransactions, } = useActivitiesQuery( { - projects, + projects: projects.map((p) => ({ ...p, date: undefined })), }, { queryKey: ["activities", address, project], @@ -96,6 +110,21 @@ export function DataProvider({ children }: { children: ReactNode }) { ? "error" : "success"; }, [transfersStatus, activitiesStatus]); + const addresses = useMemo(() => { + const accounts = + transfers?.transfers?.items.flatMap((item) => + item.transfers.reduce( + (acc, item) => [ + ...acc, + `0x${BigInt(item.fromAddress).toString(16)}`, + `0x${BigInt(item.toAddress).toString(16)}`, + ], + [] as string[], + ), + ) ?? []; + return Array.from(new Set(accounts)); + }, [transfers]); + const { usernames } = useUsernames({ addresses }); const erc20s: CardProps[] = useMemo(() => { return ( @@ -113,18 +142,29 @@ export function DataProvider({ children }: { children: ReactNode }) { getChecksumAddress(transfer.contractAddress), )?.logo_url || makeBlockie(getChecksumAddress(transfer.contractAddress)); - return { + const userAddress = + BigInt(transfer.fromAddress) === BigInt(address) + ? transfer.toAddress + : transfer.fromAddress; + const username = usernames.find( + (user) => BigInt(user.address ?? "0x0") === BigInt(userAddress), + )?.username; + const result: CardProps = { variant: "token", key: `${transfer.transactionHash}-${transfer.eventId}`, contractAddress: transfer.contractAddress, transactionHash: transfer.transactionHash, amount: value, - address: - BigInt(transfer.fromAddress) === BigInt(address) - ? transfer.toAddress - : transfer.fromAddress, + address: userAddress, + username: username ?? "", value: "$-", + name: "", + collection: "", image: image || "", + title: "", + color: theme.color, + website: "", + certified: theme.certified, action: BigInt(transfer.fromAddress) === 0n ? "mint" @@ -133,11 +173,12 @@ export function DataProvider({ children }: { children: ReactNode }) { : "receive", timestamp: timestamp / 1000, date: date, - } as CardProps; + }; + return result; }), ) || [] ); - }, [transfers, address]); + }, [transfers, address, usernames, theme]); const erc721s: CardProps[] = useMemo(() => { return ( @@ -161,20 +202,29 @@ export function DataProvider({ children }: { children: ReactNode }) { attribute?.trait?.toLowerCase() === "name", )?.value || metadata.name; const image = `https://api.cartridge.gg/x/${item.meta.project}/torii/static/${addAddressPadding(transfer.contractAddress)}/${transfer.tokenId}/image`; - return { + const userAddress = + BigInt(transfer.fromAddress) === BigInt(address) + ? transfer.toAddress + : transfer.fromAddress; + const username = usernames.find( + (user) => BigInt(user.address ?? "0x0") === BigInt(userAddress), + )?.username; + const result: CardProps = { variant: "collectible", key: `${transfer.transactionHash}-${transfer.eventId}`, contractAddress: transfer.contractAddress, transactionHash: transfer.transactionHash, - name: name || "", - collection: transfer.name, amount: "", - address: - BigInt(transfer.fromAddress) === BigInt(address) - ? transfer.toAddress - : transfer.fromAddress, + address: userAddress, + username: username ?? "", value: "", + name: name || "", + collection: transfer.name, image: image, + title: "", + color: theme.color, + website: "", + certified: theme.certified, action: BigInt(transfer.fromAddress) === 0n ? "mint" @@ -183,11 +233,12 @@ export function DataProvider({ children }: { children: ReactNode }) { : "receive", timestamp: timestamp / 1000, date: date, - } as CardProps; + }; + return result; }); }) || [] ); - }, [transfers, address]); + }, [transfers, address, usernames, theme]); const actions: CardProps[] = useMemo(() => { return ( @@ -196,18 +247,27 @@ export function DataProvider({ children }: { children: ReactNode }) { ({ transactionHash, contractAddress, entrypoint, executedAt }) => { const timestamp = new Date(executedAt).getTime(); const date = getDate(timestamp); - return { + const result: CardProps = { variant: "game", key: `${transactionHash}-${entrypoint}`, contractAddress: contractAddress, transactionHash: transactionHash, + amount: "", + address: "", + username: "", + value: "", + name: "", + collection: "", + image: theme.icon, title: entrypoint.replace(/_/g, " "), - image: theme?.icon || "", + color: theme.color, website: "", - certified: false, + certified: theme.certified, + action: "mint", timestamp: timestamp / 1000, date: date, - } as CardProps; + }; + return result; }, ), ) || [] @@ -219,27 +279,30 @@ export function DataProvider({ children }: { children: ReactNode }) { .filter((item) => item.completed) .map((item) => { const date = getDate(item.timestamp * 1000); - return { + const result: CardProps = { variant: "achievement", key: item.id, - transactionHash: "", contractAddress: "", - title: item.title, - image: item.icon, - timestamp: item.timestamp, - date: date, - website: "", - certified: false, - points: item.earning, + transactionHash: "", amount: "", address: "", + username: "", value: "", name: "", collection: "", + image: item.icon, + title: item.title, + color: theme.color, + website: "", + certified: theme.certified, action: "mint", - } as CardProps; + timestamp: item.timestamp, + date: date, + points: item.earning, + }; + return result; }); - }, [trophies]); + }, [trophies, theme]); const events = useMemo(() => { return [...erc20s, ...erc721s, ...actions, ...achievements].sort( From 0d940aac25e719d3f250fe90667814bd5aa2cf73 Mon Sep 17 00:00:00 2001 From: RM3 Date: Fri, 13 Feb 2026 15:45:11 -0300 Subject: [PATCH 4/7] fix: make collectible cards clickable --- .../keychain/src/components/inventory/collection/collectible.tsx | 1 + .../keychain/src/components/inventory/collection/collection.tsx | 1 + .../keychain/src/components/inventory/collection/collections.tsx | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/keychain/src/components/inventory/collection/collectible.tsx b/packages/keychain/src/components/inventory/collection/collectible.tsx index ea83ece5c..8997f108b 100644 --- a/packages/keychain/src/components/inventory/collection/collectible.tsx +++ b/packages/keychain/src/components/inventory/collection/collectible.tsx @@ -65,6 +65,7 @@ export function Collectible() { ? asset.name : `${asset.name} #${parseInt(BigInt(asset.tokenId).toString())}` } + clickable selectable={false} images={[...asset.imageUrls, placeholder]} totalCount={asset.amount} diff --git a/packages/keychain/src/components/inventory/collection/collection.tsx b/packages/keychain/src/components/inventory/collection/collection.tsx index b46c89edf..9e2593854 100644 --- a/packages/keychain/src/components/inventory/collection/collection.tsx +++ b/packages/keychain/src/components/inventory/collection/collection.tsx @@ -260,6 +260,7 @@ function LazyAsset({ : `${asset.name} #${parseInt(BigInt(asset.tokenId).toString())}` } images={[...asset.imageUrls, placeholder]} + clickable selectable selected={isSelected} listingCount={listingCount} diff --git a/packages/keychain/src/components/inventory/collection/collections.tsx b/packages/keychain/src/components/inventory/collection/collections.tsx index 288857137..e3d98df3a 100644 --- a/packages/keychain/src/components/inventory/collection/collections.tsx +++ b/packages/keychain/src/components/inventory/collection/collections.tsx @@ -51,6 +51,7 @@ export function Collections() { totalCount={collection.totalCount} listingCount={listingCount} selectable={false} + clickable /> ); From d19c2469b4b542b8fef5aa8d216421b4ffeedb0f Mon Sep 17 00:00:00 2001 From: RM3 Date: Fri, 13 Feb 2026 16:53:10 -0300 Subject: [PATCH 5/7] feat: added loading skeleton to token details page --- packages/keychain/src/components/activity.tsx | 7 +- .../collection/collectible-asset.tsx | 2 +- .../inventory/collection/collection-asset.tsx | 2 +- .../src/components/inventory/token/token.tsx | 95 ++++++++++--------- 4 files changed, 56 insertions(+), 50 deletions(-) diff --git a/packages/keychain/src/components/activity.tsx b/packages/keychain/src/components/activity.tsx index 81d2d51fc..9f960e74f 100644 --- a/packages/keychain/src/components/activity.tsx +++ b/packages/keychain/src/components/activity.tsx @@ -103,7 +103,6 @@ export function Activity() { { +export const LoadingState = ({ rowCount = 5 }: { rowCount?: number }) => { return (
- {Array.from({ length: 20 }).map((_, index) => ( + {Array.from({ length: rowCount }).map((_, index) => ( ))}
@@ -159,7 +158,7 @@ const LoadingState = () => { ); }; -const EmptyState = () => { +export const EmptyState = () => { return ( {events.map((props: CardProps, index: number) => ( diff --git a/packages/keychain/src/components/inventory/collection/collection-asset.tsx b/packages/keychain/src/components/inventory/collection/collection-asset.tsx index e10197339..ca6953684 100644 --- a/packages/keychain/src/components/inventory/collection/collection-asset.tsx +++ b/packages/keychain/src/components/inventory/collection/collection-asset.tsx @@ -251,7 +251,7 @@ export function CollectionAsset() { /> {events.map((props: CardProps, index: number) => ( diff --git a/packages/keychain/src/components/inventory/token/token.tsx b/packages/keychain/src/components/inventory/token/token.tsx index 94fcafab2..fd38d0053 100644 --- a/packages/keychain/src/components/inventory/token/token.tsx +++ b/packages/keychain/src/components/inventory/token/token.tsx @@ -22,6 +22,7 @@ import { useCallback, useMemo } from "react"; import { useConnection } from "@/hooks/connection"; import { useVersion } from "@/hooks/version"; import { useNavigation } from "@/context/navigation"; +import { EmptyState, LoadingState } from "@/components/activity"; export function Token() { const { address } = useParams<{ address: string }>(); @@ -116,7 +117,7 @@ function ERC20() { const accountAddress = account?.address || ""; const { controller } = useConnection(); const explorer = useExplorer(); - const { transfers } = useData(); + const { transfers, status } = useData(); const { isControllerGte } = useVersion(); const chainId = constants.StarknetChainId.SN_MAIN; // Use mainnet as default @@ -212,50 +213,56 @@ function ERC20() { chainId={chainId as constants.StarknetChainId} /> -
- {Object.entries( - txs - .filter((tx) => tx?.symbol === token.metadata.symbol) - .reduce( - (acc, tx) => { - if (!acc[tx.date]) { - acc[tx.date] = []; - } - acc[tx.date].push(tx); - return acc; - }, - {} as Record, - ), - ).map(([date, transactions]) => ( -
-

- {date} -

- {transactions.map((item) => ( - - + ) : status === "error" || !txs.length ? ( + + ) : ( +
+ {Object.entries( + txs + .filter((tx) => tx?.symbol === token.metadata.symbol) + .reduce( + (acc, tx) => { + if (!acc[tx.date]) { + acc[tx.date] = []; } - image={token.metadata.image!} - action={item.action} - timestamp={item.timestamp} - /> - - ))} -
- ))} -
+ acc[tx.date].push(tx); + return acc; + }, + {} as Record, + ), + ).map(([date, transactions]) => ( +
+

+ {date} +

+ {transactions.map((item) => ( + + + + ))} +
+ ))} +
+ )}
{compatibility && controller && ( From 4951966f0a9eb2cc23e4f6f286ffeaee1ec3a66a Mon Sep 17 00:00:00 2001 From: RM3 Date: Fri, 13 Feb 2026 18:10:13 -0300 Subject: [PATCH 6/7] chore: optimized useUsernames() --- packages/keychain/src/components/activity.tsx | 1 - .../src/components/inventory/token/token.tsx | 16 +++--------- .../keychain/src/components/provider/data.tsx | 16 ++++-------- packages/keychain/src/hooks/account.ts | 25 ++++++++++++++++--- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/packages/keychain/src/components/activity.tsx b/packages/keychain/src/components/activity.tsx index 9f960e74f..133a616c3 100644 --- a/packages/keychain/src/components/activity.tsx +++ b/packages/keychain/src/components/activity.tsx @@ -55,7 +55,6 @@ export function Activity() { {events .filter((event) => event.date === current) .map((props: CardProps, index: number) => { - console.log(`EVENT [USERNAME]:`, props.username); switch (props.variant) { case "token": return ( diff --git a/packages/keychain/src/components/inventory/token/token.tsx b/packages/keychain/src/components/inventory/token/token.tsx index fd38d0053..9f165ca11 100644 --- a/packages/keychain/src/components/inventory/token/token.tsx +++ b/packages/keychain/src/components/inventory/token/token.tsx @@ -142,7 +142,7 @@ function ERC20() { ) ?? []; return Array.from(new Set(accounts)); }, [transfers]); - const { usernames } = useUsernames({ addresses }); + const { getUsername } = useUsernames({ addresses }); const txs = useMemo(() => { if (!transfers || !token?.metadata?.image) { @@ -159,22 +159,14 @@ function ERC20() { const timestamp = new Date(transfer.executedAt).getTime(); const date = getDate(timestamp); const image = token.metadata.image; - const toUsername = usernames.find( - (user) => - BigInt(user.address ?? "0x0") === BigInt(transfer.toAddress), - )?.username; - const fromUsername = usernames.find( - (user) => - BigInt(user.address ?? "0x0") === BigInt(transfer.fromAddress), - )?.username; return { key: `${transfer.transactionHash}-${transfer.eventId}-${i}`, transactionHash: transfer.transactionHash, amount: value, to: transfer.toAddress, - toUsername, + toUsername: getUsername(transfer.toAddress), from: transfer.fromAddress, - fromUsername, + fromUsername: getUsername(transfer.fromAddress), contractAddress: transfer.contractAddress, symbol: transfer.symbol, eventId: transfer.eventId, @@ -189,7 +181,7 @@ function ERC20() { }; }); }); - }, [transfers, accountAddress, usernames, token?.metadata?.image]); + }, [transfers, accountAddress, getUsername, token?.metadata?.image]); const to = useCallback( (transactionHash: string) => { diff --git a/packages/keychain/src/components/provider/data.tsx b/packages/keychain/src/components/provider/data.tsx index f19079663..2c9b2c8d5 100644 --- a/packages/keychain/src/components/provider/data.tsx +++ b/packages/keychain/src/components/provider/data.tsx @@ -124,7 +124,7 @@ export function DataProvider({ children }: { children: ReactNode }) { ) ?? []; return Array.from(new Set(accounts)); }, [transfers]); - const { usernames } = useUsernames({ addresses }); + const { getUsername } = useUsernames({ addresses }); const erc20s: CardProps[] = useMemo(() => { return ( @@ -146,9 +146,6 @@ export function DataProvider({ children }: { children: ReactNode }) { BigInt(transfer.fromAddress) === BigInt(address) ? transfer.toAddress : transfer.fromAddress; - const username = usernames.find( - (user) => BigInt(user.address ?? "0x0") === BigInt(userAddress), - )?.username; const result: CardProps = { variant: "token", key: `${transfer.transactionHash}-${transfer.eventId}`, @@ -156,7 +153,7 @@ export function DataProvider({ children }: { children: ReactNode }) { transactionHash: transfer.transactionHash, amount: value, address: userAddress, - username: username ?? "", + username: getUsername(userAddress) ?? "", value: "$-", name: "", collection: "", @@ -178,7 +175,7 @@ export function DataProvider({ children }: { children: ReactNode }) { }), ) || [] ); - }, [transfers, address, usernames, theme]); + }, [transfers, address, getUsername, theme]); const erc721s: CardProps[] = useMemo(() => { return ( @@ -206,9 +203,6 @@ export function DataProvider({ children }: { children: ReactNode }) { BigInt(transfer.fromAddress) === BigInt(address) ? transfer.toAddress : transfer.fromAddress; - const username = usernames.find( - (user) => BigInt(user.address ?? "0x0") === BigInt(userAddress), - )?.username; const result: CardProps = { variant: "collectible", key: `${transfer.transactionHash}-${transfer.eventId}`, @@ -216,7 +210,7 @@ export function DataProvider({ children }: { children: ReactNode }) { transactionHash: transfer.transactionHash, amount: "", address: userAddress, - username: username ?? "", + username: getUsername(userAddress) ?? "", value: "", name: name || "", collection: transfer.name, @@ -238,7 +232,7 @@ export function DataProvider({ children }: { children: ReactNode }) { }); }) || [] ); - }, [transfers, address, usernames, theme]); + }, [transfers, address, getUsername, theme]); const actions: CardProps[] = useMemo(() => { return ( diff --git a/packages/keychain/src/hooks/account.ts b/packages/keychain/src/hooks/account.ts index 99bd3479d..110fbdbb5 100644 --- a/packages/keychain/src/hooks/account.ts +++ b/packages/keychain/src/hooks/account.ts @@ -11,7 +11,7 @@ import { useAddressByUsernameQuery, } from "@cartridge/ui/utils/api/cartridge"; import base64url from "base64url"; -import { useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { useMatch, useSearchParams } from "react-router-dom"; import { constants, getChecksumAddress } from "starknet"; import { useConnection } from "./connection"; @@ -271,12 +271,29 @@ export function useUsernames({ addresses }: { addresses: string[] }) { { enabled: addresses.length > 0 }, ); - return { - usernames: + const usernames = useMemo(() => { + return ( data?.accounts?.edges?.map((edge) => ({ username: edge?.node?.username, address: edge?.node?.controllers?.edges?.[0]?.node?.address, - })) ?? [], + })) ?? [] + ); + }, [data]); + + const getUsername = useCallback( + (adress: string | null | undefined) => { + return !adress + ? undefined + : usernames.find( + (user) => BigInt(user.address ?? "0x0") === BigInt(adress), + )?.username; + }, + [usernames], + ); + + return { + usernames, + getUsername, }; } From bba6a8a092e0811141a2bb8f11f53bc48d78db74 Mon Sep 17 00:00:00 2001 From: RM3 Date: Tue, 17 Feb 2026 13:19:55 -0300 Subject: [PATCH 7/7] chore: updated @cartridge/ui dependency --- examples/next/next.config.js | 10 ++++++++++ examples/next/tsconfig.json | 1 + package.json | 2 +- pnpm-lock.yaml | 23 +++++++++++------------ pnpm-workspace.yaml | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/next/next.config.js b/examples/next/next.config.js index ce18e3f5e..d3856c246 100644 --- a/examples/next/next.config.js +++ b/examples/next/next.config.js @@ -1,4 +1,6 @@ /** @type {import('next').NextConfig} */ +const path = require("path"); + const nextConfig = { productionBrowserSourceMaps: true, reactStrictMode: true, @@ -24,6 +26,14 @@ const nextConfig = { config.plugins.push(new WasmChunksFixPlugin()); } + config.resolve.alias = { + ...config.resolve.alias, + [path.resolve(__dirname, "src/assets")]: path.resolve( + path.dirname(require.resolve("@cartridge/ui")), + "assets", + ), + }; + return config; }, }; diff --git a/examples/next/tsconfig.json b/examples/next/tsconfig.json index 818b09bf0..4da2c0125 100644 --- a/examples/next/tsconfig.json +++ b/examples/next/tsconfig.json @@ -21,6 +21,7 @@ "next-env.d.ts", "**/*.ts", "**/*.tsx", + "**/*.otf", ".next/types/**/*.ts", "**/*.wasm" ], diff --git a/package.json b/package.json index 01a36fe40..7defb0711 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@cartridge/presets": "github:cartridge-gg/presets#c064e82", - "@cartridge/ui": "github:cartridge-gg/ui#e5405d6", + "@cartridge/ui": "catalog:", "tailwindcss": "catalog:", "@graphql-codegen/cli": "^2.6.2", "@graphql-codegen/typescript": "^2.4.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e299f513..6f4f066f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ catalogs: specifier: ^6.2.4 version: 6.2.4 '@cartridge/ui': - specifier: github:cartridge-gg/ui#e5405d6 + specifier: github:cartridge-gg/ui#431fb6f version: 0.7.14-alpha.2 '@eslint/js': specifier: ^9.18.0 @@ -165,8 +165,8 @@ importers: specifier: github:cartridge-gg/presets#c064e82 version: https://codeload.github.com/cartridge-gg/presets/tar.gz/c064e82 '@cartridge/ui': - specifier: github:cartridge-gg/ui#e5405d6 - version: https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@16.18.11)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) + specifier: 'catalog:' + version: https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@16.18.11)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) '@graphql-codegen/cli': specifier: ^2.6.2 version: 2.16.5(@babel/core@7.27.1)(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@16.18.11)(bufferutil@4.0.9)(encoding@0.1.13)(graphql@16.12.0)(typescript@5.8.3)(utf-8-validate@5.0.10) @@ -246,7 +246,7 @@ importers: version: link:../../packages/controller '@cartridge/ui': specifier: 'catalog:' - version: https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) + version: https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) '@starknet-react/chains': specifier: ^5.0.1 version: 5.0.1 @@ -497,7 +497,7 @@ importers: version: 5.14.0(rollup@4.40.2) ts-jest: specifier: ^29.2.5 - version: 29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.4)(jest@29.7.0(@types/node@18.19.87)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(typescript@5.8.3) + version: 29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@18.19.87)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(typescript@5.8.3) tsup: specifier: 'catalog:' version: 8.4.0(@microsoft/api-extractor@7.52.6(@types/node@18.19.87))(@swc/core@1.11.24(@swc/helpers@0.5.17))(jiti@1.21.7)(postcss@8.5.3)(tsx@4.19.4)(typescript@5.8.3)(yaml@2.7.1) @@ -570,7 +570,7 @@ importers: version: 6.2.4 '@cartridge/ui': specifier: 'catalog:' - version: https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) + version: https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4)) '@dojoengine/sdk': specifier: 1.8.12 version: 1.8.12(@effect/platform@0.93.8(effect@3.19.8))(@opentelemetry/semantic-conventions@1.38.0)(@tanstack/react-query@5.75.0(react@18.3.1))(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(bufferutil@4.0.9)(get-starknet-core@4.0.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(starknet@8.5.4)(typescript@5.8.3)(use-sync-external-store@1.6.0(react@18.3.1))(utf-8-validate@5.0.10)(zod@3.24.4) @@ -1272,8 +1272,8 @@ packages: resolution: {tarball: https://codeload.github.com/cartridge-gg/presets/tar.gz/c064e82} version: 0.0.1 - '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6': - resolution: {tarball: https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6} + '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f': + resolution: {tarball: https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f} version: 0.7.14-alpha.2 peerDependencies: react: ^18.2.0 || ^19.0.0 @@ -11243,7 +11243,7 @@ snapshots: dependencies: '@starknet-io/types-js': 0.8.4 - '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@16.18.11)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4))': + '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@16.18.11)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4))': dependencies: '@cartridge/presets': https://codeload.github.com/cartridge-gg/presets/tar.gz/90a5fe0 '@radix-ui/react-accordion': 1.2.1(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11288,7 +11288,7 @@ snapshots: - react-native - tailwindcss - '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/e5405d6(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4))': + '@cartridge/ui@https://codeload.github.com/cartridge-gg/ui/tar.gz/431fb6f(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(starknet@8.5.4)(tailwindcss@3.4.17(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(viem@2.28.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.24.4))': dependencies: '@cartridge/presets': https://codeload.github.com/cartridge-gg/presets/tar.gz/90a5fe0 '@radix-ui/react-accordion': 1.2.1(@types/react-dom@18.3.7(@types/react@18.3.20))(@types/react@18.3.20)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -22090,7 +22090,7 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(esbuild@0.25.4)(jest@29.7.0(@types/node@18.19.87)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(typescript@5.8.3): + ts-jest@29.3.2(@babel/core@7.27.1)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.1))(jest@29.7.0(@types/node@18.19.87)(ts-node@10.9.2(@swc/core@1.11.24(@swc/helpers@0.5.17))(@types/node@18.19.87)(typescript@5.8.3)))(typescript@5.8.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -22109,7 +22109,6 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.27.1) - esbuild: 0.25.4 ts-log@2.2.7: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a3ae26dfd..6172acd56 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,7 +8,7 @@ catalog: "@cartridge/arcade": "0.3.12" "@cartridge/controller-wasm": "0.9.4" "@cartridge/penpal": "^6.2.4" - "@cartridge/ui": "github:cartridge-gg/ui#e5405d6" + "@cartridge/ui": "github:cartridge-gg/ui#431fb6f" "@eslint/js": "^9.18.0" "@noble/curves": "^1.9.0" "@noble/hashes": "^1.8.0"