@mysten/create-dapp 0.5.12 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -2
- package/README.md +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -8
- package/dist/index.js.map +1 -1
- package/package.json +14 -10
- package/src/index.ts +58 -36
- package/templates/.oxlintrc.json +5 -0
- package/templates/react-client-dapp/README.md +31 -4
- package/templates/react-client-dapp/index.html +2 -48
- package/templates/react-client-dapp/package.json +17 -20
- package/templates/react-client-dapp/prettier.config.cjs +0 -1
- package/templates/react-client-dapp/src/App.tsx +12 -30
- package/templates/react-client-dapp/src/OwnedObjects.tsx +58 -31
- package/templates/react-client-dapp/src/WalletStatus.tsx +38 -13
- package/templates/react-client-dapp/src/components/ui/card.tsx +75 -0
- package/templates/react-client-dapp/src/dApp-kit.ts +24 -0
- package/templates/react-client-dapp/src/index.css +39 -0
- package/templates/react-client-dapp/src/lib/utils.ts +6 -0
- package/templates/react-client-dapp/src/main.tsx +8 -14
- package/templates/react-client-dapp/vite.config.mts +2 -1
- package/templates/react-e2e-counter/.gitattributes +2 -0
- package/templates/react-e2e-counter/README.md +53 -7
- package/templates/react-e2e-counter/index.html +2 -48
- package/templates/react-e2e-counter/package.json +21 -23
- package/templates/react-e2e-counter/prettier.config.cjs +0 -1
- package/templates/react-e2e-counter/src/App.tsx +29 -30
- package/templates/react-e2e-counter/src/Counter.tsx +147 -74
- package/templates/react-e2e-counter/src/CreateCounter.tsx +84 -43
- package/templates/react-e2e-counter/src/components/ui/button.tsx +52 -0
- package/templates/react-e2e-counter/src/components/ui/card.tsx +75 -0
- package/templates/react-e2e-counter/src/constants.ts +4 -3
- package/templates/react-e2e-counter/src/contracts/counter/counter.ts +96 -0
- package/templates/react-e2e-counter/src/contracts/utils/index.ts +243 -0
- package/templates/react-e2e-counter/src/dApp-kit.ts +48 -0
- package/templates/react-e2e-counter/src/index.css +39 -0
- package/templates/react-e2e-counter/src/lib/utils.ts +6 -0
- package/templates/react-e2e-counter/src/main.tsx +8 -14
- package/templates/react-e2e-counter/sui-codegen.config.ts +13 -0
- package/templates/react-e2e-counter/vite.config.mts +2 -1
- package/templates/react-client-dapp/src/networkConfig.ts +0 -17
- package/templates/react-e2e-counter/src/networkConfig.ts +0 -31
|
@@ -1,42 +1,69 @@
|
|
|
1
|
-
import { useCurrentAccount,
|
|
2
|
-
import {
|
|
1
|
+
import { useCurrentAccount, useCurrentClient } from "@mysten/dapp-kit-react";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
} from "./components/ui/card";
|
|
10
|
+
import { Package, Loader2 } from "lucide-react";
|
|
3
11
|
|
|
4
12
|
export function OwnedObjects() {
|
|
5
13
|
const account = useCurrentAccount();
|
|
6
|
-
const
|
|
7
|
-
"getOwnedObjects",
|
|
8
|
-
{
|
|
9
|
-
owner: account?.address as string,
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
enabled: !!account,
|
|
13
|
-
},
|
|
14
|
-
);
|
|
14
|
+
const client = useCurrentClient();
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { data, isPending, error } = useQuery({
|
|
17
|
+
queryKey: ["ownedObjects", account?.address],
|
|
18
|
+
queryFn: async () => {
|
|
19
|
+
if (!account) return null;
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const { response } = await client.stateService.listOwnedObjects({
|
|
22
|
+
owner: account.address,
|
|
23
|
+
});
|
|
24
|
+
return response.objects ?? [];
|
|
25
|
+
},
|
|
26
|
+
enabled: !!account,
|
|
27
|
+
});
|
|
23
28
|
|
|
24
|
-
if (
|
|
25
|
-
return
|
|
29
|
+
if (!account) {
|
|
30
|
+
return null;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
return (
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
<Card>
|
|
35
|
+
<CardHeader>
|
|
36
|
+
<CardTitle className="flex items-center gap-2">
|
|
37
|
+
<Package className="h-5 w-5" />
|
|
38
|
+
Owned Objects
|
|
39
|
+
</CardTitle>
|
|
40
|
+
<CardDescription>Objects owned by the connected wallet</CardDescription>
|
|
41
|
+
</CardHeader>
|
|
42
|
+
<CardContent>
|
|
43
|
+
{error ? (
|
|
44
|
+
<p className="text-destructive-foreground">
|
|
45
|
+
Error: {(error as Error)?.message || "Unknown error"}
|
|
46
|
+
</p>
|
|
47
|
+
) : isPending || !data ? (
|
|
48
|
+
<div className="flex items-center gap-2 text-muted-foreground">
|
|
49
|
+
<Loader2 className="h-4 w-4 animate-spin" />
|
|
50
|
+
Loading objects...
|
|
51
|
+
</div>
|
|
52
|
+
) : data.length === 0 ? (
|
|
53
|
+
<p className="text-muted-foreground">No objects found</p>
|
|
54
|
+
) : (
|
|
55
|
+
<div className="space-y-2">
|
|
56
|
+
{data.map((object) => (
|
|
57
|
+
<div
|
|
58
|
+
key={object.objectId}
|
|
59
|
+
className="rounded-md border bg-muted/50 p-3"
|
|
60
|
+
>
|
|
61
|
+
<p className="font-mono text-xs break-all">{object.objectId}</p>
|
|
62
|
+
</div>
|
|
63
|
+
))}
|
|
64
|
+
</div>
|
|
65
|
+
)}
|
|
66
|
+
</CardContent>
|
|
67
|
+
</Card>
|
|
41
68
|
);
|
|
42
69
|
}
|
|
@@ -1,23 +1,48 @@
|
|
|
1
|
-
import { useCurrentAccount } from "@mysten/dapp-kit";
|
|
2
|
-
import { Container, Flex, Heading, Text } from "@radix-ui/themes";
|
|
1
|
+
import { useCurrentAccount } from "@mysten/dapp-kit-react";
|
|
3
2
|
import { OwnedObjects } from "./OwnedObjects";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
} from "./components/ui/card";
|
|
10
|
+
import { Wallet, CheckCircle2 } from "lucide-react";
|
|
4
11
|
|
|
5
12
|
export function WalletStatus() {
|
|
6
13
|
const account = useCurrentAccount();
|
|
7
14
|
|
|
8
15
|
return (
|
|
9
|
-
<
|
|
10
|
-
<
|
|
16
|
+
<div className="space-y-6">
|
|
17
|
+
<Card>
|
|
18
|
+
<CardHeader>
|
|
19
|
+
<CardTitle className="flex items-center gap-2">
|
|
20
|
+
<Wallet className="h-5 w-5" />
|
|
21
|
+
Wallet Status
|
|
22
|
+
</CardTitle>
|
|
23
|
+
<CardDescription>
|
|
24
|
+
{account
|
|
25
|
+
? "Your wallet is connected"
|
|
26
|
+
: "Connect your wallet to get started"}
|
|
27
|
+
</CardDescription>
|
|
28
|
+
</CardHeader>
|
|
29
|
+
<CardContent>
|
|
30
|
+
{account ? (
|
|
31
|
+
<div className="flex items-center gap-2">
|
|
32
|
+
<CheckCircle2 className="h-4 w-4 text-green-500" />
|
|
33
|
+
<span className="font-mono text-sm break-all">
|
|
34
|
+
{account.address}
|
|
35
|
+
</span>
|
|
36
|
+
</div>
|
|
37
|
+
) : (
|
|
38
|
+
<p className="text-muted-foreground">
|
|
39
|
+
Click the connect button above to link your Sui wallet.
|
|
40
|
+
</p>
|
|
41
|
+
)}
|
|
42
|
+
</CardContent>
|
|
43
|
+
</Card>
|
|
11
44
|
|
|
12
|
-
{account ? (
|
|
13
|
-
<Flex direction="column">
|
|
14
|
-
<Text>Wallet connected</Text>
|
|
15
|
-
<Text>Address: {account.address}</Text>
|
|
16
|
-
</Flex>
|
|
17
|
-
) : (
|
|
18
|
-
<Text>Wallet not connected</Text>
|
|
19
|
-
)}
|
|
20
45
|
<OwnedObjects />
|
|
21
|
-
</
|
|
46
|
+
</div>
|
|
22
47
|
);
|
|
23
48
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "../../lib/utils";
|
|
3
|
+
|
|
4
|
+
function Card({
|
|
5
|
+
className,
|
|
6
|
+
ref,
|
|
7
|
+
...props
|
|
8
|
+
}: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn(
|
|
13
|
+
"rounded-xl border bg-card text-card-foreground shadow",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function CardHeader({
|
|
22
|
+
className,
|
|
23
|
+
ref,
|
|
24
|
+
...props
|
|
25
|
+
}: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function CardTitle({
|
|
36
|
+
className,
|
|
37
|
+
ref,
|
|
38
|
+
...props
|
|
39
|
+
}: HTMLAttributes<HTMLHeadingElement> & {
|
|
40
|
+
ref?: React.Ref<HTMLHeadingElement>;
|
|
41
|
+
}) {
|
|
42
|
+
return (
|
|
43
|
+
<h3
|
|
44
|
+
ref={ref}
|
|
45
|
+
className={cn("font-semibold leading-none tracking-tight", className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function CardDescription({
|
|
52
|
+
className,
|
|
53
|
+
ref,
|
|
54
|
+
...props
|
|
55
|
+
}: HTMLAttributes<HTMLParagraphElement> & {
|
|
56
|
+
ref?: React.Ref<HTMLParagraphElement>;
|
|
57
|
+
}) {
|
|
58
|
+
return (
|
|
59
|
+
<p
|
|
60
|
+
ref={ref}
|
|
61
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function CardContent({
|
|
68
|
+
className,
|
|
69
|
+
ref,
|
|
70
|
+
...props
|
|
71
|
+
}: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
|
|
72
|
+
return <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createDAppKit } from "@mysten/dapp-kit-react";
|
|
2
|
+
import { SuiGrpcClient } from "@mysten/sui/grpc";
|
|
3
|
+
|
|
4
|
+
const GRPC_URLS = {
|
|
5
|
+
mainnet: "https://fullnode.mainnet.sui.io:443",
|
|
6
|
+
testnet: "https://fullnode.testnet.sui.io:443",
|
|
7
|
+
devnet: "https://fullnode.devnet.sui.io:443",
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const dAppKit = createDAppKit({
|
|
11
|
+
enableBurnerWallet: import.meta.env.DEV,
|
|
12
|
+
networks: ["mainnet", "testnet", "devnet"],
|
|
13
|
+
defaultNetwork: "testnet",
|
|
14
|
+
createClient(network) {
|
|
15
|
+
return new SuiGrpcClient({ network, baseUrl: GRPC_URLS[network] });
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// global type registration necessary for the hooks to work correctly
|
|
20
|
+
declare module "@mysten/dapp-kit-react" {
|
|
21
|
+
interface Register {
|
|
22
|
+
dAppKit: typeof dAppKit;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
--color-background: oklch(0.145 0 0);
|
|
5
|
+
--color-foreground: oklch(0.985 0 0);
|
|
6
|
+
--color-card: oklch(0.145 0 0);
|
|
7
|
+
--color-card-foreground: oklch(0.985 0 0);
|
|
8
|
+
--color-primary: oklch(0.985 0 0);
|
|
9
|
+
--color-primary-foreground: oklch(0.205 0 0);
|
|
10
|
+
--color-secondary: oklch(0.269 0 0);
|
|
11
|
+
--color-secondary-foreground: oklch(0.985 0 0);
|
|
12
|
+
--color-muted: oklch(0.269 0 0);
|
|
13
|
+
--color-muted-foreground: oklch(0.708 0 0);
|
|
14
|
+
--color-accent: oklch(0.269 0 0);
|
|
15
|
+
--color-accent-foreground: oklch(0.985 0 0);
|
|
16
|
+
--color-destructive: oklch(0.396 0.141 25.723);
|
|
17
|
+
--color-destructive-foreground: oklch(0.637 0.237 25.331);
|
|
18
|
+
--color-border: oklch(0.269 0 0);
|
|
19
|
+
--color-input: oklch(0.269 0 0);
|
|
20
|
+
--color-ring: oklch(0.556 0 0);
|
|
21
|
+
--color-sui: oklch(0.7 0.2 220);
|
|
22
|
+
|
|
23
|
+
--radius-sm: 0.25rem;
|
|
24
|
+
--radius-md: 0.375rem;
|
|
25
|
+
--radius-lg: 0.5rem;
|
|
26
|
+
--radius-xl: 0.75rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
* {
|
|
30
|
+
border-color: var(--color-border);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
body {
|
|
34
|
+
background-color: var(--color-background);
|
|
35
|
+
color: var(--color-foreground);
|
|
36
|
+
font-family:
|
|
37
|
+
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
38
|
+
"Segoe UI Symbol", "Noto Color Emoji";
|
|
39
|
+
}
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import ReactDOM from "react-dom/client";
|
|
3
|
-
import "
|
|
4
|
-
import "@radix-ui/themes/styles.css";
|
|
3
|
+
import "./index.css";
|
|
5
4
|
|
|
6
|
-
import {
|
|
5
|
+
import { DAppKitProvider } from "@mysten/dapp-kit-react";
|
|
7
6
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
8
|
-
import { Theme } from "@radix-ui/themes";
|
|
9
7
|
import App from "./App.tsx";
|
|
10
|
-
import {
|
|
8
|
+
import { dAppKit } from "./dApp-kit.ts";
|
|
11
9
|
|
|
12
10
|
const queryClient = new QueryClient();
|
|
13
11
|
|
|
14
12
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
15
13
|
<React.StrictMode>
|
|
16
|
-
<
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
</WalletProvider>
|
|
22
|
-
</SuiClientProvider>
|
|
23
|
-
</QueryClientProvider>
|
|
24
|
-
</Theme>
|
|
14
|
+
<QueryClientProvider client={queryClient}>
|
|
15
|
+
<DAppKitProvider dAppKit={dAppKit}>
|
|
16
|
+
<App />
|
|
17
|
+
</DAppKitProvider>
|
|
18
|
+
</QueryClientProvider>
|
|
25
19
|
</React.StrictMode>,
|
|
26
20
|
);
|
|
@@ -6,15 +6,32 @@ Client dApp using the following tools:
|
|
|
6
6
|
- [React](https://react.dev/) as the UI framework
|
|
7
7
|
- [TypeScript](https://www.typescriptlang.org/) for type checking
|
|
8
8
|
- [Vite](https://vitejs.dev/) for build tooling
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [`@mysten/dapp-kit`](https://sdk.mystenlabs.com/dapp-kit) for connecting
|
|
12
|
-
wallets and loading data
|
|
9
|
+
- [Tailwind CSS v4](https://tailwindcss.com/) for styling
|
|
10
|
+
- [Lucide React](https://lucide.dev/) for icons
|
|
11
|
+
- [`@mysten/dapp-kit-react`](https://sdk.mystenlabs.com/dapp-kit) for connecting
|
|
12
|
+
to wallets and loading data
|
|
13
|
+
- [`@mysten/codegen`](https://sdk.mystenlabs.com/codegen) for generating
|
|
14
|
+
TypeScript bindings from Move code
|
|
13
15
|
- [pnpm](https://pnpm.io/) for package management
|
|
14
16
|
|
|
15
17
|
For a full guide on how to build this dApp from scratch, visit this
|
|
16
18
|
[guide](http://docs.sui.io/guides/developer/app-examples/e2e-counter#frontend).
|
|
17
19
|
|
|
20
|
+
## Project Structure
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
src/
|
|
24
|
+
├── components/ui/ # Reusable UI components (Button, Card)
|
|
25
|
+
├── contracts/ # Generated TypeScript bindings (via codegen)
|
|
26
|
+
├── lib/utils.ts # Utility functions (cn for classnames)
|
|
27
|
+
├── App.tsx # Main application component
|
|
28
|
+
├── Counter.tsx # Counter display and controls
|
|
29
|
+
├── CreateCounter.tsx # Counter creation component
|
|
30
|
+
├── dApp-kit.ts # dApp Kit configuration
|
|
31
|
+
├── constants.ts # Package IDs per network
|
|
32
|
+
└── index.css # Tailwind CSS with theme variables
|
|
33
|
+
```
|
|
34
|
+
|
|
18
35
|
## Deploying your Move code
|
|
19
36
|
|
|
20
37
|
### Install Sui cli
|
|
@@ -60,14 +77,29 @@ sui client publish --gas-budget 100000000 counter
|
|
|
60
77
|
```
|
|
61
78
|
|
|
62
79
|
In the output there will be an object with a `"packageId"` property. You'll want
|
|
63
|
-
to save that package ID to the `src/constants.ts` file
|
|
80
|
+
to save that package ID to the `src/constants.ts` file:
|
|
64
81
|
|
|
65
82
|
```ts
|
|
66
83
|
export const TESTNET_COUNTER_PACKAGE_ID = "<YOUR_PACKAGE_ID>";
|
|
67
84
|
```
|
|
68
85
|
|
|
69
|
-
|
|
70
|
-
|
|
86
|
+
The package ID is mapped to the local package name `@local-pkg/counter` in
|
|
87
|
+
`src/dApp-kit.ts` via MVR overrides. This allows the generated TypeScript
|
|
88
|
+
bindings to resolve the package address automatically.
|
|
89
|
+
|
|
90
|
+
### Generating TypeScript bindings
|
|
91
|
+
|
|
92
|
+
After publishing your Move code, generate the TypeScript bindings:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pnpm codegen
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This generates type-safe functions and BCS types in `src/contracts/` based on
|
|
99
|
+
your Move modules.
|
|
100
|
+
|
|
101
|
+
Now that we have published the move code, updated the package ID, and generated
|
|
102
|
+
the TypeScript bindings, we can start the app.
|
|
71
103
|
|
|
72
104
|
## Starting your dApp
|
|
73
105
|
|
|
@@ -90,3 +122,17 @@ To build your app for deployment you can run
|
|
|
90
122
|
```bash
|
|
91
123
|
pnpm build
|
|
92
124
|
```
|
|
125
|
+
|
|
126
|
+
## Customizing the UI
|
|
127
|
+
|
|
128
|
+
This template uses [Tailwind CSS v4](https://tailwindcss.com/docs) for styling
|
|
129
|
+
with [shadcn/ui](https://ui.shadcn.com/)-style components. The UI components in
|
|
130
|
+
`src/components/ui/` are based on shadcn/ui patterns and can be customized or
|
|
131
|
+
extended.
|
|
132
|
+
|
|
133
|
+
To add more shadcn/ui components, you can copy them from the
|
|
134
|
+
[shadcn/ui components](https://ui.shadcn.com/docs/components) documentation and
|
|
135
|
+
adapt them to work with your project.
|
|
136
|
+
|
|
137
|
+
Theme variables are defined in `src/index.css` using Tailwind's `@theme`
|
|
138
|
+
directive.
|
|
@@ -1,58 +1,12 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="en"
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Sui dApp Starter</title>
|
|
8
|
-
|
|
9
|
-
<style>
|
|
10
|
-
/*
|
|
11
|
-
Josh's Custom CSS Reset
|
|
12
|
-
https://www.joshwcomeau.com/css/custom-css-reset/
|
|
13
|
-
*/
|
|
14
|
-
*,
|
|
15
|
-
*::before,
|
|
16
|
-
*::after {
|
|
17
|
-
box-sizing: border-box;
|
|
18
|
-
}
|
|
19
|
-
* {
|
|
20
|
-
margin: 0;
|
|
21
|
-
}
|
|
22
|
-
body {
|
|
23
|
-
line-height: 1.5;
|
|
24
|
-
-webkit-font-smoothing: antialiased;
|
|
25
|
-
}
|
|
26
|
-
img,
|
|
27
|
-
picture,
|
|
28
|
-
video,
|
|
29
|
-
canvas,
|
|
30
|
-
svg {
|
|
31
|
-
display: block;
|
|
32
|
-
max-width: 100%;
|
|
33
|
-
}
|
|
34
|
-
input,
|
|
35
|
-
button,
|
|
36
|
-
textarea,
|
|
37
|
-
select {
|
|
38
|
-
font: inherit;
|
|
39
|
-
}
|
|
40
|
-
p,
|
|
41
|
-
h1,
|
|
42
|
-
h2,
|
|
43
|
-
h3,
|
|
44
|
-
h4,
|
|
45
|
-
h5,
|
|
46
|
-
h6 {
|
|
47
|
-
overflow-wrap: break-word;
|
|
48
|
-
}
|
|
49
|
-
#root,
|
|
50
|
-
#__next {
|
|
51
|
-
isolation: isolate;
|
|
52
|
-
}
|
|
53
|
-
</style>
|
|
54
8
|
</head>
|
|
55
|
-
<body>
|
|
9
|
+
<body class="min-h-screen antialiased">
|
|
56
10
|
<div id="root"></div>
|
|
57
11
|
<script type="module" src="/src/main.tsx"></script>
|
|
58
12
|
</body>
|
|
@@ -1,36 +1,34 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@mysten/template-react-e2e-
|
|
2
|
+
"name": "@mysten/template-react-e2e-counter",
|
|
3
3
|
"private": true,
|
|
4
4
|
"version": "0.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
8
|
"build": "tsc && vite build",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"codegen": "rm -rf src/contracts && sui-ts-codegen generate"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@mysten/dapp-kit": "workspace
|
|
14
|
-
"@mysten/sui": "workspace
|
|
15
|
-
"@
|
|
16
|
-
"@
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"react": "^
|
|
20
|
-
"react-dom": "^
|
|
21
|
-
"
|
|
13
|
+
"@mysten/dapp-kit-react": "workspace:^",
|
|
14
|
+
"@mysten/sui": "workspace:^",
|
|
15
|
+
"@nanostores/react": "^1.0.0",
|
|
16
|
+
"@tanstack/react-query": "^5.90.16",
|
|
17
|
+
"clsx": "^2.1.1",
|
|
18
|
+
"lucide-react": "^0.562.0",
|
|
19
|
+
"react": "^19.2.3",
|
|
20
|
+
"react-dom": "^19.2.3",
|
|
21
|
+
"tailwind-merge": "^3.4.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
27
|
-
"@
|
|
28
|
-
"@vitejs/plugin-react-swc": "^
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"typescript": "^5.9.2",
|
|
34
|
-
"vite": "^7.1.5"
|
|
24
|
+
"@mysten/codegen": "workspace:^",
|
|
25
|
+
"@tailwindcss/vite": "^4.0.0",
|
|
26
|
+
"@types/react": "^19.2.8",
|
|
27
|
+
"@types/react-dom": "^19.2.3",
|
|
28
|
+
"@vitejs/plugin-react-swc": "^4.2.2",
|
|
29
|
+
"prettier": "^3.7.4",
|
|
30
|
+
"tailwindcss": "^4.1.18",
|
|
31
|
+
"typescript": "^5.9.3",
|
|
32
|
+
"vite": "^7.3.1"
|
|
35
33
|
}
|
|
36
34
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ConnectButton, useCurrentAccount } from "@mysten/dapp-kit";
|
|
1
|
+
import { ConnectButton, useCurrentAccount } from "@mysten/dapp-kit-react";
|
|
2
2
|
import { isValidSuiObjectId } from "@mysten/sui/utils";
|
|
3
|
-
import { Box, Container, Flex, Heading } from "@radix-ui/themes";
|
|
4
3
|
import { useState } from "react";
|
|
5
4
|
import { Counter } from "./Counter";
|
|
6
5
|
import { CreateCounter } from "./CreateCounter";
|
|
6
|
+
import { Card, CardContent, CardHeader, CardTitle } from "./components/ui/card";
|
|
7
|
+
import { Wallet } from "lucide-react";
|
|
7
8
|
|
|
8
9
|
function App() {
|
|
9
10
|
const currentAccount = useCurrentAccount();
|
|
@@ -13,31 +14,16 @@ function App() {
|
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
py="2"
|
|
21
|
-
justify="between"
|
|
22
|
-
style={{
|
|
23
|
-
borderBottom: "1px solid var(--gray-a2)",
|
|
24
|
-
}}
|
|
25
|
-
>
|
|
26
|
-
<Box>
|
|
27
|
-
<Heading>dApp Starter Template</Heading>
|
|
28
|
-
</Box>
|
|
29
|
-
|
|
30
|
-
<Box>
|
|
17
|
+
<div className="min-h-screen">
|
|
18
|
+
<header className="sticky top-0 z-50 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
19
|
+
<div className="container mx-auto flex h-14 items-center justify-between px-4">
|
|
20
|
+
<h1 className="text-lg font-semibold">Sui Counter dApp</h1>
|
|
31
21
|
<ConnectButton />
|
|
32
|
-
</
|
|
33
|
-
</
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
pt="2"
|
|
38
|
-
px="4"
|
|
39
|
-
style={{ background: "var(--gray-a2)", minHeight: 500 }}
|
|
40
|
-
>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
|
+
|
|
25
|
+
<main className="container mx-auto px-4 py-8">
|
|
26
|
+
<div className="mx-auto max-w-md">
|
|
41
27
|
{currentAccount ? (
|
|
42
28
|
counterId ? (
|
|
43
29
|
<Counter id={counterId} />
|
|
@@ -50,11 +36,24 @@ function App() {
|
|
|
50
36
|
/>
|
|
51
37
|
)
|
|
52
38
|
) : (
|
|
53
|
-
<
|
|
39
|
+
<Card>
|
|
40
|
+
<CardHeader>
|
|
41
|
+
<CardTitle className="flex items-center gap-2">
|
|
42
|
+
<Wallet className="h-5 w-5" />
|
|
43
|
+
Connect Wallet
|
|
44
|
+
</CardTitle>
|
|
45
|
+
</CardHeader>
|
|
46
|
+
<CardContent>
|
|
47
|
+
<p className="text-muted-foreground">
|
|
48
|
+
Connect your wallet to create and interact with counters on
|
|
49
|
+
the Sui blockchain.
|
|
50
|
+
</p>
|
|
51
|
+
</CardContent>
|
|
52
|
+
</Card>
|
|
54
53
|
)}
|
|
55
|
-
</
|
|
56
|
-
</
|
|
57
|
-
|
|
54
|
+
</div>
|
|
55
|
+
</main>
|
|
56
|
+
</div>
|
|
58
57
|
);
|
|
59
58
|
}
|
|
60
59
|
|