create-stylus 0.0.5 → 0.0.6

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.
Files changed (46) hide show
  1. package/dist/cli.js +658 -0
  2. package/dist/cli.js.map +1 -0
  3. package/package.json +1 -1
  4. package/templates/base/package.json +2 -1
  5. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressStorageTab.tsx +1 -1
  6. package/templates/base/packages/nextjs/app/blockexplorer/_components/ContractTabs.tsx +1 -1
  7. package/templates/base/packages/nextjs/app/blockexplorer/_components/SearchBar.tsx +31 -12
  8. package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionsTable.tsx +16 -16
  9. package/templates/base/packages/nextjs/app/blockexplorer/address/[address]/page.tsx +1 -1
  10. package/templates/base/packages/nextjs/app/blockexplorer/page.tsx +1 -1
  11. package/templates/base/packages/nextjs/app/blockexplorer/transaction/_components/TransactionComp.tsx +1 -1
  12. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +33 -83
  13. package/templates/base/packages/nextjs/components/Footer.tsx +1 -1
  14. package/templates/base/packages/nextjs/components/Header.tsx +1 -1
  15. package/templates/base/packages/nextjs/components/ThemeProvider.tsx +10 -0
  16. package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressLinkWrapper.tsx +1 -1
  17. package/templates/base/packages/nextjs/components/scaffold-eth/Faucet.tsx +1 -1
  18. package/templates/base/packages/nextjs/components/scaffold-eth/FaucetButton.tsx +1 -1
  19. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +1 -1
  20. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/BurnerWalletModal.tsx +1 -1
  21. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +1 -1
  22. package/templates/base/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts +2 -2
  23. package/templates/base/packages/nextjs/scaffold.config.ts +4 -4
  24. package/templates/base/packages/nextjs/services/web3/wagmiConfig.tsx +1 -1
  25. package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +18 -12
  26. package/templates/base/packages/nextjs/styles/globals.css +9 -0
  27. package/templates/base/packages/nextjs/tailwind.config.js +4 -0
  28. package/templates/base/packages/nextjs/utils/scaffold-eth/decodeTxData.ts +1 -1
  29. package/templates/base/packages/nextjs/utils/scaffold-stylus/burner.ts +1 -1
  30. package/templates/base/packages/nextjs/utils/scaffold-stylus/index.ts +1 -1
  31. package/templates/base/packages/nextjs/utils/scaffold-stylus/networks.ts +1 -1
  32. package/templates/base/packages/nextjs/utils/scaffold-stylus/{chain.ts → supportedChains.ts} +5 -2
  33. package/templates/base/packages/stylus/.env.example +5 -0
  34. package/templates/base/packages/stylus/package.json +1 -1
  35. package/templates/base/packages/stylus/scripts/utils/command.ts +7 -7
  36. package/templates/base/packages/stylus/scripts/utils/deployment.ts +1 -1
  37. package/templates/base/packages/stylus/scripts/utils/network.ts +17 -2
  38. package/templates/base/packages/stylus/scripts/utils/type.ts +1 -1
  39. package/templates/base/packages/stylus/your-contract/src/lib.rs +21 -23
  40. package/templates/base/readme.md +18 -6
  41. package/templates/base/yarn.lock +590 -547
  42. package/templates/base/packages/stylus/your-contract/examples/counter.rs +0 -78
  43. package/templates/base/packages/stylus/your-contract/licenses/Apache-2.0 +0 -201
  44. package/templates/base/packages/stylus/your-contract/licenses/COPYRIGHT.md +0 -5
  45. package/templates/base/packages/stylus/your-contract/licenses/DCO.txt +0 -34
  46. package/templates/base/packages/stylus/your-contract/licenses/MIT +0 -21
@@ -1,6 +1,6 @@
1
1
  import type { Hex } from "viem";
2
2
  import { generatePrivateKey } from "viem/accounts";
3
- import { arbitrumNitro } from "./chain";
3
+ import { arbitrumNitro } from "./supportedChains";
4
4
 
5
5
  const burnerStorageKey = "burnerWallet.pk";
6
6
  export const burnerWalletId = "burnerWallet" as const;
@@ -1,3 +1,3 @@
1
1
  export * from "./burner";
