create-stylus 0.1.5 → 0.1.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 (36) hide show
  1. package/dist/cli.js +7 -8
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +1 -1
  4. package/src/main.ts +2 -4
  5. package/src/tasks/copy-template-files.ts +7 -4
  6. package/src/utils/prompt-for-missing-options.ts +1 -1
  7. package/templates/base/package.json +1 -1
  8. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +2 -2
  9. package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx +8 -4
  10. package/templates/base/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +1 -9
  11. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +138 -24
  12. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/RevealBurnerPKModal.tsx +59 -0
  13. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +3 -2
  14. package/templates/base/packages/nextjs/contracts/deployedContracts.ts +117 -1
  15. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldEventHistory.ts +107 -28
  16. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts +5 -1
  17. package/templates/base/packages/nextjs/hooks/scaffold-eth/useTransactor.tsx +7 -5
  18. package/templates/base/packages/nextjs/icons/LightBugAntIcon.tsx +7 -7
  19. package/templates/base/packages/nextjs/package.json +4 -5
  20. package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +1 -0
  21. package/templates/base/packages/nextjs/styles/globals.css +28 -22
  22. package/templates/base/packages/nextjs/tailwind.config.js +1 -1
  23. package/templates/base/packages/nextjs/utils/scaffold-eth/contract.ts +74 -2
  24. package/templates/base/packages/stylus/scripts/deploy.ts +0 -8
  25. package/templates/base/packages/stylus/your-contract/Cargo.lock +4 -4
  26. package/templates/base/packages/stylus/your-contract/Cargo.toml +1 -1
  27. package/templates/base/packages/stylus/your-contract/src/lib.rs +3 -7
  28. package/templates/base/readme.md +55 -169
  29. package/templates/base/yarn.lock +239 -297
  30. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AngularWalletAddress.tsx +0 -223
  31. package/templates/base/packages/stylus/counter/.cargo/config.toml +0 -18
  32. package/templates/base/packages/stylus/counter/Cargo.lock +0 -5788
  33. package/templates/base/packages/stylus/counter/Cargo.toml +0 -46
  34. package/templates/base/packages/stylus/counter/rust-toolchain.toml +0 -2
  35. package/templates/base/packages/stylus/counter/src/lib.rs +0 -121
  36. package/templates/base/packages/stylus/counter/src/main.rs +0 -10
@@ -23,6 +23,8 @@ import {
23
23
  Log,
24
24
  TransactionReceipt,
25
25
  WriteContractErrorType,
26
+ keccak256,
27
+ toHex,
26
28
  } from "viem";
27
29
  import { Config, UseReadContractParameters, UseWatchContractEventParameters, UseWriteContractParameters } from "wagmi";
28
30
  import { WriteContractParameters, WriteContractReturnType, simulateContract } from "wagmi/actions";
