create-stylus 0.0.5

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 (220) 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/.github/workflows/release-manual.yml +26 -0
  5. package/.yarnrc.yml +1 -0
  6. package/CONTRIBUTING.md +42 -0
  7. package/README.md +66 -0
  8. package/bin/create-dapp-ss.js +4 -0
  9. package/package.json +46 -0
  10. package/rollup.config.js +22 -0
  11. package/src/cli.ts +14 -0
  12. package/src/extensions.json +14 -0
  13. package/src/main.ts +72 -0
  14. package/src/tasks/copy-extension-file.ts +227 -0
  15. package/src/tasks/copy-template-files.ts +252 -0
  16. package/src/tasks/create-first-git-commit.ts +35 -0
  17. package/src/tasks/create-project-directory.ts +34 -0
  18. package/src/tasks/index.ts +5 -0
  19. package/src/tasks/install-packages.ts +15 -0
  20. package/src/tasks/prettier-format.ts +17 -0
  21. package/src/types.ts +31 -0
  22. package/src/utils/consts.ts +1 -0
  23. package/src/utils/find-files-recursively.ts +19 -0
  24. package/src/utils/link.ts +44 -0
  25. package/src/utils/load-extensions.ts +10 -0
  26. package/src/utils/merge-package-json.ts +33 -0
  27. package/src/utils/parse-arguments-into-options.ts +38 -0
  28. package/src/utils/prompt-for-missing-options.ts +53 -0
  29. package/src/utils/render-intro-message.ts +11 -0
  30. package/src/utils/render-outro-message.ts +34 -0
  31. package/templates/base/.github/ISSUE_TEMPLATE/bug_report.yml +58 -0
  32. package/templates/base/.github/ISSUE_TEMPLATE/config.yml +8 -0
  33. package/templates/base/.github/pull_request_template.md +16 -0
  34. package/templates/base/.github/workflows/lint.yaml +300 -0
  35. package/templates/base/.gitignore.template.mjs +19 -0
  36. package/templates/base/.gitmodules +0 -0
  37. package/templates/base/.husky/pre-commit +4 -0
  38. package/templates/base/.lintstagedrc.js +21 -0
  39. package/templates/base/.vscode/settings.json +7 -0
  40. package/templates/base/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
  41. package/templates/base/.yarn/releases/yarn-3.2.3.cjs +783 -0
  42. package/templates/base/.yarnrc.yml +11 -0
  43. package/templates/base/CONTRIBUTING.md +86 -0
  44. package/templates/base/LICENCE +21 -0
  45. package/templates/base/dist/cli.js +683 -0
  46. package/templates/base/dist/cli.js.map +1 -0
  47. package/templates/base/nitro-devnode/LICENSE +201 -0
  48. package/templates/base/nitro-devnode/README.md +70 -0
  49. package/templates/base/nitro-devnode/run-dev-node.sh +132 -0
  50. package/templates/base/nitro-devnode/start-chain-with-cors.sh +150 -0
  51. package/templates/base/nitro-devnode/stylus-deployer-bytecode.txt +1 -0
  52. package/templates/base/nitro-devnode/stylus-dev/Dockerfile +10 -0
  53. package/templates/base/package.json +44 -0
  54. package/templates/base/packages/nextjs/.env.example +13 -0
  55. package/templates/base/packages/nextjs/.eslintignore +11 -0
  56. package/templates/base/packages/nextjs/.eslintrc.json +15 -0
  57. package/templates/base/packages/nextjs/.gitignore.template.mjs +42 -0
  58. package/templates/base/packages/nextjs/.prettierrc.js +9 -0
  59. package/templates/base/packages/nextjs/.prettierrc.json +8 -0
  60. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressCodeTab.tsx +27 -0
  61. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressComponent.tsx +36 -0
  62. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressLogsTab.tsx +21 -0
  63. package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressStorageTab.tsx +61 -0
  64. package/templates/base/packages/nextjs/app/blockexplorer/_components/BackButton.tsx +12 -0
  65. package/templates/base/packages/nextjs/app/blockexplorer/_components/ContractTabs.tsx +102 -0
  66. package/templates/base/packages/nextjs/app/blockexplorer/_components/PaginationButton.tsx +39 -0
  67. package/templates/base/packages/nextjs/app/blockexplorer/_components/SearchBar.tsx +49 -0
  68. package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionHash.tsx +28 -0
  69. package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionsTable.tsx +71 -0
  70. package/templates/base/packages/nextjs/app/blockexplorer/_components/index.tsx +7 -0
  71. package/templates/base/packages/nextjs/app/blockexplorer/address/[address]/page.tsx +101 -0
  72. package/templates/base/packages/nextjs/app/blockexplorer/layout.tsx +12 -0
  73. package/templates/base/packages/nextjs/app/blockexplorer/page.tsx +83 -0
  74. package/templates/base/packages/nextjs/app/blockexplorer/transaction/[txHash]/page.tsx +23 -0
  75. package/templates/base/packages/nextjs/app/blockexplorer/transaction/_components/TransactionComp.tsx +152 -0
  76. package/templates/base/packages/nextjs/app/debug/_components/DebugContracts.tsx +73 -0
  77. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractInput.tsx +84 -0
  78. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractReadMethods.tsx +43 -0
  79. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +164 -0
  80. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractVariables.tsx +50 -0
  81. package/templates/base/packages/nextjs/app/debug/_components/contract/ContractWriteMethods.tsx +49 -0
  82. package/templates/base/packages/nextjs/app/debug/_components/contract/DisplayVariable.tsx +85 -0
  83. package/templates/base/packages/nextjs/app/debug/_components/contract/InheritanceTooltip.tsx +14 -0
  84. package/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx +102 -0
  85. package/templates/base/packages/nextjs/app/debug/_components/contract/Tuple.tsx +44 -0
  86. package/templates/base/packages/nextjs/app/debug/_components/contract/TupleArray.tsx +142 -0
  87. package/templates/base/packages/nextjs/app/debug/_components/contract/TxReceipt.tsx +42 -0
  88. package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx +144 -0
  89. package/templates/base/packages/nextjs/app/debug/_components/contract/index.tsx +8 -0
  90. package/templates/base/packages/nextjs/app/debug/_components/contract/utilsContract.tsx +166 -0
  91. package/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx +114 -0
  92. package/templates/base/packages/nextjs/app/debug/page.tsx +14 -0
  93. package/templates/base/packages/nextjs/app/layout.tsx +67 -0
  94. package/templates/base/packages/nextjs/app/not-found.tsx +16 -0
  95. package/templates/base/packages/nextjs/app/page.tsx +94 -0
  96. package/templates/base/packages/nextjs/components/Background.tsx +37 -0
  97. package/templates/base/packages/nextjs/components/Card.tsx +40 -0
  98. package/templates/base/packages/nextjs/components/Footer.tsx +93 -0
  99. package/templates/base/packages/nextjs/components/Header.tsx +114 -0
  100. package/templates/base/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +77 -0
  101. package/templates/base/packages/nextjs/components/SwitchTheme.tsx +41 -0
  102. package/templates/base/packages/nextjs/components/ThemeProvider.tsx +13 -0
  103. package/templates/base/packages/nextjs/components/assets/BuidlGuidlLogo.tsx +18 -0
  104. package/templates/base/packages/nextjs/components/scaffold-eth/Address/Address.tsx +187 -0
  105. package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressCopyIcon.tsx +23 -0
  106. package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressLinkWrapper.tsx +29 -0
  107. package/templates/base/packages/nextjs/components/scaffold-eth/Balance.tsx +75 -0
  108. package/templates/base/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx +17 -0
  109. package/templates/base/packages/nextjs/components/scaffold-eth/Faucet.tsx +131 -0
  110. package/templates/base/packages/nextjs/components/scaffold-eth/FaucetButton.tsx +75 -0
  111. package/templates/base/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +120 -0
  112. package/templates/base/packages/nextjs/components/scaffold-eth/Input/Bytes32Input.tsx +31 -0
  113. package/templates/base/packages/nextjs/components/scaffold-eth/Input/BytesInput.tsx +28 -0
  114. package/templates/base/packages/nextjs/components/scaffold-eth/Input/EtherInput.tsx +128 -0
  115. package/templates/base/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx +66 -0
  116. package/templates/base/packages/nextjs/components/scaffold-eth/Input/IntegerInput.tsx +63 -0
  117. package/templates/base/packages/nextjs/components/scaffold-eth/Input/index.ts +9 -0
  118. package/templates/base/packages/nextjs/components/scaffold-eth/Input/utils.ts +109 -0
  119. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +121 -0
  120. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressQRCodeModal.tsx +33 -0
  121. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/BurnerWalletModal.tsx +63 -0
  122. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/NetworkOptions.tsx +48 -0
  123. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/WrongNetworkDropdown.tsx +32 -0
  124. package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +89 -0
  125. package/templates/base/packages/nextjs/components/scaffold-eth/index.tsx +7 -0
  126. package/templates/base/packages/nextjs/contracts/deployedContracts.ts +9 -0
  127. package/templates/base/packages/nextjs/contracts/externalContracts.ts +16 -0
  128. package/templates/base/packages/nextjs/eslint.config.mjs +32 -0
  129. package/templates/base/packages/nextjs/hooks/scaffold-eth/index.ts +17 -0
  130. package/templates/base/packages/nextjs/hooks/scaffold-eth/useAnimationConfig.ts +20 -0
  131. package/templates/base/packages/nextjs/hooks/scaffold-eth/useContractLogs.ts +40 -0
  132. package/templates/base/packages/nextjs/hooks/scaffold-eth/useCopyToClipboard.ts +19 -0
  133. package/templates/base/packages/nextjs/hooks/scaffold-eth/useDeployedContractInfo.ts +86 -0
  134. package/templates/base/packages/nextjs/hooks/scaffold-eth/useDisplayUsdMode.ts +21 -0
  135. package/templates/base/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts +133 -0
  136. package/templates/base/packages/nextjs/hooks/scaffold-eth/useInitializeNativeCurrencyPrice.ts +32 -0
  137. package/templates/base/packages/nextjs/hooks/scaffold-eth/useNativeCurrencyPrice.ts +34 -0
  138. package/templates/base/packages/nextjs/hooks/scaffold-eth/useNetworkColor.ts +22 -0
  139. package/templates/base/packages/nextjs/hooks/scaffold-eth/useOutsideClick.ts +23 -0
  140. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldContract.ts +65 -0
  141. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldEventHistory.ts +213 -0
  142. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldReadContract.ts +80 -0
  143. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWatchContractEvent.ts +40 -0
  144. package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts +191 -0
  145. package/templates/base/packages/nextjs/hooks/scaffold-eth/useSelectedNetwork.ts +18 -0
  146. package/templates/base/packages/nextjs/hooks/scaffold-eth/useTargetNetwork.ts +23 -0
  147. package/templates/base/packages/nextjs/hooks/scaffold-eth/useTransactor.tsx +114 -0
  148. package/templates/base/packages/nextjs/hooks/scaffold-eth/useWatchBalance.ts +21 -0
  149. package/templates/base/packages/nextjs/icons/CompassIcon.tsx +39 -0
  150. package/templates/base/packages/nextjs/icons/DarkBugAntIcon.tsx +30 -0
  151. package/templates/base/packages/nextjs/icons/LightBugAntIcon.tsx +52 -0
  152. package/templates/base/packages/nextjs/next-env.d.ts +5 -0
  153. package/templates/base/packages/nextjs/next.config.js +19 -0
  154. package/templates/base/packages/nextjs/package.json +58 -0
  155. package/templates/base/packages/nextjs/postcss.config.js +6 -0
  156. package/templates/base/packages/nextjs/public/debug-image.png +0 -0
  157. package/templates/base/packages/nextjs/public/favicon.png +0 -0
  158. package/templates/base/packages/nextjs/public/logo.svg +8 -0
  159. package/templates/base/packages/nextjs/public/manifest.json +5 -0
  160. package/templates/base/packages/nextjs/public/thumbnail.jpg +0 -0
  161. package/templates/base/packages/nextjs/react-copy-to-clipboard.d.ts +44 -0
  162. package/templates/base/packages/nextjs/scaffold.config.ts +56 -0
  163. package/templates/base/packages/nextjs/services/store/store.ts +39 -0
  164. package/templates/base/packages/nextjs/services/web3/wagmiConfig.tsx +44 -0
  165. package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +51 -0
  166. package/templates/base/packages/nextjs/styles/globals.css +80 -0
  167. package/templates/base/packages/nextjs/tailwind.config.js +97 -0
  168. package/templates/base/packages/nextjs/tsconfig.json +28 -0
  169. package/templates/base/packages/nextjs/types/abitype/abi.d.ts +16 -0
  170. package/templates/base/packages/nextjs/types/utils.ts +3 -0
  171. package/templates/base/packages/nextjs/utils/scaffold-eth/block.ts +17 -0
  172. package/templates/base/packages/nextjs/utils/scaffold-eth/common.ts +8 -0
  173. package/templates/base/packages/nextjs/utils/scaffold-eth/contract.ts +352 -0
  174. package/templates/base/packages/nextjs/utils/scaffold-eth/contractsData.ts +11 -0
  175. package/templates/base/packages/nextjs/utils/scaffold-eth/decodeTxData.ts +65 -0
  176. package/templates/base/packages/nextjs/utils/scaffold-eth/fetchPriceFromUniswap.ts +72 -0
  177. package/templates/base/packages/nextjs/utils/scaffold-eth/getMetadata.ts +50 -0
  178. package/templates/base/packages/nextjs/utils/scaffold-eth/getParsedError.ts +35 -0
  179. package/templates/base/packages/nextjs/utils/scaffold-eth/index.ts +6 -0
  180. package/templates/base/packages/nextjs/utils/scaffold-eth/notification.tsx +90 -0
  181. package/templates/base/packages/nextjs/utils/scaffold-stylus/burner.ts +59 -0
  182. package/templates/base/packages/nextjs/utils/scaffold-stylus/chain.ts +42 -0
  183. package/templates/base/packages/nextjs/utils/scaffold-stylus/index.ts +3 -0
  184. package/templates/base/packages/nextjs/utils/scaffold-stylus/networks.ts +94 -0
  185. package/templates/base/packages/nextjs/vercel.json +3 -0
  186. package/templates/base/packages/stylus/.env.example +16 -0
  187. package/templates/base/packages/stylus/.eslintrc.js +23 -0
  188. package/templates/base/packages/stylus/.gitignore.template.mjs +7 -0
  189. package/templates/base/packages/stylus/jest.config.js +15 -0
  190. package/templates/base/packages/stylus/package.json +48 -0
  191. package/templates/base/packages/stylus/scripts/deploy.ts +46 -0
  192. package/templates/base/packages/stylus/scripts/deploy_contract.ts +84 -0
  193. package/templates/base/packages/stylus/scripts/deploy_wrapper.ts +39 -0
  194. package/templates/base/packages/stylus/scripts/export_abi.ts +87 -0
  195. package/templates/base/packages/stylus/scripts/index.ts +0 -0
  196. package/templates/base/packages/stylus/scripts/new_module.sh +35 -0
  197. package/templates/base/packages/stylus/scripts/test_network.ts +31 -0
  198. package/templates/base/packages/stylus/scripts/utils/command.ts +152 -0
  199. package/templates/base/packages/stylus/scripts/utils/contract.ts +228 -0
  200. package/templates/base/packages/stylus/scripts/utils/deployment.ts +260 -0
  201. package/templates/base/packages/stylus/scripts/utils/index.ts +6 -0
  202. package/templates/base/packages/stylus/scripts/utils/network.ts +132 -0
  203. package/templates/base/packages/stylus/scripts/utils/type.ts +51 -0
  204. package/templates/base/packages/stylus/scripts/utils.ts +3 -0
  205. package/templates/base/packages/stylus/tsconfig.json +41 -0
  206. package/templates/base/packages/stylus/your-contract/.cargo/config.toml +18 -0
  207. package/templates/base/packages/stylus/your-contract/Cargo.lock +5761 -0
  208. package/templates/base/packages/stylus/your-contract/Cargo.toml +48 -0
  209. package/templates/base/packages/stylus/your-contract/examples/counter.rs +78 -0
  210. package/templates/base/packages/stylus/your-contract/header.png +0 -0
  211. package/templates/base/packages/stylus/your-contract/licenses/Apache-2.0 +201 -0
  212. package/templates/base/packages/stylus/your-contract/licenses/COPYRIGHT.md +5 -0
  213. package/templates/base/packages/stylus/your-contract/licenses/DCO.txt +34 -0
  214. package/templates/base/packages/stylus/your-contract/licenses/MIT +21 -0
  215. package/templates/base/packages/stylus/your-contract/rust-toolchain.toml +2 -0
  216. package/templates/base/packages/stylus/your-contract/src/lib.rs +241 -0
  217. package/templates/base/packages/stylus/your-contract/src/main.rs +10 -0
  218. package/templates/base/readme.md +352 -0
  219. package/templates/base/yarn.lock +17859 -0
  220. package/tsconfig.json +13 -0
