Skip to content

Commit

Permalink
✨ Add icons and hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
bal7hazar committed Dec 19, 2024
1 parent 92fa77f commit ca0e2d7
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/profile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@cartridge/utils": "workspace:*",
"@hookform/resolvers": "^3.9.1",
"compare-versions": "^6.1.1",
"lodash": "^4.17.21",
"posthog-js": "^1.181.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand All @@ -31,6 +32,7 @@
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@types/lodash": "^4.17.13",
"@types/node": "^20.6.0",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
Expand Down
89 changes: 88 additions & 1 deletion packages/profile/src/hooks/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,102 @@ import {
useAccountNameQuery,
useAddressByUsernameQuery,
} from "@cartridge/utils/api/cartridge";
import { useEffect, useMemo, useRef } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useParams } from "react-router-dom";
import { useStarkAddress } from "./starknetid";
import { useWallet } from "./wallet";

export function useUsername({ address }: { address: string }) {
const { data } = useAccountNameQuery({ address });

return { username: data?.accounts?.edges?.[0]?.node?.username ?? "" };
}

export function useAddress({ username }: { username: string }) {
const { isReady } = useIndexerAPI();
const { data, isFetching } = useAddressByUsernameQuery(
{ username },
{ enabled: isReady && !!username },
);

return {
address: data?.account?.controllers?.edges?.[0]?.node?.address ?? "",
isFetching,
};
}

export function useAccountInfo({ nameOrAddress }: { nameOrAddress: string }) {
const [starkName, setStarkName] = useState("");
const [controllerName, setControllerName] = useState("");

useEffect(() => {
// If the address ends with .stark, set the stark name
if (nameOrAddress.endsWith(".stark")) {
setStarkName(nameOrAddress);
setControllerName("");
return;
}
// If the address matches a controller name, set the controller name
if (
nameOrAddress.match(/^[a-z0-9]+$/) &&
nameOrAddress.length >= 3 &&
nameOrAddress.length <= 30
) {
setControllerName(nameOrAddress);
setStarkName("");
return;
}
// Otherwise, clear the names
setStarkName("");
setControllerName("");
}, [nameOrAddress]);

// Fetch the stark address
const { address: starkAddress, isFetching: isFetchingStarkAddress } =
useStarkAddress({ name: starkName });
// Fetch the controller address
const {
address: controllerAddress,
isFetching: isFetchingControllerAddress,
} = useAddress({ username: controllerName });

const name = useMemo(() => {
if (starkName) {
return starkName;
}
if (controllerName) {
return controllerName;
}
return "";
}, [starkName, controllerName]);

const address = useMemo(() => {
if (starkAddress) {
return starkAddress;
}
if (controllerAddress) {
return controllerAddress;
}
if (nameOrAddress.startsWith("0x")) {
return nameOrAddress;
}
return "";
}, [starkAddress, controllerAddress, nameOrAddress]);

// Fetch class hash
const { wallet, isFetching: isFetchingClassHash } = useWallet({ address });

return {
name,
address,
wallet,
isFetching:
isFetchingStarkAddress ||
isFetchingControllerAddress ||
isFetchingClassHash,
};
}

export function useAccount() {
const params = useParams<{
username: string;
Expand Down
15 changes: 15 additions & 0 deletions packages/profile/src/hooks/starknetid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useQuery } from "react-query";

export const STARKNET_ID_API_URL = "https://api.starknet.id/domain_to_addr";

export const useStarkAddress = ({ name }: { name: string }) => {
const { data, isFetching } = useQuery({
enabled: !!name && name.includes(".stark"),
staleTime: 5 * 60 * 1000, // 5 minutes
queryKey: ["starknetid", name],
queryFn: () =>
fetch(`${STARKNET_ID_API_URL}?domain=${name}`).then((res) => res.json()),
});

return { address: data?.addr ?? "", isFetching };
};
62 changes: 62 additions & 0 deletions packages/profile/src/hooks/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useQuery } from "react-query";
import { useConnection } from "./context";
import { useMemo } from "react";