2
- export * from "./chain";
2
+ export * from "./supportedChains";
3
3
  export * from "./networks";
@@ -1,6 +1,6 @@
1
1
  import * as chains from "viem/chains";
2
2
  import scaffoldConfig from "~~/scaffold.config";
3
- import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
3
+ import { arbitrumNitro } from "~~/utils/scaffold-stylus/supportedChains";
4
4
 
5
5
  type ChainAttributes = {
6
6
  // color | [lightThemeColor, darkThemeColor]
@@ -1,8 +1,9 @@
1
1
  import { defineChain } from "viem";
2
+ import { arbitrum, arbitrumSepolia, arbitrumNova } from "viem/chains";
2
3
 
3
- export const arbitrumNitro = defineChain({
4
+ const arbitrumNitro = defineChain({
4
5
  id: 412346,
5
- name: "Arbitrum Nitro",
6
+ name: "Arbitrum Nitro DevNode",
6
7
  network: "arbitrum-nitro",
7
8
  nativeCurrency: {
8
9
  name: "Ether",
@@ -40,3 +41,5 @@ export const arbitrumNitro = defineChain({
40
41
  },
41
42
  ],
42
43
  });
44
+
45
+ export { arbitrum, arbitrumSepolia, arbitrumNova, arbitrumNitro };
@@ -14,3 +14,8 @@ PRIVATE_KEY_SEPOLIA=
14
14
  ACCOUNT_ADDRESS_MAINNET=
15
15
  RPC_URL_MAINNET=
16
16
  PRIVATE_KEY_MAINNET=
17
+
18
+ ## nova
19
+ ACCOUNT_ADDRESS_NOVA=
20
+ RPC_URL_NOVA=
21
+ PRIVATE_KEY_NOVA=
@@ -11,7 +11,7 @@
11
11
  "deploy": "ts-node scripts/deploy_wrapper.ts",
12
12
  "test:networks": "ts-node scripts/test_network.ts",
13
13
  "export-abi": "ts-node scripts/export_abi.ts",
14
- "clean": "rm -rf dist",
14
+ "clean-contracts": "git clean -xdf -e .env -e your-contract/ -e node_modules/",
15
15
  "test": "cargo test",
16
16
  "lint": "eslint scripts --ext .ts",
17
17
  "lint:fix": "eslint scripts --ext .ts --fix",
@@ -8,13 +8,6 @@ export async function buildDeployCommand(
8
8
  ) {
9
9
  let baseCommand = `cargo stylus deploy --endpoint='${config.chain?.rpcUrl}' --private-key='${config.privateKey}'`;
10
10
 
11
- if (
12
- deployOptions.constructorArgs &&
13
- deployOptions.constructorArgs.length > 0
14
- ) {
15
- baseCommand += ` --constructor-args='${deployOptions.constructorArgs.join(" ")}'`;
16
- }
17
-
18
11
  if (deployOptions.estimateGas) {
19
12
  return `${baseCommand} --estimate-gas`;
20
13
  }
@@ -27,6 +20,13 @@ export async function buildDeployCommand(
27
20
  baseCommand += ` --max-fee-per-gas-gwei=${deployOptions.maxFee}`;
28
21
  }
29
22
 
23
+ if (
24
+ deployOptions.constructorArgs &&
25
+ deployOptions.constructorArgs.length > 0
26
+ ) {
27
+ baseCommand += ` --constructor-args ${deployOptions.constructorArgs.map((arg) => `"${arg}"`).join(" ")} `;
28
+ }
29
+
30
30
  return baseCommand;
31
31
  }
32
32
 
@@ -1,7 +1,7 @@
1
1
  import { config as dotenvConfig } from "dotenv";
2
2
  import * as path from "path";
3
3
  import * as fs from "fs";
4
- import { arbitrumNitro } from "../../../nextjs/utils/scaffold-stylus/chain";
4
+ import { arbitrumNitro } from "../../../nextjs/utils/scaffold-stylus/supportedChains";
5
5
  import { DeploymentConfig, DeployOptions, DeploymentData } from "./type";
6
6
  import { getAccountAddress, getChain, getPrivateKey } from "./network";
7
7
  import { getContractNameFromCargoToml } from "./contract";
@@ -1,6 +1,6 @@
1
- import { arbitrum, arbitrumSepolia } from "viem/chains";
1
+ import { arbitrum, arbitrumNova, arbitrumSepolia } from "viem/chains";
2
2
  import { Address, Chain } from "viem";
3
- import { arbitrumNitro } from "../../../nextjs/utils/scaffold-stylus/chain";
3
+ import { arbitrumNitro } from "../../../nextjs/utils/scaffold-stylus/supportedChains";
4
4
  import * as path from "path";
5
5
  import * as fs from "fs";
6
6
  import { config as dotenvConfig } from "dotenv";
@@ -15,12 +15,14 @@ export const SUPPORTED_NETWORKS: Record<string, Chain> = {
15
15
  arbitrum,
16
16
  arbitrumSepolia,
17
17
  arbitrumNitro: arbitrumNitro as Chain,
18
+ arbitrumNova: arbitrumNova as Chain,
18
19
  };
19
20
 
20
21
  export const ALIASES: Record<string, string> = {
21
22
  mainnet: "arbitrum",
22
23
  sepolia: "arbitrumSepolia",
23
24
  devnet: "arbitrumNitro",
25
+ nova: "arbitrumNova",
24
26
  };
25
27
 
26
28
  export function getChain(networkName: string): SupportedNetworkMinimal | null {
@@ -67,6 +69,12 @@ export function getPrivateKey(networkName: string): string {
67
69
  } else {
68
70
  throw new Error("PRIVATE_KEY_SEPOLIA is not set");
69
71
  }
72
+ case "arbitrumnova":
73
+ if (process.env["PRIVATE_KEY_NOVA"]) {
74
+ return process.env["PRIVATE_KEY_NOVA"];
75
+ } else {
76
+ throw new Error("PRIVATE_KEY_NOVA is not set");
77
+ }
70
78
  default:
71
79
  return (
72
80
  process.env["PRIVATE_KEY"] ||
@@ -82,6 +90,8 @@ export const getAccountAddress = (networkName: string): Address | undefined => {
82
90
  return process.env["ACCOUNT_ADDRESS_MAINNET"] as Address;
83
91
  case "arbitrumsepolia":
84
92
  return process.env["ACCOUNT_ADDRESS_SEPOLIA"] as Address;
93
+ case "arbitrumnova":
94
+ return process.env["ACCOUNT_ADDRESS_NOVA"] as Address;
85
95
  default:
86
96
  return (
87
97
  (process.env["ACCOUNT_ADDRESS"] as Address) ||
@@ -103,6 +113,11 @@ function getRpcUrlFromChain(chain: Chain): string {
103
113
  return process.env["RPC_URL_SEPOLIA"];
104
114
  }
105
115
  break;
116
+ case arbitrumNova.id:
117
+ if (process.env["RPC_URL_NOVA"]) {
118
+ return process.env["RPC_URL_NOVA"];
119
+ }
120
+ break;
106
121
  default:
107
122
  if (process.env["RPC_URL"]) {
108
123
  return process.env["RPC_URL"];
@@ -13,7 +13,7 @@ export interface DeployCommandOptions
13
13
  export interface DeployOptions {
14
14
  contract?: string;
15
15
  name?: string;
16
- constructorArgs?: string[];
16
+ constructorArgs?: NonNullable<unknown>[];
17
17
  network?: string;
18
18
  estimateGas?: boolean;
19
19
  maxFee?: string;
@@ -20,13 +20,13 @@ use alloc::vec::Vec;
20
20
  /// Import items from the SDK. The prelude contains common traits and macros.
21
21
  use stylus_sdk::{
22
22
  alloy_primitives::{Address, U256},
23
- prelude::*,
24
23
  alloy_sol_types::sol,
24
+ prelude::*,
25
25
  stylus_core::log,
26
26
  };
27
27
 
28
28
  /// Import OpenZeppelin Ownable functionality
29
- use openzeppelin_stylus::access::ownable::{self, Ownable, IOwnable};
29
+ use openzeppelin_stylus::access::ownable::{self, IOwnable, Ownable};
30
30
 
31
31
  /// Error types for the contract
32
32
  #[derive(SolidityError, Debug)]
@@ -38,9 +38,7 @@ pub enum Error {
38
38
  impl From<ownable::Error> for Error {
39
39
  fn from(value: ownable::Error) -> Self {
40
40
  match value {
41
- ownable::Error::UnauthorizedAccount(e) => {
42
- Error::UnauthorizedAccount(e)
43
- }
41
+ ownable::Error::UnauthorizedAccount(e) => Error::UnauthorizedAccount(e),
44
42
  ownable::Error::InvalidOwner(e) => Error::InvalidOwner(e),
45
43
  }
46
44
  }
@@ -103,14 +101,15 @@ impl YourContract {
103
101
  pub fn set_greeting(&mut self, new_greeting: String) {
104
102
  // Change state variables
105
103
  self.greeting.set_str(&new_greeting);
106
-
104
+
107
105
  // Increment counters
108
106
  let current_total = self.total_counter.get();
109
107
  self.total_counter.set(current_total + U256::from(1));
110
-
108
+
111
109
  let sender: Address = self.vm().msg_sender();
112
110
  let current_user_count = self.user_greeting_counter.get(sender);
113
- self.user_greeting_counter.insert(sender, current_user_count + U256::from(1));
111
+ self.user_greeting_counter
112
+ .insert(sender, current_user_count + U256::from(1));
114
113
 
115
114
  // Set premium based on msg.value
116
115
  let msg_value = self.vm().msg_value();
@@ -118,13 +117,15 @@ impl YourContract {
118
117
  self.premium.set(is_premium);
119
118
 
120
119
  // Emit the event
121
- log(self.vm(),
120
+ log(
121
+ self.vm(),
122
122
  GreetingChange {
123
- greetingSetter: sender,
124
- newGreeting: new_greeting,
125
- premium: is_premium,
126
- value: msg_value,
127
- });
123
+ greetingSetter: sender,
124
+ newGreeting: new_greeting,
125
+ premium: is_premium,
126
+ value: msg_value,
127
+ },
128
+ );
128
129
  }
129
130
 
130
131
  /// Function that allows the owner to withdraw all the Ether in the contract
@@ -139,7 +140,7 @@ impl YourContract {
139
140
  let owner = self.ownable.owner();
140
141
  let _ = self.vm().transfer_eth(owner, balance);
141
142
  }
142
-
143
+
143
144
  Ok(())
144
145
  }
145
146
 
@@ -160,10 +161,7 @@ impl IOwnable for YourContract {
160
161
  self.ownable.owner()
161
162
  }
162
163
 
163
- fn transfer_ownership(
164
- &mut self,
165
- new_owner: Address,
166
- ) -> Result<(), Self::Error> {
164
+ fn transfer_ownership(&mut self, new_owner: Address) -> Result<(), Self::Error> {
167
165
  Ok(self.ownable.transfer_ownership(new_owner)?)
168
166
  }
169
167
 
@@ -181,11 +179,11 @@ impl IOwnable for YourContract {
181
179
  // fn test_your_contract() {
182
180
  // let vm = TestVM::default();
183
181
  // let mut contract = YourContract::from(&vm);
184
-
182
+
185
183
  // // Test initialization
186
184
  // let owner_addr = Address::from([1u8; 20]);
187
185
  // contract.init(owner_addr);
188
-
186
+
189
187
  // assert_eq!(contract.owner(), owner_addr);
190
188
  // assert_eq!(contract.greeting(), "Building Unstoppable Apps!!!");
191
189
  // assert_eq!(contract.premium(), false);
@@ -214,7 +212,7 @@ impl IOwnable for YourContract {
214
212
  // fn test_withdraw() {
215
213
  // let vm = TestVM::default();
216
214
  // let mut contract = YourContract::from(&vm);
217
-
215
+
218
216
  // // Initialize with owner
219
217
  // let owner_addr = vm.addr(); // Use VM address as owner for testing
220
218
  // contract.init(owner_addr);
@@ -228,7 +226,7 @@ impl IOwnable for YourContract {
228
226
  // fn test_withdraw_not_owner() {
229
227
  // let vm = TestVM::default();
230
228
  // let mut contract = YourContract::from(&vm);
231
-
229
+
232
230
  // // Initialize with different owner
233
231
  // let owner_addr = Address::from([1u8; 20]);
234
232
  // contract.init(owner_addr);
@@ -21,8 +21,8 @@
21
21
 
22
22
  Before you begin, you need to install the following tools:
23
23
 
24
- - [Node (>= v18.17)](https://nodejs.org/en/download/)
25
- - Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
24
+ - [Node (>= v20.18)](https://nodejs.org/en/download/)
25
+ - Yarn ([v2+](https://yarnpkg.com/getting-started/install))
26
26
  - [Git](https://git-scm.com/downloads)
27
27
  - [Rust](https://www.rust-lang.org/tools/install)
28
28
  - [Docker](https://docs.docker.com/engine/install/)
@@ -208,7 +208,9 @@ yarn deploy --network <network>
208
208
  - **Always keep your private key secure and never commit it to version control**
209
209
  - Consider using environment variable management tools for production deployments
210
210
 
211
- ## Verify your contract
211
+ ## Verify your contract (Highly Experimental)
212
+
213
+ <details>
212
214
 
213
215
  #### Prerequisites
214
216
 
@@ -219,7 +221,9 @@ Your contract must meet Arbiscan's verification requirements:
219
221
  - No custom optimization settings
220
222
  - No specific compiler version requirements
221
223
 
222
- ### Local Verification
224
+ Check full documentation for more [details](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts-arbiscan#step-4-set-evm-version)
225
+
226
+ ### Stylus Local Verification (Under Development)
223
227
 
224
228
  Make sure your constructor does not contain any args
225
229
 
@@ -243,6 +247,8 @@ This runs `cargo stylus verify` locally after deployment, which:
243
247
  - Ensures reproducibility across different environments
244
248
  - Validates the deployment transaction
245
249
 
250
+ **Note:** This feature is still under development and may not work as expected. Check full documentation for more [details](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts)
251
+
246
252
  ### Arbiscan Verification
247
253
 
248
254
  For public verification on Arbiscan, follow these steps:
@@ -259,11 +265,13 @@ For public verification on Arbiscan, follow these steps:
259
265
  - Provide any constructor arguments if applicable
260
266
  - Submit for verification
261
267
 
262
- Check official document for detail instructions: https://docs.arbitrum.io/stylus/how-tos/verifying-contracts-arbiscan
268
+ Check official document for detail instructions: <https://docs.arbitrum.io/stylus/how-tos/verifying-contracts-arbiscan>
263
269
 
264
270
  > **Note**: Arbiscan verification for Stylus contracts is still evolving. If you encounter issues, consider using the local verification method or check Arbiscan's latest documentation for Stylus-specific instructions.
265
271
 
266
- ### 🛠️ Troubleshooting Common Issues
272
+ </details>
273
+
274
+ ## 🛠️ Troubleshooting Common Issues
267
275
 
268
276
  #### 1. `stylus` Not Recognized
269
277
 
@@ -286,9 +294,11 @@ If the version is displayed, `stylus` has been successfully installed and the pa
286
294
  If you face issues with the ABI not being generated, you can try one of the following solutions:
287
295
 
288
296
  - **Restart Docker Node**: Pause and restart the Docker node and the local setup of the project. You can do this by deleting all ongoing running containers and then restarting the local terminal using:
297
+
289
298
  ```bash
290
299
  yarn run dev
291
300
  ```
301
+
292
302
  - **Modify the Script**: In the `run-dev-node.sh` script, replace the line:
293
303
 
294
304
  ```bash
@@ -302,6 +312,7 @@ If you face issues with the ABI not being generated, you can try one of the foll
302
312
  ```
303
313
 
304
314
  - **Access Denied Issue**: If you encounter an access denied permission error during ABI generation, run the following command and then execute the script again:
315
+
305
316
  ```bash
306
317
  sudo chown -R $USER:$USER target
307
318
  ```
@@ -333,6 +344,7 @@ Shell scripts created in Windows often have `CRLF` line endings, which cause iss
333
344
  ```
334
345
 
335
346
  4. Run the Script in WSL:
347
+
336
348
  ```bash
337
349
  bash run-dev-node.sh
338
350
  ```