@@ -0,0 +1,20 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ const ANIMATION_TIME = 2000;
4
+
5
+ export function useAnimationConfig(data: any) {
6
+ const [showAnimation, setShowAnimation] = useState(false);
7
+ const [prevData, setPrevData] = useState();
8
+
9
+ useEffect(() => {
10
+ if (prevData !== undefined && prevData !== data) {
11
+ setShowAnimation(true);
12
+ setTimeout(() => setShowAnimation(false), ANIMATION_TIME);
13
+ }
14
+ setPrevData(data);
15
+ }, [data, prevData]);
16
+
17
+ return {
18
+ showAnimation,
19
+ };
20
+ }
@@ -0,0 +1,40 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useTargetNetwork } from "./useTargetNetwork";
3
+ import { Address, Log } from "viem";
4
+ import { usePublicClient } from "wagmi";
5
+
6
+ export const useContractLogs = (address: Address) => {
7
+ const [logs, setLogs] = useState<Log[]>([]);
8
+ const { targetNetwork } = useTargetNetwork();
9
+ const client = usePublicClient({ chainId: targetNetwork.id });
10
+
11
+ useEffect(() => {
12
+ const fetchLogs = async () => {
13
+ if (!client) return console.error("Client not found");
14
+ try {
15
+ const existingLogs = await client.getLogs({
16
+ address: address,
17
+ fromBlock: 0n,
18
+ toBlock: "latest",
19
+ });
20
+ setLogs(existingLogs);
21
+ } catch (error) {
22
+ console.error("Failed to fetch logs:", error);
23
+ }
24
+ };
25
+ fetchLogs();
26
+
27
+ return client?.watchBlockNumber({
28
+ onBlockNumber: async (_blockNumber, prevBlockNumber) => {
29
+ const newLogs = await client.getLogs({
30
+ address: address,
31
+ fromBlock: prevBlockNumber,
32
+ toBlock: "latest",
33
+ });
34
+ setLogs(prevLogs => [...prevLogs, ...newLogs]);
35
+ },
36
+ });
37
+ }, [address, client]);
38
+
39
+ return logs;
40
+ };
@@ -0,0 +1,19 @@
1
+ import { useState } from "react";
2
+
3
+ export const useCopyToClipboard = () => {
4
+ const [isCopiedToClipboard, setIsCopiedToClipboard] = useState(false);
5
+
6
+ const copyToClipboard = async (text: string) => {
7
+ try {
8
+ await navigator.clipboard.writeText(text);
9
+ setIsCopiedToClipboard(true);
10
+ setTimeout(() => {
11
+ setIsCopiedToClipboard(false);
12
+ }, 800);
13
+ } catch (err) {
14
+ console.error("Failed to copy text:", err);
15
+ }
16
+ };
17
+
18
+ return { copyToClipboard, isCopiedToClipboard };
19
+ };
@@ -0,0 +1,86 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useIsMounted } from "usehooks-ts";
3
+ import { usePublicClient } from "wagmi";
4
+ import { useSelectedNetwork } from "~~/hooks/scaffold-eth";
5
+ import {
6
+ Contract,
7
+ ContractCodeStatus,
8
+ ContractName,
9
+ UseDeployedContractConfig,
10
+ contracts,
11
+ } from "~~/utils/scaffold-eth/contract";
12
+
13
+ type DeployedContractData<TContractName extends ContractName> = {
14
+ data: Contract<TContractName> | undefined;
15
+ isLoading: boolean;
16
+ };
17
+
18
+ /**
19
+ * Gets the matching contract info for the provided contract name from the contracts present in deployedContracts.ts
20
+ * and externalContracts.ts corresponding to targetNetworks configured in scaffold.config.ts
21
+ */
22
+ export function useDeployedContractInfo<TContractName extends ContractName>(
23
+ config: UseDeployedContractConfig<TContractName>,
24
+ ): DeployedContractData<TContractName>;
25
+ /**
26
+ * @deprecated Use object parameter version instead: useDeployedContractInfo({ contractName: "YourContract" })
27
+ */
28
+ export function useDeployedContractInfo<TContractName extends ContractName>(
29
+ contractName: TContractName,
30
+ ): DeployedContractData<TContractName>;
31
+
32
+ export function useDeployedContractInfo<TContractName extends ContractName>(
33
+ configOrName: UseDeployedContractConfig<TContractName> | TContractName,
34
+ ): DeployedContractData<TContractName> {
35
+ const isMounted = useIsMounted();
36
+
37
+ const finalConfig: UseDeployedContractConfig<TContractName> =
38
+ typeof configOrName === "string" ? { contractName: configOrName } : (configOrName as any);
39
+
40
+ useEffect(() => {
41
+ if (typeof configOrName === "string") {
42
+ console.warn(
43
+ "Using `useDeployedContractInfo` with a string parameter is deprecated. Please use the object parameter version instead.",
44
+ );
45
+ }
46
+ }, [configOrName]);
47
+ const { contractName, chainId } = finalConfig;
48
+ const selectedNetwork = useSelectedNetwork(chainId);
49
+ const deployedContract = contracts?.[selectedNetwork.id]?.[contractName as ContractName] as Contract<TContractName>;
50
+ const [status, setStatus] = useState<ContractCodeStatus>(ContractCodeStatus.LOADING);
51
+ const publicClient = usePublicClient({ chainId: selectedNetwork.id });
52
+
53
+ useEffect(() => {
54
+ const checkContractDeployment = async () => {
55
+ try {
56
+ if (!isMounted() || !publicClient) return;
57
+
58
+ if (!deployedContract) {
59
+ setStatus(ContractCodeStatus.NOT_FOUND);
60
+ return;
61
+ }
62
+
63
+ const code = await publicClient.getBytecode({
64
+ address: deployedContract.address,
65
+ });
66
+
67
+ // If contract code is `0x` => no contract deployed on that address
68
+ if (code === "0x") {
69
+ setStatus(ContractCodeStatus.NOT_FOUND);
70
+ return;
71
+ }
72
+ setStatus(ContractCodeStatus.DEPLOYED);
73
+ } catch (e) {
74
+ console.error(e);
75
+ setStatus(ContractCodeStatus.NOT_FOUND);
76
+ }
77
+ };
78
+
79
+ checkContractDeployment();
80
+ }, [isMounted, contractName, deployedContract, publicClient]);
81
+
82
+ return {
83
+ data: status === ContractCodeStatus.DEPLOYED ? deployedContract : undefined,
84
+ isLoading: status === ContractCodeStatus.LOADING,
85
+ };
86
+ }
@@ -0,0 +1,21 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useGlobalState } from "~~/services/store/store";
3
+
4
+ export const useDisplayUsdMode = ({ defaultUsdMode = false }: { defaultUsdMode?: boolean }) => {
5
+ const nativeCurrencyPrice = useGlobalState(state => state.nativeCurrency.price);
6
+ const isPriceFetched = nativeCurrencyPrice > 0;
7
+ const predefinedUsdMode = isPriceFetched ? Boolean(defaultUsdMode) : false;
8
+ const [displayUsdMode, setDisplayUsdMode] = useState(predefinedUsdMode);
9
+
10
+ useEffect(() => {
11
+ setDisplayUsdMode(predefinedUsdMode);
12
+ }, [predefinedUsdMode]);
13
+
14
+ const toggleDisplayUsdMode = useCallback(() => {
15
+ if (isPriceFetched) {
16
+ setDisplayUsdMode(!displayUsdMode);
17
+ }
18
+ }, [displayUsdMode, isPriceFetched]);
19
+
20
+ return { displayUsdMode, toggleDisplayUsdMode };
21
+ };
@@ -0,0 +1,133 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import {
3
+ Block,
4
+ Hash,
5
+ Transaction,
6
+ TransactionReceipt,
7
+ createTestClient,
8
+ publicActions,
9
+ walletActions,
10
+ webSocket,
11
+ } from "viem";
12
+ import { decodeTransactionData } from "~~/utils/scaffold-eth";
13
+ import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
14
+
15
+ const BLOCKS_PER_PAGE = 20;
16
+
17
+ export const testClient = createTestClient({
18
+ chain: arbitrumNitro,
19
+ mode: "hardhat",
20
+ transport: webSocket("ws://127.0.0.1:8547"),
21
+ })
22
+ .extend(publicActions)
23
+ .extend(walletActions);
24
+
25
+ export const useFetchBlocks = () => {
26
+ const [blocks, setBlocks] = useState<Block[]>([]);
27
+ const [transactionReceipts, setTransactionReceipts] = useState<{
28
+ [key: string]: TransactionReceipt;
29
+ }>({});
30
+ const [currentPage, setCurrentPage] = useState(0);
31
+ const [totalBlocks, setTotalBlocks] = useState(0n);
32
+ const [error, setError] = useState<Error | null>(null);
33
+
34
+ const fetchBlocks = useCallback(async () => {
35
+ setError(null);
36
+
37
+ try {
38
+ const blockNumber = await testClient.getBlockNumber();
39
+ setTotalBlocks(blockNumber);
40
+
41
+ const startingBlock = blockNumber - BigInt(currentPage * BLOCKS_PER_PAGE);
42
+ const blockNumbersToFetch = Array.from(
43
+ { length: Number(BLOCKS_PER_PAGE < startingBlock + 1n ? BLOCKS_PER_PAGE : startingBlock + 1n) },
44
+ (_, i) => startingBlock - BigInt(i),
45
+ );
46
+
47
+ const blocksWithTransactions = blockNumbersToFetch.map(async blockNumber => {
48
+ try {
49
+ return testClient.getBlock({ blockNumber, includeTransactions: true });
50
+ } catch (err) {
51
+ setError(err instanceof Error ? err : new Error("An error occurred."));
52
+ throw err;
53
+ }
54
+ });
55
+ const fetchedBlocks = await Promise.all(blocksWithTransactions);
56
+
57
+ fetchedBlocks.forEach(block => {
58
+ block.transactions.forEach(tx => decodeTransactionData(tx as Transaction));
59
+ });
60
+
61
+ const txReceipts = await Promise.all(
62
+ fetchedBlocks.flatMap(block =>
63
+ block.transactions.map(async tx => {
64
+ try {
65
+ const receipt = await testClient.getTransactionReceipt({ hash: (tx as Transaction).hash });
66
+ return { [(tx as Transaction).hash]: receipt };
67
+ } catch (err) {
68
+ setError(err instanceof Error ? err : new Error("An error occurred."));
69
+ throw err;
70
+ }
71
+ }),
72
+ ),
73
+ );
74
+
75
+ setBlocks(fetchedBlocks);
76
+ setTransactionReceipts(prevReceipts => ({ ...prevReceipts, ...Object.assign({}, ...txReceipts) }));
77
+ } catch (err) {
78
+ setError(err instanceof Error ? err : new Error("An error occurred."));
79
+ }
80
+ }, [currentPage]);
81
+
82
+ useEffect(() => {
83
+ fetchBlocks();
84
+ }, [fetchBlocks]);
85
+
86
+ useEffect(() => {
87
+ const handleNewBlock = async (newBlock: any) => {
88
+ try {
89
+ if (currentPage === 0) {
90
+ if (newBlock.transactions.length > 0) {
91
+ const transactionsDetails = await Promise.all(
92
+ newBlock.transactions.map((txHash: string) => testClient.getTransaction({ hash: txHash as Hash })),
93
+ );
94
+ newBlock.transactions = transactionsDetails;
95
+ }
96
+
97
+ newBlock.transactions.forEach((tx: Transaction) => decodeTransactionData(tx as Transaction));
98
+
99
+ const receipts = await Promise.all(
100
+ newBlock.transactions.map(async (tx: Transaction) => {
101
+ try {
102
+ const receipt = await testClient.getTransactionReceipt({ hash: (tx as Transaction).hash });
103
+ return { [(tx as Transaction).hash]: receipt };
104
+ } catch (err) {
105
+ setError(err instanceof Error ? err : new Error("An error occurred fetching receipt."));
106
+ throw err;
107
+ }
108
+ }),
109
+ );
110
+
111
+ setBlocks(prevBlocks => [newBlock, ...prevBlocks.slice(0, BLOCKS_PER_PAGE - 1)]);
112
+ setTransactionReceipts(prevReceipts => ({ ...prevReceipts, ...Object.assign({}, ...receipts) }));
113
+ }
114
+ if (newBlock.number) {
115
+ setTotalBlocks(newBlock.number);
116
+ }
117
+ } catch (err) {
118
+ setError(err instanceof Error ? err : new Error("An error occurred."));
119
+ }
120
+ };
121
+
122
+ return testClient.watchBlocks({ onBlock: handleNewBlock, includeTransactions: true });
123
+ }, [currentPage]);
124
+
125
+ return {
126
+ blocks,
127
+ transactionReceipts,
128
+ currentPage,
129
+ totalBlocks,
130
+ setCurrentPage,
131
+ error,
132
+ };
133
+ };
@@ -0,0 +1,32 @@
1
+ import { useCallback, useEffect } from "react";
2
+ import { useTargetNetwork } from "./useTargetNetwork";
3
+ import { useInterval } from "usehooks-ts";
4
+ import scaffoldConfig from "~~/scaffold.config";
5
+ import { useGlobalState } from "~~/services/store/store";
6
+ import { fetchPriceFromUniswap } from "~~/utils/scaffold-eth";
7
+
8
+ const enablePolling = false;
9
+
10
+ /**
11
+ * Get the price of Native Currency based on Native Token/DAI trading pair from Uniswap SDK
12
+ */
13
+ export const useInitializeNativeCurrencyPrice = () => {
14
+ const setNativeCurrencyPrice = useGlobalState(state => state.setNativeCurrencyPrice);
15
+ const setIsNativeCurrencyFetching = useGlobalState(state => state.setIsNativeCurrencyFetching);
16
+ const { targetNetwork } = useTargetNetwork();
17
+
18
+ const fetchPrice = useCallback(async () => {
19
+ setIsNativeCurrencyFetching(true);
20
+ const price = await fetchPriceFromUniswap(targetNetwork);
21
+ setNativeCurrencyPrice(price);
22
+ setIsNativeCurrencyFetching(false);
23
+ }, [setIsNativeCurrencyFetching, setNativeCurrencyPrice, targetNetwork]);
24
+
25
+ // Get the price of ETH from Uniswap on mount
26
+ useEffect(() => {
27
+ fetchPrice();
28
+ }, [fetchPrice]);
29
+
30
+ // Get the price of ETH from Uniswap at a given interval
31
+ useInterval(fetchPrice, enablePolling ? scaffoldConfig.pollingInterval : null);
32
+ };
@@ -0,0 +1,34 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useTargetNetwork } from "./useTargetNetwork";
3
+ import { useInterval } from "usehooks-ts";
4
+ import scaffoldConfig from "~~/scaffold.config";
5
+ import { fetchPriceFromUniswap } from "~~/utils/scaffold-eth";
6
+
7
+ const enablePolling = false;
8
+
9
+ /**
10
+ * Get the price of Native Currency based on Native Token/DAI trading pair from Uniswap SDK
11
+ */
12
+ export const useNativeCurrencyPrice = () => {
13
+ const { targetNetwork } = useTargetNetwork();
14
+ const [nativeCurrencyPrice, setNativeCurrencyPrice] = useState(0);
15
+
16
+ // Get the price of ETH from Uniswap on mount
17
+ useEffect(() => {
18
+ (async () => {
19
+ const price = await fetchPriceFromUniswap(targetNetwork);
20
+ setNativeCurrencyPrice(price);
21
+ })();
22
+ }, [targetNetwork]);
23
+
24
+ // Get the price of ETH from Uniswap at a given interval
25
+ useInterval(
26
+ async () => {
27
+ const price = await fetchPriceFromUniswap(targetNetwork);
28
+ setNativeCurrencyPrice(price);
29
+ },
30
+ enablePolling ? scaffoldConfig.pollingInterval : null,
31
+ );
32
+
33
+ return nativeCurrencyPrice;
34
+ };
@@ -0,0 +1,22 @@
1
+ import { useTheme } from "next-themes";
2
+ import { useSelectedNetwork } from "~~/hooks/scaffold-eth";
3
+ import { AllowedChainIds, ChainWithAttributes } from "~~/utils/scaffold-stylus";
4
+
5
+ export const DEFAULT_NETWORK_COLOR: [string, string] = ["#666666", "#bbbbbb"];
6
+
7
+ export function getNetworkColor(network: ChainWithAttributes, isDarkMode: boolean) {
8
+ const colorConfig = network.color ?? DEFAULT_NETWORK_COLOR;
9
+ return Array.isArray(colorConfig) ? (isDarkMode ? colorConfig[1] : colorConfig[0]) : colorConfig;
10
+ }
11
+
12
+ /**
13
+ * Gets the color of the target network
14
+ */
15
+ export const useNetworkColor = (chainId?: AllowedChainIds) => {
16
+ const { resolvedTheme } = useTheme();
17
+
18
+ const chain = useSelectedNetwork(chainId);
19
+ const isDarkMode = resolvedTheme === "dark";
20
+
21
+ return getNetworkColor(chain, isDarkMode);
22
+ };
@@ -0,0 +1,23 @@
1
+ import React, { useEffect } from "react";
2
+
3
+ /**
4
+ * Handles clicks outside of passed ref element
5
+ * @param ref - react ref of the element
6
+ * @param callback - callback function to call when clicked outside
7
+ */
8
+ export const useOutsideClick = (ref: React.RefObject<HTMLElement | null>, callback: { (): void }) => {
9
+ useEffect(() => {
10
+ function handleOutsideClick(event: MouseEvent) {
11
+ if (!(event.target instanceof Element)) {
12
+ return;
13
+ }
14
+
15
+ if (ref.current && !ref.current.contains(event.target)) {
16
+ callback();
17
+ }
18
+ }
19
+
20
+ document.addEventListener("click", handleOutsideClick);
21
+ return () => document.removeEventListener("click", handleOutsideClick);
22
+ }, [ref, callback]);
23
+ };
@@ -0,0 +1,65 @@
1
+ import { Account, Address, Chain, Client, Transport, getContract } from "viem";
2
+ import { usePublicClient } from "wagmi";
3
+ import { GetWalletClientReturnType } from "wagmi/actions";
4
+ import { useSelectedNetwork } from "~~/hooks/scaffold-eth";
5
+ import { useDeployedContractInfo } from "~~/hooks/scaffold-eth";
6
+ import { AllowedChainIds } from "~~/utils/scaffold-stylus";
7
+ import { Contract, ContractName } from "~~/utils/scaffold-eth/contract";
8
+
9
+ /**
10
+ * Gets a viem instance of the contract present in deployedContracts.ts or externalContracts.ts corresponding to
11
+ * targetNetworks configured in scaffold.config.ts. Optional walletClient can be passed for doing write transactions.
12
+ * @param config - The config settings for the hook
13
+ * @param config.contractName - deployed contract name
14
+ * @param config.walletClient - optional walletClient from wagmi useWalletClient hook can be passed for doing write transactions
15
+ * @param config.chainId - optional chainId that is configured with the scaffold project to make use for multi-chain interactions.
16
+ */
17
+ export const useScaffoldContract = <
18
+ TContractName extends ContractName,
19
+ TWalletClient extends Exclude<GetWalletClientReturnType, null> | undefined,
20
+ >({
21
+ contractName,
22
+ walletClient,
23
+ chainId,
24
+ }: {
25
+ contractName: TContractName;
26
+ walletClient?: TWalletClient | null;
27
+ chainId?: AllowedChainIds;
28
+ }) => {
29
+ const selectedNetwork = useSelectedNetwork(chainId);
30
+ const { data: deployedContractData, isLoading: deployedContractLoading } = useDeployedContractInfo({
31
+ contractName,
32
+ chainId: selectedNetwork?.id as AllowedChainIds,
33
+ });
34
+
35
+ const publicClient = usePublicClient({ chainId: selectedNetwork?.id });
36
+
37
+ let contract = undefined;
38
+ if (deployedContractData && publicClient) {
39
+ contract = getContract<
40
+ Transport,
41
+ Address,
42
+ Contract<TContractName>["abi"],
43
+ TWalletClient extends Exclude<GetWalletClientReturnType, null>
44
+ ? {
45
+ public: Client<Transport, Chain>;
46
+ wallet: TWalletClient;
47
+ }
48
+ : { public: Client<Transport, Chain> },
49
+ Chain,
50
+ Account
51
+ >({
52
+ address: deployedContractData.address,
53
+ abi: deployedContractData.abi as Contract<TContractName>["abi"],
54
+ client: {
55
+ public: publicClient,
56
+ wallet: walletClient ? walletClient : undefined,
57
+ } as any,
58
+ });
59
+ }
60
+
61
+ return {
62
+ data: contract,
63
+ isLoading: deployedContractLoading,
64
+ };
65
+ };