Skip to content

feat: create reusable hooks and add sql hook to sdk #376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 16, 2025
Merged
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
15 changes: 15 additions & 0 deletions .changeset/great-kiwis-peel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@dojoengine/sdk": patch
"@dojoengine/core": patch
"@dojoengine/create-burner": patch
"@dojoengine/create-dojo": patch
"@dojoengine/predeployed-connector": patch
"@dojoengine/react": patch
"@dojoengine/state": patch
"@dojoengine/torii-client": patch
"@dojoengine/torii-wasm": patch
"@dojoengine/utils": patch
"@dojoengine/utils-wasm": patch
---

Add @dojoengine/sdk/state @dojoengine/sdk/react @dojoengine/sdk/sql // Moves hooks to sdk // Update examples
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { useCallback, useEffect, useState } from "react";
import { Button } from "./ui/button";
import { useAccount, useSendTransaction } from "@starknet-react/core";
import { useDojoDb } from "@/dojo/provider";
import { ensureStarkFelt } from "@/lib/utils";

import { ParsedEntity, QueryBuilder, SDK } from "@dojoengine/sdk";
import { useDojoSDK } from "@dojoengine/sdk/react";
import { Subscription } from "@dojoengine/torii-wasm";
import { dojoConfig } from "@/../dojoConfig";
import { SchemaType } from "@/typescript/models.gen";
import { setupWorld } from "@/typescript/contracts.gen";
import { dojoConfig } from "@/../dojoConfig";

import { addAddressPadding } from "starknet";
import { Button } from "./ui/button";
import { useAccount, useSendTransaction } from "@starknet-react/core";

export default function CallerCounter() {
const [count, setCount] = useState(0);
Expand All @@ -29,7 +31,7 @@ export default function CallerCounter() {
setIsLoading(true);
}, [incrementCallerCounter, setIsLoading]);

const { db } = useDojoDb();
const { sdk } = useDojoSDK<typeof setupWorld, SchemaType>();
useEffect(() => {
async function getEntity(db: SDK<SchemaType>, address: string) {
const entity = await db.getEntities({
Expand All @@ -53,10 +55,10 @@ export default function CallerCounter() {

return parseInt(count.toString(), 16);
}
if (address && db) {
getEntity(db, address).then(setCount).catch(console.error);
if (address && sdk) {
getEntity(sdk, address).then(setCount).catch(console.error);
}
}, [address, db]);
}, [address, sdk]);
Comment on lines +58 to +61
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error boundary for SDK initialization.

The SDK usage should be wrapped in proper error handling to gracefully handle initialization failures.

-if (address && sdk) {
+try {
+  if (address && sdk) {
     getEntity(sdk, address).then(setCount).catch(console.error);
+  }
+} catch (error) {
+  console.error('Failed to initialize SDK:', error);
+  // Consider showing a user-friendly error message
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (address && sdk) {
getEntity(sdk, address).then(setCount).catch(console.error);
}
}, [address, db]);
}, [address, sdk]);
try {
if (address && sdk) {
getEntity(sdk, address).then(setCount).catch(console.error);
}
} catch (error) {
console.error('Failed to initialize SDK:', error);
// Consider showing a user-friendly error message
}
}, [address, sdk]);


