From 2c4bae18d6ef02f97b56327a802e186a908177c4 Mon Sep 17 00:00:00 2001 From: hayes-mysten <135670682+hayes-mysten@users.noreply.github.com> Date: Tue, 28 Nov 2023 10:06:19 -0800 Subject: [PATCH] [docs] update docs for create-dapp command (#15068) ## Description We previously documented the command as `pnpm create @mysten/create-dapp` but should be using `pnpm create @mysten/dapp` which will work when converted to yarn or npm (the `create-` prefix for the package name is automatically applied by the `create` command) ## Test Plan How did you test the new or updated feature? --- If your changes are not user-facing and not a breaking change, you can skip the following section. Otherwise, please indicate what changed, and then add to the Release Notes section as highlighted during the release process. ### Type of Change (Check all that apply) - [ ] protocol change - [ ] user-visible impact - [ ] breaking change for a client SDKs - [ ] breaking change for FNs (FN binary must upgrade) - [ ] breaking change for validators or node operators (must upgrade binaries) - [ ] breaking change for on-chain data layout - [ ] necessitate either a data wipe or data migration ### Release notes --- .../developer/app-examples/coin-flip.mdx | 467 +++++++++--------- .../developer/app-examples/e2e-counter.mdx | 332 ++++++------- .../developer/first-app/client-tssdk.mdx | 157 +++--- sdk/create-dapp/README.md | 2 +- sdk/docs/pages/dapp-kit/create-dapp.mdx | 2 +- 5 files changed, 480 insertions(+), 480 deletions(-) diff --git a/docs/content/guides/developer/app-examples/coin-flip.mdx b/docs/content/guides/developer/app-examples/coin-flip.mdx index fc999d53b3508..6554bf1086b06 100644 --- a/docs/content/guides/developer/app-examples/coin-flip.mdx +++ b/docs/content/guides/developer/app-examples/coin-flip.mdx @@ -611,7 +611,7 @@ The following instructions are using `pnpm` as the package manager. Follow the [ First, initialize your frontend project. To do this rapidly, use the [`create-dapp` tool](https://sui-typescript-docs.vercel.app/dapp-kit/create-dapp) to bootstrap the project using [dApp Kit](https://sui-typescript-docs.vercel.app/dapp-kit). Run the following command in your terminal or console: ``` -pnpm create @mysten/create-dapp +pnpm create @mysten/dapp ``` This CLI command prompts you through a couple of steps: @@ -620,6 +620,7 @@ This CLI command prompts you through a couple of steps: 1. `react-client-dapp`: This starter template contains the minimum dApp Kit template code that you can start with. This variant is meant for developers already familiar with the dApp Kit and who don't want unnecessary template code. 1. `react-e2e-counter`: This starter template contains a simple counter Sui Move smart contract with the frontend template code interacting with it. This variant is meant for developers trying to learn how to use dApp Kit. + 1. It prompts you to name your project folder. Done. Your project has all necessary code to get you started. Lastly, `cd` into your project folder and run `pnpm install` to install all dependencies. @@ -650,65 +651,65 @@ The following frontend code snippets include only the most relevant sections. Re As is common in other React projects, `App.tsx` is where you implement the outer layout: ```typescript title='App.tsx' -import { ConnectButton, useCurrentAccount } from "@mysten/dapp-kit"; -import { Box, Callout, Container, Flex, Grid, Heading } from "@radix-ui/themes"; -import { PlayerSesh } from "./containers/Player/PlayerSesh"; -import { HouseSesh } from "./containers/House/HouseSesh"; -import { HOUSECAP_ID, PACKAGE_ID } from "./constants"; -import { InfoCircledIcon } from "@radix-ui/react-icons"; +import { ConnectButton, useCurrentAccount } from '@mysten/dapp-kit'; +import { InfoCircledIcon } from '@radix-ui/react-icons'; +import { Box, Callout, Container, Flex, Grid, Heading } from '@radix-ui/themes'; + +import { HOUSECAP_ID, PACKAGE_ID } from './constants'; +import { HouseSesh } from './containers/House/HouseSesh'; +import { PlayerSesh } from './containers/Player/PlayerSesh'; function App() { - const account = useCurrentAccount(); - return ( - <> - - - Satoshi Coin Flip Single Player - - - - - - - - - Package ID: {PACKAGE_ID} - - - HouseCap ID: {HOUSECAP_ID} - - - - - - - - You need to connect to wallet that publish the smart contract - package - - - - {!account ? ( - - Please connect wallet to continue - - ) : ( - - - - - )} - - - ); + const account = useCurrentAccount(); + return ( + <> + + + Satoshi Coin Flip Single Player + + + + + + + + + Package ID: {PACKAGE_ID} + + + HouseCap ID: {HOUSECAP_ID} + + + + + + + + You need to connect to wallet that publish the smart contract package + + + + {!account ? ( + + Please connect wallet to continue + + ) : ( + + + + + )} + + + ); } export default App; @@ -811,52 +812,54 @@ Great, now you know how to initialize the `HouseData` shared object. Move to the In this game, the users must create a `Counter` object to start the game. So there should be a place in the Player column UI to list the existing `Counter` object information for the player to choose. It seems likely that you will reuse the fetching logic for the `Counter` object in several places in your UI, so it’s good practice to isolate this logic into a React hook, which you call `useFetchCounterNft()` in `useFetchCounterNft.ts`: ```typescript title='containers/Player/useFetchCounterNft.ts' -import { useCurrentAccount, useSuiClientQuery } from "@mysten/dapp-kit"; -import {} from "react"; -import { PACKAGE_ID } from "../../constants"; +import { useCurrentAccount, useSuiClientQuery } from '@mysten/dapp-kit'; + +import 'react'; + +import { PACKAGE_ID } from '../../constants'; // React hook to fetch CounterNFT owned by connected wallet // This hook is to demonstrate how to use `@mysten/dapp-kit` React hook to query data // besides using SuiClient directly export function useFetchCounterNft() { - const account = useCurrentAccount(); - - if (!account) { - return { data: [] }; - } - - // Fetch CounterNFT owned by current connected wallet - // Only fetch the 1st one - const { data, isLoading, isError, error, refetch } = useSuiClientQuery( - "getOwnedObjects", - { - owner: account.address, - limit: 1, - filter: { - MatchAll: [ - { - StructType: `${PACKAGE_ID}::counter_nft::Counter`, - }, - { - AddressOwner: account.address, - }, - ], - }, - options: { - showOwner: true, - showType: true, - }, - }, - { queryKey: ["CounterNFT"] }, - ); - - return { - data: data && data.data.length > 0 ? data?.data : [], - isLoading, - isError, - error, - refetch, - }; + const account = useCurrentAccount(); + + if (!account) { + return { data: [] }; + } + + // Fetch CounterNFT owned by current connected wallet + // Only fetch the 1st one + const { data, isLoading, isError, error, refetch } = useSuiClientQuery( + 'getOwnedObjects', + { + owner: account.address, + limit: 1, + filter: { + MatchAll: [ + { + StructType: `${PACKAGE_ID}::counter_nft::Counter`, + }, + { + AddressOwner: account.address, + }, + ], + }, + options: { + showOwner: true, + showType: true, + }, + }, + { queryKey: ['CounterNFT'] }, + ); + + return { + data: data && data.data.length > 0 ? data?.data : [], + isLoading, + isError, + error, + refetch, + }; } ``` @@ -870,40 +873,39 @@ That’s it, now put the hook into the UI component `PlayerListCounterNft.tsx` a ```typescript title='containers/Player/PlayerListCounterNft.tsx' export function PlayerListCounterNft() { - const { data, isLoading, error, refetch } = useFetchCounterNft(); - const { mutate: execCreateCounterNFT } = useSignAndExecuteTransactionBlock(); - - return ( - - - Counter NFTs - - - {error && Error: {error.message}} - - - {data.length > 0 ? ( - data.map((it) => { - return ( - - - Object ID: - - {it.data?.objectId} - - Object Type: - - {it.data?.type} - - ); - }) - ) : ( - No CounterNFT Owned - )} - - - - ); + const { data, isLoading, error, refetch } = useFetchCounterNft(); + const { mutate: execCreateCounterNFT } = useSignAndExecuteTransactionBlock(); + + return ( + + + Counter NFTs + + + {error && Error: {error.message}} + + + {data.length > 0 ? ( + data.map((it) => { + return ( + + + Object ID: + + {it.data?.objectId} + + Object Type: + + {it.data?.type} + + ); + }) + ) : ( + No CounterNFT Owned + )} + + + ); } ``` @@ -914,27 +916,26 @@ As you might recall with `TransactionBlock`, outputs from the transaction can be ```typescript title='containers/Player/PlayerListCounterNft.tsx' const txb = new TransactionBlock(); const [counterNft] = txb.moveCall({ - target: `${PACKAGE_ID}::counter_nft::mint`, + target: `${PACKAGE_ID}::counter_nft::mint`, }); txb.moveCall({ - target: `${PACKAGE_ID}::counter_nft::transfer_to_sender`, - arguments: [counterNft], + target: `${PACKAGE_ID}::counter_nft::transfer_to_sender`, + arguments: [counterNft], }); - execCreateCounterNFT( - { - transactionBlock: txb, - }, - { - onError: (err) => { - toast.error(err.message); - }, - onSuccess: (result) => { - toast.success(`Digest: ${result.digest}`); - refetch?.(); - }, - }, + { + transactionBlock: txb, + }, + { + onError: (err) => { + toast.error(err.message); + }, + onSuccess: (result) => { + toast.success(`Digest: ${result.digest}`); + refetch?.(); + }, + }, ); ``` @@ -945,33 +946,31 @@ Great, now you can create the game with the created `Counter` object. Isolate th const txb = new TransactionBlock(); // Player stake -const [stakeCoin] = txb.splitCoins(txb.gas, [ - MIST_PER_SUI * BigInt(stake), -]); +const [stakeCoin] = txb.splitCoins(txb.gas, [MIST_PER_SUI * BigInt(stake)]); // Create the game with CounterNFT txb.moveCall({ - target: `${PACKAGE_ID}::single_player_satoshi::start_game`, - arguments: [ - txb.pure.string(guess), - txb.object(counterNFTData[0].data?.objectId!), - stakeCoin, - txb.object(houseDataId), - ], + target: `${PACKAGE_ID}::single_player_satoshi::start_game`, + arguments: [ + txb.pure.string(guess), + txb.object(counterNFTData[0].data?.objectId!), + stakeCoin, + txb.object(houseDataId), + ], }); execCreateGame( - { - transactionBlock: txb, - }, - { - onError: (err) => { - toast.error(err.message); - }, - onSuccess: (result: SuiTransactionBlockResponse) => { - toast.success(`Digest: ${result.digest}`); - }, - }, + { + transactionBlock: txb, + }, + { + onError: (err) => { + toast.error(err.message); + }, + onSuccess: (result: SuiTransactionBlockResponse) => { + toast.success(`Digest: ${result.digest}`); + }, + }, ); ``` @@ -985,70 +984,70 @@ All of this logic is in `HouseFinishGame.tsx`: ```typescript title='containers/House/HouseFinishGame.tsx' // This component will help the House to automatically finish the game whenever new game is started export function HouseFinishGame() { - const suiClient = useSuiClient(); - const { mutate: execFinishGame } = useSignAndExecuteTransactionBlock(); - - const [housePrivHex] = useContext(HouseKeypairContext); - const [houseDataId] = useContext(HouseDataContext); - - useEffect(() => { - // Subscribe to NewGame event - const unsub = suiClient.subscribeEvent({ - filter: { - MoveEventType: `${PACKAGE_ID}::single_player_satoshi::NewGame`, - }, - onMessage(event) { - console.log(event); - const { game_id, vrf_input } = event.parsedJson as { - game_id: string; - vrf_input: number[]; - }; - - toast.info(`NewGame started ID: ${game_id}`); - - console.log(housePrivHex); - - try { - const houseSignedInput = bls.sign( - new Uint8Array(vrf_input), - curveUtils.hexToBytes(housePrivHex), - ); - - // Finish the game immediately after new game started - const txb = new TransactionBlock(); - txb.moveCall({ - target: `${PACKAGE_ID}::single_player_satoshi::finish_game`, - arguments: [ - txb.pure.id(game_id), - txb.pure(bcs.vector(bcs.U8).serialize(houseSignedInput)), - txb.object(houseDataId), - ], - }); - execFinishGame( - { - transactionBlock: txb, - }, - { - onError: (err) => { - toast.error(err.message); - }, - onSuccess: (result: SuiTransactionBlockResponse) => { - toast.success(`Digest: ${result.digest}`); - }, - }, - ); - } catch (err) { - console.error(err); - } - }, - }); - - return () => { - (async () => (await unsub)())(); - }; - }, [housePrivHex, houseDataId, suiClient]); - - return null; + const suiClient = useSuiClient(); + const { mutate: execFinishGame } = useSignAndExecuteTransactionBlock(); + + const [housePrivHex] = useContext(HouseKeypairContext); + const [houseDataId] = useContext(HouseDataContext); + + useEffect(() => { + // Subscribe to NewGame event + const unsub = suiClient.subscribeEvent({ + filter: { + MoveEventType: `${PACKAGE_ID}::single_player_satoshi::NewGame`, + }, + onMessage(event) { + console.log(event); + const { game_id, vrf_input } = event.parsedJson as { + game_id: string; + vrf_input: number[]; + }; + + toast.info(`NewGame started ID: ${game_id}`); + + console.log(housePrivHex); + + try { + const houseSignedInput = bls.sign( + new Uint8Array(vrf_input), + curveUtils.hexToBytes(housePrivHex), + ); + + // Finish the game immediately after new game started + const txb = new TransactionBlock(); + txb.moveCall({ + target: `${PACKAGE_ID}::single_player_satoshi::finish_game`, + arguments: [ + txb.pure.id(game_id), + txb.pure(bcs.vector(bcs.U8).serialize(houseSignedInput)), + txb.object(houseDataId), + ], + }); + execFinishGame( + { + transactionBlock: txb, + }, + { + onError: (err) => { + toast.error(err.message); + }, + onSuccess: (result: SuiTransactionBlockResponse) => { + toast.success(`Digest: ${result.digest}`); + }, + }, + ); + } catch (err) { + console.error(err); + } + }, + }); + + return () => { + (async () => (await unsub)())(); + }; + }, [housePrivHex, houseDataId, suiClient]); + + return null; } ``` diff --git a/docs/content/guides/developer/app-examples/e2e-counter.mdx b/docs/content/guides/developer/app-examples/e2e-counter.mdx index 72065d886931d..687b9e4c05276 100644 --- a/docs/content/guides/developer/app-examples/e2e-counter.mdx +++ b/docs/content/guides/developer/app-examples/e2e-counter.mdx @@ -9,13 +9,13 @@ This example walks you through building a basic distributed counter app, coverin If haven't followed Client App with Sui TypeScript SDK, run the following command in a terminal or console to scaffold a new app: ```bash -pnpm create @mysten/create-dapp --template react-client-dapp +pnpm create @mysten/dapp --template react-client-dapp ``` To get a head start, you can automatically create this example using the following `template` value instead: ```bash -pnpm create @mysten/create-dapp --template react-e2e-counter +pnpm create @mysten/dapp --template react-e2e-counter ``` ## Adding a Move module @@ -146,21 +146,21 @@ Now that you've published your Move code, you can start building your UI to use ```ts export function CreateCounter(props: { onCreated: (id: string) => void }) { - return ( -
- -
- ); - - function create() { - props.onCreated('TODO'); - } + return ( +
+ +
+ ); + + function create() { + props.onCreated('TODO'); + } } ``` @@ -171,32 +171,32 @@ To do this, you need to construct a `TransactionBlock`, with the appropriate `mo First, import `TransactionBlock` from `@mysten/sui.js`, `COUNTER_PACKAGE_ID` from your constants.ts file created previously, and `useSignAndExecuteTransactionBlock` from `@mysten/dapp-kit`. ```ts -import { useSignAndExecuteTransactionBlock } from "@mysten/dapp-kit"; -import { TransactionBlock } from "@mysten/sui.js/transactions"; +import { useSignAndExecuteTransactionBlock } from '@mysten/dapp-kit'; +import { TransactionBlock } from '@mysten/sui.js/transactions'; -import { COUNTER_PACKAGE_ID } from "./constants"; +import { COUNTER_PACKAGE_ID } from './constants'; ``` Next, call the `useSignAndExecuteTransactionBlock` hook in your component, which provides a `mutate` function you can use in your `create` function: ```ts export function CreateCounter(props: { onCreated: (id: string) => void }) { - const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); - return ( -
- -
- ); - - function create() { - // TODO - } + const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); + return ( +
+ +
+ ); + + function create() { + // TODO + } } ``` @@ -239,10 +239,10 @@ To get an instance of `SuiClient`, you can use the `useSuiClient` hook from dApp import { useSignAndExecuteTransactionBlock, useSuiClient } from '@mysten/dapp-kit'; export function CreateCounter(props: { onCreated: (id: string) => void }) { - const suiClient = useSuiClient(); - const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); + const suiClient = useSuiClient(); + const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); - return - {ownedByCurrentAccount ? ( - - ) : null} - - ); - - function executeMoveCall(method: 'increment' | 'reset') { - // TODO - } + const currentAccount = useCurrentAccount(); + const { data, refetch } = useSuiClientQuery('getObject', { + id, + options: { + showContent: true, + }, + }); + + if (!data?.data) return
Not found
; + + const ownedByCurrentAccount = getCounterFields(data.data)?.owner === currentAccount?.address; + + return ( +
+
Count: {getCounterFields(data.data)?.value}
+ + + {ownedByCurrentAccount ? ( + + ) : null} +
+ ); + + function executeMoveCall(method: 'increment' | 'reset') { + // TODO + } } function getCounterFields(data: SuiObjectData) { - if (data.content?.dataType !== 'moveObject') { - return null; - } + if (data.content?.dataType !== 'moveObject') { + return null; + } - return data.content.fields as { value: number; owner: string }; + return data.content.fields as { value: number; owner: string }; } ``` @@ -379,51 +379,51 @@ The code also adds an `executeMoveCall` function that still needs implementing. ```ts import { - useCurrentAccount, - useSignAndExecuteTransactionBlock, - useSuiClient, - useSuiClientQuery, -} from "@mysten/dapp-kit"; -import { SuiObjectData } from "@mysten/sui.js/client"; -import { TransactionBlock } from "@mysten/sui.js/transactions"; + useCurrentAccount, + useSignAndExecuteTransactionBlock, + useSuiClient, + useSuiClientQuery, +} from '@mysten/dapp-kit'; +import { SuiObjectData } from '@mysten/sui.js/client'; +import { TransactionBlock } from '@mysten/sui.js/transactions'; -import { COUNTER_PACKAGE_ID } from "./constants"; +import { COUNTER_PACKAGE_ID } from './constants'; export function Counter({ id }: { id: string }) { - const currentAccount = useCurrentAccount(); - const suiClient = useSuiClient(); - const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); - - // ... - - function executeMoveCall(method: "increment" | "reset") { - const txb = new TransactionBlock(); - - if (method === "reset") { - txb.moveCall({ - arguments: [txb.object(id), txb.pure.u64(0)], - target: `${COUNTER_PACKAGE_ID}::counter::set_value`, - }); - } else { - txb.moveCall({ - arguments: [txb.object(id)], - target: `${COUNTER_PACKAGE_ID}::counter::increment`, - }); - } - - signAndExecute( - { - transactionBlock: txb, - }, - { - onSuccess: (tx) => { - suiClient.waitForTransactionBlock({ digest: tx.digest }).then(() => { - refetch(); - }); - }, - }, - ); - } + const currentAccount = useCurrentAccount(); + const suiClient = useSuiClient(); + const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock(); + + // ... + + function executeMoveCall(method: 'increment' | 'reset') { + const txb = new TransactionBlock(); + + if (method === 'reset') { + txb.moveCall({ + arguments: [txb.object(id), txb.pure.u64(0)], + target: `${COUNTER_PACKAGE_ID}::counter::set_value`, + }); + } else { + txb.moveCall({ + arguments: [txb.object(id)], + target: `${COUNTER_PACKAGE_ID}::counter::increment`, + }); + } + + signAndExecute( + { + transactionBlock: txb, + }, + { + onSuccess: (tx) => { + suiClient.waitForTransactionBlock({ digest: tx.digest }).then(() => { + refetch(); + }); + }, + }, + ); + } } ``` diff --git a/docs/content/guides/developer/first-app/client-tssdk.mdx b/docs/content/guides/developer/first-app/client-tssdk.mdx index 9e57f2e955f79..c44805ce65a7b 100644 --- a/docs/content/guides/developer/first-app/client-tssdk.mdx +++ b/docs/content/guides/developer/first-app/client-tssdk.mdx @@ -7,8 +7,9 @@ This exercise walks you through setting up dApp Kit in a React App, allowing you {@include: ../../../snippets/info-pnpm-required.mdx} ```bash -pnpm create @mysten/create-dapp --template react-client-dapp +pnpm create @mysten/dapp --template react-client-dapp ``` + ## What is the Sui TypeScript SDK? The Sui TypeScript SDK (@mysten/sui.js) provides all the low-level functionality needed to interact with Sui ecosystem from TypeScript. You can use it in any TypeScript or JavaScript project, including web apps, Node.js apps, or mobile apps written with tools like React Native that support TypeScript. @@ -49,11 +50,11 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient(); ReactDOM.createRoot(document.getElementById('root')!).render( - - - - - , + + + + + , ); ``` @@ -66,18 +67,18 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient(); const networks = { - devnet: { url: getFullnodeUrl('devnet') }, - mainnet: { url: getFullnodeUrl('mainnet') }, + devnet: { url: getFullnodeUrl('devnet') }, + mainnet: { url: getFullnodeUrl('mainnet') }, }; ReactDOM.createRoot(document.getElementById('root')!).render( - - - - - - - , + + + + + + + , ); ``` @@ -92,20 +93,20 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient(); const networks = { - devnet: { url: getFullnodeUrl('devnet') }, - mainnet: { url: getFullnodeUrl('mainnet') }, + devnet: { url: getFullnodeUrl('devnet') }, + mainnet: { url: getFullnodeUrl('mainnet') }, }; ReactDOM.createRoot(document.getElementById('root')!).render( - - - - - - - - - , + + + + + + + + + , ); ``` @@ -117,13 +118,13 @@ With all `Providers` set up, you can use dApp Kit hooks and components. To allow import { ConnectButton } from '@mysten/dapp-kit'; function App() { - return ( -
-
- -
-
- ); + return ( +
+
+ +
+
+ ); } ``` @@ -137,25 +138,25 @@ Now that you have a way for users to connect their wallets, you can start using import { ConnectButton, useCurrentAccount } from '@mysten/dapp-kit'; function App() { - return ( -
-
- -
- - -
- ); + return ( +
+
+ +
+ + +
+ ); } function ConnectedAccount() { - const { account } = useCurrentAccount(); + const { account } = useCurrentAccount(); - if (!account) { - return null; - } + if (!account) { + return null; + } - return
Connected to {account.address}
; + return
Connected to {account.address}
; } ``` @@ -167,43 +168,43 @@ Now that you have the account to connect to, you can query for objects the conne import { useCurrentAccount, useSuiClientQuery } from '@mysten/dapp-kit'; function ConnectedAccount() { - const { account } = useCurrentAccount(); - - if (!account) { - return null; - } - - return ( -
-
Connected to {account.address}
; - -
- ); + const { account } = useCurrentAccount(); + + if (!account) { + return null; + } + + return ( +
+
Connected to {account.address}
; + +
+ ); } function OwnedObjects({ address }: { address: string }) { - const { data } = useSuiClientQuery('getOwnedObjects', { - owner: address, - }); - if (!data) { - return null; - } - - return ( - - ); + const { data } = useSuiClientQuery('getOwnedObjects', { + owner: address, + }); + if (!data) { + return null; + } + + return ( + + ); } ``` -You now have a dApp connected to wallets and can query data from RPC nodes. +You now have a dApp connected to wallets and can query data from RPC nodes. ## Related links diff --git a/sdk/create-dapp/README.md b/sdk/create-dapp/README.md index bb5be630e053a..73af38ac197bb 100644 --- a/sdk/create-dapp/README.md +++ b/sdk/create-dapp/README.md @@ -5,7 +5,7 @@ You can get started quickly by running the following command: ```bash -pnpm create @mysten/create-dapp +pnpm create @mysten/dapp ``` This will prompt you through creating a new dApp project. It will ask you for the name/directory and diff --git a/sdk/docs/pages/dapp-kit/create-dapp.mdx b/sdk/docs/pages/dapp-kit/create-dapp.mdx index 25b62b13b0dea..6f9d7208e43f2 100644 --- a/sdk/docs/pages/dapp-kit/create-dapp.mdx +++ b/sdk/docs/pages/dapp-kit/create-dapp.mdx @@ -5,7 +5,7 @@ You can get started quickly by running the following command: ```bash -pnpm create @mysten/create-dapp +pnpm create @mysten/dapp ``` This will prompt you through creating a new dApp project. It will ask you for the name/directory and