@@ -292,7 +294,7 @@ export type UseScaffoldEventHistoryConfig<
292
294
  > = {
293
295
  contractName: TContractName;
294
296
  eventName: IsContractDeclarationMissing<string, TEventName>;
295
- fromBlock: bigint;
297
+ fromBlock?: bigint;
296
298
  toBlock?: bigint;
297
299
  chainId?: AllowedChainIds;
298
300
  filters?: EventFilters<TContractName, TEventName>;
@@ -335,17 +337,87 @@ export type UseScaffoldEventHistoryData<
335
337
 
336
338
  export type AbiParameterTuple = Extract<AbiParameter, { type: "tuple" | `tuple[${string}]` }>;
337
339
 
340
+ /**
341
+ * Enhanced error parsing that creates a lookup table from all deployed contracts
342
+ * to decode error signatures from any contract in the system
343
+ */
344
+ export const getParsedErrorWithAllAbis = (error: any, chainId: AllowedChainIds): string => {
345
+ const originalParsedError = getParsedError(error);
346
+
347
+ // Check if this is an unrecognized error signature
348
+ if (/Encoded error signature.*not found on ABI/i.test(originalParsedError)) {
349
+ const signatureMatch = originalParsedError.match(/0x[a-fA-F0-9]{8}/);
350
+ const signature = signatureMatch ? signatureMatch[0] : "";
351
+
352
+ if (!signature) {
353
+ return originalParsedError;
354
+ }
355
+
356
+ try {
357
+ // Get all deployed contracts for the current chain
358
+ const chainContracts = (deployedContractsData as GenericContractsDeclaration)[chainId];
359
+
360
+ if (!chainContracts) {
361
+ return originalParsedError;
362
+ }
363
+
364
+ // Build a lookup table of error signatures to error names
365
+ const errorLookup: Record<string, { name: string; contract: string; signature: string }> = {};
366
+
367
+ Object.entries(chainContracts).forEach(([contractName, contract]: [string, any]) => {
368
+ if (contract.abi) {
369
+ contract.abi.forEach((item: any) => {
370
+ if (item.type === "error") {
371
+ // Create the proper error signature like Solidity does
372
+ const errorName = item.name;
373
+ const inputs = item.inputs || [];
374
+ const inputTypes = inputs.map((input: any) => input.type).join(",");
375
+ const errorSignature = `${errorName}(${inputTypes})`;
376
+
377
+ // Hash the signature and take the first 4 bytes (8 hex chars)
378
+ const hash = keccak256(toHex(errorSignature));
379
+ const errorSelector = hash.slice(0, 10); // 0x + 8 chars = 10 total
380
+
381
+ errorLookup[errorSelector] = {
382
+ name: errorName,
383
+ contract: contractName,
384
+ signature: errorSignature,
385
+ };
386
+ }
387
+ });
388
+ }
389
+ });
390
+
391
+ // Check if we can find the error in our lookup
392
+ const errorInfo = errorLookup[signature];
393
+ if (errorInfo) {
394
+ return `Contract function execution reverted with the following reason:\n${errorInfo.signature} from ${errorInfo.contract} contract`;
395
+ }
396
+
397
+ // If not found in simple lookup, provide a helpful message with context
398
+ return `${originalParsedError}\n\nThis error occurred when calling a function that internally calls another contract. Check the contract that your function calls internally for more details.`;
399
+ } catch (lookupError) {
400
+ console.log("Failed to create error lookup table:", lookupError);
401
+ }
402
+ }
403
+
404
+ return originalParsedError;
405
+ };
406
+
338
407
  export const simulateContractWriteAndNotifyError = async ({
339
408
  wagmiConfig,
340
409
  writeContractParams: params,
410
+ chainId,
341
411
  }: {
342
412
  wagmiConfig: Config;
343
413
  writeContractParams: WriteContractVariables<Abi, string, any[], Config, number>;
414
+ chainId: AllowedChainIds;
344
415
  }) => {
345
416
  try {
346
417
  await simulateContract(wagmiConfig, params);
347
418
  } catch (error) {
348
- const parsedError = getParsedError(error);
419
+ const parsedError = getParsedErrorWithAllAbis(error, chainId);
420
+
349
421
  notification.error(parsedError);
350
422
  throw error;
351
423
  }
@@ -36,14 +36,6 @@ export default async function deployScript(deployOptions: DeployOptions) {
36
36
  ...deployOptions,
37
37
  });
38
38
 
39
- // EXAMPLE: Deploy to Orbit Chains, uncomment to try
40
- // await deployStylusContract({
41
- // contract: "counter",
42
- // constructorArgs: [100],
43
- // isOrbit: true,
44
- // ...deployOptions,
45
- // });
46
-
47
39
  // EXAMPLE: Deploy your contract with a custom name, uncomment to try
48
40
  // await deployStylusContract({
49
41
  // contract: "your-contract",
@@ -3066,9 +3066,9 @@ dependencies = [
3066
3066
 
3067
3067
  [[package]]
3068
3068
  name = "openzeppelin-stylus"
3069
- version = "0.2.0"
3069
+ version = "0.3.0"
3070
3070
  source = "registry+https://github.com/rust-lang/crates.io-index"
3071
- checksum = "4a5bdc0165c9dd0628a88cbeb8c059b59fdb301156364c6759d838cbd4a581a2"
3071
+ checksum = "cef3971d2d38f992397ed222826d213489f19a4b1936ac482fb5fa23926a4fd4"
3072
3072
  dependencies = [
3073
3073
  "alloy-primitives",
3074
3074
  "alloy-sol-macro",
@@ -3082,9 +3082,9 @@ dependencies = [
3082
3082
 
3083
3083
  [[package]]
3084
3084
  name = "openzeppelin-stylus-proc"
3085
- version = "0.2.2"
3085
+ version = "0.3.0"
3086
3086
  source = "registry+https://github.com/rust-lang/crates.io-index"
3087
- checksum = "f592a114a2f3bbfb29303435064b4444ea3d9c4283b667f551a8543e8da8896f"
3087
+ checksum = "e070fcdfd2bc4cd6dcd32d61797467439277d7cc8e7eea73dd42c7ccd22b0e1d"
3088
3088
  dependencies = [
3089
3089
  "convert_case",
3090
3090
  "proc-macro2",
@@ -13,7 +13,7 @@ alloy-primitives = "=0.8.20"
13
13
  alloy-sol-types = "=0.8.20"
14
14
  stylus-sdk = "0.9.0"
15
15
  hex = { version = "0.4", default-features = false }
16
- openzeppelin-stylus = "=0.2.0"
16
+ openzeppelin-stylus = "0.3.0"
17
17
 
18
18
  [dev-dependencies]
19
19
  alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
@@ -64,15 +64,13 @@ sol_storage! {
64
64
 
65
65
  /// Declare that `YourContract` is a contract with the following external methods.
66
66
  #[public]
67
- #[implements(IOwnable<Error = Error>)]
67
+ #[implements(IOwnable)]
68
68
  impl YourContract {
69
69
  #[constructor]
70
70
  pub fn constructor(&mut self, initial_owner: Address) -> Result<(), Error> {
71
71
  // Initialize Ownable with the initial owner using OpenZeppelin pattern
72
72
  self.ownable.constructor(initial_owner)?;
73
73
  self.greeting.set_str("Building Unstoppable Apps!!!");
74
- self.premium.set(false);
75
- self.total_counter.set(U256::ZERO);
76
74
  Ok(())
77
75
  }
78
76
 
@@ -155,17 +153,15 @@ impl YourContract {
155
153
  /// Implementation of the IOwnable interface
156
154
  #[public]
157
155
  impl IOwnable for YourContract {
158
- type Error = Error;
159
-
160
156
  fn owner(&self) -> Address {
161
157
  self.ownable.owner()
162
158
  }
163
159
 
164
- fn transfer_ownership(&mut self, new_owner: Address) -> Result<(), Self::Error> {
160
+ fn transfer_ownership(&mut self, new_owner: Address) -> Result<(), Vec<u8>> {
165
161
  Ok(self.ownable.transfer_ownership(new_owner)?)
166
162
  }
167
163
 
168
- fn renounce_ownership(&mut self) -> Result<(), Self::Error> {
164
+ fn renounce_ownership(&mut self) -> Result<(), Vec<u8>> {
169
165
  Ok(self.ownable.renounce_ownership()?)
170
166
  }
171
167
  }
@@ -24,7 +24,6 @@ Before you begin, you need to install the following tools:
24
24
  - [Node (>= v20.18)](https://nodejs.org/en/download/)
25
25
  - Yarn ([v2+](https://yarnpkg.com/getting-started/install))
26
26
  - [Git](https://git-scm.com/downloads)
27
- - [Rust](https://www.rust-lang.org/tools/install)
28
27
  - [Docker](https://docs.docker.com/engine/install/)
29
28
  - [Foundry Cast](https://getfoundry.sh/)
30
29
 
@@ -32,19 +31,30 @@ Before you begin, you need to install the following tools:
32
31
 
33
32
  To get started with Scaffold-Stylus, follow the steps below:
34
33
 
35
- ### 1. Clone this repo & install dependencies
34
+ ### 1. Install Stylus tools (or use stylusup)
35
+
36
+ If you prefer a one-liner, install via stylusup (recommended):
37
+
38
+ Tool for installing all the Stylus essentials for development. [Stylusup](https://stylusup.sh/#) will install the latest stable versions of:
39
+
40
+ - [Rust](https://www.rust-lang.org/tools/install) (if not present) to provide the core programming environment.
41
+ - [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus/blob/main/README.md) (latest version) a tool for creating and managing Stylus projects.
42
+ - Adding WebAssembly support to compile Rust code for blockchain environments.
43
+ - Optionally collecting and sending telemetry data to track installation statistics.
36
44
 
37
45
  ```bash
38
- git clone https://github.com/Arb-Stylus/scaffold-stylus.git
39
- cd scaffold-stylus
40
- yarn install
41
- # Initialize submodules (required for Nitro dev node)
42
- git submodule update --init --recursive
46
+ curl -s https://stylusup.sh/install.sh | sh
47
+ ```
48
+
49
+ ### Alternatively, install Rust and the Stylus CLI tool with Cargo:
50
+
51
+ ```bash
52
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
43
53
  ```
44
54
 
45
- ### 2. Install Stylus tools
55
+ Check the [Rust installation guide](https://www.rust-lang.org/tools/install) for more information.
46
56
 
47
- Install [Rust](https://www.rust-lang.org/tools/install), and then install the Stylus CLI tool with Cargo:
57
+ Then install the Stylus CLI tools:
48
58
 
49
59
  ```bash
50
60
  cargo install --force cargo-stylus cargo-stylus-check
@@ -58,8 +68,8 @@ cargo install --force cargo-stylus cargo-stylus-check
58
68
  Set default `toolchain` match `rust-toolchain.toml` and add the `wasm32-unknown-unknown` build target to your Rust compiler:
59
69
 
60
70
  ```bash
61
- rustup default 1.87
62
- rustup target add wasm32-unknown-unknown --toolchain 1.87
71
+ rustup default 1.89
72
+ rustup target add wasm32-unknown-unknown --toolchain 1.89
63
73
  ```
64
74
 
65
75
  You should now have it available as a Cargo subcommand:
@@ -68,7 +78,34 @@ You should now have it available as a Cargo subcommand:
68
78
  cargo stylus --help
69
79
  ```
70
80
 
71
- ### 3. Run a local network
81
+ ### 2. Create a new project (recommended)
82
+
83
+ Use the interactive setup to scaffold a new project:
84
+
85
+ ```bash
86
+ npx create-stylus@latest
87
+ ```
88
+
89
+ Then navigate into your project directory:
90
+
91
+ ```bash
92
+ cd <project-name>
93
+ yarn install
94
+ # Initialize submodules (required for Nitro dev node)
95
+ git submodule update --init --recursive
96
+ ```
97
+
98
+ ### 3. Clone this repo & install dependencies (alternative)
99
+
100
+ ```bash
101
+ git clone https://github.com/Arb-Stylus/scaffold-stylus.git
102
+ cd scaffold-stylus
103
+ yarn install
104
+ # Initialize submodules (required for Nitro dev node)
105
+ git submodule update --init --recursive
106
+ ```
107
+
108
+ ### 4. Run a local network
72
109
 
73
110
  In your first terminal:
74
111
 
@@ -78,7 +115,7 @@ yarn chain
78
115
 
79
116
  This command starts a local Stylus-compatible network using the Nitro dev node script (`./nitro-devnode/run-dev-node.sh`). The network runs on your local machine and can be used for testing and development. You can customize the Nitro dev node configuration in the `nitro-devnode` submodule.
80
117
 
81
- ### 4. Deploy the test contract
118
+ ### 5. Deploy the test contract
82
119
 
83
120
  In your second terminal:
84
121
 
@@ -88,7 +125,7 @@ yarn deploy
88
125
 
89
126
  This command deploys a test smart contract to the local network. The contract is located in `packages/stylus/your-contract/src` and can be modified to suit your needs. The `yarn deploy` command uses the deploy script located in `packages/stylus/scripts` to deploy the contract to the network. You can also customize the deploy script .
90
127
 
91
- ### 5. Start your NextJS app
128
+ ### 6. Start your NextJS app
92
129
 
93
130
  In your third terminal:
94
131
 
@@ -98,7 +135,7 @@ yarn start
98
135
 
99
136
  Visit your app at: `http://localhost:3000`. You can interact with your smart contract using the **Debug Contracts** page, which provides a user-friendly interface for testing your contract's functions and viewing its state.
100
137
 
101
- ### 6. Test your smart contract
138
+ ### 7. Test your smart contract
102
139
 
103
140
  ```bash
104
141
  yarn stylus:test
@@ -179,7 +216,7 @@ To deploy your contracts to other networks (other than the default local Nitro d
179
216
  Open `packages/nextjs/scaffold.config.ts` and update the `targetNetworks` array to include your target chain. This ensures your frontend connects to the correct network and generates the proper ABI in `deployedContracts.ts`:
180
217
 
181
218
  ```ts
182
- import * as chains from "viem/chains";
219
+ import * as chains from "./utils/scaffold-stylus/supportedChains";
183
220
  // ...
184
221
  targetNetworks: [chains.arbitrumSepolia],
185
222
  ```
@@ -218,162 +255,11 @@ Your contract must have an `initialize()` function as the replacement for the co
218
255
 
219
256
  ## Verify your contract (Highly Experimental)
220
257
 
221
- <details>
222
-
223
- #### Prerequisites
224
-
225
- Your contract must meet Arbiscan's verification requirements:
226
-
227
- - No external libraries
228
- - No constructor arguments
229
- - No custom optimization settings
230
- - No specific compiler version requirements
231
-
232
- Check full documentation for more [details](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts-arbiscan#step-4-set-evm-version)
233
-
234
- ### Stylus Local Verification (Under Development)
235
-
236
- Make sure your contract does not include constructor or constructor does not contain any args
237
-
238
- ```rs
239
- [#constructor]
240
- pub fn constructor(&mut self)
241
- ```
242
-
243
- The scaffold includes built-in local verification to ensure your Stylus contract deployments are reproducible. To enable verification during deployment, set `verify: true` in your deployment script:
244
-
245
- ```ts
246
- await deployStylusContract({
247
- contract: "your-contract",
248
- verify: true,
249
- ...deployOptions,
250
- });
251
- ```
252
-
253
- This runs `cargo stylus verify` locally after deployment, which:
254
-
255
- - Verifies that the deployed bytecode matches your source code
256
- - Ensures reproducibility across different environments
257
- - Validates the deployment transaction
258
-
259
- **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)
260
-
261
- ### Arbiscan Verification
262
-
263
- For public verification on Arbiscan, follow these steps:
264
-
265
- #### Steps
266
-
267
- 1. **Create a dedicated repository** containing only your contract source code
268
- 2. **Navigate to Arbiscan**:
269
- - Go to [Arbiscan Verify Contract](https://arbiscan.io/verifyContract)
270
- - Enter your deployed contract address
271
- 3. **Follow the verification process**:
272
- - Select "Solidity (Standard-Json-Input)" as the compiler type
273
- - Enter your contract source code (github link)
274
- - Provide any constructor arguments if applicable
275
- - Submit for verification
276
-
277
- Check official document for detail instructions: <https://docs.arbitrum.io/stylus/how-tos/verifying-contracts-arbiscan>
278
-
279
- > **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.
280
-
281
- **Tip**: If you still want to initialize your contract, then add your own `initialize()` function and initialize it yourself
282
- Sample :
283
-
284
- ```
285
- pub fn initialize(&mut self, initial_number: U256) {
286
- if !self.is_initialized.get() {
287
- self.number.set(initial_number);
288
- self.is_initialized.set(true);
289
- } else {
290
- panic!("Counter already initialized");
291
- }
292
- }
293
- ```
294
-
295
- Then use `cast --rpc-url <your-rpc-url> --private-key <your-private-key> [deployed-contract-address] "initialize(uint256)" <initial_number>`
296
- Or check [`deploy_contract.ts` lines 95-118](packages/stylus/scripts/deploy_contract.ts#L95-L118) and add it to your `deploy.ts` script.
297
-
298
- </details>
258
+ Visit our [Verify section](https://arb-stylus.github.io/scaffold-stylus-docs/recipes/verify-contract-custom-chain)
299
259
 
300
260
  ## 🛠️ Troubleshooting Common Issues
301
261
 
302
- #### 1. `stylus` Not Recognized
303
-
304
- If you encounter an error stating that `stylus` is not recognized as an external or internal command, run the following command in your terminal:
305
-
306
- ```bash
307
- sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev
308
- ```
309
-
310
- After that, check if `stylus` is installed by running:
311
-
312
- ```bash
313
- cargo stylus --version
314
- ```
315
-
316
- If the version is displayed, `stylus` has been successfully installed and the path is correctly set.
317
-
318
- #### 2. ABI Not Generated
319
-
320
- If you face issues with the ABI not being generated, you can try one of the following solutions:
321
-
322
- - **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:
323
-
324
- ```bash
325
- yarn run dev
326
- ```
327
-
328
- - **Modify the Script**: In the `run-dev-node.sh` script, replace the line:
329
-
330
- ```bash
331
- cargo stylus export-abi
332
- ```
333
-
334
- with:
335
-
336
- ```bash
337
- cargo run --manifest-path=Cargo.toml --features export-abi
338
- ```
339
-
340
- - **Access Denied Issue**: If you encounter an access denied permission error during ABI generation, run the following command and then execute the script again:
341
-
342
- ```bash
343
- sudo chown -R $USER:$USER target
344
- ```
345
-
346
- #### 3. 🚨 Fixing Line Endings and Running Shell Scripts in WSL
347
-
348
- > ⚠️ This guide provides step-by-step instructions to resolve the Command not found error caused by CRLF line endings in shell scripts when running in a WSL environment.
349
-
350
- Shell scripts created in Windows often have `CRLF` line endings, which cause issues in Unix-like environments such as WSL. To fix this:
351
-
352
- **Using `dos2unix`:**
353
-
354
- 1. Install `dos2unix` (if not already installed):
355
-
356
- ```bash
357
- sudo apt install dos2unix
358
- ```
359
-
360
- 2. Convert the script's line endings:
361
-
362
- ```bash
363
- dos2unix run-dev-node.sh
364
- ```
365
-
366
- 3. Make the Script Executable:
367
-
368
- ```bash
369
- chmod +x run-dev-node.sh
370
- ```
371
-
372
- 4. Run the Script in WSL:
373
-
374
- ```bash
375
- bash run-dev-node.sh
376
- ```
262
+ Visit our [Troubleshooting section](https://arb-stylus.github.io/scaffold-stylus-docs/quick-start/troubleshooting)
377
263
 
378
264
  ---
379
265