create-stylus 1.1.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.
Files changed (222) hide show
  1. package/.github/issue_template.md +7 -0
  2. package/.github/pull_request_template.md +11 -0
  3. package/.github/workflows/release-alpha.yml +32 -0
  4. package/.yarnrc.yml +1 -0
  5. package/CONTRIBUTING.md +42 -0
  6. package/README.md +66 -0
  7. package/bin/create-dapp-ss.js +4 -0
  8. package/dist/cli.js +656 -0
  9. package/dist/cli.js.map +1 -0
  10. package/package.json +46 -0
  11. package/rollup.config.js +22 -0
  12. package/src/cli.ts +14 -0
  13. package/src/extensions.json +14 -0
  14. package/src/main.ts +70 -0
  15. package/src/tasks/copy-extension-file.ts +227 -0
  16. package/src/tasks/copy-template-files.ts +252 -0
  17. package/src/tasks/create-first-git-commit.ts +35 -0
  18. package/src/tasks/create-project-directory.ts +34 -0
  19. package/src/tasks/index.ts +5 -0
  20. package/src/tasks/install-packages.ts +15 -0
  21. package/src/tasks/prettier-format.ts +17 -0
  22. package/src/types.ts +31 -0
  23. package/src/utils/consts.ts +1 -0
  24. package/src/utils/find-files-recursively.ts +19 -0
  25. package/src/utils/link.ts +44 -0
  26. package/src/utils/load-extensions.ts +10 -0
  27. package/src/utils/merge-package-json.ts +33 -0
  28. package/src/utils/parse-arguments-into-options.ts +38 -0
  29. package/src/utils/prompt-for-missing-options.ts +53 -0
  30. package/src/utils/render-intro-message.ts +11 -0
  31. package/src/utils/render-outro-message.ts +34 -0
  32. package/templates/base/.github/ISSUE_TEMPLATE/bug_report.yml +58 -0
  33. package/templates/base/.github/ISSUE_TEMPLATE/config.yml +8 -0
  34. package/templates/base/.github/pull_request_template.md +16 -0
  35. package/templates/base/.github/workflows/lint.yaml +300 -0
  36. package/templates/base/.gitignore.template.mjs +19 -0
  37. package/templates/base/.gitmodules +0 -0
  38. package/templates/base/.husky/pre-commit +4 -0
  39. package/templates/base/.lintstagedrc.js +21 -0
  40. package/templates/base/.vscode/settings.json +7 -0
  41. package/templates/base/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
  42. package/templates/base/.yarn/releases/yarn-3.2.3.cjs +783 -0
  43. package/templates/base/.yarnrc.yml +11 -0
  44. package/templates/base/CONTRIBUTING.md +86 -0
  45. package/templates/base/LICENCE +21 -0
  46. package/templates/base/nitro-devnode/LICENSE +201 -0
  47. package/templates/base/nitro-devnode/README.md +70 -0
  48. package/templates/base/nitro-devnode/run-dev-node.sh +132 -0
  49. package/templates/base/nitro-devnode/start-chain-with-cors.sh +150 -0
  50. package/templates/base/nitro-devnode/stylus-deployer-bytecode.txt +1 -0
  51. package/templates/base/nitro-devnode/stylus-dev/Dockerfile +10 -0
  52. package/templates/base/package.json +43 -0
  53. package/templates/base/packages/nextjs/.env.example +13 -0
  54. package/templates/base/packages/nextjs/.eslintignore +11 -0
  55. package/templates/base/packages/nextjs/.eslintrc.json +15 -0
  56. package/templates/base/packages/nextjs/.gitignore.template.mjs +42 -0
  57. package/templates/base/packages/nextjs/.prettierrc.js +9 -0
  58. package/templates/base/packages/nextjs/.prettierrc.json +8 -0
  59. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressCodeTab.tsx +27 -0
  60. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressComponent.tsx +36 -0
  61. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressLogsTab.tsx +21 -0
  62. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressStorageTab.tsx +61 -0
  63. package/templates/base/packages/nextjs/app/blockexplorer/_components/BackButton.tsx +12 -0
  64. package/templates/base/packages/nextjs/app/blockexplorer/_components/ContractTabs.tsx +102 -0
  65. package/templates/base/packages/nextjs/app/blockexplorer/_components/PaginationButton.tsx +39 -0
  66. package/templates/base/packages/nextjs/app/blockexplorer/_components/SearchBar.tsx +49 -0
  67. package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionHash.tsx +28 -0
  68. package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionsTable.tsx +71 -0
  69. package/templates/base/packages/nextjs/app/blockexplorer/_components/index.tsx +7 -0
  70. package/templates/base/packages/nextjs/app/blockexplorer/address/[address]/page.tsx +101 -0
  71. package/templates/base/packages/nextjs/app/blockexplorer/layout.tsx +12 -0
  72. package/templates/base/packages/nextjs/app/blockexplorer/page.tsx +83 -0
  73. package/templates/base/packages/nextjs/app/blockexplorer/transaction/[txHash]/page.tsx +23 -0
  74. package/templates/base/packages/nextjs/app/blockexplorer/transaction/_components/TransactionComp.tsx +152 -0
  75. package/templates/base/packages/nextjs/app/debug/_components/DebugContracts.tsx +73 -0
  76. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractInput.tsx +84 -0
  77. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractReadMethods.tsx +43 -0
  78. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +164 -0
  79. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractVariables.tsx +50 -0
  80. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractWriteMethods.tsx +49 -0
  81. package/templates/base/packages/nextjs/app/debug/_components/contract/DisplayVariable.tsx +85 -0
  82. package/templates/base/packages/nextjs/app/debug/_components/contract/InheritanceTooltip.tsx +14 -0
  83. package/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx +102 -0
  84. package/templates/base/packages/nextjs/app/debug/_components/contract/Tuple.tsx +44 -0
  85. package/templates/base/packages/nextjs/app/debug/_components/contract/TupleArray.tsx +142 -0
  86. package/templates/base/packages/nextjs/app/debug/_components/contract/TxReceipt.tsx +42 -0
  87. package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx +144 -0
  88. package/templates/base/packages/nextjs/app/debug/_components/contract/index.tsx +8 -0
  89. package/templates/base/packages/nextjs/app/debug/_components/contract/utilsContract.tsx +166 -0
  90. package/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx +114 -0
  91. package/templates/base/packages/nextjs/app/debug/page.tsx +14 -0
  92. package/templates/base/packages/nextjs/app/layout.tsx +67 -0
  93. package/templates/base/packages/nextjs/app/not-found.tsx +16 -0
  94. package/templates/base/packages/nextjs/app/page.tsx +94 -0
  95. package/templates/base/packages/nextjs/components/Background.tsx +37 -0
  96. package/templates/base/packages/nextjs/components/Card.tsx +40 -0
  97. package/templates/base/packages/nextjs/components/Footer.tsx +93 -0
  98. package/templates/base/packages/nextjs/components/Header.tsx +114 -0
  99. package/templates/base/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +77 -0
  100. package/templates/base/packages/nextjs/components/SwitchTheme.tsx +41 -0
  101. package/templates/base/packages/nextjs/components/ThemeProvider.tsx +13 -0
  102. package/templates/base/packages/nextjs/components/assets/BuidlGuidlLogo.tsx +18 -0
  103. package/templates/base/packages/nextjs/components/scaffold-eth/Address/Address.tsx +187 -0
  104. package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressCopyIcon.tsx +23 -0
  105. package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressLinkWrapper.tsx +29 -0
  106. package/templates/base/packages/nextjs/components/scaffold-eth/Balance.tsx +75 -0
  107. package/templates/base/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx +17 -0
  108. package/templates/base/packages/nextjs/components/scaffold-eth/Faucet.tsx +131 -0
  109. package/templates/base/packages/nextjs/components/scaffold-eth/FaucetButton.tsx +75 -0
  110. package/templates/base/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +120 -0
  111. package/templates/base/packages/nextjs/components/scaffold-eth/Input/Bytes32Input.tsx +31 -0
  112. package/templates/base/packages/nextjs/components/scaffold-eth/Input/BytesInput.tsx +28 -0
  113. package/templates/base/packages/nextjs/components/scaffold-eth/Input/EtherInput.tsx +128 -0
  114. package/templates/base/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx +66 -0
  115. package/templates/base/packages/nextjs/components/scaffold-eth/Input/IntegerInput.tsx +63 -0
  116. package/templates/base/packages/nextjs/components/scaffold-eth/Input/index.ts +9 -0
  117. package/templates/base/packages/nextjs/components/scaffold-eth/Input/utils.ts +109 -0
  118. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +121 -0
  119. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressQRCodeModal.tsx +33 -0
  120. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/BurnerWalletModal.tsx +63 -0
  121. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/NetworkOptions.tsx +48 -0
  122. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/WrongNetworkDropdown.tsx +32 -0
  123. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +89 -0
  124. package/templates/base/packages/nextjs/components/scaffold-eth/index.tsx +7 -0
  125. package/templates/base/packages/nextjs/contracts/deployedContracts.ts +9 -0
  126. package/templates/base/packages/nextjs/contracts/externalContracts.ts +16 -0
  127. package/templates/base/packages/nextjs/eslint.config.mjs +32 -0
  128. package/templates/base/packages/nextjs/hooks/scaffold-eth/index.ts +17 -0
  129. package/templates/base/packages/nextjs/hooks/scaffold-eth/useAnimationConfig.ts +20 -0
  130. package/templates/base/packages/nextjs/hooks/scaffold-eth/useContractLogs.ts +40 -0
  131. package/templates/base/packages/nextjs/hooks/scaffold-eth/useCopyToClipboard.ts +19 -0
  132. package/templates/base/packages/nextjs/hooks/scaffold-eth/useDeployedContractInfo.ts +86 -0
  133. package/templates/base/packages/nextjs/hooks/scaffold-eth/useDisplayUsdMode.ts +21 -0
  134. package/templates/base/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts +133 -0
  135. package/templates/base/packages/nextjs/hooks/scaffold-eth/useInitializeNativeCurrencyPrice.ts +32 -0
  136. package/templates/base/packages/nextjs/hooks/scaffold-eth/useNativeCurrencyPrice.ts +34 -0
  137. package/templates/base/packages/nextjs/hooks/scaffold-eth/useNetworkColor.ts +22 -0
  138. package/templates/base/packages/nextjs/hooks/scaffold-eth/useOutsideClick.ts +23 -0
  139. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldContract.ts +65 -0
  140. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldEventHistory.ts +213 -0
  141. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldReadContract.ts +80 -0
  142. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWatchContractEvent.ts +40 -0
  143. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts +191 -0
  144. package/templates/base/packages/nextjs/hooks/scaffold-eth/useSelectedNetwork.ts +18 -0
  145. package/templates/base/packages/nextjs/hooks/scaffold-eth/useTargetNetwork.ts +23 -0
  146. package/templates/base/packages/nextjs/hooks/scaffold-eth/useTransactor.tsx +114 -0
  147. package/templates/base/packages/nextjs/hooks/scaffold-eth/useWatchBalance.ts +21 -0
  148. package/templates/base/packages/nextjs/icons/CompassIcon.tsx +39 -0
  149. package/templates/base/packages/nextjs/icons/DarkBugAntIcon.tsx +30 -0
  150. package/templates/base/packages/nextjs/icons/LightBugAntIcon.tsx +52 -0
  151. package/templates/base/packages/nextjs/next-env.d.ts +5 -0
  152. package/templates/base/packages/nextjs/next.config.js +19 -0
  153. package/templates/base/packages/nextjs/package.json +58 -0
  154. package/templates/base/packages/nextjs/postcss.config.js +6 -0
  155. package/templates/base/packages/nextjs/public/debug-image.png +0 -0
  156. package/templates/base/packages/nextjs/public/favicon.png +0 -0
  157. package/templates/base/packages/nextjs/public/logo.svg +8 -0
  158. package/templates/base/packages/nextjs/public/manifest.json +5 -0
  159. package/templates/base/packages/nextjs/public/thumbnail.jpg +0 -0
  160. package/templates/base/packages/nextjs/react-copy-to-clipboard.d.ts +44 -0
  161. package/templates/base/packages/nextjs/scaffold.config.ts +56 -0
  162. package/templates/base/packages/nextjs/services/store/store.ts +39 -0
  163. package/templates/base/packages/nextjs/services/web3/wagmiConfig.tsx +44 -0
  164. package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +51 -0
  165. package/templates/base/packages/nextjs/styles/globals.css +80 -0
  166. package/templates/base/packages/nextjs/tailwind.config.js +97 -0
  167. package/templates/base/packages/nextjs/tsconfig.json +28 -0
  168. package/templates/base/packages/nextjs/types/abitype/abi.d.ts +16 -0
  169. package/templates/base/packages/nextjs/types/utils.ts +3 -0
  170. package/templates/base/packages/nextjs/utils/scaffold-eth/block.ts +17 -0
  171. package/templates/base/packages/nextjs/utils/scaffold-eth/common.ts +8 -0
  172. package/templates/base/packages/nextjs/utils/scaffold-eth/contract.ts +352 -0
  173. package/templates/base/packages/nextjs/utils/scaffold-eth/contractsData.ts +11 -0
  174. package/templates/base/packages/nextjs/utils/scaffold-eth/decodeTxData.ts +65 -0
  175. package/templates/base/packages/nextjs/utils/scaffold-eth/fetchPriceFromUniswap.ts +72 -0
  176. package/templates/base/packages/nextjs/utils/scaffold-eth/getMetadata.ts +50 -0
  177. package/templates/base/packages/nextjs/utils/scaffold-eth/getParsedError.ts +35 -0
  178. package/templates/base/packages/nextjs/utils/scaffold-eth/index.ts +6 -0
  179. package/templates/base/packages/nextjs/utils/scaffold-eth/notification.tsx +90 -0
  180. package/templates/base/packages/nextjs/utils/scaffold-stylus/burner.ts +59 -0
  181. package/templates/base/packages/nextjs/utils/scaffold-stylus/chain.ts +42 -0
  182. package/templates/base/packages/nextjs/utils/scaffold-stylus/index.ts +3 -0
  183. package/templates/base/packages/nextjs/utils/scaffold-stylus/networks.ts +94 -0
  184. package/templates/base/packages/nextjs/vercel.json +3 -0
  185. package/templates/base/packages/stylus/.env.example +13 -0
  186. package/templates/base/packages/stylus/.eslintrc.js +23 -0
  187. package/templates/base/packages/stylus/.gitignore.template.mjs +7 -0
  188. package/templates/base/packages/stylus/README.md +263 -0
  189. package/templates/base/packages/stylus/header.png +0 -0
  190. package/templates/base/packages/stylus/jest.config.js +15 -0
  191. package/templates/base/packages/stylus/package.json +49 -0
  192. package/templates/base/packages/stylus/scripts/deploy.ts +29 -0
  193. package/templates/base/packages/stylus/scripts/deploy_all_contracts.ts +59 -0
  194. package/templates/base/packages/stylus/scripts/deploy_contract.ts +93 -0
  195. package/templates/base/packages/stylus/scripts/deploy_wrapper.ts +79 -0
  196. package/templates/base/packages/stylus/scripts/export_abi.ts +87 -0
  197. package/templates/base/packages/stylus/scripts/index.ts +0 -0
  198. package/templates/base/packages/stylus/scripts/new_module.sh +35 -0
  199. package/templates/base/packages/stylus/scripts/test_network.ts +31 -0
  200. package/templates/base/packages/stylus/scripts/utils/command.ts +165 -0
  201. package/templates/base/packages/stylus/scripts/utils/contract.ts +219 -0
  202. package/templates/base/packages/stylus/scripts/utils/deployment.ts +136 -0
  203. package/templates/base/packages/stylus/scripts/utils/index.ts +6 -0
  204. package/templates/base/packages/stylus/scripts/utils/network.ts +112 -0
  205. package/templates/base/packages/stylus/scripts/utils/type.ts +48 -0
  206. package/templates/base/packages/stylus/scripts/utils.ts +3 -0
  207. package/templates/base/packages/stylus/tsconfig.json +41 -0
  208. package/templates/base/packages/stylus/your-contract/.cargo/config.toml +18 -0
  209. package/templates/base/packages/stylus/your-contract/Cargo.lock +5744 -0
  210. package/templates/base/packages/stylus/your-contract/Cargo.toml +46 -0
  211. package/templates/base/packages/stylus/your-contract/examples/counter.rs +78 -0
  212. package/templates/base/packages/stylus/your-contract/header.png +0 -0
  213. package/templates/base/packages/stylus/your-contract/licenses/Apache-2.0 +201 -0
  214. package/templates/base/packages/stylus/your-contract/licenses/COPYRIGHT.md +5 -0
  215. package/templates/base/packages/stylus/your-contract/licenses/DCO.txt +34 -0
  216. package/templates/base/packages/stylus/your-contract/licenses/MIT +21 -0
  217. package/templates/base/packages/stylus/your-contract/rust-toolchain.toml +2 -0
  218. package/templates/base/packages/stylus/your-contract/src/lib.rs +211 -0
  219. package/templates/base/packages/stylus/your-contract/src/main.rs +10 -0
  220. package/templates/base/readme.md +187 -0
  221. package/templates/base/yarn.lock +17860 -0
  222. package/tsconfig.json +13 -0
