@mysten/create-dapp 0.5.13 → 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 +39 -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 +10 -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 +14 -17
- 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 +18 -20
- 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,106 +1,179 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useCurrentAccount,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "@
|
|
7
|
-
import type { SuiObjectData } from "@mysten/sui/client";
|
|
3
|
+
useCurrentClient,
|
|
4
|
+
useDAppKit,
|
|
5
|
+
} from "@mysten/dapp-kit-react";
|
|
6
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
8
7
|
import { Transaction } from "@mysten/sui/transactions";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
import {
|
|
9
|
+
Counter as CounterStruct,
|
|
10
|
+
increment,
|
|
11
|
+
setValue,
|
|
12
|
+
} from "./contracts/counter/counter";
|
|
13
|
+
import { Button } from "./components/ui/button";
|
|
14
|
+
import {
|
|
15
|
+
Card,
|
|
16
|
+
CardContent,
|
|
17
|
+
CardDescription,
|
|
18
|
+
CardHeader,
|
|
19
|
+
CardTitle,
|
|
20
|
+
} from "./components/ui/card";
|
|
21
|
+
import { Plus, RotateCcw } from "lucide-react";
|
|
13
22
|
|
|
14
23
|
export function Counter({ id }: { id: string }) {
|
|
15
|
-
const
|
|
16
|
-
const suiClient = useSuiClient();
|
|
24
|
+
const client = useCurrentClient();
|
|
17
25
|
const currentAccount = useCurrentAccount();
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
const dAppKit = useDAppKit();
|
|
27
|
+
const queryClient = useQueryClient();
|
|
28
|
+
|
|
29
|
+
// Fetch counter object with React Query
|
|
30
|
+
const { data, isPending, error } = useQuery({
|
|
31
|
+
queryKey: ["counter", id],
|
|
32
|
+
queryFn: async () => {
|
|
33
|
+
const { object } = await client.getObject({
|
|
34
|
+
objectId: id,
|
|
35
|
+
include: { content: true },
|
|
36
|
+
});
|
|
37
|
+
return object;
|
|
24
38
|
},
|
|
25
39
|
});
|
|
26
40
|
|
|
27
|
-
|
|
41
|
+
// Mutation for executing move calls
|
|
42
|
+
const incrementMutation = useMutation({
|
|
43
|
+
mutationFn: async () => {
|
|
44
|
+
const tx = new Transaction();
|
|
45
|
+
tx.add(increment({ arguments: { counter: id } }));
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
|
|
47
|
+
const result = await dAppKit.signAndExecuteTransaction({
|
|
48
|
+
transaction: tx,
|
|
49
|
+
});
|
|
31
50
|
|
|
32
|
-
|
|
51
|
+
if (result.$kind === "FailedTransaction") {
|
|
52
|
+
throw new Error("Transaction failed");
|
|
53
|
+
}
|
|
33
54
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
55
|
+
await client.waitForTransaction({ result });
|
|
56
|
+
return result;
|
|
57
|
+
},
|
|
58
|
+
onSuccess: () => {
|
|
59
|
+
queryClient.invalidateQueries({ queryKey: ["counter", id] });
|
|
60
|
+
},
|
|
61
|
+
onError: (err) => {
|
|
62
|
+
console.error(err);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
45
65
|
|
|
46
|
-
|
|
47
|
-
|
|
66
|
+
const resetMutation = useMutation({
|
|
67
|
+
mutationFn: async () => {
|
|
68
|
+
const tx = new Transaction();
|
|
69
|
+
tx.add(setValue({ arguments: { counter: id, value: 0 } }));
|
|
70
|
+
|
|
71
|
+
const result = await dAppKit.signAndExecuteTransaction({
|
|
48
72
|
transaction: tx,
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
setWaitingForTxn("");
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
);
|
|
59
|
-
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (result.$kind === "FailedTransaction") {
|
|
76
|
+
throw new Error("Transaction failed");
|
|
77
|
+
}
|
|
60
78
|
|
|
61
|
-
|
|
79
|
+
await client.waitForTransaction({ result });
|
|
80
|
+
return result;
|
|
81
|
+
},
|
|
82
|
+
onSuccess: () => {
|
|
83
|
+
queryClient.invalidateQueries({ queryKey: ["counter", id] });
|
|
84
|
+
},
|
|
85
|
+
onError: (err) => {
|
|
86
|
+
console.error(err);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const isAnyMutationPending =
|
|
91
|
+
incrementMutation.isPending || resetMutation.isPending;
|
|
92
|
+
|
|
93
|
+
if (isPending) {
|
|
94
|
+
return (
|
|
95
|
+
<Card>
|
|
96
|
+
<CardContent className="flex items-center justify-center py-12">
|
|
97
|
+
<div className="text-muted-foreground">Loading...</div>
|
|
98
|
+
</CardContent>
|
|
99
|
+
</Card>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
62
102
|
|
|
63
|
-
if (error)
|
|
103
|
+
if (error) {
|
|
104
|
+
return (
|
|
105
|
+
<Card>
|
|
106
|
+
<CardContent className="py-6">
|
|
107
|
+
<p className="text-destructive-foreground">
|
|
108
|
+
Error: {(error as Error)?.message || "Unknown error"}
|
|
109
|
+
</p>
|
|
110
|
+
</CardContent>
|
|
111
|
+
</Card>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
64
114
|
|
|
65
|
-
if (!data
|
|
115
|
+
if (!data) {
|
|
116
|
+
return (
|
|
117
|
+
<Card>
|
|
118
|
+
<CardContent className="py-6">
|
|
119
|
+
<p className="text-muted-foreground">Counter not found</p>
|
|
120
|
+
</CardContent>
|
|
121
|
+
</Card>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
66
124
|
|
|
67
|
-
const
|
|
68
|
-
|
|
125
|
+
const fields = getCounterFields(data);
|
|
126
|
+
const ownedByCurrentAccount = fields?.owner === currentAccount?.address;
|
|
69
127
|
|
|
70
128
|
return (
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
129
|
+
<Card>
|
|
130
|
+
<CardHeader>
|
|
131
|
+
<CardTitle>Counter</CardTitle>
|
|
132
|
+
<CardDescription className="font-mono text-xs break-all">
|
|
133
|
+
{id}
|
|
134
|
+
</CardDescription>
|
|
135
|
+
</CardHeader>
|
|
136
|
+
<CardContent className="space-y-6">
|
|
137
|
+
<div className="text-center">
|
|
138
|
+
<span className="text-6xl font-bold tabular-nums">
|
|
139
|
+
{fields?.value ?? 0}
|
|
140
|
+
</span>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="flex gap-2 justify-center">
|
|
77
143
|
<Button
|
|
78
|
-
onClick={() =>
|
|
79
|
-
|
|
144
|
+
onClick={() => incrementMutation.mutate()}
|
|
145
|
+
loading={incrementMutation.isPending}
|
|
146
|
+
disabled={isAnyMutationPending}
|
|
80
147
|
>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
) : (
|
|
84
|
-
"Increment"
|
|
85
|
-
)}
|
|
148
|
+
<Plus className="h-4 w-4" />
|
|
149
|
+
Increment
|
|
86
150
|
</Button>
|
|
87
|
-
{ownedByCurrentAccount
|
|
151
|
+
{ownedByCurrentAccount && (
|
|
88
152
|
<Button
|
|
89
|
-
|
|
90
|
-
|
|
153
|
+
variant="secondary"
|
|
154
|
+
onClick={() => resetMutation.mutate()}
|
|
155
|
+
loading={resetMutation.isPending}
|
|
156
|
+
disabled={isAnyMutationPending}
|
|
91
157
|
>
|
|
92
|
-
|
|
158
|
+
<RotateCcw className="h-4 w-4" />
|
|
159
|
+
Reset
|
|
93
160
|
</Button>
|
|
94
|
-
)
|
|
95
|
-
</
|
|
96
|
-
</
|
|
97
|
-
|
|
161
|
+
)}
|
|
162
|
+
</div>
|
|
163
|
+
</CardContent>
|
|
164
|
+
</Card>
|
|
98
165
|
);
|
|
99
166
|
}
|
|
100
|
-
|
|
101
|
-
|
|
167
|
+
|
|
168
|
+
function getCounterFields(data: { content?: Uint8Array }) {
|
|
169
|
+
if (!data.content) {
|
|
102
170
|
return null;
|
|
103
171
|
}
|
|
104
172
|
|
|
105
|
-
|
|
173
|
+
try {
|
|
174
|
+
const parsed = CounterStruct.parse(data.content);
|
|
175
|
+
return { value: Number(parsed.value), owner: parsed.owner };
|
|
176
|
+
} catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
106
179
|
}
|
|
@@ -1,60 +1,101 @@
|
|
|
1
1
|
import { Transaction } from "@mysten/sui/transactions";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
2
|
+
import { useCurrentClient, useDAppKit } from "@mysten/dapp-kit-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { create as createCounter } from "./contracts/counter/counter";
|
|
5
|
+
import { Button } from "./components/ui/button";
|
|
6
|
+
import {
|
|
7
|
+
Card,
|
|
8
|
+
CardContent,
|
|
9
|
+
CardDescription,
|
|
10
|
+
CardHeader,
|
|
11
|
+
CardTitle,
|
|
12
|
+
} from "./components/ui/card";
|
|
13
|
+
import { PlusCircle } from "lucide-react";
|
|
6
14
|
|
|
7
15
|
export function CreateCounter({
|
|
8
16
|
onCreated,
|
|
9
17
|
}: {
|
|
10
18
|
onCreated: (id: string) => void;
|
|
11
19
|
}) {
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const client = useCurrentClient();
|
|
21
|
+
const dAppKit = useDAppKit();
|
|
22
|
+
const [isPending, setIsPending] = useState(false);
|
|
23
|
+
const [error, setError] = useState<string | null>(null);
|
|
24
|
+
|
|
25
|
+
async function create() {
|
|
26
|
+
setIsPending(true);
|
|
27
|
+
setError(null);
|
|
28
|
+
|
|
21
29
|
const tx = new Transaction();
|
|
22
30
|
|
|
23
|
-
tx.
|
|
24
|
-
arguments: [],
|
|
25
|
-
target: `${counterPackageId}::counter::create`,
|
|
26
|
-
});
|
|
31
|
+
tx.add(createCounter());
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
{
|
|
33
|
+
try {
|
|
34
|
+
const result = await dAppKit.signAndExecuteTransaction({
|
|
30
35
|
transaction: tx,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
onCreated(effects?.created?.[0]?.reference?.objectId!);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (result.$kind === "FailedTransaction") {
|
|
39
|
+
throw new Error("Transaction failed");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const txResult = await client.waitForTransaction({
|
|
43
|
+
digest: result.Transaction.digest,
|
|
44
|
+
include: {
|
|
45
|
+
effects: true,
|
|
42
46
|
},
|
|
43
|
-
}
|
|
44
|
-
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (txResult.$kind === "FailedTransaction") {
|
|
50
|
+
throw new Error("Transaction failed");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Find the created object from the effects
|
|
54
|
+
const createdObject = txResult.Transaction.effects?.changedObjects?.find(
|
|
55
|
+
(obj: { idOperation?: string; objectId?: string }) =>
|
|
56
|
+
obj.idOperation === "Created",
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const id = createdObject?.objectId;
|
|
60
|
+
|
|
61
|
+
if (!id) {
|
|
62
|
+
throw new Error("Counter object ID not found in transaction effects");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
onCreated(id);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error(err);
|
|
68
|
+
setError(err instanceof Error ? err.message : "An error occurred");
|
|
69
|
+
setIsPending(false);
|
|
70
|
+
}
|
|
45
71
|
}
|
|
46
72
|
|
|
47
73
|
return (
|
|
48
|
-
<
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</
|
|
58
|
-
|
|
74
|
+
<Card>
|
|
75
|
+
<CardHeader>
|
|
76
|
+
<CardTitle className="flex items-center gap-2">
|
|
77
|
+
<PlusCircle className="h-5 w-5" />
|
|
78
|
+
Create Counter
|
|
79
|
+
</CardTitle>
|
|
80
|
+
<CardDescription>
|
|
81
|
+
Deploy a new counter object on the Sui blockchain.
|
|
82
|
+
</CardDescription>
|
|
83
|
+
</CardHeader>
|
|
84
|
+
<CardContent>
|
|
85
|
+
{error && (
|
|
86
|
+
<div className="mb-4 p-3 rounded-md bg-red-50 border border-red-200 text-red-800 text-sm">
|
|
87
|
+
{error}
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
<Button
|
|
91
|
+
size="lg"
|
|
92
|
+
className="w-full"
|
|
93
|
+
onClick={create}
|
|
94
|
+
loading={isPending}
|
|
95
|
+
>
|
|
96
|
+
Create Counter
|
|
97
|
+
</Button>
|
|
98
|
+
</CardContent>
|
|
99
|
+
</Card>
|
|
59
100
|
);
|
|
60
101
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
2
|
+
import { cn } from "../../lib/utils";
|
|
3
|
+
import { Loader2 } from "lucide-react";
|
|
4
|
+
|
|
5
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
6
|
+
variant?: "default" | "secondary" | "outline" | "ghost";
|
|
7
|
+
size?: "default" | "sm" | "lg";
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function Button({
|
|
13
|
+
className,
|
|
14
|
+
variant = "default",
|
|
15
|
+
size = "default",
|
|
16
|
+
loading = false,
|
|
17
|
+
disabled,
|
|
18
|
+
children,
|
|
19
|
+
ref,
|
|
20
|
+
...props
|
|
21
|
+
}: ButtonProps) {
|
|
22
|
+
return (
|
|
23
|
+
<button
|
|
24
|
+
className={cn(
|
|
25
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
26
|
+
{
|
|
27
|
+
"bg-primary text-primary-foreground shadow hover:bg-primary/90":
|
|
28
|
+
variant === "default",
|
|
29
|
+
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80":
|
|
30
|
+
variant === "secondary",
|
|
31
|
+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground":
|
|
32
|
+
variant === "outline",
|
|
33
|
+
"hover:bg-accent hover:text-accent-foreground": variant === "ghost",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"h-9 px-4 py-2": size === "default",
|
|
37
|
+
"h-8 rounded-md px-3 text-xs": size === "sm",
|
|
38
|
+
"h-10 rounded-md px-8": size === "lg",
|
|
39
|
+
},
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
ref={ref}
|
|
43
|
+
disabled={disabled || loading}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{loading && <Loader2 className="h-4 w-4 animate-spin" />}
|
|
47
|
+
{children}
|
|
48
|
+
</button>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { Button };
|
|
@@ -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 };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
1
|
+
// TODO: Update these with your deployed package IDs after running `sui client publish`
|
|
2
|
+
export const DEVNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
|
|
3
|
+
export const TESTNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
|
|
4
|
+
export const MAINNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**************************************************************
|
|
2
|
+
* THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
|
|
3
|
+
**************************************************************/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This example demonstrates a basic use of a shared object. Rules:
|
|
7
|
+
*
|
|
8
|
+
* - anyone can create and share a counter
|
|
9
|
+
* - everyone can increment a counter by 1
|
|
10
|
+
* - the owner of the counter can reset it to any value
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
MoveStruct,
|
|
15
|
+
normalizeMoveArguments,
|
|
16
|
+
type RawTransactionArgument,
|
|
17
|
+
} from "../utils/index.js";
|
|
18
|
+
import { bcs } from "@mysten/sui/bcs";
|
|
19
|
+
import { type Transaction } from "@mysten/sui/transactions";
|
|
20
|
+
const $moduleName = "@local-pkg/counter::counter";
|
|
21
|
+
export const Counter = new MoveStruct({
|
|
22
|
+
name: `${$moduleName}::Counter`,
|
|
23
|
+
fields: {
|
|
24
|
+
id: bcs.Address,
|
|
25
|
+
owner: bcs.Address,
|
|
26
|
+
value: bcs.u64(),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
export interface CreateOptions {
|
|
30
|
+
package?: string;
|
|
31
|
+
arguments?: [];
|
|
32
|
+
}
|
|
33
|
+
/** Create and share a Counter object. */
|
|
34
|
+
export function create(options: CreateOptions = {}) {
|
|
35
|
+
const packageAddress = options.package ?? "@local-pkg/counter";
|
|
36
|
+
return (tx: Transaction) =>
|
|
37
|
+
tx.moveCall({
|
|
38
|
+
package: packageAddress,
|
|
39
|
+
module: "counter",
|
|
40
|
+
function: "create",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export interface IncrementArguments {
|
|
44
|
+
counter: RawTransactionArgument<string>;
|
|
45
|
+
}
|
|
46
|
+
export interface IncrementOptions {
|
|
47
|
+
package?: string;
|
|
48
|
+
arguments: IncrementArguments | [counter: RawTransactionArgument<string>];
|
|
49
|
+
}
|
|
50
|
+
/** Increment a counter by 1. */
|
|
51
|
+
export function increment(options: IncrementOptions) {
|
|
52
|
+
const packageAddress = options.package ?? "@local-pkg/counter";
|
|
53
|
+
const argumentsTypes = [null] satisfies (string | null)[];
|
|
54
|
+
const parameterNames = ["counter"];
|
|
55
|
+
return (tx: Transaction) =>
|
|
56
|
+
tx.moveCall({
|
|
57
|
+
package: packageAddress,
|
|
58
|
+
module: "counter",
|
|
59
|
+
function: "increment",
|
|
60
|
+
arguments: normalizeMoveArguments(
|
|
61
|
+
options.arguments,
|
|
62
|
+
argumentsTypes,
|
|
63
|
+
parameterNames,
|
|
64
|
+
),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export interface SetValueArguments {
|
|
68
|
+
counter: RawTransactionArgument<string>;
|
|
69
|
+
value: RawTransactionArgument<number | bigint>;
|
|
70
|
+
}
|
|
71
|
+
export interface SetValueOptions {
|
|
72
|
+
package?: string;
|
|
73
|
+
arguments:
|
|
74
|
+
| SetValueArguments
|
|
75
|
+
| [
|
|
76
|
+
counter: RawTransactionArgument<string>,
|
|
77
|
+
value: RawTransactionArgument<number | bigint>,
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
/** Set value (only runnable by the Counter owner) */
|
|
81
|
+
export function setValue(options: SetValueOptions) {
|
|
82
|
+
const packageAddress = options.package ?? "@local-pkg/counter";
|
|
83
|
+
const argumentsTypes = [null, "u64"] satisfies (string | null)[];
|
|
84
|
+
const parameterNames = ["counter", "value"];
|
|
85
|
+
return (tx: Transaction) =>
|
|
86
|
+
tx.moveCall({
|
|
87
|
+
package: packageAddress,
|
|
88
|
+
module: "counter",
|
|
89
|
+
function: "set_value",
|
|
90
|
+
arguments: normalizeMoveArguments(
|
|
91
|
+
options.arguments,
|
|
92
|
+
argumentsTypes,
|
|
93
|
+
parameterNames,
|
|
94
|
+
),
|
|
95
|
+
});
|
|
96
|
+
}
|