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,63 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { parseEther } from "viem";
3
+ import { CommonInputProps, InputBase, IntegerVariant, isValidInteger } from "~~/components/scaffold-eth";
4
+
5
+ type IntegerInputProps = CommonInputProps<string> & {
6
+ variant?: IntegerVariant;
7
+ disableMultiplyBy1e18?: boolean;
8
+ };
9
+
10
+ export const IntegerInput = ({
11
+ value,
12
+ onChange,
13
+ name,
14
+ placeholder,
15
+ disabled,
16
+ variant = IntegerVariant.UINT256,
17
+ disableMultiplyBy1e18 = false,
18
+ }: IntegerInputProps) => {
19
+ const [inputError, setInputError] = useState(false);
20
+ const multiplyBy1e18 = useCallback(() => {
21
+ if (!value) {
22
+ return;
23
+ }
24
+ return onChange(parseEther(value).toString());
25
+ }, [onChange, value]);
26
+
27
+ useEffect(() => {
28
+ if (isValidInteger(variant, value)) {
29
+ setInputError(false);
30
+ } else {
31
+ setInputError(true);
32
+ }
33
+ }, [value, variant]);
34
+
35
+ return (
36
+ <InputBase
37
+ name={name}
38
+ value={value}
39
+ placeholder={placeholder}
40
+ error={inputError}
41
+ onChange={onChange}
42
+ disabled={disabled}
43
+ suffix={
44
+ !inputError &&
45
+ !disableMultiplyBy1e18 && (
46
+ <div
47
+ className="space-x-4 flex tooltip tooltip-top tooltip-secondary before:content-[attr(data-tip)] before:right-[-10px] before:left-auto before:transform-none"
48
+ data-tip="Multiply by 1e18 (wei)"
49
+ >
50
+ <button
51
+ className={`${disabled ? "cursor-not-allowed" : "cursor-pointer"} font-semibold px-4 text-accent`}
52
+ onClick={multiplyBy1e18}
53
+ disabled={disabled}
54
+ type="button"
55
+ >
56
+
57
+ </button>
58
+ </div>
59
+ )
60
+ }
61
+ />
62
+ );
63
+ };
@@ -0,0 +1,9 @@
1
+ "use client";
2
+
3
+ export * from "./AddressInput";
4
+ export * from "./Bytes32Input";
5
+ export * from "./BytesInput";
6
+ export * from "./EtherInput";
7
+ export * from "./InputBase";
8
+ export * from "./IntegerInput";
9
+ export * from "./utils";
@@ -0,0 +1,109 @@
1
+ export type CommonInputProps<T = string> = {
2
+ value: T;
3
+ onChange: (newValue: T) => void;
4
+ name?: string;
5
+ placeholder?: string;
6
+ disabled?: boolean;
7
+ };
8
+
9
+ export enum IntegerVariant {
10
+ UINT8 = "uint8",
11
+ UINT16 = "uint16",
12
+ UINT24 = "uint24",
13
+ UINT32 = "uint32",
14
+ UINT40 = "uint40",
15
+ UINT48 = "uint48",
16
+ UINT56 = "uint56",
17
+ UINT64 = "uint64",
18
+ UINT72 = "uint72",
19
+ UINT80 = "uint80",
20
+ UINT88 = "uint88",
21
+ UINT96 = "uint96",
22
+ UINT104 = "uint104",
23
+ UINT112 = "uint112",
24
+ UINT120 = "uint120",
25
+ UINT128 = "uint128",
26
+ UINT136 = "uint136",
27
+ UINT144 = "uint144",
28
+ UINT152 = "uint152",
29
+ UINT160 = "uint160",
30
+ UINT168 = "uint168",
31
+ UINT176 = "uint176",
32
+ UINT184 = "uint184",
33
+ UINT192 = "uint192",
34
+ UINT200 = "uint200",
35
+ UINT208 = "uint208",
36
+ UINT216 = "uint216",
37
+ UINT224 = "uint224",
38
+ UINT232 = "uint232",
39
+ UINT240 = "uint240",
40
+ UINT248 = "uint248",
41
+ UINT256 = "uint256",
42
+ INT8 = "int8",
43
+ INT16 = "int16",
44
+ INT24 = "int24",
45
+ INT32 = "int32",
46
+ INT40 = "int40",
47
+ INT48 = "int48",
48
+ INT56 = "int56",
49
+ INT64 = "int64",
50
+ INT72 = "int72",
51
+ INT80 = "int80",
52
+ INT88 = "int88",
53
+ INT96 = "int96",
54
+ INT104 = "int104",
55
+ INT112 = "int112",
56
+ INT120 = "int120",
57
+ INT128 = "int128",
58
+ INT136 = "int136",
59
+ INT144 = "int144",
60
+ INT152 = "int152",
61
+ INT160 = "int160",
62
+ INT168 = "int168",
63
+ INT176 = "int176",
64
+ INT184 = "int184",
65
+ INT192 = "int192",
66
+ INT200 = "int200",
67
+ INT208 = "int208",
68
+ INT216 = "int216",
69
+ INT224 = "int224",
70
+ INT232 = "int232",
71
+ INT240 = "int240",
72
+ INT248 = "int248",
73
+ INT256 = "int256",
74
+ }
75
+
76
+ export const SIGNED_NUMBER_REGEX = /^-?\d+\.?\d*$/;
77
+ export const UNSIGNED_NUMBER_REGEX = /^\.?\d+\.?\d*$/;
78
+
79
+ export const isValidInteger = (dataType: IntegerVariant, value: string) => {
80
+ const isSigned = dataType.startsWith("i");
81
+ const bitcount = Number(dataType.substring(isSigned ? 3 : 4));
82
+
83
+ let valueAsBigInt;
84
+ try {
85
+ valueAsBigInt = BigInt(value);
86
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
+ } catch (e) {}
88
+ if (typeof valueAsBigInt !== "bigint") {
89
+ if (!value || typeof value !== "string") {
90
+ return true;
91
+ }
92
+ return isSigned ? SIGNED_NUMBER_REGEX.test(value) || value === "-" : UNSIGNED_NUMBER_REGEX.test(value);
93
+ } else if (!isSigned && valueAsBigInt < 0) {
94
+ return false;
95
+ }
96
+ const hexString = valueAsBigInt.toString(16);
97
+ const significantHexDigits = hexString.match(/.*x0*(.*)$/)?.[1] ?? "";
98
+ if (
99
+ significantHexDigits.length * 4 > bitcount ||
100
+ (isSigned && significantHexDigits.length * 4 === bitcount && parseInt(significantHexDigits.slice(-1)?.[0], 16) < 8)
101
+ ) {
102
+ return false;
103
+ }
104
+ return true;
105
+ };
106
+
107
+ // Treat any dot-separated string as a potential ENS name
108
+ const ensRegex = /.+\..+/;
109
+ export const isENS = (address = "") => ensRegex.test(address);
@@ -0,0 +1,121 @@
1
+ import { useRef, useState } from "react";
2
+ import { NetworkOptions } from "./NetworkOptions";
3
+ import { getAddress } from "viem";
4
+ import { Address } from "viem";
5
+ import { useDisconnect } from "wagmi";
6
+ import {
7
+ ArrowLeftEndOnRectangleIcon,
8
+ ArrowsRightLeftIcon,
9
+ CheckCircleIcon,
10
+ ChevronDownIcon,
11
+ DocumentDuplicateIcon,
12
+ QrCodeIcon,
13
+ UserCircleIcon,
14
+ } from "@heroicons/react/24/outline";
15
+ import { BlockieAvatar, isENS } from "~~/components/scaffold-eth";
16
+ import { useCopyToClipboard, useOutsideClick } from "~~/hooks/scaffold-eth";
17
+ import { getTargetNetworks } from "~~/utils/scaffold-stylus";
18
+ import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
19
+
20
+ const allowedNetworks = getTargetNetworks();
21
+
22
+ type AddressInfoDropdownProps = {
23
+ address: Address;
24
+ displayName: string;
25
+ ensAvatar?: string;
26
+ onSwitchAccount: () => void;
27
+ };
28
+
29
+ export const AddressInfoDropdown = ({ address, ensAvatar, displayName, onSwitchAccount }: AddressInfoDropdownProps) => {
30
+ const { disconnect } = useDisconnect();
31
+ const checkSumAddress = getAddress(address);
32
+
33
+ const { copyToClipboard: copyAddressToClipboard, isCopiedToClipboard: isAddressCopiedToClipboard } =
34
+ useCopyToClipboard();
35
+ const [selectingNetwork, setSelectingNetwork] = useState(false);
36
+ const dropdownRef = useRef<HTMLDetailsElement>(null);
37
+
38
+ const closeDropdown = () => {
39
+ setSelectingNetwork(false);
40
+ dropdownRef.current?.removeAttribute("open");
41
+ };
42
+
43
+ useOutsideClick(dropdownRef, closeDropdown);
44
+
45
+ return (
46
+ <>
47
+ <details ref={dropdownRef} className="gradient-border rounded-full inline-block dropdown dropdown-end leading-3">
48
+ <summary
49
+ tabIndex={0}
50
+ className="bg-base-100 rounded-full flex items-center px-4 py-2 shadow-md dropdown-toggle gap-0 !h-auto"
51
+ >
52
+ <BlockieAvatar address={checkSumAddress} size={30} ensImage={ensAvatar} />
53
+ <span className="ml-2 mr-1">
54
+ {isENS(displayName) ? displayName : checkSumAddress?.slice(0, 6) + "..." + checkSumAddress?.slice(-4)}
55
+ </span>
56
+ <ChevronDownIcon className="h-6 w-4 ml-2 sm:ml-0" />
57
+ </summary>
58
+ <ul
59
+ tabIndex={0}
60
+ className="dropdown-content menu z-[2] p-2 mt-2 shadow-center shadow-accent rounded-box gap-1 gradient-border"
61
+ >
62
+ <NetworkOptions hidden={!selectingNetwork} />
63
+ <li className={selectingNetwork ? "hidden" : ""}>
64
+ <div
65
+ className="h-8 btn-sm rounded-xl! flex gap-3 py-3 cursor-pointer"
66
+ onClick={() => copyAddressToClipboard(checkSumAddress)}
67
+ >
68
+ {isAddressCopiedToClipboard ? (
69
+ <>
70
+ <CheckCircleIcon className="text-xl font-normal h-6 w-4 ml-2 sm:ml-0" aria-hidden="true" />
71
+ <span className="whitespace-nowrap">Copied!</span>
72
+ </>
73
+ ) : (
74
+ <>
75
+ <DocumentDuplicateIcon className="text-xl font-normal h-6 w-4 ml-2 sm:ml-0" aria-hidden="true" />
76
+ <span className="whitespace-nowrap">Copy address</span>
77
+ </>
78
+ )}
79
+ </div>
80
+ </li>
81
+ <li className={selectingNetwork ? "hidden" : ""}>
82
+ <label htmlFor="qrcode-modal" className="h-8 btn-sm rounded-xl! flex gap-3 py-3">
83
+ <QrCodeIcon className="h-6 w-4 ml-2 sm:ml-0" />
84
+ <span className="whitespace-nowrap">View QR Code</span>
85
+ </label>
86
+ </li>
87
+ {allowedNetworks.some(network => network.id === arbitrumNitro.id) && (
88
+ <li className={selectingNetwork ? "hidden" : ""}>
89
+ <button className="menu-item btn-sm !rounded-xl flex gap-3 py-3" type="button" onClick={onSwitchAccount}>
90
+ <UserCircleIcon className="h-6 w-4 ml-2 sm:ml-0" />
91
+ <span className="whitespace-nowrap">Switch account</span>
92
+ </button>
93
+ </li>
94
+ )}
95
+ {allowedNetworks.length > 1 ? (
96
+ <li className={selectingNetwork ? "hidden" : ""}>
97
+ <button
98
+ className="h-8 btn-sm rounded-xl! flex gap-3 py-3"
99
+ type="button"
100
+ onClick={() => {
101
+ setSelectingNetwork(true);
102
+ }}
103
+ >
104
+ <ArrowsRightLeftIcon className="h-6 w-4 ml-2 sm:ml-0" /> <span>Switch Network</span>
105
+ </button>
106
+ </li>
107
+ ) : null}
108
+ <li className={selectingNetwork ? "hidden" : ""}>
109
+ <button
110
+ className="menu-item text-error h-8 btn-sm rounded-xl! flex gap-3 py-3"
111
+ type="button"
112
+ onClick={() => disconnect()}
113
+ >
114
+ <ArrowLeftEndOnRectangleIcon className="h-6 w-4 ml-2 sm:ml-0" /> <span>Disconnect</span>
115
+ </button>
116
+ </li>
117
+ </ul>
118
+ </details>
119
+ </>
120
+ );
121
+ };
@@ -0,0 +1,33 @@
1
+ import { QRCodeSVG } from "qrcode.react";
2
+ import { Address as AddressType } from "viem";
3
+ import { Address } from "~~/components/scaffold-eth";
4
+
5
+ type AddressQRCodeModalProps = {
6
+ address: AddressType;
7
+ modalId: string;
8
+ };
9
+
10
+ export const AddressQRCodeModal = ({ address, modalId }: AddressQRCodeModalProps) => {
11
+ return (
12
+ <>
13
+ <div>
14
+ <input type="checkbox" id={`${modalId}`} className="modal-toggle" />
15
+ <label htmlFor={`${modalId}`} className="modal cursor-pointer">
16
+ <label className="modal-box relative">
17
+ {/* dummy input to capture event onclick on modal box */}
18
+ <input className="h-0 w-0 absolute top-0 left-0" />
19
+ <label htmlFor={`${modalId}`} className="btn btn-ghost btn-sm btn-circle absolute right-3 top-3">
20
+
21
+ </label>
22
+ <div className="space-y-3 py-6">
23
+ <div className="flex flex-col items-center gap-6">
24
+ <QRCodeSVG value={address} size={256} />
25
+ <Address address={address} format="long" disableAddressLink onlyEnsOrAddress />
26
+ </div>
27
+ </div>
28
+ </label>
29
+ </label>
30
+ </div>
31
+ </>
32
+ );
33
+ };
@@ -0,0 +1,63 @@
1
+ import { useRef, useState } from "react";
2
+ import { BlockieAvatar } from "..";
3
+ import { useTheme } from "next-themes";
4
+ import { useOutsideClick } from "~~/hooks/scaffold-eth/useOutsideClick";
5
+ import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
6
+
7
+ interface BurnerWalletModalProps {
8
+ isOpen: boolean;
9
+ onClose: () => void;
10
+ onSelectAccount: (privateKey: string) => void;
11
+ }
12
+
13
+ export const BurnerWalletModal = ({ isOpen, onClose, onSelectAccount }: BurnerWalletModalProps) => {
14
+ const [selectedAccount, setSelectedAccount] = useState<string | null>(null);
15
+ const modalRef = useRef<HTMLDivElement>(null);
16
+ const { resolvedTheme } = useTheme();
17
+ const isDarkMode = resolvedTheme === "dark";
18
+
19
+ useOutsideClick(modalRef, onClose);
20
+
21
+ if (!isOpen) return null;
22
+
23
+ const handleAccountSelect = (privateKey: string, address: string) => {
24
+ setSelectedAccount(address);
25
+ onSelectAccount(privateKey);
26
+ onClose();
27
+ };
28
+
29
+ return (
30
+ <div className="fixed inset-0 z-50 flex items-center justify-center backdrop-blur-sm">
31
+ <div
32
+ ref={modalRef}
33
+ className={`rounded-2xl p-6 max-w-md w-full mx-4 ${isDarkMode ? "bg-[#272727]" : "gradient-border-light"}`}
34
+ >
35
+ <div className="flex justify-center items-center mb-4 w-full">
36
+ <h3 className="text-lg font-semibold text-center">Choose account</h3>
37
+ </div>
38
+
39
+ <div className="space-y-2">
40
+ {arbitrumNitro.accounts.map(account => (
41
+ <button
42
+ key={account.address}
43
+ onClick={() => handleAccountSelect(account.privateKey, account.address)}
44
+ className={`w-full p-3 text-left rounded-lg border ${
45
+ isDarkMode ? "border-black hover:bg-black" : "gradient-border-light-hover hover:text-white"
46
+ } transition-colors`}
47
+ >
48
+ <div className="flex justify-between items-center">
49
+ <div className="flex gap-[30px] items-center">
50
+ <BlockieAvatar address={account.address} size={28} />
51
+ <div className="text-sm font-medium">
52
+ {account.address.slice(0, 6)}...{account.address.slice(-4)}
53
+ </div>
54
+ </div>
55
+ <div className="text-xs text-base-content/50">{account.address === selectedAccount ? "✓" : ""}</div>
56
+ </div>
57
+ </button>
58
+ ))}
59
+ </div>
60
+ </div>
61
+ </div>
62
+ );
63
+ };
@@ -0,0 +1,48 @@
1
+ import { useTheme } from "next-themes";
2
+ import { useAccount, useSwitchChain } from "wagmi";
3
+ import { ArrowsRightLeftIcon } from "@heroicons/react/24/solid";
4
+ import { getNetworkColor } from "~~/hooks/scaffold-eth";
5
+ import { getTargetNetworks } from "~~/utils/scaffold-stylus";
6
+
7
+ const allowedNetworks = getTargetNetworks();
8
+
9
+ type NetworkOptionsProps = {
10
+ hidden?: boolean;
11
+ };
12
+
13
+ export const NetworkOptions = ({ hidden = false }: NetworkOptionsProps) => {
14
+ const { switchChain } = useSwitchChain();
15
+ const { chain } = useAccount();
16
+ const { resolvedTheme } = useTheme();
17
+ const isDarkMode = resolvedTheme === "dark";
18
+
19
+ return (
20
+ <>
21
+ {allowedNetworks
22
+ .filter(allowedNetwork => allowedNetwork.id !== chain?.id)
23
+ .map(allowedNetwork => (
24
+ <li key={allowedNetwork.id} className={hidden ? "hidden" : ""}>
25
+ <button
26
+ className="menu-item btn-sm rounded-xl! flex gap-3 py-3 whitespace-nowrap"
27
+ type="button"
28
+ onClick={() => {
29
+ switchChain?.({ chainId: allowedNetwork.id });
30
+ }}
31
+ >
32
+ <ArrowsRightLeftIcon className="h-6 w-4 ml-2 sm:ml-0" />
33
+ <span>
34
+ Switch to{" "}
35
+ <span
36
+ style={{
37
+ color: getNetworkColor(allowedNetwork, isDarkMode),
38
+ }}
39
+ >
40
+ {allowedNetwork.name}
41
+ </span>
42
+ </span>
43
+ </button>
44
+ </li>
45
+ ))}
46
+ </>
47
+ );
48
+ };
@@ -0,0 +1,32 @@
1
+ import { NetworkOptions } from "./NetworkOptions";
2
+ import { useDisconnect } from "wagmi";
3
+ import { ArrowLeftEndOnRectangleIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
4
+
5
+ export const WrongNetworkDropdown = () => {
6
+ const { disconnect } = useDisconnect();
7
+
8
+ return (
9
+ <div className="dropdown dropdown-end mr-2">
10
+ <label tabIndex={0} className="btn btn-error btn-sm dropdown-toggle gap-1">
11
+ <span>Wrong network</span>
12
+ <ChevronDownIcon className="h-6 w-4 ml-2 sm:ml-0" />
13
+ </label>
14
+ <ul
15
+ tabIndex={0}
16
+ className="dropdown-content menu p-2 mt-1 shadow-center shadow-accent bg-base-200 rounded-box gap-1"
17
+ >
18
+ <NetworkOptions />
19
+ <li>
20
+ <button
21
+ className="menu-item text-error btn-sm rounded-xl! flex gap-3 py-3"
22
+ type="button"
23
+ onClick={() => disconnect()}
24
+ >
25
+ <ArrowLeftEndOnRectangleIcon className="h-6 w-4 ml-2 sm:ml-0" />
26
+ <span>Disconnect</span>
27
+ </button>
28
+ </li>
29
+ </ul>
30
+ </div>
31
+ );
32
+ };
@@ -0,0 +1,89 @@
1
+ "use client";
2
+
3
+ // @refresh reset
4
+ import { useState } from "react";
5
+ import { Balance } from "../Balance";
6
+ import { AddressInfoDropdown } from "./AddressInfoDropdown";
7
+ import { AddressQRCodeModal } from "./AddressQRCodeModal";
8
+ import { BurnerWalletModal } from "./BurnerWalletModal";
9
+ import { WrongNetworkDropdown } from "./WrongNetworkDropdown";
10
+ import { ConnectButton } from "@rainbow-me/rainbowkit";
11
+ import { Address } from "viem";
12
+ import { useNetworkColor } from "~~/hooks/scaffold-eth";
13
+ import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
14
+ import { saveBurnerPK } from "~~/utils/scaffold-stylus/burner";
15
+ import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
16
+
17
+ /**
18
+ * Custom Wagmi Connect Button (watch balance + custom design)
19
+ */
20
+ export const RainbowKitCustomConnectButton = () => {
21
+ const networkColor = useNetworkColor();
22
+ const { targetNetwork } = useTargetNetwork();
23
+ const [isBurnerModalOpen, setIsBurnerModalOpen] = useState(false);
24
+
25
+ const handleBurnerWalletSelect = async (privateKey: string) => {
26
+ saveBurnerPK({ privateKey: privateKey as `0x${string}` });
27
+ window.location.reload();
28
+ };
29
+
30
+ return (
31
+ <>
32
+ <ConnectButton.Custom>
33
+ {({ account, chain, openConnectModal, mounted }) => {
34
+ const connected = mounted && account && chain;
35
+
36
+ const handleConnect = () => {
37
+ if (targetNetwork.id === arbitrumNitro.id) {
38
+ setIsBurnerModalOpen(true);
39
+ } else {
40
+ openConnectModal();
41
+ }
42
+ };
43
+
44
+ return (
45
+ <>
46
+ {(() => {
47
+ if (!connected) {
48
+ return (
49
+ <button className="btn bg-secondary btn-sm" onClick={handleConnect} type="button">
50
+ Connect
51
+ </button>
52
+ );
53
+ }
54
+
55
+ if (chain.unsupported || chain.id !== targetNetwork.id) {
56
+ return <WrongNetworkDropdown />;
57
+ }
58
+
59
+ return (
60
+ <>
61
+ <div className="flex flex-col items-center mr-1">
62
+ <Balance address={account.address as Address} className="min-h-0 h-auto" />
63
+ <span className="text-xs" style={{ color: networkColor }}>
64
+ {chain.name}
65
+ </span>
66
+ </div>
67
+ <AddressInfoDropdown
68
+ address={account.address as Address}
69
+ displayName={account.displayName}
70
+ ensAvatar={account.ensAvatar}
71
+ onSwitchAccount={() => setIsBurnerModalOpen(true)}
72
+ />
73
+ <AddressQRCodeModal address={account.address as Address} modalId="qrcode-modal" />
74
+ </>
75
+ );
76
+ })()}
77
+ </>
78
+ );
79
+ }}
80
+ </ConnectButton.Custom>
81
+
82
+ <BurnerWalletModal
83
+ isOpen={isBurnerModalOpen}
84
+ onClose={() => setIsBurnerModalOpen(false)}
85
+ onSelectAccount={handleBurnerWalletSelect}
86
+ />
87
+ </>
88
+ );
89
+ };
@@ -0,0 +1,7 @@
1
+ export * from "./Address/Address";
2
+ export * from "./Balance";
3
+ export * from "./BlockieAvatar";
4
+ export * from "./Faucet";
5
+ export * from "./FaucetButton";
6
+ export * from "./Input";
7
+ export * from "./RainbowKitCustomConnectButton";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This file is autogenerated by scaffold-stylus.
3
+ * You should not edit it manually or your changes might be overwritten.
4
+ */
5
+ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
6
+
7
+ const deployedContracts = {} as const;
8
+
9
+ export default deployedContracts satisfies GenericContractsDeclaration;
@@ -0,0 +1,16 @@
1
+ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
2
+
3
+ /**
4
+ * @example
5
+ * const externalContracts = {
6
+ * 1: {
7
+ * DAI: {
8
+ * address: "0x...",
9
+ * abi: [...],
10
+ * },
11
+ * },
12
+ * } as const;
13
+ */
14
+ const externalContracts = {} as const;
15
+
16
+ export default externalContracts satisfies GenericContractsDeclaration;
@@ -0,0 +1,32 @@
1
+ import { FlatCompat } from "@eslint/eslintrc";
2
+ import prettierPlugin from "eslint-plugin-prettier";
3
+ import { defineConfig } from "eslint/config";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+ const compat = new FlatCompat({
10
+ baseDirectory: __dirname,
11
+ });
12
+
13
+ export default defineConfig([
14
+ {
15
+ plugins: {
16
+ prettier: prettierPlugin,
17
+ },
18
+ extends: compat.extends("next/core-web-vitals", "next/typescript", "prettier"),
19
+
20
+ rules: {
21
+ "@typescript-eslint/no-explicit-any": "off",
22
+ "@typescript-eslint/ban-ts-comment": "off",
23
+
24
+ "prettier/prettier": [
25
+ "warn",
26
+ {
27
+ endOfLine: "auto",
28
+ },
29
+ ],
30
+ },
31
+ },
32
+ ]);
@@ -0,0 +1,17 @@
1
+ export * from "./useAnimationConfig";
2
+ export * from "./useContractLogs";
3
+ export * from "./useCopyToClipboard";
4
+ export * from "./useDeployedContractInfo";
5
+ export * from "./useFetchBlocks";
6
+ export * from "./useInitializeNativeCurrencyPrice";
7
+ export * from "./useNetworkColor";
8
+ export * from "./useOutsideClick";
9
+ export * from "./useScaffoldContract";
10
+ export * from "./useScaffoldEventHistory";
11
+ export * from "./useScaffoldReadContract";
12
+ export * from "./useScaffoldWatchContractEvent";
13
+ export * from "./useScaffoldWriteContract";
14
+ export * from "./useTargetNetwork";
15
+ export * from "./useTransactor";
16
+ export * from "./useWatchBalance";
17
+ export * from "./useSelectedNetwork";