@iota/create-dapp 0.1.0 → 0.2.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @iota/create-dapp
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6eabd18: Changes for compatibility with the node, simplification of exposed APIs and general
8
+ improvements.
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies [6eabd18]
13
+ - @iota/dapp-kit@0.3.0
14
+ - @iota/iota-sdk@0.3.0
15
+
3
16
  ## 0.1.0
4
17
 
5
18
  ### Minor Changes
package/README.md CHANGED
@@ -27,7 +27,7 @@ you including:
27
27
  - [Vite](https://vitejs.dev/)
28
28
  - [Radix UI](https://www.radix-ui.com/)
29
29
  - [ESLint](https://eslint.org/)
30
- - [`@iota/dapp-kit`]()
30
+ - [`@iota/dapp-kit`](https://wiki.iota.org/references/ts-sdk/dapp-kit)
31
31
 
32
32
  These templates are still new, and would love to get feedback and suggestions for improvements or
33
33
  future templates. Please open an issue on GitHub if you have any feedback.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@iota/create-dapp",
3
- "author": "IOTA Foundation <contact@iota.org>",
4
- "description": "A CLI for creating new Iota dApps",
5
- "version": "0.1.0",
3
+ "author": "IOTA Foundation <info@iota.org>",
4
+ "description": "A CLI for creating new IOTA dApps",
5
+ "version": "0.2.0",
6
6
  "license": "Apache-2.0",
7
7
  "files": [
8
8
  "CHANGELOG.md",
@@ -20,14 +20,14 @@
20
20
  "url": "https://github.com/iotaledger/iota/issues/new"
21
21
  },
22
22
  "devDependencies": {
23
- "typescript": "^5.3.3",
23
+ "typescript": "^5.5.3",
24
24
  "@iota/build-scripts": "0.0.0"
25
25
  },
26
26
  "dependencies": {
27
- "@types/node": "^20.4.2",
27
+ "@types/node": "^20.14.10",
28
28
  "enquirer": "^2.4.1",
29
- "@iota/dapp-kit": "0.2.0",
30
- "@iota/iota-sdk": "0.2.0"
29
+ "@iota/dapp-kit": "0.3.0",
30
+ "@iota/iota-sdk": "0.3.0"
31
31
  },
32
32
  "sideEffects": false,
33
33
  "bin": "./bin/index.js",
@@ -1,4 +1,4 @@
1
- # Iota dApp Starter Template
1
+ # IOTA dApp Starter Template
2
2
 
3
3
  This dApp was created using `@iota/create-dapp` that sets up a basic React
4
4
  Client dApp using the following tools:
@@ -8,8 +8,8 @@ Client dApp using the following tools:
8
8
  - [Vite](https://vitejs.dev/) for build tooling
9
9
  - [Radix UI](https://www.radix-ui.com/) for pre-built UI components
10
10
  - [ESLint](https://eslint.org/)
11
- - [`@iota/dapp-kit`]() for connecting to
12
- wallets and loading data
11
+ - [`@iota/dapp-kit`](https://wiki.iota.org/references/ts-sdk/dapp-kit) for
12
+ connecting to wallets and loading data
13
13
  - [pnpm](https://pnpm.io/) for package management
14
14
 
15
15
  ## Starting your dApp
@@ -4,7 +4,7 @@
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
- <title>Iota dApp Starter</title>
7
+ <title>IOTA dApp Starter</title>
8
8
 
9
9
  <style>
10
10
  /*
@@ -14,22 +14,22 @@
14
14
  "@iota/iota-sdk": "workspace:*",
15
15
  "@radix-ui/colors": "^3.0.0",
16
16
  "@radix-ui/react-icons": "^1.3.0",
17
- "@radix-ui/themes": "^2.0.0",
18
- "@tanstack/react-query": "^5.0.0",
17
+ "@radix-ui/themes": "^3.1.1",
18
+ "@tanstack/react-query": "^5.50.1",
19
19
  "react": "^18.3.1",
20
20
  "react-dom": "^18.3.1"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/react": "^18.3.3",
24
- "@types/react-dom": "^18.2.7",
25
- "@typescript-eslint/eslint-plugin": "^6.1.0",
26
- "@typescript-eslint/parser": "^6.1.0",
27
- "@vitejs/plugin-react-swc": "^3.3.2",
28
- "eslint": "^8.45.0",
29
- "eslint-plugin-react-hooks": "^4.6.0",
30
- "eslint-plugin-react-refresh": "^0.4.3",
31
- "prettier": "^3.0.0",
32
- "typescript": "^5.3.3",
33
- "vite": "^4.4.4"
24
+ "@types/react-dom": "^18.3.0",
25
+ "@typescript-eslint/eslint-plugin": "^7.16.0",
26
+ "@typescript-eslint/parser": "^7.16.0",
27
+ "@vitejs/plugin-react-swc": "^3.7.0",
28
+ "eslint": "^9.6.0",
29
+ "eslint-plugin-react-hooks": "^4.6.2",
30
+ "eslint-plugin-react-refresh": "^0.4.7",
31
+ "prettier": "^3.3.2",
32
+ "typescript": "^5.5.3",
33
+ "vite": "^5.3.3"
34
34
  }
35
35
  }
@@ -1,4 +1,5 @@
1
- // Copyright (c) 2024 IOTA Stiftung
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // Modifications Copyright (c) 2024 IOTA Stiftung
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
 
4
5
  import React from "react";
@@ -6,30 +7,19 @@ import ReactDOM from "react-dom/client";
6
7
  import "@iota/dapp-kit/dist/index.css";
7
8
  import "@radix-ui/themes/styles.css";
8
9
 
9
- import { getFullnodeUrl } from "@iota/iota-sdk/client";
10
- import {
11
- IotaClientProvider,
12
- WalletProvider,
13
- createNetworkConfig,
14
- } from "@iota/dapp-kit";
10
+ import { IotaClientProvider, WalletProvider } from "@iota/dapp-kit";
15
11
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
16
12
  import { Theme } from "@radix-ui/themes";
17
13
  import App from "./App.tsx";
14
+ import { networkConfig } from "./networkConfig.ts";
18
15
 
19
16
  const queryClient = new QueryClient();
20
17
 
21
- const { networkConfig } = createNetworkConfig({
22
- localnet: { url: getFullnodeUrl("localnet") },
23
- devnet: { url: getFullnodeUrl("devnet") },
24
- testnet: { url: getFullnodeUrl("testnet") },
25
- mainnet: { url: getFullnodeUrl("mainnet") },
26
- });
27
-
28
18
  ReactDOM.createRoot(document.getElementById("root")!).render(
29
19
  <React.StrictMode>
30
20
  <Theme appearance="dark">
31
21
  <QueryClientProvider client={queryClient}>
32
- <IotaClientProvider networks={networkConfig} defaultNetwork="devnet">
22
+ <IotaClientProvider networks={networkConfig} defaultNetwork="testnet">
33
23
  <WalletProvider autoConnect>
34
24
  <App />
35
25
  </WalletProvider>
@@ -0,0 +1,17 @@
1
+ import { getFullnodeUrl } from "@iota/iota-sdk/client";
2
+ import { createNetworkConfig } from "@iota/dapp-kit";
3
+
4
+ const { networkConfig, useNetworkVariable, useNetworkVariables } =
5
+ createNetworkConfig({
6
+ devnet: {
7
+ url: getFullnodeUrl("devnet"),
8
+ },
9
+ testnet: {
10
+ url: getFullnodeUrl("testnet"),
11
+ },
12
+ mainnet: {
13
+ url: getFullnodeUrl("mainnet"),
14
+ },
15
+ });
16
+
17
+ export { useNetworkVariable, useNetworkVariables, networkConfig };
@@ -1,4 +1,4 @@
1
- # Iota dApp Starter Template
1
+ # IOTA dApp Starter Template
2
2
 
3
3
  This dApp was created using `@iota/create-dapp` that sets up a basic React
4
4
  Client dApp using the following tools:
@@ -8,25 +8,28 @@ Client dApp using the following tools:
8
8
  - [Vite](https://vitejs.dev/) for build tooling
9
9
  - [Radix UI](https://www.radix-ui.com/) for pre-built UI components
10
10
  - [ESLint](https://eslint.org/) for linting
11
- - [`@iota/dapp-kit`]() for connecting to
12
- wallets and loading data
11
+ - [`@iota/dapp-kit`](https://wiki.iota.org/references/ts-sdk/dapp-kit) for
12
+ connecting to wallets and loading data
13
13
  - [pnpm](https://pnpm.io/) for package management
14
14
 
15
+ For a full guide on how to build this dApp from scratch, visit this
16
+ [guide](http://wiki.iota.org/guides/developer/app-examples/e2e-counter#frontend).
17
+
15
18
  ## Deploying your Move code
16
19
 
17
- ### Install Iota cli
20
+ ### Install IOTA cli
18
21
 
19
- Before deploying your move code, ensure that you have installed the Iota CLI.
22
+ Before deploying your move code, ensure that you have installed the IOTA CLI.
20
23
  You can follow the
21
- [Iota installation instruction](https://docs.iota.io/build/install) to get
24
+ [IOTA installation instruction](https://wiki.iota.org/build/install) to get
22
25
  everything set up.
23
26
 
24
- This template uses `devnet` by default, so we'll need to set up a devnet
27
+ This template uses `testnet` by default, so we'll need to set up a testnet
25
28
  environment in the CLI:
26
29
 
27
30
  ```bash
28
- iota client new-env --alias devnet --rpc https://fullnode.devnet.iota.io:443
29
- iota client switch --env devnet
31
+ iota client new-env --alias testnet --rpc https://fullnode.testnet.iota.org:443
32
+ iota client switch --env testnet
30
33
  ```
31
34
 
32
35
  If you haven't set up an address in the iota client yet, you can use the
@@ -44,11 +47,11 @@ with your new address:
44
47
  iota client switch --address 0xYOUR_ADDRESS...
45
48
  ```
46
49
 
47
- We can ensure we have some Iota in our new wallet by requesting Iota from the
50
+ We can ensure we have some IOTA in our new wallet by requesting IOTA from the
48
51
  faucet (make sure to replace the address with your address):
49
52
 
50
53
  ```bash
51
- curl --location --request POST 'https://faucet.devnet.iota.io/gas' \
54
+ curl --location --request POST 'https://faucet.testnet.iota.org/gas' \
52
55
  --header 'Content-Type: application/json' \
53
56
  --data-raw '{
54
57
  "FixedAmountRequest": {
@@ -60,7 +63,7 @@ curl --location --request POST 'https://faucet.devnet.iota.io/gas' \
60
63
  ### Publishing the move package
61
64
 
62
65
  The move code for this template is located in the `move` directory. To publish
63
- it, you can enter the `move` directory, and publish it with the Iota CLI:
66
+ it, you can enter the `move` directory, and publish it with the IOTA CLI:
64
67
 
65
68
  ```bash
66
69
  cd move
@@ -71,7 +74,7 @@ In the output there will be an object with a `"packageId"` property. You'll want
71
74
  to save that package ID to the `src/constants.ts` file as `PACKAGE_ID`:
72
75
 
73
76
  ```ts
74
- export const DEVNET_COUNTER_PACKAGE_ID = "<YOUR_PACKAGE_ID>";
77
+ export const TESTNET_COUNTER_PACKAGE_ID = "<YOUR_PACKAGE_ID>";
75
78
  ```
76
79
 
77
80
  Now that we have published the move code, and update the package ID, we can
@@ -4,7 +4,7 @@
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
- <title>Iota dApp Starter</title>
7
+ <title>IOTA dApp Starter</title>
8
8
 
9
9
  <style>
10
10
  /*
@@ -1,9 +1,10 @@
1
1
  [package]
2
2
  name = "counter"
3
3
  version = "0.0.1"
4
+ edition = "2024.beta"
4
5
 
5
6
  [dependencies]
6
- Iota = { git = "https://github.com/iotaledger/iota.git", subdir = "crates/iota-framework/packages/iota-framework", rev = "framework/devnet" }
7
+ Iota = { git = "https://github.com/iotaledger/iota.git", subdir = "crates/iota-framework/packages/iota-framework", rev = "devnet" }
7
8
 
8
9
  [addresses]
9
10
  counter = "0x0"
@@ -8,47 +8,30 @@
8
8
  /// - everyone can increment a counter by 1
9
9
  /// - the owner of the counter can reset it to any value
10
10
  module counter::counter {
11
- use iota::transfer;
12
- use iota::object::{Self, UID};
13
- use iota::tx_context::{Self, TxContext};
14
-
15
- /// A shared counter.
16
- struct Counter has key {
17
- id: UID,
18
- owner: address,
19
- value: u64
20
- }
21
-
22
- public fun owner(counter: &Counter): address {
23
- counter.owner
24
- }
25
-
26
- public fun value(counter: &Counter): u64 {
27
- counter.value
28
- }
29
-
30
- /// Create and share a Counter object.
31
- public fun create(ctx: &mut TxContext) {
32
- transfer::share_object(Counter {
33
- id: object::new(ctx),
34
- owner: tx_context::sender(ctx),
35
- value: 0
36
- })
37
- }
38
-
39
- /// Increment a counter by 1.
40
- public fun increment(counter: &mut Counter) {
41
- counter.value = counter.value + 1;
42
- }
43
-
44
- /// Set value (only runnable by the Counter owner)
45
- public fun set_value(counter: &mut Counter, value: u64, ctx: &TxContext) {
46
- assert!(counter.owner == tx_context::sender(ctx), 0);
47
- counter.value = value;
48
- }
49
-
50
- /// Assert a value for the counter.
51
- public fun assert_value(counter: &Counter, value: u64) {
52
- assert!(counter.value == value, 0)
53
- }
11
+ /// A shared counter.
12
+ public struct Counter has key {
13
+ id: UID,
14
+ owner: address,
15
+ value: u64
16
+ }
17
+
18
+ /// Create and share a Counter object.
19
+ public fun create(ctx: &mut TxContext) {
20
+ transfer::share_object(Counter {
21
+ id: object::new(ctx),
22
+ owner: ctx.sender(),
23
+ value: 0
24
+ })
25
+ }
26
+
27
+ /// Increment a counter by 1.
28
+ public fun increment(counter: &mut Counter) {
29
+ counter.value = counter.value + 1;
30
+ }
31
+
32
+ /// Set value (only runnable by the Counter owner)
33
+ public fun set_value(counter: &mut Counter, value: u64, ctx: &TxContext) {
34
+ assert!(counter.owner == ctx.sender(), 0);
35
+ counter.value = value;
36
+ }
54
37
  }
@@ -14,22 +14,22 @@
14
14
  "@iota/iota-sdk": "workspace:*",
15
15
  "@radix-ui/colors": "^3.0.0",
16
16
  "@radix-ui/react-icons": "^1.3.0",
17
- "@radix-ui/themes": "^2.0.0",
18
- "@tanstack/react-query": "^5.0.0",
17
+ "@radix-ui/themes": "^3.1.1",
18
+ "@tanstack/react-query": "^5.50.1",
19
19
  "react": "^18.3.1",
20
20
  "react-dom": "^18.3.1"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/react": "^18.3.3",
24
- "@types/react-dom": "^18.2.7",
24
+ "@types/react-dom": "^18.3.0",
25
25
  "@typescript-eslint/eslint-plugin": "^6.1.0",
26
26
  "@typescript-eslint/parser": "^6.1.0",
27
- "@vitejs/plugin-react-swc": "^3.3.2",
27
+ "@vitejs/plugin-react-swc": "^3.7.0",
28
28
  "eslint": "^8.45.0",
29
- "eslint-plugin-react-hooks": "^4.6.0",
30
- "eslint-plugin-react-refresh": "^0.4.3",
31
- "prettier": "^3.0.0",
32
- "typescript": "^5.3.3",
33
- "vite": "^4.4.4"
29
+ "eslint-plugin-react-hooks": "^4.6.2",
30
+ "eslint-plugin-react-refresh": "^0.4.7",
31
+ "prettier": "^3.3.2",
32
+ "typescript": "^5.5.3",
33
+ "vite": "^5.3.3"
34
34
  }
35
35
  }
@@ -1,4 +1,5 @@
1
- // Copyright (c) 2024 IOTA Stiftung
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // Modifications Copyright (c) 2024 IOTA Stiftung
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
 
4
5
  import { ConnectButton, useCurrentAccount } from "@iota/dapp-kit";
@@ -1,22 +1,34 @@
1
- // Copyright (c) 2024 IOTA Stiftung
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // Modifications Copyright (c) 2024 IOTA Stiftung
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
 
4
5
  import {
5
6
  useCurrentAccount,
6
- useSignAndExecuteTransactionBlock,
7
+ useSignAndExecuteTransaction,
7
8
  useIotaClient,
8
9
  useIotaClientQuery,
9
10
  } from "@iota/dapp-kit";
10
11
  import type { IotaObjectData } from "@iota/iota-sdk/client";
11
- import { TransactionBlock } from "@iota/iota-sdk/transactions";
12
+ import { Transaction } from "@iota/iota-sdk/transactions";
12
13
  import { Button, Flex, Heading, Text } from "@radix-ui/themes";
13
14
  import { useNetworkVariable } from "./networkConfig";
14
15
 
15
16
  export function Counter({ id }: { id: string }) {
16
- const client = useIotaClient();
17
- const currentAccount = useCurrentAccount();
18
17
  const counterPackageId = useNetworkVariable("counterPackageId");
19
- const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock();
18
+ const iotaClient = useIotaClient();
19
+ const currentAccount = useCurrentAccount();
20
+ const { mutate: signAndExecute } = useSignAndExecuteTransaction({
21
+ execute: async ({ bytes, signature }) =>
22
+ await iotaClient.executeTransactionBlock({
23
+ transactionBlock: bytes,
24
+ signature,
25
+ options: {
26
+ // Raw effects are required so the effects can be reported back to the wallet
27
+ showRawEffects: true,
28
+ showEffects: true,
29
+ },
30
+ }),
31
+ });
20
32
  const { data, isPending, error, refetch } = useIotaClientQuery("getObject", {
21
33
  id,
22
34
  options: {
@@ -26,33 +38,27 @@ export function Counter({ id }: { id: string }) {
26
38
  });
27
39
 
28
40
  const executeMoveCall = (method: "increment" | "reset") => {
29
- const txb = new TransactionBlock();
41
+ const tx = new Transaction();
30
42
 
31
43
  if (method === "reset") {
32
- txb.moveCall({
33
- arguments: [txb.object(id), txb.pure.u64(0)],
44
+ tx.moveCall({
45
+ arguments: [tx.object(id), tx.pure.u64(0)],
34
46
  target: `${counterPackageId}::counter::set_value`,
35
47
  });
36
48
  } else {
37
- txb.moveCall({
38
- arguments: [txb.object(id)],
49
+ tx.moveCall({
50
+ arguments: [tx.object(id)],
39
51
  target: `${counterPackageId}::counter::increment`,
40
52
  });
41
53
  }
42
54
 
43
55
  signAndExecute(
44
56
  {
45
- transactionBlock: txb,
46
- options: {
47
- showEffects: true,
48
- showObjectChanges: true,
49
- },
57
+ transaction: tx,
50
58
  },
51
59
  {
52
- onSuccess: (tx) => {
53
- client.waitForTransactionBlock({ digest: tx.digest }).then(() => {
54
- refetch();
55
- });
60
+ onSuccess: async () => {
61
+ await refetch();
56
62
  },
57
63
  },
58
64
  );
@@ -1,12 +1,6 @@
1
- // Copyright (c) 2024 IOTA Stiftung
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- import { TransactionBlock } from "@iota/iota-sdk/transactions";
1
+ import { Transaction } from "@iota/iota-sdk/transactions";
5
2
  import { Button, Container } from "@radix-ui/themes";
6
- import {
7
- useSignAndExecuteTransactionBlock,
8
- useIotaClient,
9
- } from "@iota/dapp-kit";
3
+ import { useSignAndExecuteTransaction, useIotaClient } from "@iota/dapp-kit";
10
4
  import { useNetworkVariable } from "./networkConfig";
11
5
 
12
6
  export function CreateCounter({
@@ -14,9 +8,20 @@ export function CreateCounter({
14
8
  }: {
15
9
  onCreated: (id: string) => void;
16
10
  }) {
17
- const client = useIotaClient();
18
11
  const counterPackageId = useNetworkVariable("counterPackageId");
19
- const { mutate: signAndExecute } = useSignAndExecuteTransactionBlock();
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
+ });
20
25
 
21
26
  return (
22
27
  <Container>
@@ -32,34 +37,23 @@ export function CreateCounter({
32
37
  );
33
38
 
34
39
  function create() {
35
- const txb = new TransactionBlock();
40
+ const tx = new Transaction();
36
41
 
37
- txb.moveCall({
42
+ tx.moveCall({
38
43
  arguments: [],
39
44
  target: `${counterPackageId}::counter::create`,
40
45
  });
41
46
 
42
47
  signAndExecute(
43
48
  {
44
- transactionBlock: txb,
45
- options: {
46
- showEffects: true,
47
- showObjectChanges: true,
48
- },
49
+ transaction: tx,
49
50
  },
50
51
  {
51
- onSuccess: (tx) => {
52
- client
53
- .waitForTransactionBlock({
54
- digest: tx.digest,
55
- })
56
- .then(() => {
57
- const objectId = tx.effects?.created?.[0]?.reference?.objectId;
58
-
59
- if (objectId) {
60
- onCreated(objectId);
61
- }
62
- });
52
+ onSuccess: (result) => {
53
+ const objectId = result.effects?.created?.[0]?.reference?.objectId;
54
+ if (objectId) {
55
+ onCreated(objectId);
56
+ }
63
57
  },
64
58
  },
65
59
  );
@@ -1,2 +1,3 @@
1
1
  export const DEVNET_COUNTER_PACKAGE_ID = "0xTODO";
2
+ export const TESTNET_COUNTER_PACKAGE_ID = "0xTODO";
2
3
  export const MAINNET_COUNTER_PACKAGE_ID = "0xTODO";
@@ -15,7 +15,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
15
15
  <React.StrictMode>
16
16
  <Theme appearance="dark">
17
17
  <QueryClientProvider client={queryClient}>
18
- <IotaClientProvider networks={networkConfig} defaultNetwork="devnet">
18
+ <IotaClientProvider networks={networkConfig} defaultNetwork="testnet">
19
19
  <WalletProvider autoConnect>
20
20
  <App />
21
21
  </WalletProvider>
@@ -1,9 +1,11 @@
1
- // Copyright (c) 2024 IOTA Stiftung
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // Modifications Copyright (c) 2024 IOTA Stiftung
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
 
4
5
  import { getFullnodeUrl } from "@iota/iota-sdk/client";
5
6
  import {
6
7
  DEVNET_COUNTER_PACKAGE_ID,
8
+ TESTNET_COUNTER_PACKAGE_ID,
7
9
  MAINNET_COUNTER_PACKAGE_ID,
8
10
  } from "./constants.ts";
9
11
  import { createNetworkConfig } from "@iota/dapp-kit";
@@ -16,6 +18,12 @@ const { networkConfig, useNetworkVariable, useNetworkVariables } =
16
18
  counterPackageId: DEVNET_COUNTER_PACKAGE_ID,
17
19
  },
18
20
  },
21
+ testnet: {
22
+ url: getFullnodeUrl("testnet"),
23
+ variables: {
24
+ counterPackageId: TESTNET_COUNTER_PACKAGE_ID,
25
+ },
26
+ },
19
27
  mainnet: {
20
28
  url: getFullnodeUrl("mainnet"),
21
29
  variables: {