@@ -0,0 +1,263 @@
1
+ ![Image](./header.png)
2
+
3
+ # Stylus Hello World
4
+
5
+ Project starter template for writing Arbitrum Stylus programs in Rust using the [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs). It includes a Rust implementation of a basic counter Ethereum smart contract:
6
+
7
+ ```js
8
+ // SPDX-License-Identifier: UNLICENSED
9
+ pragma solidity ^0.8.13;
10
+
11
+ contract Counter {
12
+ uint256 public number;
13
+
14
+ function setNumber(uint256 newNumber) public {
15
+ number = newNumber;
16
+ }
17
+
18
+ function increment() public {
19
+ number++;
20
+ }
21
+ }
22
+ ```
23
+
24
+ To set up more minimal example that still uses the Stylus SDK, use `cargo stylus new --minimal <YOUR_PROJECT_NAME>` under [OffchainLabs/cargo-stylus](https://github.com/OffchainLabs/cargo-stylus).
25
+
26
+ ## Quick Start
27
+
28
+ Install [Rust](https://www.rust-lang.org/tools/install), and then install the Stylus CLI tool with Cargo
29
+
30
+ ```bash
31
+ cargo install --force cargo-stylus cargo-stylus-check
32
+ ```
33
+
34
+ Add the `wasm32-unknown-unknown` build target to your Rust compiler:
35
+
36
+ ```
37
+ rustup target add wasm32-unknown-unknown
38
+ ```
39
+
40
+ You should now have it available as a Cargo subcommand:
41
+
42
+ ```bash
43
+ cargo stylus --help
44
+ ```
45
+
46
+ Then, clone the template:
47
+
48
+ ```
49
+ git clone https://github.com/OffchainLabs/stylus-hello-world && cd stylus-hello-world
50
+ ```
51
+
52
+ ### Testnet Information
53
+
54
+ All testnet information, including faucets and RPC endpoints can be found [here](https://docs.arbitrum.io/stylus/reference/testnet-information).
55
+
56
+ ### ABI Export
57
+
58
+ You can export the Solidity ABI for your program by using the `cargo stylus` tool as follows:
59
+
60
+ ```bash
61
+ cargo stylus export-abi
62
+ ```
63
+
64
+ which outputs:
65
+
66
+ ```js
67
+ /**
68
+ * This file was automatically generated by Stylus and represents a Rust program.
69
+ * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs).
70
+ */
71
+
72
+ // SPDX-License-Identifier: MIT-OR-APACHE-2.0
73
+ pragma solidity ^0.8.23;
74
+
75
+ interface ICounter {
76
+ function number() external view returns (uint256);
77
+
78
+ function setNumber(uint256 new_number) external;
79
+
80
+ function mulNumber(uint256 new_number) external;
81
+
82
+ function addNumber(uint256 new_number) external;
83
+
84
+ function increment() external;
85
+ }
86
+ ```
87
+
88
+ Exporting ABIs uses a feature that is enabled by default in your Cargo.toml:
89
+
90
+ ```toml
91
+ [features]
92
+ export-abi = ["stylus-sdk/export-abi"]
93
+ ```
94
+
95
+ ## Deploying
96
+
97
+ You can use the `cargo stylus` command to also deploy your program to the Stylus testnet. We can use the tool to first check
98
+ our program compiles to valid WASM for Stylus and will succeed a deployment onchain without transacting. By default, this will use the Stylus testnet public RPC endpoint. See here for [Stylus testnet information](https://docs.arbitrum.io/stylus/reference/testnet-information)
99
+
100
+ ```bash
101
+ cargo stylus check
102
+ ```
103
+
104
+ If successful, you should see:
105
+
106
+ ```bash
107
+ Finished release [optimized] target(s) in 1.88s
108
+ Reading WASM file at stylus-hello-world/target/wasm32-unknown-unknown/release/stylus-hello-world.wasm
109
+ Compressed WASM size: 8.9 KB
110
+ Program succeeded Stylus onchain activation checks with Stylus version: 1
111
+ ```
112
+
113
+ Next, we can estimate the gas costs to deploy and activate our program before we send our transaction. Check out the [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) README to see the different wallet options for this step:
114
+
115
+ ```bash
116
+ cargo stylus deploy \
117
+ --private-key-path=<PRIVKEY_FILE_PATH> \
118
+ --estimate-gas
119
+ ```
120
+
121
+ You will then see the estimated gas cost for deploying before transacting:
122
+
123
+ ```bash
124
+ Deploying program to address e43a32b54e48c7ec0d3d9ed2d628783c23d65020
125
+ Estimated gas for deployment: 1874876
126
+ ```
127
+
128
+ The above only estimates gas for the deployment tx by default. To estimate gas for activation, first deploy your program using `--mode=deploy-only`, and then run `cargo stylus deploy` with the `--estimate-gas` flag, `--mode=activate-only`, and specify `--activate-program-address`.
129
+
130
+ Here's how to deploy:
131
+
132
+ ```bash
133
+ cargo stylus deploy \
134
+ --private-key-path=<PRIVKEY_FILE_PATH>
135
+ ```
136
+
137
+ The CLI will send 2 transactions to deploy and activate your program onchain.
138
+
139
+ ```bash
140
+ Compressed WASM size: 8.9 KB
141
+ Deploying program to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09
142
+ Estimated gas: 1973450
143
+ Submitting tx...
144
+ Confirmed tx 0x42db…7311, gas used 1973450
145
+ Activating program at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09
146
+ Estimated gas: 14044638
147
+ Submitting tx...
148
+ Confirmed tx 0x0bdb…3307, gas used 14044638
149
+ ```
150
+
151
+ Once both steps are successful, you can interact with your program as you would with any Ethereum smart contract.
152
+
153
+ ## Network Configuration
154
+
155
+ This template includes enhanced deployment scripts that support automatic RPC URL resolution from viem's chain definitions. You can now specify a network name instead of manually providing RPC URLs.
156
+
157
+ ### Using Network Names
158
+
159
+ Instead of setting `RPC_URL` in your environment, you can use the `NETWORK` environment variable:
160
+
161
+ ```bash
162
+ # Deploy to Arbitrum One (mainnet)
163
+ NETWORK=arbitrum yarn deploy
164
+ NETWORK=mainnet yarn deploy # alias for arbitrum
165
+
166
+ # Deploy to Arbitrum Sepolia testnet
167
+ NETWORK=arbitrumSepolia yarn deploy
168
+ NETWORK=testnet yarn deploy # alias for arbitrumSepolia
169
+ ```
170
+
171
+ ### Available Networks
172
+
173
+ This template supports Arbitrum networks only. You can test which networks are available and their RPC URLs:
174
+
175
+ ```bash
176
+ yarn test:networks
177
+ ```
178
+
179
+ This will show you all supported networks and their corresponding RPC endpoints.
180
+
181
+ ### Fallback Behavior
182
+
183
+ If a network name is not supported (only `arbitrum`, `arbitrumSepolia`, `mainnet`, and `testnet` are supported), the system will:
184
+
185
+ 1. Show a warning message indicating the network isn't supported
186
+ 2. Fall back to the `RPC_URL` environment variable (or default to `http://localhost:8547`)
187
+ 3. Continue with deployment using the fallback endpoint
188
+
189
+ ### Environment Variables
190
+
191
+ You can still use the traditional approach with `RPC_URL`:
192
+
193
+ ```bash
194
+ RPC_URL=https://your-custom-rpc.com yarn deploy
195
+ ```
196
+
197
+ Or combine both (network takes precedence):
198
+
199
+ ```bash
200
+ NETWORK=mainnet RPC_URL=https://fallback-rpc.com yarn deploy
201
+ ```
202
+
203
+ ## Calling Your Program
204
+
205
+ This template includes an example of how to call and transact with your program in Rust using [ethers-rs](https://github.com/gakonst/ethers-rs) under the `examples/counter.rs`. However, your programs are also Ethereum ABI equivalent if using the Stylus SDK. **They can be called and transacted with using any other Ethereum tooling.**
206
+
207
+ By using the program address from your deployment step above, and your wallet, you can attempt to call the counter program and increase its value in storage:
208
+
209
+ ```rs
210
+ abigen!(
211
+ Counter,
212
+ r#"[
213
+ function number() external view returns (uint256)
214
+ function setNumber(uint256 number) external
215
+ function increment() external
216
+ ]"#
217
+ );
218
+ let counter = Counter::new(address, client);
219
+ let num = counter.number().call().await;
220
+ println!("Counter number value = {:?}", num);
221
+
222
+ let _ = counter.increment().send().await?.await?;
223
+ println!("Successfully incremented counter via a tx");
224
+
225
+ let num = counter.number().call().await;
226
+ println!("New counter number value = {:?}", num);
227
+ ```
228
+
229
+ Before running, set the following env vars or place them in a `.env` file (see: [.env.example](./.env.example)) in this project:
230
+
231
+ ```
232
+ RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
233
+ STYLUS_CONTRACT_ADDRESS=<the onchain address of your deployed program>
234
+ PRIV_KEY_PATH=<the file path for your priv key to transact with>
235
+ ```
236
+
237
+ Next, run:
238
+
239
+ ```
240
+ cargo run --example counter --target=<YOUR_ARCHITECTURE>
241
+ ```
242
+
243
+ Where you can find `YOUR_ARCHITECTURE` by running `rustc -vV | grep host`. For M1 Apple computers, for example, this is `aarch64-apple-darwin` and for most Linux x86 it is `x86_64-unknown-linux-gnu`
244
+
245
+ ## Build Options
246
+
247
+ By default, the cargo stylus tool will build your project for WASM using sensible optimizations, but you can control how this gets compiled by seeing the full README for [cargo stylus](https://github.com/OffchainLabs/cargo-stylus). If you wish to optimize the size of your compiled WASM, see the different options available [here](https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md).
248
+
249
+ ## Peeking Under the Hood
250
+
251
+ The [stylus-sdk](https://github.com/OffchainLabs/stylus-sdk-rs) contains many features for writing Stylus programs in Rust. It also provides helpful macros to make the experience for Solidity developers easier. These macros expand your code into pure Rust code that can then be compiled to WASM. If you want to see what the `stylus-hello-world` boilerplate expands into, you can use `cargo expand` to see the pure Rust code that will be deployed onchain.
252
+
253
+ First, run `cargo install cargo-expand` if you don't have the subcommand already, then:
254
+
255
+ ```
256
+ cargo expand --all-features --release --target=<YOUR_ARCHITECTURE>
257
+ ```
258
+
259
+ Where you can find `YOUR_ARCHITECTURE` by running `rustc -vV | grep host`. For M1 Apple computers, for example, this is `aarch64-apple-darwin`.
260
+
261
+ ## License
262
+
263
+ This project is fully open source, including an Apache-2.0 or MIT license at your choosing under your own copyright.
@@ -0,0 +1,15 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ roots: ['<rootDir>/scripts'],
5
+ testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
6
+ transform: {
7
+ '^.+\\.ts$': 'ts-jest',
8
+ },
9
+ collectCoverageFrom: [
10
+ 'scripts/**/*.ts',
11
+ '!scripts/**/*.d.ts',
12
+ ],
13
+ coverageDirectory: 'coverage',
14
+ coverageReporters: ['text', 'lcov', 'html'],
15
+ };
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@ss/stylus",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript project for Stylus dApp",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "start": "node dist/index.js",
11
+ "deploy": "ts-node scripts/deploy_wrapper.ts",
12
+ "test:networks": "ts-node scripts/test_network.ts",
13
+ "export-abi": "ts-node scripts/export_abi.ts",
14
+ "clean": "rm -rf dist",
15
+ "test": "cargo test",
16
+ "lint": "eslint scripts --ext .ts",
17
+ "lint:fix": "eslint scripts --ext .ts --fix",
18
+ "new-module": "bash scripts/new_module.sh"
19
+ },
20
+ "keywords": [
21
+ "stylus",
22
+ "typescript",
23
+ "arbitrum",
24
+ "blockchain"
25
+ ],
26
+ "author": "",
27
+ "license": "MIT",
28
+ "devDependencies": {
29
+ "@types/node": "^20.0.0",
30
+ "@types/yargs": "^17.0.32",
31
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
32
+ "@typescript-eslint/parser": "^6.0.0",
33
+ "eslint": "^8.0.0",
34
+ "jest": "^29.0.0",
35
+ "ts-jest": "^29.0.0",
36
+ "typescript": "^5.3.0",
37
+ "yargs": "^17.7.2"
38
+ },
39
+ "dependencies": {
40
+ "@tanstack/react-query": "^5.81.5",
41
+ "abitype": "^1.0.8",
42
+ "dotenv": "^16.0.0",
43
+ "ethers": "^6.15.0",
44
+ "prettier": "^3.6.2",
45
+ "toml": "^3.0.0",
46
+ "ts-node": "^10.9.2",
47
+ "viem": "^1.19.9"
48
+ }
49
+ }
@@ -0,0 +1,29 @@
1
+ import deployStylusContract from "./deploy_contract";
2
+ import {
3
+ getDeploymentConfig,
4
+ printDeployedAddresses,
5
+ } from "./utils/";
6
+ import { DeployOptions } from "./utils/type";
7
+
8
+ /**
9
+ * Define your deployment logic here
10
+ */
11
+ export default async function deployScript(deployOptions: DeployOptions) {
12
+ // Deploy a single contract
13
+ await deployStylusContract({
14
+ contract: "your-contract",
15
+ ...deployOptions,
16
+ });
17
+
18
+ // deploy your contract with a custom name
19
+ await deployStylusContract({
20
+ contract: "your-contract",
21
+ name: "my-contract",
22
+ ...deployOptions,
23
+ });
24
+
25
+ // Print the deployed addresses
26
+ const config = getDeploymentConfig(deployOptions);
27
+ console.log("\n\n");
28
+ printDeployedAddresses(config.deploymentDir);
29
+ }
@@ -0,0 +1,59 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import deployStylusContract from "./deploy_contract";
4
+ import {
5
+ clearDeploymentDir,
6
+ ensureDeploymentDirectory,
7
+ getDeploymentConfig,
8
+ isContractFolder,
9
+ printDeployedAddresses,
10
+ } from "./utils/";
11
+ import { DeployOptions } from "./utils/type";
12
+
13
+ /**
14
+ * Deploy all contracts in the stylus folder
15
+ * @param deployOptions - The deploy options
16
+ * @returns void
17
+ */
18
+ export default async function deployAllStylusContracts(
19
+ deployOptions: DeployOptions,
20
+ ) {
21
+ const contractsRoot = ".";
22
+ const entries = fs.readdirSync(contractsRoot, { withFileTypes: true });
23
+
24
+ const config = getDeploymentConfig(deployOptions);
25
+ clearDeploymentDir();
26
+ ensureDeploymentDirectory(config.deploymentDir);
27
+
28
+ console.log(`📄 Deploying all contracts`);
29
+ console.log(`📡 Using endpoint: ${config.chain?.rpcUrl}`);
30
+ if (config.chain) {
31
+ console.log(`🌐 Network specified: ${config.chain?.name}`);
32
+ }
33
+ console.log(`🔑 Using private key: ${config.privateKey.substring(0, 10)}...`);
34
+ console.log(`📁 Deployment directory: ${config.deploymentDir}`);
35
+
36
+ for (const entry of entries) {
37
+ if (!entry.isDirectory()) continue;
38
+ const contractFolder = path.join(contractsRoot, entry.name);
39
+ if (isContractFolder(contractFolder)) {
40
+ try {
41
+ await deployStylusContract(
42
+ {
43
+ contract: entry.name,
44
+ ...deployOptions,
45
+ },
46
+ {
47
+ isSingleCommand: false,
48
+ },
49
+ );
50
+ } catch (e) {
51
+ console.error(`❌ Failed to deploy contract in: ${contractFolder}`);
52
+ console.error(e);
53
+ }
54
+ }
55
+ }
56
+
57
+ console.log("\n\n");
58
+ printDeployedAddresses(config.deploymentDir);
59
+ }
@@ -0,0 +1,93 @@
1
+ import {
2
+ getDeploymentConfig,
3
+ ensureDeploymentDirectory,
4
+ executeCommand,
5
+ generateContractAddress,
6
+ extractDeployedAddress,
7
+ saveDeployedAddress,
8
+ clearDeploymentDir,
9
+ // estimateGasPrice,
10
+ } from "./utils/";
11
+ import { exportStylusAbi } from "./export_abi";
12
+ import {
13
+ DeployOptions,
14
+ AdditionalOptions,
15
+ } from "./utils/type";
16
+ import { buildDeployCommand } from "./utils/command";
17
+
18
+ /**
19
+ * Deploy a single contract using cargo stylus
20
+ * @param deployOptions - The deploy options
21
+ * @param additionalOptions - The additional options
22
+ * @returns void
23
+ */
24
+ export default async function deployStylusContract(
25
+ deployOptions: DeployOptions,
26
+ additionalOptions: AdditionalOptions = {
27
+ isSingleCommand: true,
28
+ shouldClearDeploymentDir: false,
29
+ },
30
+ ) {
31
+ console.log(`\n🚀 Deploying contract in: ${deployOptions.contract}`);
32
+
33
+ const config = getDeploymentConfig(deployOptions);
34
+ if (additionalOptions.shouldClearDeploymentDir) {
35
+ clearDeploymentDir();
36
+ ensureDeploymentDirectory(config.deploymentDir);
37
+ }
38
+
39
+ console.log(`📄 Contract name: ${config.contractName}`);
40
+
41
+ config.contractAddress = generateContractAddress();
42
+
43
+ if (additionalOptions.isSingleCommand) {
44
+ console.log(`📡 Using endpoint: ${config.chain?.rpcUrl}`);
45
+ if (config.chain) {
46
+ console.log(`🌐 Network specified: ${config.chain?.name}`);
47
+ }
48
+ console.log(
49
+ `🔑 Using private key: ${config.privateKey.substring(0, 10)}...`,
50
+ );
51
+ console.log(`📁 Deployment directory: ${config.deploymentDir}`);
52
+ }
53
+
54
+ try {
55
+ // Step 1: Deploy the contract using cargo stylus with contract address
56
+ // --contract-address='${config.contractAddress}' deactivated for now as it's not working. Issue https://github.com/OffchainLabs/cargo-stylus/issues/171
57
+ const deployCommand = await buildDeployCommand(config, deployOptions);
58
+ const deployOutput = await executeCommand(
59
+ deployCommand,
60
+ deployOptions.contract!,
61
+ "Deploying contract with cargo stylus",
62
+ );
63
+
64
+ if (deployOptions.estimateGas) {
65
+ console.log(deployOutput);
66
+ process.exit(0);
67
+ }
68
+
69
+ // Extract the actual deployed address from the output
70
+ const deployedAddress = extractDeployedAddress(deployOutput);
71
+ if (deployedAddress) {
72
+ config.contractAddress = deployedAddress;
73
+ console.log(`📋 Contract deployed at address: ${config.contractAddress}`);
74
+ } else {
75
+ console.log(`📋 Using fallback address: ${config.contractAddress}`);
76
+ }
77
+
78
+ // Save the deployed address to addresses.json
79
+ saveDeployedAddress(config);
80
+
81
+ // Step 2: Export ABI using the shared function
82
+ await exportStylusAbi(config.contractFolder, config.contractName, false);
83
+
84
+ console.log(`✅ Successfully deployed contract in: ${deployOptions.contract}`);
85
+ if (additionalOptions.isSingleCommand) {
86
+ console.log(`📋 Contract deployed at address: ${config.contractAddress}`);
87
+ console.log(`📋 Chain ID: ${config.chain?.id}`);
88
+ }
89
+ } catch (error) {
90
+ console.error(`❌ Deployment failed in: ${deployOptions.contract}`, error);
91
+ process.exit(1);
92
+ }
93
+ }
@@ -0,0 +1,79 @@
1
+ import * as fs from "fs";
2
+ import deployStylusContract from "./deploy_contract";
3
+ import { hideBin } from "yargs/helpers";
4
+ import yargs from "yargs";
5
+ import { DeployCommandOptions, DeployOptions } from "./utils/type";
6
+ import deployAllStylusContracts from "./deploy_all_contracts";
7
+ import deployScript from "./deploy";
8
+
9
+ /**
10
+ * Entry point for the deploy script
11
+ * This script is used to deploy a single contract or all contracts in the stylus folder
12
+ */
13
+ if (require.main === module) {
14
+ // Use yargs for argument parsing
15
+ const argv = yargs(hideBin(process.argv))
16
+ .usage("Usage: yarn deploy --name <contractName> --network <network>")
17
+ .option("all", {
18
+ alias: "a",
19
+ describe: "Deploy all contracts in the stylus folder",
20
+ type: "boolean",
21
+ demandOption: false,
22
+ })
23
+ .option("contract", {
24
+ alias: "c",
25
+ describe: "Name of the contract folder",
26
+ type: "string",
27
+ demandOption: false,
28
+ })
29
+ .option("name", {
30
+ alias: "n",
31
+ describe: "Name of the contract",
32
+ type: "string",
33
+ demandOption: false,
34
+ })
35
+ .option("network", {
36
+ alias: "net",
37
+ describe: "Network to deploy to",
38
+ type: "string",
39
+ demandOption: false,
40
+ })
41
+ .option("estimate-gas", {
42
+ alias: "eg",
43
+ describe: "Estimate gas for the deployment",
44
+ type: "boolean",
45
+ demandOption: false,
46
+ })
47
+ .option("max-fee", {
48
+ alias: "mf",
49
+ describe: "Max fee per gas gwei",
50
+ type: "string",
51
+ demandOption: false,
52
+ })
53
+ .help()
54
+ .parseSync() as DeployCommandOptions;
55
+
56
+ if (argv.all) {
57
+ deployAllStylusContracts(argv as DeployOptions).catch((error) => {
58
+ console.error("Fatal error:", error);
59
+ process.exit(1);
60
+ });
61
+ } else if (argv.contract) {
62
+ if (!fs.existsSync(argv.contract)) {
63
+ console.error(`❌ Contract folder does not exist: ${argv.contract}`);
64
+ process.exit(1);
65
+ }
66
+
67
+ deployStylusContract(argv as DeployOptions, {
68
+ shouldClearDeploymentDir: true,
69
+ }).catch((error) => {
70
+ console.error("Fatal error:", error);
71
+ process.exit(1);
72
+ });
73
+ } else {
74
+ deployScript(argv as DeployOptions).catch((error) => {
75
+ console.error("Fatal error:", error);
76
+ process.exit(1);
77
+ });
78
+ }
79
+ }
@@ -0,0 +1,87 @@
1
+ import * as path from "path";
2
+ import * as fs from "fs";
3
+ import {
4
+ getExportConfig,
5
+ ensureDeploymentDirectory,
6
+ executeCommand,
7
+ generateTsAbi,
8
+ handleSolcError,
9
+ } from "./utils/";
10
+
11
+ export async function exportStylusAbi(
12
+ contractFolder: string,
13
+ contractName: string,
14
+ isSingleCommand: boolean = true,
15
+ ) {
16
+ console.log("📄 Starting Stylus ABI export...");
17
+
18
+ const config = getExportConfig(contractFolder, contractName);
19
+
20
+ // If contractAddress is not set, error and exit
21
+ if (!config.contractAddress) {
22
+ console.error(
23
+ `❌ Contract address not found. Please deploy the contract first or ensure it is saved in ${path.resolve(config.deploymentDir, "addresses.json")}`,
24
+ );
25
+ process.exit(1);
26
+ }
27
+
28
+ if (isSingleCommand) {
29
+ console.log(`📄 Contract name: ${config.contractName}`);
30
+ console.log(`📁 Deployment directory: ${config.deploymentDir}`);
31
+ console.log(`📍 Contract address: ${config.contractAddress}`);
32
+ console.log(`🔗 Chain ID: ${config.chainId}`);
33
+ }
34
+
35
+ try {
36
+ // Ensure deployment directory exists
37
+ ensureDeploymentDirectory(config.deploymentDir);
38
+
39
+ // Export ABI
40
+ const exportCommand = `cargo stylus export-abi --output='../${config.deploymentDir}/${config.contractFolder}' --json`;
41
+ await executeCommand(exportCommand, contractFolder, "Exporting ABI");
42
+
43
+ console.log(
44
+ `📄 ABI file location: ${config.deploymentDir}/${config.contractFolder}`,
45
+ );
46
+
47
+ // Verify the ABI file was created
48
+ const abiFilePath = path.resolve(
49
+ config.deploymentDir,
50
+ `${config.contractFolder}`,
51
+ );
52
+ if (fs.existsSync(abiFilePath)) {
53
+ console.log(`✅ ABI file verified at: ${abiFilePath}`);
54
+ } else {
55
+ console.warn(
56
+ `⚠️ ABI file not found at expected location: ${abiFilePath}`,
57
+ );
58
+ }
59
+
60
+ // do not Generate TypeScript ABI when called from yarn script
61
+ if (!isSingleCommand) {
62
+ await generateTsAbi(
63
+ abiFilePath,
64
+ config.contractName,
65
+ config.contractAddress,
66
+ config.chainId,
67
+ );
68
+ }
69
+ } catch (error) {
70
+ handleSolcError(error as Error);
71
+ process.exit(1);
72
+ }
73
+ }
74
+
75
+ // Allow running this file directly
76
+ if (require.main === module) {
77
+ // Get contract folder from command line args, default to 'your-contract'
78
+ const contractFolder = process.argv[2] || "your-contract";
79
+ if (!fs.existsSync(contractFolder)) {
80
+ console.error(`❌ Contract folder does not exist: ${contractFolder}`);
81
+ process.exit(1);
82
+ }
83
+ exportStylusAbi(contractFolder, contractFolder).catch((error) => {
84
+ console.error("Fatal error:", error);
85
+ process.exit(1);
86
+ });
87
+ }