Skip to content
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

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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);

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