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.
- package/.github/issue_template.md +7 -0
- package/.github/pull_request_template.md +11 -0
- package/.github/workflows/release-alpha.yml +32 -0
- package/.github/workflows/release-manual.yml +26 -0
- package/.yarnrc.yml +1 -0
- package/CONTRIBUTING.md +42 -0
- package/README.md +66 -0
- package/bin/create-dapp-ss.js +4 -0
- package/package.json +46 -0
- package/rollup.config.js +22 -0
- package/src/cli.ts +14 -0
- package/src/extensions.json +14 -0
- package/src/main.ts +72 -0
- package/src/tasks/copy-extension-file.ts +227 -0
- package/src/tasks/copy-template-files.ts +252 -0
- package/src/tasks/create-first-git-commit.ts +35 -0
- package/src/tasks/create-project-directory.ts +34 -0
- package/src/tasks/index.ts +5 -0
- package/src/tasks/install-packages.ts +15 -0
- package/src/tasks/prettier-format.ts +17 -0
- package/src/types.ts +31 -0
- package/src/utils/consts.ts +1 -0
- package/src/utils/find-files-recursively.ts +19 -0
- package/src/utils/link.ts +44 -0
- package/src/utils/load-extensions.ts +10 -0
- package/src/utils/merge-package-json.ts +33 -0
- package/src/utils/parse-arguments-into-options.ts +38 -0
- package/src/utils/prompt-for-missing-options.ts +53 -0
- package/src/utils/render-intro-message.ts +11 -0
- package/src/utils/render-outro-message.ts +34 -0
- package/templates/base/.github/ISSUE_TEMPLATE/bug_report.yml +58 -0
- package/templates/base/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/templates/base/.github/pull_request_template.md +16 -0
- package/templates/base/.github/workflows/lint.yaml +300 -0
- package/templates/base/.gitignore.template.mjs +19 -0
- package/templates/base/.gitmodules +0 -0
- package/templates/base/.husky/pre-commit +4 -0
- package/templates/base/.lintstagedrc.js +21 -0
- package/templates/base/.vscode/settings.json +7 -0
- package/templates/base/.yarn/plugins/@yarnpkg/plugin-typescript.cjs +9 -0
- package/templates/base/.yarn/releases/yarn-3.2.3.cjs +783 -0
- package/templates/base/.yarnrc.yml +11 -0
- package/templates/base/CONTRIBUTING.md +86 -0
- package/templates/base/LICENCE +21 -0
- package/templates/base/dist/cli.js +683 -0
- package/templates/base/dist/cli.js.map +1 -0
- package/templates/base/nitro-devnode/LICENSE +201 -0
- package/templates/base/nitro-devnode/README.md +70 -0
- package/templates/base/nitro-devnode/run-dev-node.sh +132 -0
- package/templates/base/nitro-devnode/start-chain-with-cors.sh +150 -0
- package/templates/base/nitro-devnode/stylus-deployer-bytecode.txt +1 -0
- package/templates/base/nitro-devnode/stylus-dev/Dockerfile +10 -0
- package/templates/base/package.json +44 -0
- package/templates/base/packages/nextjs/.env.example +13 -0
- package/templates/base/packages/nextjs/.eslintignore +11 -0
- package/templates/base/packages/nextjs/.eslintrc.json +15 -0
- package/templates/base/packages/nextjs/.gitignore.template.mjs +42 -0
- package/templates/base/packages/nextjs/.prettierrc.js +9 -0
- package/templates/base/packages/nextjs/.prettierrc.json +8 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressCodeTab.tsx +27 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressComponent.tsx +36 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressLogsTab.tsx +21 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/AddressStorageTab.tsx +61 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/BackButton.tsx +12 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/ContractTabs.tsx +102 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/PaginationButton.tsx +39 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/SearchBar.tsx +49 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionHash.tsx +28 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/TransactionsTable.tsx +71 -0
- package/templates/base/packages/nextjs/app/blockexplorer/_components/index.tsx +7 -0
- package/templates/base/packages/nextjs/app/blockexplorer/address/[address]/page.tsx +101 -0
- package/templates/base/packages/nextjs/app/blockexplorer/layout.tsx +12 -0
- package/templates/base/packages/nextjs/app/blockexplorer/page.tsx +83 -0
- package/templates/base/packages/nextjs/app/blockexplorer/transaction/[txHash]/page.tsx +23 -0
- package/templates/base/packages/nextjs/app/blockexplorer/transaction/_components/TransactionComp.tsx +152 -0
- package/templates/base/packages/nextjs/app/debug/_components/DebugContracts.tsx +73 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractInput.tsx +84 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractReadMethods.tsx +43 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +164 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractVariables.tsx +50 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractWriteMethods.tsx +49 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/DisplayVariable.tsx +85 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/InheritanceTooltip.tsx +14 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx +102 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/Tuple.tsx +44 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/TupleArray.tsx +142 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/TxReceipt.tsx +42 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx +144 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/index.tsx +8 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/utilsContract.tsx +166 -0
- package/templates/base/packages/nextjs/app/debug/_components/contract/utilsDisplay.tsx +114 -0
- package/templates/base/packages/nextjs/app/debug/page.tsx +14 -0
- package/templates/base/packages/nextjs/app/layout.tsx +67 -0
- package/templates/base/packages/nextjs/app/not-found.tsx +16 -0
- package/templates/base/packages/nextjs/app/page.tsx +94 -0
- package/templates/base/packages/nextjs/components/Background.tsx +37 -0
- package/templates/base/packages/nextjs/components/Card.tsx +40 -0
- package/templates/base/packages/nextjs/components/Footer.tsx +93 -0
- package/templates/base/packages/nextjs/components/Header.tsx +114 -0
- package/templates/base/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +77 -0
- package/templates/base/packages/nextjs/components/SwitchTheme.tsx +41 -0
- package/templates/base/packages/nextjs/components/ThemeProvider.tsx +13 -0
- package/templates/base/packages/nextjs/components/assets/BuidlGuidlLogo.tsx +18 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Address/Address.tsx +187 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressCopyIcon.tsx +23 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Address/AddressLinkWrapper.tsx +29 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Balance.tsx +75 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/BlockieAvatar.tsx +17 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Faucet.tsx +131 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/FaucetButton.tsx +75 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +120 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/Bytes32Input.tsx +31 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/BytesInput.tsx +28 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/EtherInput.tsx +128 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx +66 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/IntegerInput.tsx +63 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/index.ts +9 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/utils.ts +109 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +121 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressQRCodeModal.tsx +33 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/BurnerWalletModal.tsx +63 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/NetworkOptions.tsx +48 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/WrongNetworkDropdown.tsx +32 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +89 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/index.tsx +7 -0
- package/templates/base/packages/nextjs/contracts/deployedContracts.ts +9 -0
- package/templates/base/packages/nextjs/contracts/externalContracts.ts +16 -0
- package/templates/base/packages/nextjs/eslint.config.mjs +32 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/index.ts +17 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useAnimationConfig.ts +20 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useContractLogs.ts +40 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useCopyToClipboard.ts +19 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useDeployedContractInfo.ts +86 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useDisplayUsdMode.ts +21 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useFetchBlocks.ts +133 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useInitializeNativeCurrencyPrice.ts +32 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useNativeCurrencyPrice.ts +34 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useNetworkColor.ts +22 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useOutsideClick.ts +23 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldContract.ts +65 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldEventHistory.ts +213 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldReadContract.ts +80 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWatchContractEvent.ts +40 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts +191 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useSelectedNetwork.ts +18 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useTargetNetwork.ts +23 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useTransactor.tsx +114 -0
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useWatchBalance.ts +21 -0
- package/templates/base/packages/nextjs/icons/CompassIcon.tsx +39 -0
- package/templates/base/packages/nextjs/icons/DarkBugAntIcon.tsx +30 -0
- package/templates/base/packages/nextjs/icons/LightBugAntIcon.tsx +52 -0
- package/templates/base/packages/nextjs/next-env.d.ts +5 -0
- package/templates/base/packages/nextjs/next.config.js +19 -0
- package/templates/base/packages/nextjs/package.json +58 -0
- package/templates/base/packages/nextjs/postcss.config.js +6 -0
- package/templates/base/packages/nextjs/public/debug-image.png +0 -0
- package/templates/base/packages/nextjs/public/favicon.png +0 -0
- package/templates/base/packages/nextjs/public/logo.svg +8 -0
- package/templates/base/packages/nextjs/public/manifest.json +5 -0
- package/templates/base/packages/nextjs/public/thumbnail.jpg +0 -0
- package/templates/base/packages/nextjs/react-copy-to-clipboard.d.ts +44 -0
- package/templates/base/packages/nextjs/scaffold.config.ts +56 -0
- package/templates/base/packages/nextjs/services/store/store.ts +39 -0
- package/templates/base/packages/nextjs/services/web3/wagmiConfig.tsx +44 -0
- package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +51 -0
- package/templates/base/packages/nextjs/styles/globals.css +80 -0
- package/templates/base/packages/nextjs/tailwind.config.js +97 -0
- package/templates/base/packages/nextjs/tsconfig.json +28 -0
- package/templates/base/packages/nextjs/types/abitype/abi.d.ts +16 -0
- package/templates/base/packages/nextjs/types/utils.ts +3 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/block.ts +17 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/common.ts +8 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/contract.ts +352 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/contractsData.ts +11 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/decodeTxData.ts +65 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/fetchPriceFromUniswap.ts +72 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/getMetadata.ts +50 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/getParsedError.ts +35 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/index.ts +6 -0
- package/templates/base/packages/nextjs/utils/scaffold-eth/notification.tsx +90 -0
- package/templates/base/packages/nextjs/utils/scaffold-stylus/burner.ts +59 -0
- package/templates/base/packages/nextjs/utils/scaffold-stylus/chain.ts +42 -0
- package/templates/base/packages/nextjs/utils/scaffold-stylus/index.ts +3 -0
- package/templates/base/packages/nextjs/utils/scaffold-stylus/networks.ts +94 -0
- package/templates/base/packages/nextjs/vercel.json +3 -0
- package/templates/base/packages/stylus/.env.example +16 -0
- package/templates/base/packages/stylus/.eslintrc.js +23 -0
- package/templates/base/packages/stylus/.gitignore.template.mjs +7 -0
- package/templates/base/packages/stylus/jest.config.js +15 -0
- package/templates/base/packages/stylus/package.json +48 -0
- package/templates/base/packages/stylus/scripts/deploy.ts +46 -0
- package/templates/base/packages/stylus/scripts/deploy_contract.ts +84 -0
- package/templates/base/packages/stylus/scripts/deploy_wrapper.ts +39 -0
- package/templates/base/packages/stylus/scripts/export_abi.ts +87 -0
- package/templates/base/packages/stylus/scripts/index.ts +0 -0
- package/templates/base/packages/stylus/scripts/new_module.sh +35 -0
- package/templates/base/packages/stylus/scripts/test_network.ts +31 -0
- package/templates/base/packages/stylus/scripts/utils/command.ts +152 -0
- package/templates/base/packages/stylus/scripts/utils/contract.ts +228 -0
- package/templates/base/packages/stylus/scripts/utils/deployment.ts +260 -0
- package/templates/base/packages/stylus/scripts/utils/index.ts +6 -0
- package/templates/base/packages/stylus/scripts/utils/network.ts +132 -0
- package/templates/base/packages/stylus/scripts/utils/type.ts +51 -0
- package/templates/base/packages/stylus/scripts/utils.ts +3 -0
- package/templates/base/packages/stylus/tsconfig.json +41 -0
- package/templates/base/packages/stylus/your-contract/.cargo/config.toml +18 -0
- package/templates/base/packages/stylus/your-contract/Cargo.lock +5761 -0
- package/templates/base/packages/stylus/your-contract/Cargo.toml +48 -0
- package/templates/base/packages/stylus/your-contract/examples/counter.rs +78 -0
- package/templates/base/packages/stylus/your-contract/header.png +0 -0
- package/templates/base/packages/stylus/your-contract/licenses/Apache-2.0 +201 -0
- package/templates/base/packages/stylus/your-contract/licenses/COPYRIGHT.md +5 -0
- package/templates/base/packages/stylus/your-contract/licenses/DCO.txt +34 -0
- package/templates/base/packages/stylus/your-contract/licenses/MIT +21 -0
- package/templates/base/packages/stylus/your-contract/rust-toolchain.toml +2 -0
- package/templates/base/packages/stylus/your-contract/src/lib.rs +241 -0
- package/templates/base/packages/stylus/your-contract/src/main.rs +10 -0
- package/templates/base/readme.md +352 -0
- package/templates/base/yarn.lock +17859 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TransactionReceipt } from "viem";
|
|
2
|
+
import { CheckCircleIcon, DocumentDuplicateIcon } from "@heroicons/react/24/outline";
|
|
3
|
+
import { ObjectFieldDisplay } from "~~/app/debug/_components/contract";
|
|
4
|
+
import { useCopyToClipboard } from "~~/hooks/scaffold-eth/useCopyToClipboard";
|
|
5
|
+
import { replacer } from "~~/utils/scaffold-eth/common";
|
|
6
|
+
|
|
7
|
+
export const TxReceipt = ({ txResult }: { txResult: TransactionReceipt }) => {
|
|
8
|
+
const { copyToClipboard: copyTxResultToClipboard, isCopiedToClipboard: isTxResultCopiedToClipboard } =
|
|
9
|
+
useCopyToClipboard();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className="flex text-sm rounded-3xl peer-checked:rounded-b-none min-h-0 bg-secondary py-0">
|
|
13
|
+
<div className="mt-1 pl-2">
|
|
14
|
+
{isTxResultCopiedToClipboard ? (
|
|
15
|
+
<CheckCircleIcon
|
|
16
|
+
className="ml-1.5 text-xl font-normal text-base-content h-5 w-5 cursor-pointer"
|
|
17
|
+
aria-hidden="true"
|
|
18
|
+
/>
|
|
19
|
+
) : (
|
|
20
|
+
<DocumentDuplicateIcon
|
|
21
|
+
className="ml-1.5 text-xl font-normal h-5 w-5 cursor-pointer"
|
|
22
|
+
aria-hidden="true"
|
|
23
|
+
onClick={() => copyTxResultToClipboard(JSON.stringify(txResult, replacer, 2))}
|
|
24
|
+
/>
|
|
25
|
+
)}
|
|
26
|
+
</div>
|
|
27
|
+
<div tabIndex={0} className="flex-wrap collapse collapse-arrow">
|
|
28
|
+
<input type="checkbox" className="min-h-0! peer" />
|
|
29
|
+
<div className="collapse-title text-sm min-h-0! py-1.5 pl-1 after:top-4!">
|
|
30
|
+
<strong>Transaction Receipt</strong>
|
|
31
|
+
</div>
|
|
32
|
+
<div className="collapse-content overflow-auto bg-secondary rounded-t-none rounded-3xl pl-0!">
|
|
33
|
+
<pre className="text-xs">
|
|
34
|
+
{Object.entries(txResult).map(([k, v]) => (
|
|
35
|
+
<ObjectFieldDisplay name={k} value={v} size="xs" leftPad={false} key={k} />
|
|
36
|
+
))}
|
|
37
|
+
</pre>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { InheritanceTooltip } from "./InheritanceTooltip";
|
|
5
|
+
import { Abi, AbiFunction } from "abitype";
|
|
6
|
+
import { Address, TransactionReceipt } from "viem";
|
|
7
|
+
import { useAccount, useConfig, useWaitForTransactionReceipt, useWriteContract } from "wagmi";
|
|
8
|
+
import {
|
|
9
|
+
ContractInput,
|
|
10
|
+
TxReceipt,
|
|
11
|
+
getFunctionInputKey,
|
|
12
|
+
getInitialFormState,
|
|
13
|
+
getParsedContractFunctionArgs,
|
|
14
|
+
transformAbiFunction,
|
|
15
|
+
} from "~~/app/debug/_components/contract";
|
|
16
|
+
import { IntegerInput } from "~~/components/scaffold-eth";
|
|
17
|
+
import { useTransactor } from "~~/hooks/scaffold-eth";
|
|
18
|
+
import { useTargetNetwork } from "~~/hooks/scaffold-eth/useTargetNetwork";
|
|
19
|
+
import { simulateContractWriteAndNotifyError } from "~~/utils/scaffold-eth/contract";
|
|
20
|
+
|
|
21
|
+
type WriteOnlyFunctionFormProps = {
|
|
22
|
+
abi: Abi;
|
|
23
|
+
abiFunction: AbiFunction;
|
|
24
|
+
onChange: () => void;
|
|
25
|
+
contractAddress: Address;
|
|
26
|
+
inheritedFrom?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const WriteOnlyFunctionForm = ({
|
|
30
|
+
abi,
|
|
31
|
+
abiFunction,
|
|
32
|
+
onChange,
|
|
33
|
+
contractAddress,
|
|
34
|
+
inheritedFrom,
|
|
35
|
+
}: WriteOnlyFunctionFormProps) => {
|
|
36
|
+
const [form, setForm] = useState<Record<string, any>>(() => getInitialFormState(abiFunction));
|
|
37
|
+
const [txValue, setTxValue] = useState<string>("");
|
|
38
|
+
const { chain } = useAccount();
|
|
39
|
+
const writeTxn = useTransactor();
|
|
40
|
+
const { targetNetwork } = useTargetNetwork();
|
|
41
|
+
const writeDisabled = !chain || chain?.id !== targetNetwork.id;
|
|
42
|
+
|
|
43
|
+
const { data: result, isPending, writeContractAsync } = useWriteContract();
|
|
44
|
+
|
|
45
|
+
const wagmiConfig = useConfig();
|
|
46
|
+
|
|
47
|
+
const handleWrite = async () => {
|
|
48
|
+
if (writeContractAsync) {
|
|
49
|
+
try {
|
|
50
|
+
const writeContractObj = {
|
|
51
|
+
address: contractAddress,
|
|
52
|
+
functionName: abiFunction.name,
|
|
53
|
+
abi: abi,
|
|
54
|
+
args: getParsedContractFunctionArgs(form),
|
|
55
|
+
value: BigInt(txValue),
|
|
56
|
+
};
|
|
57
|
+
await simulateContractWriteAndNotifyError({ wagmiConfig, writeContractParams: writeContractObj });
|
|
58
|
+
|
|
59
|
+
const makeWriteWithParams = () => writeContractAsync(writeContractObj);
|
|
60
|
+
await writeTxn(makeWriteWithParams);
|
|
61
|
+
onChange();
|
|
62
|
+
} catch (e: any) {
|
|
63
|
+
console.error("⚡️ ~ file: WriteOnlyFunctionForm.tsx:handleWrite ~ error", e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const [displayedTxResult, setDisplayedTxResult] = useState<TransactionReceipt>();
|
|
69
|
+
const { data: txResult } = useWaitForTransactionReceipt({
|
|
70
|
+
hash: result,
|
|
71
|
+
});
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
setDisplayedTxResult(txResult);
|
|
74
|
+
}, [txResult]);
|
|
75
|
+
|
|
76
|
+
// TODO use `useMemo` to optimize also update in ReadOnlyFunctionForm
|
|
77
|
+
const transformedFunction = transformAbiFunction(abiFunction);
|
|
78
|
+
const inputs = transformedFunction.inputs.map((input, inputIndex) => {
|
|
79
|
+
const key = getFunctionInputKey(abiFunction.name, input, inputIndex);
|
|
80
|
+
return (
|
|
81
|
+
<ContractInput
|
|
82
|
+
key={key}
|
|
83
|
+
setForm={updatedFormValue => {
|
|
84
|
+
setDisplayedTxResult(undefined);
|
|
85
|
+
setForm(updatedFormValue);
|
|
86
|
+
}}
|
|
87
|
+
form={form}
|
|
88
|
+
stateObjectKey={key}
|
|
89
|
+
paramType={input}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
const zeroInputs = inputs.length === 0 && abiFunction.stateMutability !== "payable";
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<div className="py-5 space-y-3 first:pt-0 last:pb-1">
|
|
97
|
+
<div className={`flex gap-3 ${zeroInputs ? "flex-row justify-between items-center" : "flex-col"}`}>
|
|
98
|
+
<p className="font-medium my-0 break-words">
|
|
99
|
+
{abiFunction.name}
|
|
100
|
+
<InheritanceTooltip inheritedFrom={inheritedFrom} />
|
|
101
|
+
</p>
|
|
102
|
+
{inputs}
|
|
103
|
+
{abiFunction.stateMutability === "payable" ? (
|
|
104
|
+
<div className="flex flex-col gap-1.5 w-full">
|
|
105
|
+
<div className="flex items-center ml-2">
|
|
106
|
+
<span className="text-xs font-medium mr-2 leading-none">payable value</span>
|
|
107
|
+
<span className="block text-xs font-extralight leading-none">wei</span>
|
|
108
|
+
</div>
|
|
109
|
+
<IntegerInput
|
|
110
|
+
value={txValue}
|
|
111
|
+
onChange={updatedTxValue => {
|
|
112
|
+
setDisplayedTxResult(undefined);
|
|
113
|
+
setTxValue(updatedTxValue);
|
|
114
|
+
}}
|
|
115
|
+
placeholder="value (wei)"
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
) : null}
|
|
119
|
+
<div className="flex justify-between gap-2">
|
|
120
|
+
{!zeroInputs && (
|
|
121
|
+
<div className="grow basis-0">{displayedTxResult ? <TxReceipt txResult={displayedTxResult} /> : null}</div>
|
|
122
|
+
)}
|
|
123
|
+
<div
|
|
124
|
+
className={`flex ${
|
|
125
|
+
writeDisabled &&
|
|
126
|
+
"tooltip tooltip-bottom tooltip-secondary before:content-[attr(data-tip)] before:-translate-x-1/3 before:left-auto before:transform-none"
|
|
127
|
+
}`}
|
|
128
|
+
data-tip={`${writeDisabled && "Wallet not connected or in the wrong network"}`}
|
|
129
|
+
>
|
|
130
|
+
<button className="btn btn-secondary btn-sm" disabled={writeDisabled || isPending} onClick={handleWrite}>
|
|
131
|
+
{isPending && <span className="loading loading-spinner loading-xs"></span>}
|
|
132
|
+
Send 💸
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
{zeroInputs && txResult ? (
|
|
138
|
+
<div className="grow basis-0">
|
|
139
|
+
<TxReceipt txResult={txResult} />
|
|
140
|
+
</div>
|
|
141
|
+
) : null}
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./ContractInput";
|
|
2
|
+
export * from "./ContractUI";
|
|
3
|
+
export * from "./DisplayVariable";
|
|
4
|
+
export * from "./ReadOnlyFunctionForm";
|
|
5
|
+
export * from "./TxReceipt";
|
|
6
|
+
export * from "./utilsContract";
|
|
7
|
+
export * from "./utilsDisplay";
|
|
8
|
+
export * from "./WriteOnlyFunctionForm";
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { AbiFunction, AbiParameter } from "abitype";
|
|
2
|
+
import { AbiParameterTuple } from "~~/utils/scaffold-eth/contract";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generates a key based on function metadata
|
|
6
|
+
*/
|
|
7
|
+
const getFunctionInputKey = (functionName: string, input: AbiParameter, inputIndex: number): string => {
|
|
8
|
+
const name = input?.name || `input_${inputIndex}_`;
|
|
9
|
+
return functionName + "_" + name + "_" + input.internalType + "_" + input.type;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const isJsonString = (str: string) => {
|
|
13
|
+
try {
|
|
14
|
+
JSON.parse(str);
|
|
15
|
+
return true;
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const isBigInt = (str: string) => {
|
|
23
|
+
if (str.trim().length === 0 || str.startsWith("0")) return false;
|
|
24
|
+
try {
|
|
25
|
+
BigInt(str);
|
|
26
|
+
return true;
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Recursive function to deeply parse JSON strings, correctly handling nested arrays and encoded JSON strings
|
|
34
|
+
const deepParseValues = (value: any): any => {
|
|
35
|
+
if (typeof value === "string") {
|
|
36
|
+
// first try with bigInt because we losse precision with JSON.parse
|
|
37
|
+
if (isBigInt(value)) {
|
|
38
|
+
return BigInt(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isJsonString(value)) {
|
|
42
|
+
const parsed = JSON.parse(value);
|
|
43
|
+
return deepParseValues(parsed);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// It's a string but not a JSON string, return as is
|
|
47
|
+
return value;
|
|
48
|
+
} else if (Array.isArray(value)) {
|
|
49
|
+
// If it's an array, recursively parse each element
|
|
50
|
+
return value.map(element => deepParseValues(element));
|
|
51
|
+
} else if (typeof value === "object" && value !== null) {
|
|
52
|
+
// If it's an object, recursively parse each value
|
|
53
|
+
return Object.entries(value).reduce((acc: any, [key, val]) => {
|
|
54
|
+
acc[key] = deepParseValues(val);
|
|
55
|
+
return acc;
|
|
56
|
+
}, {});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Handle boolean values represented as strings
|
|
60
|
+
if (value === "true" || value === "1" || value === "0x1" || value === "0x01" || value === "0x0001") {
|
|
61
|
+
return true;
|
|
62
|
+
} else if (value === "false" || value === "0" || value === "0x0" || value === "0x00" || value === "0x0000") {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return value;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* parses form input with array support
|
|
71
|
+
*/
|
|
72
|
+
const getParsedContractFunctionArgs = (form: Record<string, any>) => {
|
|
73
|
+
return Object.keys(form).map(key => {
|
|
74
|
+
const valueOfArg = form[key];
|
|
75
|
+
|
|
76
|
+
// Attempt to deeply parse JSON strings
|
|
77
|
+
return deepParseValues(valueOfArg);
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const getInitialFormState = (abiFunction: AbiFunction) => {
|
|
82
|
+
const initialForm: Record<string, any> = {};
|
|
83
|
+
if (!abiFunction.inputs) return initialForm;
|
|
84
|
+
abiFunction.inputs.forEach((input, inputIndex) => {
|
|
85
|
+
const key = getFunctionInputKey(abiFunction.name, input, inputIndex);
|
|
86
|
+
initialForm[key] = "";
|
|
87
|
+
});
|
|
88
|
+
return initialForm;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const getInitialTupleFormState = (abiTupleParameter: AbiParameterTuple) => {
|
|
92
|
+
const initialForm: Record<string, any> = {};
|
|
93
|
+
if (abiTupleParameter.components.length === 0) return initialForm;
|
|
94
|
+
|
|
95
|
+
abiTupleParameter.components.forEach((component, componentIndex) => {
|
|
96
|
+
const key = getFunctionInputKey(abiTupleParameter.name || "tuple", component, componentIndex);
|
|
97
|
+
initialForm[key] = "";
|
|
98
|
+
});
|
|
99
|
+
return initialForm;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const getInitialTupleArrayFormState = (abiTupleParameter: AbiParameterTuple) => {
|
|
103
|
+
const initialForm: Record<string, any> = {};
|
|
104
|
+
if (abiTupleParameter.components.length === 0) return initialForm;
|
|
105
|
+
abiTupleParameter.components.forEach((component, componentIndex) => {
|
|
106
|
+
const key = getFunctionInputKey("0_" + abiTupleParameter.name || "tuple", component, componentIndex);
|
|
107
|
+
initialForm[key] = "";
|
|
108
|
+
});
|
|
109
|
+
return initialForm;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const adjustInput = (input: AbiParameterTuple): AbiParameter => {
|
|
113
|
+
if (input.type.startsWith("tuple[")) {
|
|
114
|
+
const depth = (input.type.match(/\[\]/g) || []).length;
|
|
115
|
+
return {
|
|
116
|
+
...input,
|
|
117
|
+
components: transformComponents(input.components, depth, {
|
|
118
|
+
internalType: input.internalType || "struct",
|
|
119
|
+
name: input.name,
|
|
120
|
+
}),
|
|
121
|
+
};
|
|
122
|
+
} else if (input.components) {
|
|
123
|
+
return {
|
|
124
|
+
...input,
|
|
125
|
+
components: input.components.map(value => adjustInput(value as AbiParameterTuple)),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return input;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const transformComponents = (
|
|
132
|
+
components: readonly AbiParameter[],
|
|
133
|
+
depth: number,
|
|
134
|
+
parentComponentData: { internalType?: string; name?: string },
|
|
135
|
+
): AbiParameter[] => {
|
|
136
|
+
// Base case: if depth is 1 or no components, return the original components
|
|
137
|
+
if (depth === 1 || !components) {
|
|
138
|
+
return [...components];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Recursive case: wrap components in an additional tuple layer
|
|
142
|
+
const wrappedComponents: AbiParameter = {
|
|
143
|
+
internalType: `${parentComponentData.internalType || "struct"}`.replace(/\[\]/g, "") + "[]".repeat(depth - 1),
|
|
144
|
+
name: `${parentComponentData.name || "tuple"}`,
|
|
145
|
+
type: `tuple${"[]".repeat(depth - 1)}`,
|
|
146
|
+
components: transformComponents(components, depth - 1, parentComponentData),
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return [wrappedComponents];
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const transformAbiFunction = (abiFunction: AbiFunction): AbiFunction => {
|
|
153
|
+
return {
|
|
154
|
+
...abiFunction,
|
|
155
|
+
inputs: abiFunction.inputs.map(value => adjustInput(value as AbiParameterTuple)),
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export {
|
|
160
|
+
getFunctionInputKey,
|
|
161
|
+
getInitialFormState,
|
|
162
|
+
getParsedContractFunctionArgs,
|
|
163
|
+
getInitialTupleFormState,
|
|
164
|
+
getInitialTupleArrayFormState,
|
|
165
|
+
transformAbiFunction,
|
|
166
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ReactElement, useState } from "react";
|
|
2
|
+
import { TransactionBase, TransactionReceipt, formatEther, isAddress, isHex } from "viem";
|
|
3
|
+
import { ArrowsRightLeftIcon } from "@heroicons/react/24/solid";
|
|
4
|
+
import { Address } from "~~/components/scaffold-eth";
|
|
5
|
+
import { replacer } from "~~/utils/scaffold-eth/common";
|
|
6
|
+
|
|
7
|
+
type DisplayContent =
|
|
8
|
+
| string
|
|
9
|
+
| number
|
|
10
|
+
| bigint
|
|
11
|
+
| Record<string, any>
|
|
12
|
+
| TransactionBase
|
|
13
|
+
| TransactionReceipt
|
|
14
|
+
| undefined
|
|
15
|
+
| unknown;
|
|
16
|
+
|
|
17
|
+
type ResultFontSize = "sm" | "base" | "xs" | "lg" | "xl" | "2xl" | "3xl";
|
|
18
|
+
|
|
19
|
+
export const displayTxResult = (
|
|
20
|
+
displayContent: DisplayContent | DisplayContent[],
|
|
21
|
+
fontSize: ResultFontSize = "base",
|
|
22
|
+
): string | ReactElement | number => {
|
|
23
|
+
if (displayContent == null) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof displayContent === "bigint") {
|
|
28
|
+
return <NumberDisplay value={displayContent} />;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (typeof displayContent === "string") {
|
|
32
|
+
if (isAddress(displayContent)) {
|
|
33
|
+
return <Address address={displayContent} size={fontSize} onlyEnsOrAddress />;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (isHex(displayContent)) {
|
|
37
|
+
return displayContent; // don't add quotes
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (Array.isArray(displayContent)) {
|
|
42
|
+
return <ArrayDisplay values={displayContent} size={fontSize} />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (typeof displayContent === "object") {
|
|
46
|
+
return <StructDisplay struct={displayContent} size={fontSize} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return JSON.stringify(displayContent, replacer, 2);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const NumberDisplay = ({ value }: { value: bigint }) => {
|
|
53
|
+
const [isEther, setIsEther] = useState(false);
|
|
54
|
+
|
|
55
|
+
const asNumber = Number(value);
|
|
56
|
+
if (asNumber <= Number.MAX_SAFE_INTEGER && asNumber >= Number.MIN_SAFE_INTEGER) {
|
|
57
|
+
return String(value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div className="flex items-baseline">
|
|
62
|
+
{isEther ? "Ξ" + formatEther(value) : String(value)}
|
|
63
|
+
<span
|
|
64
|
+
className="tooltip tooltip-secondary font-sans ml-2"
|
|
65
|
+
data-tip={isEther ? "Multiply by 1e18" : "Divide by 1e18"}
|
|
66
|
+
>
|
|
67
|
+
<button className="btn btn-ghost btn-circle btn-xs" onClick={() => setIsEther(!isEther)}>
|
|
68
|
+
<ArrowsRightLeftIcon className="h-3 w-3 opacity-65" />
|
|
69
|
+
</button>
|
|
70
|
+
</span>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const ObjectFieldDisplay = ({
|
|
76
|
+
name,
|
|
77
|
+
value,
|
|
78
|
+
size,
|
|
79
|
+
leftPad = true,
|
|
80
|
+
}: {
|
|
81
|
+
name: string;
|
|
82
|
+
value: DisplayContent;
|
|
83
|
+
size: ResultFontSize;
|
|
84
|
+
leftPad?: boolean;
|
|
85
|
+
}) => {
|
|
86
|
+
return (
|
|
87
|
+
<div className={`flex flex-row items-baseline ${leftPad ? "ml-4" : ""}`}>
|
|
88
|
+
<span className="text-base-content/60 mr-2">{name}:</span>
|
|
89
|
+
<span className="text-base-content">{displayTxResult(value, size)}</span>
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const ArrayDisplay = ({ values, size }: { values: DisplayContent[]; size: ResultFontSize }) => {
|
|
95
|
+
return (
|
|
96
|
+
<div className="flex flex-col gap-y-1">
|
|
97
|
+
{values.length ? "array" : "[]"}
|
|
98
|
+
{values.map((v, i) => (
|
|
99
|
+
<ObjectFieldDisplay key={i} name={`[${i}]`} value={v} size={size} />
|
|
100
|
+
))}
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const StructDisplay = ({ struct, size }: { struct: Record<string, any>; size: ResultFontSize }) => {
|
|
106
|
+
return (
|
|
107
|
+
<div className="flex flex-col gap-y-1">
|
|
108
|
+
struct
|
|
109
|
+
{Object.entries(struct).map(([k, v]) => (
|
|
110
|
+
<ObjectFieldDisplay key={k} name={k} value={v} size={size} />
|
|
111
|
+
))}
|
|
112
|
+
</div>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DebugContracts } from "./_components/DebugContracts";
|
|
2
|
+
import type { NextPage } from "next";
|
|
3
|
+
import { getMetadata } from "~~/utils/scaffold-eth/getMetadata";
|
|
4
|
+
|
|
5
|
+
export const metadata = getMetadata({
|
|
6
|
+
title: "Debug Contracts",
|
|
7
|
+
description: "Debug your deployed 🏗 Scaffold-Stylus contracts in an easy way",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const Debug: NextPage = () => {
|
|
11
|
+
return <DebugContracts />;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default Debug;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DM_Sans } from "next/font/google";
|
|
2
|
+
import "@rainbow-me/rainbowkit/styles.css";
|
|
3
|
+
import { Metadata } from "next";
|
|
4
|
+
import { ScaffoldEthAppWithProviders } from "~~/components/ScaffoldEthAppWithProviders";
|
|
5
|
+
import { ThemeProvider } from "~~/components/ThemeProvider";
|
|
6
|
+
import "~~/styles/globals.css";
|
|
7
|
+
|
|
8
|
+
const dmSans = DM_Sans({
|
|
9
|
+
subsets: ["latin"],
|
|
10
|
+
variable: "--font-dm-sans",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const baseUrl = process.env.VERCEL_URL
|
|
14
|
+
? `https://${process.env.VERCEL_URL}`
|
|
15
|
+
: `http://localhost:${process.env.PORT || 3000}`;
|
|
16
|
+
const imageUrl = `${baseUrl}/thumbnail.jpg`;
|
|
17
|
+
|
|
18
|
+
const title = "Create Stylus Dapp";
|
|
19
|
+
const titleTemplate = "%s | Create Stylus Dapp";
|
|
20
|
+
const description = "Built with 🏗 Scaffold-Stylus";
|
|
21
|
+
|
|
22
|
+
export const metadata: Metadata = {
|
|
23
|
+
metadataBase: new URL(baseUrl),
|
|
24
|
+
title: {
|
|
25
|
+
default: title,
|
|
26
|
+
template: titleTemplate,
|
|
27
|
+
},
|
|
28
|
+
description,
|
|
29
|
+
openGraph: {
|
|
30
|
+
title: {
|
|
31
|
+
default: title,
|
|
32
|
+
template: titleTemplate,
|
|
33
|
+
},
|
|
34
|
+
description,
|
|
35
|
+
images: [
|
|
36
|
+
{
|
|
37
|
+
url: imageUrl,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
twitter: {
|
|
42
|
+
card: "summary_large_image",
|
|
43
|
+
images: [imageUrl],
|
|
44
|
+
title: {
|
|
45
|
+
default: title,
|
|
46
|
+
template: titleTemplate,
|
|
47
|
+
},
|
|
48
|
+
description,
|
|
49
|
+
},
|
|
50
|
+
icons: {
|
|
51
|
+
icon: [{ url: "/favicon.png", sizes: "32x32", type: "image/png" }],
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => {
|
|
56
|
+
return (
|
|
57
|
+
<html suppressHydrationWarning>
|
|
58
|
+
<body className={`${dmSans.variable} font-sans`} suppressHydrationWarning>
|
|
59
|
+
<ThemeProvider>
|
|
60
|
+
<ScaffoldEthAppWithProviders>{children}</ScaffoldEthAppWithProviders>
|
|
61
|
+
</ThemeProvider>
|
|
62
|
+
</body>
|
|
63
|
+
</html>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default ScaffoldEthApp;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
|
|
3
|
+
export default function NotFound() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex items-center h-full flex-1 justify-center bg-base-200">
|
|
6
|
+
<div className="text-center">
|
|
7
|
+
<h1 className="text-6xl font-bold m-0 mb-1">404</h1>
|
|
8
|
+
<h2 className="text-2xl font-semibold m-0">Page Not Found</h2>
|
|
9
|
+
<p className="text-base-content/70 m-0 mb-4">The page you're looking for doesn't exist.</p>
|
|
10
|
+
<Link href="/" className="btn btn-primary">
|
|
11
|
+
Go Home
|
|
12
|
+
</Link>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { NextPage } from "next";
|
|
4
|
+
import { useTheme } from "next-themes";
|
|
5
|
+
import { useAccount } from "wagmi";
|
|
6
|
+
import { Card } from "~~/components/Card";
|
|
7
|
+
import { Address } from "~~/components/scaffold-eth";
|
|
8
|
+
import CompassIcon from "~~/icons/CompassIcon";
|
|
9
|
+
import DarkBugAntIcon from "~~/icons/DarkBugAntIcon";
|
|
10
|
+
import LightBugAntIcon from "~~/icons/LightBugAntIcon";
|
|
11
|
+
|
|
12
|
+
const Home: NextPage = () => {
|
|
13
|
+
const { address: connectedAddress } = useAccount();
|
|
14
|
+
const { resolvedTheme } = useTheme();
|
|
15
|
+
const isDarkMode = resolvedTheme === "dark";
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<div className="flex items-center flex-col justify-between flex-grow pt-10">
|
|
20
|
+
<div className="flex flex-col justify-center flex-grow">
|
|
21
|
+
<div className="px-5">
|
|
22
|
+
<h1 className="text-center">
|
|
23
|
+
<span className="block text-2xl mb-2">Welcome to</span>
|
|
24
|
+
<span className="block text-4xl font-bold">Scaffold-Stylus</span>
|
|
25
|
+
</h1>
|
|
26
|
+
<div className="flex justify-center items-center space-x-2 my-4">
|
|
27
|
+
<p className={`my-2 font-medium ${!isDarkMode ? "text-[#E3066E]" : ""}`}>Connected Address:</p>
|
|
28
|
+
<Address address={connectedAddress} />
|
|
29
|
+
</div>
|
|
30
|
+
<p className="text-center text-lg">
|
|
31
|
+
Get started by editing{" "}
|
|
32
|
+
<code
|
|
33
|
+
className="italic bg-base-300 text-black text-base font-bold max-w-full break-words break-all inline-block"
|
|
34
|
+
style={{
|
|
35
|
+
backgroundColor: isDarkMode ? "white" : "#F0F0F0",
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
packages/nextjs/app/page.tsx
|
|
39
|
+
</code>
|
|
40
|
+
</p>
|
|
41
|
+
<p className="text-center text-lg">
|
|
42
|
+
Edit your smart contract{" "}
|
|
43
|
+
<code
|
|
44
|
+
className="italic bg-base-300 text-black text-base font-bold max-w-full break-words break-all inline-block"
|
|
45
|
+
style={{
|
|
46
|
+
backgroundColor: isDarkMode ? "white" : "#F0F0F0",
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
lib.rs
|
|
50
|
+
</code>{" "}
|
|
51
|
+
in{" "}
|
|
52
|
+
<code
|
|
53
|
+
className="italic bg-base-300 text-black text-base font-bold max-w-full break-words break-all inline-block"
|
|
54
|
+
style={{
|
|
55
|
+
backgroundColor: isDarkMode ? "white" : "#F0F0F0",
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
packages/stylus/your-contract/src
|
|
59
|
+
</code>
|
|
60
|
+
</p>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div
|
|
65
|
+
className="h-auto sm:h-[306px] mb-3 w-full py-11"
|
|
66
|
+
style={{
|
|
67
|
+
backgroundColor: isDarkMode ? "#050505" : "white",
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<div className="flex justify-center items-center h-full gap-12 flex-col sm:flex-row">
|
|
71
|
+
{/* Debug Contracts Card */}
|
|
72
|
+
<Card
|
|
73
|
+
icon={isDarkMode ? <DarkBugAntIcon /> : <LightBugAntIcon />}
|
|
74
|
+
description={<>Tinker with your smart contract using the</>}
|
|
75
|
+
linkHref="/debug"
|
|
76
|
+
linkText="Debug Contracts"
|
|
77
|
+
isDarkMode={isDarkMode}
|
|
78
|
+
/>
|
|
79
|
+
{/* Block Explorer Card */}
|
|
80
|
+
<Card
|
|
81
|
+
icon={<CompassIcon />}
|
|
82
|
+
description={<>Explore your local transactions with the</>}
|
|
83
|
+
linkHref="/blockexplorer"
|
|
84
|
+
linkText="Block Explorer"
|
|
85
|
+
isDarkMode={isDarkMode}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export default Home;
|