@iota/create-dapp 0.0.0-experimental-20250611113847
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 +142 -0
- package/LICENSE +201 -0
- package/README.md +35 -0
- package/bin/index.js +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +103 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
- package/src/index.ts +131 -0
- package/templates/react-client-dapp/README.md +35 -0
- package/templates/react-client-dapp/eslint.config.js +28 -0
- package/templates/react-client-dapp/index.html +59 -0
- package/templates/react-client-dapp/package.json +37 -0
- package/templates/react-client-dapp/prettier.config.cjs +4 -0
- package/templates/react-client-dapp/src/App.tsx +39 -0
- package/templates/react-client-dapp/src/OwnedObjects.tsx +42 -0
- package/templates/react-client-dapp/src/WalletStatus.tsx +23 -0
- package/templates/react-client-dapp/src/main.tsx +26 -0
- package/templates/react-client-dapp/src/networkConfig.ts +17 -0
- package/templates/react-client-dapp/src/vite-env.d.ts +1 -0
- package/templates/react-client-dapp/tsconfig.json +25 -0
- package/templates/react-client-dapp/tsconfig.node.json +10 -0
- package/templates/react-client-dapp/vite.config.ts +7 -0
- package/templates/react-e2e-counter/README.md +100 -0
- package/templates/react-e2e-counter/eslint.config.js +28 -0
- package/templates/react-e2e-counter/index.html +59 -0
- package/templates/react-e2e-counter/move/counter/Move.toml +10 -0
- package/templates/react-e2e-counter/move/counter/sources/counter.move +37 -0
- package/templates/react-e2e-counter/package.json +37 -0
- package/templates/react-e2e-counter/prettier.config.cjs +4 -0
- package/templates/react-e2e-counter/src/App.tsx +61 -0
- package/templates/react-e2e-counter/src/Counter.tsx +96 -0
- package/templates/react-e2e-counter/src/CreateCounter.tsx +61 -0
- package/templates/react-e2e-counter/src/constants.ts +3 -0
- package/templates/react-e2e-counter/src/main.tsx +26 -0
- package/templates/react-e2e-counter/src/networkConfig.ts +31 -0
- package/templates/react-e2e-counter/src/vite-env.d.ts +1 -0
- package/templates/react-e2e-counter/tsconfig.json +25 -0
- package/templates/react-e2e-counter/tsconfig.node.json +10 -0
- package/templates/react-e2e-counter/vite.config.ts +7 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ConnectButton, useCurrentAccount } from "@iota/dapp-kit";
|
|
2
|
+
import { isValidIotaObjectId } from "@iota/iota-sdk/utils";
|
|
3
|
+
import { Box, Container, Flex, Heading } from "@radix-ui/themes";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Counter } from "./Counter";
|
|
6
|
+
import { CreateCounter } from "./CreateCounter";
|
|
7
|
+
|
|
8
|
+
function App() {
|
|
9
|
+
const currentAccount = useCurrentAccount();
|
|
10
|
+
const [counterId, setCounter] = useState(() => {
|
|
11
|
+
const hash = window.location.hash.slice(1);
|
|
12
|
+
return isValidIotaObjectId(hash) ? hash : null;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<Flex
|
|
18
|
+
position="sticky"
|
|
19
|
+
px="4"
|
|
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>
|
|
31
|
+
<ConnectButton />
|
|
32
|
+
</Box>
|
|
33
|
+
</Flex>
|
|
34
|
+
<Container>
|
|
35
|
+
<Container
|
|
36
|
+
mt="5"
|
|
37
|
+
pt="2"
|
|
38
|
+
px="4"
|
|
39
|
+
style={{ background: "var(--gray-a2)", minHeight: 500 }}
|
|
40
|
+
>
|
|
41
|
+
{currentAccount ? (
|
|
42
|
+
counterId ? (
|
|
43
|
+
<Counter id={counterId} />
|
|
44
|
+
) : (
|
|
45
|
+
<CreateCounter
|
|
46
|
+
onCreated={(id) => {
|
|
47
|
+
window.location.hash = id;
|
|
48
|
+
setCounter(id);
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
) : (
|
|
53
|
+
<Heading>Please connect your wallet</Heading>
|
|
54
|
+
)}
|
|
55
|
+
</Container>
|
|
56
|
+
</Container>
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default App;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useCurrentAccount,
|
|
3
|
+
useSignAndExecuteTransaction,
|
|
4
|
+
useIotaClient,
|
|
5
|
+
useIotaClientQuery,
|
|
6
|
+
} from "@iota/dapp-kit";
|
|
7
|
+
import type { IotaObjectData } from "@iota/iota-sdk/client";
|
|
8
|
+
import { Transaction } from "@iota/iota-sdk/transactions";
|
|
9
|
+
import { Button, Flex, Heading, Text } from "@radix-ui/themes";
|
|
10
|
+
import { useNetworkVariable } from "./networkConfig";
|
|
11
|
+
|
|
12
|
+
export function Counter({ id }: { id: string }) {
|
|
13
|
+
const counterPackageId = useNetworkVariable("counterPackageId");
|
|
14
|
+
const iotaClient = useIotaClient();
|
|
15
|
+
const currentAccount = useCurrentAccount();
|
|
16
|
+
const { mutate: signAndExecute } = useSignAndExecuteTransaction({
|
|
17
|
+
execute: async ({ bytes, signature }) =>
|
|
18
|
+
await iotaClient.executeTransactionBlock({
|
|
19
|
+
transactionBlock: bytes,
|
|
20
|
+
signature,
|
|
21
|
+
options: {
|
|
22
|
+
// Raw effects are required so the effects can be reported back to the wallet
|
|
23
|
+
showRawEffects: true,
|
|
24
|
+
showEffects: true,
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
const { data, isPending, error, refetch } = useIotaClientQuery("getObject", {
|
|
29
|
+
id,
|
|
30
|
+
options: {
|
|
31
|
+
showContent: true,
|
|
32
|
+
showOwner: true,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const executeMoveCall = (method: "increment" | "reset") => {
|
|
37
|
+
const tx = new Transaction();
|
|
38
|
+
|
|
39
|
+
if (method === "reset") {
|
|
40
|
+
tx.moveCall({
|
|
41
|
+
arguments: [tx.object(id), tx.pure.u64(0)],
|
|
42
|
+
target: `${counterPackageId}::counter::set_value`,
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
tx.moveCall({
|
|
46
|
+
arguments: [tx.object(id)],
|
|
47
|
+
target: `${counterPackageId}::counter::increment`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
signAndExecute(
|
|
52
|
+
{
|
|
53
|
+
transaction: tx,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
onSuccess: async () => {
|
|
57
|
+
await refetch();
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (isPending) return <Text>Loading...</Text>;
|
|
64
|
+
|
|
65
|
+
if (error) return <Text>Error: {error.message}</Text>;
|
|
66
|
+
|
|
67
|
+
if (!data.data) return <Text>Not found</Text>;
|
|
68
|
+
|
|
69
|
+
const ownedByCurrentAccount =
|
|
70
|
+
getCounterFields(data.data)?.owner === currentAccount?.address;
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<>
|
|
74
|
+
<Heading size="3">Counter {id}</Heading>
|
|
75
|
+
|
|
76
|
+
<Flex direction="column" gap="2">
|
|
77
|
+
<Text>Count: {getCounterFields(data.data)?.value}</Text>
|
|
78
|
+
<Flex direction="row" gap="2">
|
|
79
|
+
<Button onClick={() => executeMoveCall("increment")}>
|
|
80
|
+
Increment
|
|
81
|
+
</Button>
|
|
82
|
+
{ownedByCurrentAccount ? (
|
|
83
|
+
<Button onClick={() => executeMoveCall("reset")}>Reset</Button>
|
|
84
|
+
) : null}
|
|
85
|
+
</Flex>
|
|
86
|
+
</Flex>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
function getCounterFields(data: IotaObjectData) {
|
|
91
|
+
if (data.content?.dataType !== "moveObject") {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return data.content.fields as { value: number; owner: string };
|
|
96
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Transaction } from "@iota/iota-sdk/transactions";
|
|
2
|
+
import { Button, Container } from "@radix-ui/themes";
|
|
3
|
+
import { useSignAndExecuteTransaction, useIotaClient } from "@iota/dapp-kit";
|
|
4
|
+
import { useNetworkVariable } from "./networkConfig";
|
|
5
|
+
|
|
6
|
+
export function CreateCounter({
|
|
7
|
+
onCreated,
|
|
8
|
+
}: {
|
|
9
|
+
onCreated: (id: string) => void;
|
|
10
|
+
}) {
|
|
11
|
+
const counterPackageId = useNetworkVariable("counterPackageId");
|
|
12
|
+
const iotaClient = useIotaClient();
|
|
13
|
+
const { mutate: signAndExecute } = useSignAndExecuteTransaction({
|
|
14
|
+
execute: async ({ bytes, signature }) =>
|
|
15
|
+
await iotaClient.executeTransactionBlock({
|
|
16
|
+
transactionBlock: bytes,
|
|
17
|
+
signature,
|
|
18
|
+
options: {
|
|
19
|
+
// Raw effects are required so the effects can be reported back to the wallet
|
|
20
|
+
showRawEffects: true,
|
|
21
|
+
showEffects: true,
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Container>
|
|
28
|
+
<Button
|
|
29
|
+
size="3"
|
|
30
|
+
onClick={() => {
|
|
31
|
+
create();
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
Create Counter
|
|
35
|
+
</Button>
|
|
36
|
+
</Container>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
function create() {
|
|
40
|
+
const tx = new Transaction();
|
|
41
|
+
|
|
42
|
+
tx.moveCall({
|
|
43
|
+
arguments: [],
|
|
44
|
+
target: `${counterPackageId}::counter::create`,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
signAndExecute(
|
|
48
|
+
{
|
|
49
|
+
transaction: tx,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
onSuccess: (result) => {
|
|
53
|
+
const objectId = result.effects?.created?.[0]?.reference?.objectId;
|
|
54
|
+
if (objectId) {
|
|
55
|
+
onCreated(objectId);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import "@iota/dapp-kit/dist/index.css";
|
|
4
|
+
import "@radix-ui/themes/styles.css";
|
|
5
|
+
|
|
6
|
+
import { IotaClientProvider, WalletProvider } from "@iota/dapp-kit";
|
|
7
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
8
|
+
import { Theme } from "@radix-ui/themes";
|
|
9
|
+
import App from "./App.tsx";
|
|
10
|
+
import { networkConfig } from "./networkConfig.ts";
|
|
11
|
+
|
|
12
|
+
const queryClient = new QueryClient();
|
|
13
|
+
|
|
14
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
15
|
+
<React.StrictMode>
|
|
16
|
+
<Theme appearance="dark">
|
|
17
|
+
<QueryClientProvider client={queryClient}>
|
|
18
|
+
<IotaClientProvider networks={networkConfig} defaultNetwork="testnet">
|
|
19
|
+
<WalletProvider autoConnect>
|
|
20
|
+
<App />
|
|
21
|
+
</WalletProvider>
|
|
22
|
+
</IotaClientProvider>
|
|
23
|
+
</QueryClientProvider>
|
|
24
|
+
</Theme>
|
|
25
|
+
</React.StrictMode>,
|
|
26
|
+
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getFullnodeUrl } from "@iota/iota-sdk/client";
|
|
2
|
+
import {
|
|
3
|
+
DEVNET_COUNTER_PACKAGE_ID,
|
|
4
|
+
TESTNET_COUNTER_PACKAGE_ID,
|
|
5
|
+
MAINNET_COUNTER_PACKAGE_ID,
|
|
6
|
+
} from "./constants.ts";
|
|
7
|
+
import { createNetworkConfig } from "@iota/dapp-kit";
|
|
8
|
+
|
|
9
|
+
const { networkConfig, useNetworkVariable, useNetworkVariables } =
|
|
10
|
+
createNetworkConfig({
|
|
11
|
+
devnet: {
|
|
12
|
+
url: getFullnodeUrl("devnet"),
|
|
13
|
+
variables: {
|
|
14
|
+
counterPackageId: DEVNET_COUNTER_PACKAGE_ID,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
testnet: {
|
|
18
|
+
url: getFullnodeUrl("testnet"),
|
|
19
|
+
variables: {
|
|
20
|
+
counterPackageId: TESTNET_COUNTER_PACKAGE_ID,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
mainnet: {
|
|
24
|
+
url: getFullnodeUrl("mainnet"),
|
|
25
|
+
variables: {
|
|
26
|
+
counterPackageId: MAINNET_COUNTER_PACKAGE_ID,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export { useNetworkVariable, useNetworkVariables, networkConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src"],
|
|
24
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
+
}
|