useEffect(() => {
async function subscribeToEntityUpdates(
Expand Down Expand Up @@ -100,8 +102,8 @@ export default function CallerCounter() {
});
setSub(sub);
}
if (address && db && sub === null) {
subscribeToEntityUpdates(db, address)
if (address && sdk && sub === null) {
subscribeToEntityUpdates(sdk, address)
.then(() => {})
.catch(console.error);
}
Expand All @@ -110,7 +112,7 @@ export default function CallerCounter() {
sub.free();
}
};
}, [address, db, sub]);
}, [address, sdk, sub]);
return (
<fieldset className="grid gap-6 rounded-lg border p-4">
<legend className="-ml-1 px-1 text-sm font-medium">
Expand Down
5 changes: 3 additions & 2 deletions examples/example-vite-kitchen-sink/src/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { Label } from "./ui/label";
import { Textarea } from "./ui/textarea";
import { useCallback, useEffect, useRef, useState, KeyboardEvent } from "react";
import { useForm } from "react-hook-form";
import { useDojoDb } from "@/dojo/provider";
import { useAccount } from "@starknet-react/core";
import { toValidAscii } from "@/lib/utils";
import { ParsedEntity, SDK } from "@dojoengine/sdk";
import { Subscription } from "@dojoengine/torii-wasm";
import { shortAddress } from "@/lib/utils";
import { Message, SchemaType } from "@/typescript/models.gen";
import { useDojoSDK } from "@dojoengine/sdk/react";
import { setupWorld } from "@/typescript/contracts.gen";

interface MessageItem {
content: string;
Expand All @@ -30,7 +31,7 @@ export default function Chat() {
const [sub, setSub] = useState<Subscription | null>(null);
const formRef = useRef<HTMLFormElement>(null);

const { db } = useDojoDb();
const { sdk: db } = useDojoSDK<typeof setupWorld, SchemaType>();
const publish = useCallback(
async (data: FormValues) => {
if (!account || !db) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useCallback, useEffect, useState } from "react";
import { Button } from "./ui/button";
import { useSendTransaction } from "@starknet-react/core";
import { useDojoDb } from "@/dojo/provider";
import { ParsedEntity, QueryBuilder, SDK } from "@dojoengine/sdk";
import { Subscription } from "@dojoengine/torii-wasm";
import { dojoConfig } from "@/../dojoConfig";
import { SchemaType } from "@/typescript/models.gen";
import { addAddressPadding } from "starknet";
import { useDojoSDK } from "@dojoengine/sdk/react";
import { setupWorld } from "@/typescript/contracts.gen";

export default function GlobalCOunter() {
const [count, setCount] = useState(0);
Expand All @@ -26,7 +26,7 @@ export default function GlobalCOunter() {
setIsLoading(true);
}, [incrementGlobalCounter, setIsLoading]);

const { db } = useDojoDb();
const { sdk: db } = useDojoSDK<typeof setupWorld, SchemaType>();

useEffect(() => {
async function getEntity(db: SDK<SchemaType>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Subscription } from "@dojoengine/torii-wasm";
import { useAccount } from "@starknet-react/core";
import { ParsedEntity, QueryBuilder, SDK } from "@dojoengine/sdk";
import { SchemaType } from "@/typescript/models.gen";
import { useDojoDb } from "@/dojo/provider";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
Expand All @@ -17,6 +16,8 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown";
import { CairoCustomEnum } from "starknet";
import { useDojoSDK } from "@dojoengine/sdk/react";
import { setupWorld } from "@/typescript/contracts.gen";

interface ThemeState {
current: string | null;
Expand Down Expand Up @@ -47,7 +48,10 @@ export default function ThemeSwitchButton() {
const [entityId, setEntityId] = useState<string | null>(null);
const { address, account } = useAccount();
const [sub, setSub] = useState<Subscription | null>(null);
const { db, actions } = useDojoDb();
const { sdk: db, client: actions } = useDojoSDK<
typeof setupWorld,
SchemaType
>();

const handleChangeTheme = useCallback(
async (theme: AvailableTheme) => {
Expand Down
21 changes: 0 additions & 21 deletions examples/example-vite-kitchen-sink/src/dojo/provider.tsx

This file was deleted.

18 changes: 10 additions & 8 deletions examples/example-vite-kitchen-sink/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import Home from "./app/page";
import "./app/globals.css";

import { init } from "@dojoengine/sdk";
import { env, getRpcUrl } from "@/env";
import { DojoSdkProvider } from "@dojoengine/sdk/react";
import { dojoConfig } from "../dojoConfig";
import { DojoContext } from "@/dojo/provider";
import { DojoProvider } from "@dojoengine/core";
import { setupWorld } from "./typescript/contracts.gen";
import { SchemaType, schema } from "./typescript/models.gen";

import { env, getRpcUrl } from "@/env";

async function main() {
const db = await init<SchemaType>(
const sdk = await init<SchemaType>(
{
client: {
rpcUrl: getRpcUrl(),
Expand All @@ -32,16 +32,18 @@ async function main() {
},
schema
);
const provider = new DojoProvider(dojoConfig.manifest, getRpcUrl());
const actions = setupWorld(provider);

createRoot(document.getElementById("root")!).render(
<StrictMode>
<DojoContext.Provider value={{ db, provider, actions }}>
<DojoSdkProvider
sdk={sdk}
dojoConfig={dojoConfig}
clientFn={setupWorld}
>
<RootLayout>
<Home />
</RootLayout>
</DojoContext.Provider>
</DojoSdkProvider>
</StrictMode>
);
}
Expand Down
25 changes: 5 additions & 20 deletions examples/example-vite-react-sdk/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
import { useEffect, useMemo } from "react";
import {
ParsedEntity,
QueryBuilder,
SDK,
createDojoStore,
} from "@dojoengine/sdk";
import { ParsedEntity, QueryBuilder } from "@dojoengine/sdk";
import { getEntityIdFromKeys } from "@dojoengine/utils";
import { AccountInterface, addAddressPadding, CairoCustomEnum } from "starknet";

import { ModelsMapping, SchemaType } from "./typescript/models.gen.ts";
import { useDojo } from "./useDojo.tsx";
import useModel from "./useModel.tsx";
import { useSystemCalls } from "./useSystemCalls.ts";
import { useAccount } from "@starknet-react/core";
import { WalletAccount } from "./wallet-account.tsx";
import { HistoricalEvents } from "./historical-events.tsx";

/**
* Global store for managing Dojo game state.
*/
export const useDojoStore = createDojoStore<SchemaType>();
import { useDojoSDK, useModel } from "@dojoengine/sdk/react";

/**
* Main application component that provides game functionality and UI.
* Handles entity subscriptions, state management, and user interactions.
*
* @param props.sdk - The Dojo SDK instance configured with the game schema
*/
function App({ sdk }: { sdk: SDK<SchemaType> }) {
const {
setup: { client },
} = useDojo();
function App() {
const { useDojoStore, client, sdk } = useDojoSDK();
const { account } = useAccount();
const state = useDojoStore((state) => state);
const entities = useDojoStore((state) => state.entities);
Expand Down Expand Up @@ -160,7 +147,6 @@ function App({ sdk }: { sdk: SDK<SchemaType> }) {
: "Need to Spawn"}
</div>
<div className="col-span-3 text-center text-base text-white">
{/* @ts-expect-error we have an option here so type is ok */}
{moves && moves.last_direction.isSome()
? moves.last_direction.unwrap()
: ""}
Expand Down Expand Up @@ -280,7 +266,6 @@ function App({ sdk }: { sdk: SDK<SchemaType> }) {
"N/A"}
</td>
<td className="border border-gray-700 p-2">
{/* @ts-expect-error we have an option here so type is ok */}
{lastDirection}
</td>
<td className="border border-gray-700 p-2">
Expand All @@ -296,7 +281,7 @@ function App({ sdk }: { sdk: SDK<SchemaType> }) {
</div>

{/* // Here sdk is passed as props but this can be done via contexts */}
<HistoricalEvents sdk={sdk} />
<HistoricalEvents />
</div>
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions examples/example-vite-react-sdk/src/historical-events.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { ParsedEntity, SDK } from "@dojoengine/sdk";
import { ParsedEntity } from "@dojoengine/sdk";
import { useAccount } from "@starknet-react/core";
import { SchemaType } from "./typescript/models.gen";
import { AccountInterface, addAddressPadding } from "starknet";
import { useEffect, useState } from "react";
import { Subscription } from "@dojoengine/torii-client";
import { useDojoSDK } from "@dojoengine/sdk/react";

export function HistoricalEvents({ sdk }: { sdk: SDK<SchemaType> }) {
export function HistoricalEvents() {
const { account } = useAccount();
const { sdk } = useDojoSDK();
const [events, setEvents] = useState<ParsedEntity<SchemaType>[][]>([]);
const [subscription, setSubscription] = useState<Subscription | null>(null);

Comment on lines +9 to 13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Fix needed for TypeScript type issue in historical-events.tsx

The @ts-expect-error comment marked with "FIX: type here" indicates a known type issue that needs addressing, unlike other similar comments in the codebase which are intentional workarounds. Consider implementing proper type definitions for the event data.

🔗 Analysis chain

Consider addressing the TypeScript type issue.

The code includes a @ts-expect-error comment indicating a known type issue. Consider creating proper type definitions for the event data to improve type safety.

Let's check if there are similar type issues elsewhere in the codebase:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for ts-expect-error comments related to types
rg "@ts-expect-error" -A 2

Length of output: 6894

Expand Down
18 changes: 11 additions & 7 deletions examples/example-vite-react-sdk/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { createRoot } from "react-dom/client";

import App from "./App.tsx";

import "./index.css";
// Dojo related imports
import { init } from "@dojoengine/sdk";
import { DojoSdkProvider } from "@dojoengine/sdk/react";
import { SchemaType, schema } from "./typescript/models.gen.ts";
import { setupWorld } from "./typescript/contracts.gen.ts";

import "./index.css";
import { dojoConfig } from "../dojoConfig.ts";
import { DojoContextProvider } from "./DojoContext.tsx";
import { setupBurnerManager } from "@dojoengine/create-burner";
import StarknetProvider from "./starknet-provider.tsx";

/**
Expand Down Expand Up @@ -38,13 +40,15 @@ async function main() {

createRoot(document.getElementById("root")!).render(
<StrictMode>
<DojoContextProvider
burnerManager={await setupBurnerManager(dojoConfig)}
<DojoSdkProvider
sdk={sdk}
dojoConfig={dojoConfig}
clientFn={setupWorld}
>
<StarknetProvider>
<App sdk={sdk} />
<App />
</StarknetProvider>
</DojoContextProvider>
</DojoSdkProvider>
</StrictMode>
);
}
Expand Down
28 changes: 0 additions & 28 deletions examples/example-vite-react-sdk/src/useDojo.tsx

This file was deleted.

Loading
Loading