const ARGENT_CLASS_HASH = BigInt(
"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f",
);
const BRAAVOS_BASE_ACCOUNT_CLASS_HASH: BigInt = BigInt(
"0x013bfe114fb1cf405bfc3a7f8dbe2d91db146c17521d40dcf57e16d6b59fa8e6",
);
const BRAAVOS_ACCOUNT_CLASS_HASH: BigInt = BigInt(
"0x00816dd0297efc55dc1e7559020a3a825e81ef734b558f03c83325d4da7e6253",
);
const OZ_ACCOUNT_CLASS_HASH: BigInt = BigInt(
"0x04a444ef8caf8fa0db05da60bf0ad9bae264c73fa7e32c61d245406f5523174b",
);
const CONTROLLER_CLASS_HASH: BigInt = BigInt(
"0x511dd75da368f5311134dee2356356ac4da1538d2ad18aa66d57c47e3757d59",
);

export type Wallet = "Controller" | "ArgentX" | "Braavos" | "OpenZeppelin";

export function useWallet({ address }: { address: string }) {
const { provider } = useConnection();

const { data, isFetching } = useQuery({
enabled: !!address && address.startsWith("0x"),
staleTime: 5 * 60 * 1000, // 5 minutes
queryKey: ["classhash", address],
queryFn: async () => {
try {
return await provider.getClassHashAt(BigInt(address));
} catch (error) {
return null;
}
},
});

const wallet: Wallet | null = useMemo(() => {
console.log("data", data);
if (!data) return null;
const classHash = BigInt(data);
if (classHash === ARGENT_CLASS_HASH) {
return "ArgentX";
}
if (
classHash === BRAAVOS_BASE_ACCOUNT_CLASS_HASH ||
classHash === BRAAVOS_ACCOUNT_CLASS_HASH
) {
return "Braavos";
}
if (classHash === OZ_ACCOUNT_CLASS_HASH) {
return "OpenZeppelin";
}
if (classHash === CONTROLLER_CLASS_HASH) {
return "Controller";
}
return null;
}, [data]);

return { wallet, isFetching };
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { forwardRef, memo } from "react";
import { iconVariants } from "../utils";
import { IconProps } from "../types";

export const BravosIcon = memo(
export const BraavosIcon = memo(
forwardRef<SVGSVGElement, IconProps>(
({ className, size, ...props }, forwardedRef) => (
<svg
Expand All @@ -28,4 +28,4 @@ export const BravosIcon = memo(
),
);

BravosIcon.displayName = "BravosIcon";
BraavosIcon.displayName = "BraavosIcon";
3 changes: 2 additions & 1 deletion packages/ui-next/src/components/icons/brand/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from "./argent";
export * from "./bravos";
export * from "./braavos";
export * from "./briq";
export * from "./cartridge";
export * from "./cartridge-face";
Expand All @@ -22,6 +22,7 @@ export * from "./no-game";
export * from "./non-fungible-football"; // outdated
export * from "./olmech";
export * from "./opensea";
export * from "./open-zeppelin";
export * from "./optimism";
export * from "./quixotic";
export * from "./realms";
Expand Down
26 changes: 26 additions & 0 deletions packages/ui-next/src/components/icons/brand/open-zeppelin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { forwardRef, memo } from "react";
import { iconVariants } from "../utils";
import { IconProps } from "../types";

export const OpenZeppelinIcon = memo(
forwardRef<SVGSVGElement, IconProps>(
({ className, size, ...props }, forwardedRef) => (
<svg
viewBox="0 0 24 24"
className={iconVariants({ size, className })}
ref={forwardedRef}
{...props}
>
<path d="M4.9735 4H19.0474L16.6426 8.06041H4.9735V4Z" fill="currentColor"/>
<path d="M4.95129 19.9997C5.41539 19.2221 5.86184 18.479 6.30195 17.7464C7.60132 15.5835 8.84544 13.5126 10.3253 10.9176C11.025 9.74535 12.2342 9.01693 13.7269 9.01693H16.0724L9.52236 19.9997H4.95129Z" fill="currentColor"/>
<path d="M14.5933 16.0019C13.4017 16.0019 12.551 16.5648 12.0218 17.4709C11.5804 18.2264 11.1743 18.9005 10.7277 19.6416C10.6569 19.7592 10.585 19.8784 10.5119 20H19.0487V15.9901L14.5933 16.0019Z" fill="currentColor"/>


</svg>
),
),
);

OpenZeppelinIcon.displayName = "OpenZeppelinIcon";


0 comments on commit ca0e2d7

Please sign in to comment.