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,50 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
|
|
3
|
+
const baseUrl = process.env.VERCEL_PROJECT_PRODUCTION_URL
|
|
4
|
+
? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
|
|
5
|
+
: `http://localhost:${process.env.PORT || 3000}`;
|
|
6
|
+
const titleTemplate = "%s | Scaffold-Stylus";
|
|
7
|
+
|
|
8
|
+
export const getMetadata = ({
|
|
9
|
+
title,
|
|
10
|
+
description,
|
|
11
|
+
imageRelativePath = "/thumbnail.jpg",
|
|
12
|
+
}: {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
imageRelativePath?: string;
|
|
16
|
+
}): Metadata => {
|
|
17
|
+
const imageUrl = `${baseUrl}${imageRelativePath}`;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
metadataBase: new URL(baseUrl),
|
|
21
|
+
title: {
|
|
22
|
+
default: title,
|
|
23
|
+
template: titleTemplate,
|
|
24
|
+
},
|
|
25
|
+
description: description,
|
|
26
|
+
openGraph: {
|
|
27
|
+
title: {
|
|
28
|
+
default: title,
|
|
29
|
+
template: titleTemplate,
|
|
30
|
+
},
|
|
31
|
+
description: description,
|
|
32
|
+
images: [
|
|
33
|
+
{
|
|
34
|
+
url: imageUrl,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
twitter: {
|
|
39
|
+
title: {
|
|
40
|
+
default: title,
|
|
41
|
+
template: titleTemplate,
|
|
42
|
+
},
|
|
43
|
+
description: description,
|
|
44
|
+
images: [imageUrl],
|
|
45
|
+
},
|
|
46
|
+
icons: {
|
|
47
|
+
icon: [{ url: "/favicon.png", sizes: "32x32", type: "image/png" }],
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BaseError as BaseViemError, ContractFunctionRevertedError } from "viem";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses an viem/wagmi error to get a displayable string
|
|
5
|
+
* @param e - error object
|
|
6
|
+
* @returns parsed error string
|
|
7
|
+
*/
|
|
8
|
+
export const getParsedError = (error: any): string => {
|
|
9
|
+
const parsedError = error?.walk ? error.walk() : error;
|
|
10
|
+
|
|
11
|
+
if (parsedError instanceof BaseViemError) {
|
|
12
|
+
if (parsedError.details) {
|
|
13
|
+
return parsedError.details;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (parsedError.shortMessage) {
|
|
17
|
+
if (
|
|
18
|
+
parsedError instanceof ContractFunctionRevertedError &&
|
|
19
|
+
parsedError.data &&
|
|
20
|
+
parsedError.data.errorName !== "Error"
|
|
21
|
+
) {
|
|
22
|
+
const customErrorArgs = parsedError.data.args?.toString() ?? "";
|
|
23
|
+
return `${parsedError.shortMessage.replace(/reverted\.$/, "reverted with the following reason:")}\n${
|
|
24
|
+
parsedError.data.errorName
|
|
25
|
+
}(${customErrorArgs})`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return parsedError.shortMessage;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return parsedError.message ?? parsedError.name ?? "An unknown error occurred";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return parsedError?.message ?? "An unknown error occurred";
|
|
35
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Toast, ToastPosition, toast } from "react-hot-toast";
|
|
3
|
+
import { XMarkIcon } from "@heroicons/react/20/solid";
|
|
4
|
+
import {
|
|
5
|
+
CheckCircleIcon,
|
|
6
|
+
ExclamationCircleIcon,
|
|
7
|
+
ExclamationTriangleIcon,
|
|
8
|
+
InformationCircleIcon,
|
|
9
|
+
} from "@heroicons/react/24/solid";
|
|
10
|
+
|
|
11
|
+
type NotificationProps = {
|
|
12
|
+
content: React.ReactNode;
|
|
13
|
+
status: "success" | "info" | "loading" | "error" | "warning";
|
|
14
|
+
duration?: number;
|
|
15
|
+
icon?: string;
|
|
16
|
+
position?: ToastPosition;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type NotificationOptions = {
|
|
20
|
+
duration?: number;
|
|
21
|
+
icon?: string;
|
|
22
|
+
position?: ToastPosition;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const ENUM_STATUSES = {
|
|
26
|
+
success: <CheckCircleIcon className="w-7 text-success" />,
|
|
27
|
+
loading: <span className="w-6 loading loading-spinner"></span>,
|
|
28
|
+
error: <ExclamationCircleIcon className="w-7 text-error" />,
|
|
29
|
+
info: <InformationCircleIcon className="w-7 text-info" />,
|
|
30
|
+
warning: <ExclamationTriangleIcon className="w-7 text-warning" />,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const DEFAULT_DURATION = 3000;
|
|
34
|
+
const DEFAULT_POSITION: ToastPosition = "top-center";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Custom Notification
|
|
38
|
+
*/
|
|
39
|
+
const Notification = ({
|
|
40
|
+
content,
|
|
41
|
+
status,
|
|
42
|
+
duration = DEFAULT_DURATION,
|
|
43
|
+
icon,
|
|
44
|
+
position = DEFAULT_POSITION,
|
|
45
|
+
}: NotificationProps) => {
|
|
46
|
+
return toast.custom(
|
|
47
|
+
(t: Toast) => (
|
|
48
|
+
<div
|
|
49
|
+
className={`flex flex-row items-start justify-between max-w-sm rounded-xl shadow-center shadow-accent bg-base-200 p-4 transform-gpu relative transition-all duration-500 ease-in-out space-x-2
|
|
50
|
+
${
|
|
51
|
+
position.substring(0, 3) == "top"
|
|
52
|
+
? `hover:translate-y-1 ${t.visible ? "top-0" : "-top-96"}`
|
|
53
|
+
: `hover:-translate-y-1 ${t.visible ? "bottom-0" : "-bottom-96"}`
|
|
54
|
+
}`}
|
|
55
|
+
>
|
|
56
|
+
<div className="leading-[0] self-center">{icon ? icon : ENUM_STATUSES[status]}</div>
|
|
57
|
+
<div className={`overflow-x-hidden break-words whitespace-pre-line ${icon ? "mt-1" : ""}`}>{content}</div>
|
|
58
|
+
|
|
59
|
+
<div className={`cursor-pointer text-lg ${icon ? "mt-1" : ""}`} onClick={() => toast.dismiss(t.id)}>
|
|
60
|
+
<XMarkIcon className="w-6 cursor-pointer" onClick={() => toast.remove(t.id)} />
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
),
|
|
64
|
+
{
|
|
65
|
+
duration: status === "loading" ? Infinity : duration,
|
|
66
|
+
position,
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const notification = {
|
|
72
|
+
success: (content: React.ReactNode, options?: NotificationOptions) => {
|
|
73
|
+
return Notification({ content, status: "success", ...options });
|
|
74
|
+
},
|
|
75
|
+
info: (content: React.ReactNode, options?: NotificationOptions) => {
|
|
76
|
+
return Notification({ content, status: "info", ...options });
|
|
77
|
+
},
|
|
78
|
+
warning: (content: React.ReactNode, options?: NotificationOptions) => {
|
|
79
|
+
return Notification({ content, status: "warning", ...options });
|
|
80
|
+
},
|
|
81
|
+
error: (content: React.ReactNode, options?: NotificationOptions) => {
|
|
82
|
+
return Notification({ content, status: "error", ...options });
|
|
83
|
+
},
|
|
84
|
+
loading: (content: React.ReactNode, options?: NotificationOptions) => {
|
|
85
|
+
return Notification({ content, status: "loading", ...options });
|
|
86
|
+
},
|
|
87
|
+
remove: (toastId: string) => {
|
|
88
|
+
toast.remove(toastId);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Hex } from "viem";
|
|
2
|
+
import { generatePrivateKey } from "viem/accounts";
|
|
3
|
+
import { arbitrumNitro } from "./chain";
|
|
4
|
+
|
|
5
|
+
const burnerStorageKey = "burnerWallet.pk";
|
|
6
|
+
export const burnerWalletId = "burnerWallet" as const;
|
|
7
|
+
export const burnerWalletName = "Burner Wallet" as const;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Checks if the private key is valid
|
|
11
|
+
*/
|
|
12
|
+
const isValidPK = (pk: Hex | string | undefined | null): boolean => {
|
|
13
|
+
return pk?.length === 64 || pk?.length === 66;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Save the current burner private key to storage
|
|
18
|
+
*/
|
|
19
|
+
export const saveBurnerPK = ({
|
|
20
|
+
privateKey,
|
|
21
|
+
useSessionStorage = false,
|
|
22
|
+
}: {
|
|
23
|
+
privateKey: Hex;
|
|
24
|
+
useSessionStorage?: boolean;
|
|
25
|
+
}): void => {
|
|
26
|
+
if (typeof window !== "undefined" && window != null) {
|
|
27
|
+
const storage = useSessionStorage ? window.sessionStorage : window.localStorage;
|
|
28
|
+
storage?.setItem(burnerStorageKey, privateKey);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Gets the current burner private key from local/session storage
|
|
34
|
+
*/
|
|
35
|
+
export const loadBurnerPK = ({ useSessionStorage = false }: { useSessionStorage?: boolean } = {}): Hex => {
|
|
36
|
+
let currentSk: Hex = "0x";
|
|
37
|
+
if (typeof window !== "undefined" && window != null) {
|
|
38
|
+
const storage = useSessionStorage ? window.sessionStorage : window.localStorage;
|
|
39
|
+
currentSk = (storage?.getItem?.(burnerStorageKey)?.replaceAll('"', "") ?? "0x") as Hex;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!!currentSk && isValidPK(currentSk)) {
|
|
43
|
+
return currentSk;
|
|
44
|
+
}
|
|
45
|
+
// If no burner is found in storage, we will generate a random private key
|
|
46
|
+
const newDefaultPrivateKey = generatePrivateKey();
|
|
47
|
+
saveBurnerPK({ privateKey: newDefaultPrivateKey, useSessionStorage });
|
|
48
|
+
return newDefaultPrivateKey;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Initializes the burner private key if it is not already set
|
|
53
|
+
*/
|
|
54
|
+
export const initBurnerPK = () => {
|
|
55
|
+
const currentPK = loadBurnerPK();
|
|
56
|
+
if (!arbitrumNitro.accounts.find(account => account.privateKey === currentPK)) {
|
|
57
|
+
saveBurnerPK({ privateKey: arbitrumNitro.accounts[0].privateKey });
|
|
58
|
+
}
|
|
59
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineChain } from "viem";
|
|
2
|
+
|
|
3
|
+
export const arbitrumNitro = defineChain({
|
|
4
|
+
id: 412346,
|
|
5
|
+
name: "Arbitrum Nitro",
|
|
6
|
+
network: "arbitrum-nitro",
|
|
7
|
+
nativeCurrency: {
|
|
8
|
+
name: "Ether",
|
|
9
|
+
symbol: "ETH",
|
|
10
|
+
decimals: 18,
|
|
11
|
+
},
|
|
12
|
+
rpcUrls: {
|
|
13
|
+
default: {
|
|
14
|
+
http: ["http://localhost:8547"],
|
|
15
|
+
},
|
|
16
|
+
public: {
|
|
17
|
+
http: ["http://localhost:8547"],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
accounts: [
|
|
21
|
+
{
|
|
22
|
+
privateKey: "0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659",
|
|
23
|
+
address: "0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
privateKey: "0x64cf8b4376aca8e153f2aca74b7f5f59e19b8bbb2da594a98095729ba12a9f6c",
|
|
27
|
+
address: "0xDD09b55496EaA3cFAe23137ABDeA52a9a979B70e",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
privateKey: "0x7a56d99de9eb0977d6dfab1f8465b2705a4c3ca9342ad4fc8cc97aa6f42056c4",
|
|
31
|
+
address: "0xE9cB1563bE49002383D08386ee287aF7BAD08c3b",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
privateKey: "0xc011740e64cd1bcefb4b5b869ac1169f79e8524cd7c6d409b3fe5b7dfd92afa6",
|
|
35
|
+
address: "0x838d568Ffb16BC74083e88fd769df85E8d3afcE6",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
privateKey: "0xf2e04103742c7623c6019ca2b7e4710c1bad9bde003383d29f92c6be026fa29c",
|
|
39
|
+
address: "0xA491d1134388c78AeEDf6b1Ca3F21657015Ff8E1",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as chains from "viem/chains";
|
|
2
|
+
import scaffoldConfig from "~~/scaffold.config";
|
|
3
|
+
import { arbitrumNitro } from "~~/utils/scaffold-stylus/chain";
|
|
4
|
+
|
|
5
|
+
type ChainAttributes = {
|
|
6
|
+
// color | [lightThemeColor, darkThemeColor]
|
|
7
|
+
color: string | [string, string];
|
|
8
|
+
// Used to fetch price by providing mainnet token address
|
|
9
|
+
// for networks having native currency other than ETH
|
|
10
|
+
nativeCurrencyTokenAddress?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type ChainWithAttributes = chains.Chain & Partial<ChainAttributes>;
|
|
14
|
+
export type AllowedChainIds = (typeof scaffoldConfig.targetNetworks)[number]["id"];
|
|
15
|
+
|
|
16
|
+
// Mapping of chainId to RPC chain name an format followed by alchemy and infura
|
|
17
|
+
export const RPC_CHAIN_NAMES: Record<number, string> = {
|
|
18
|
+
[chains.mainnet.id]: "eth-mainnet",
|
|
19
|
+
[chains.arbitrum.id]: "arb-mainnet",
|
|
20
|
+
[chains.arbitrumSepolia.id]: "arb-sepolia",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const getAlchemyHttpUrl = (chainId: number) => {
|
|
24
|
+
return scaffoldConfig.alchemyApiKey && RPC_CHAIN_NAMES[chainId]
|
|
25
|
+
? `https://${RPC_CHAIN_NAMES[chainId]}.g.alchemy.com/v2/${scaffoldConfig.alchemyApiKey}`
|
|
26
|
+
: undefined;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const NETWORKS_EXTRA_DATA: Record<string, ChainAttributes> = {
|
|
30
|
+
[arbitrumNitro.id]: {
|
|
31
|
+
color: "#b8af0c",
|
|
32
|
+
},
|
|
33
|
+
[chains.mainnet.id]: {
|
|
34
|
+
color: "#ff8b9e",
|
|
35
|
+
},
|
|
36
|
+
[chains.arbitrum.id]: {
|
|
37
|
+
color: "#28a0f0",
|
|
38
|
+
},
|
|
39
|
+
[chains.arbitrumSepolia.id]: {
|
|
40
|
+
color: "#28a0f0",
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gives the block explorer transaction URL, returns empty string if the network is a local chain
|
|
46
|
+
*/
|
|
47
|
+
export function getBlockExplorerTxLink(chainId: number, txnHash: string) {
|
|
48
|
+
const chainNames = Object.keys(chains);
|
|
49
|
+
|
|
50
|
+
const targetChainArr = chainNames.filter(chainName => {
|
|
51
|
+
const wagmiChain = chains[chainName as keyof typeof chains];
|
|
52
|
+
return wagmiChain.id === chainId;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (targetChainArr.length === 0) {
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const targetChain = targetChainArr[0] as keyof typeof chains;
|
|
60
|
+
const blockExplorerTxURL = chains[targetChain]?.blockExplorers?.default?.url;
|
|
61
|
+
|
|
62
|
+
if (!blockExplorerTxURL) {
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return `${blockExplorerTxURL}/tx/${txnHash}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Gives the block explorer URL for a given address.
|
|
71
|
+
* Defaults to Arbiscan if no (wagmi) block explorer is configured for the network.
|
|
72
|
+
*/
|
|
73
|
+
export function getBlockExplorerAddressLink(network: chains.Chain, address: string) {
|
|
74
|
+
const blockExplorerBaseURL = network.blockExplorers?.default?.url;
|
|
75
|
+
if (network.id === arbitrumNitro.id) {
|
|
76
|
+
return `/blockexplorer/address/${address}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!blockExplorerBaseURL) {
|
|
80
|
+
return `https://arbiscan.io/address/${address}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return `${blockExplorerBaseURL}/address/${address}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @returns targetNetworks array containing networks configured in scaffold.config including extra network metadata
|
|
88
|
+
*/
|
|
89
|
+
export function getTargetNetworks(): ChainWithAttributes[] {
|
|
90
|
+
return scaffoldConfig.targetNetworks.map(targetNetwork => ({
|
|
91
|
+
...targetNetwork,
|
|
92
|
+
...NETWORKS_EXTRA_DATA[targetNetwork.id],
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
DEPLOYMENT_DIR=
|
|
2
|
+
|
|
3
|
+
## devnet
|
|
4
|
+
# ACCOUNT_ADDRESS=
|
|
5
|
+
# RPC_URL=
|
|
6
|
+
# PRIVATE_KEY=
|
|
7
|
+
|
|
8
|
+
## sepolia
|
|
9
|
+
ACCOUNT_ADDRESS_SEPOLIA=
|
|
10
|
+
RPC_URL_SEPOLIA=
|
|
11
|
+
PRIVATE_KEY_SEPOLIA=
|
|
12
|
+
|
|
13
|
+
## mainnet
|
|
14
|
+
ACCOUNT_ADDRESS_MAINNET=
|
|
15
|
+
RPC_URL_MAINNET=
|
|
16
|
+
PRIVATE_KEY_MAINNET=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
parser: '@typescript-eslint/parser',
|
|
3
|
+
extends: [
|
|
4
|
+
'eslint:recommended',
|
|
5
|
+
'plugin:@typescript-eslint/recommended',
|
|
6
|
+
],
|
|
7
|
+
plugins: ['@typescript-eslint'],
|
|
8
|
+
env: {
|
|
9
|
+
node: true,
|
|
10
|
+
es2022: true,
|
|
11
|
+
},
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 2022,
|
|
14
|
+
sourceType: 'module',
|
|
15
|
+
},
|
|
16
|
+
rules: {
|
|
17
|
+
'@typescript-eslint/no-unused-vars': 'error',
|
|
18
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
19
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
20
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
21
|
+
'@typescript-eslint/no-inferrable-types': 'off',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
preset: 'ts-jest',
|
|
3
|
+
testEnvironment: 'node',
|
|
4
|
+
roots: ['<rootDir>/scripts'],
|
|
5
|
+
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.ts$': 'ts-jest',
|
|
8
|
+
},
|
|
9
|
+
collectCoverageFrom: [
|
|
10
|
+
'scripts/**/*.ts',
|
|
11
|
+
'!scripts/**/*.d.ts',
|
|
12
|
+
],
|
|
13
|
+
coverageDirectory: 'coverage',
|
|
14
|
+
coverageReporters: ['text', 'lcov', 'html'],
|
|
15
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ss/stylus",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript project for Stylus dApp",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"start": "node dist/index.js",
|
|
11
|
+
"deploy": "ts-node scripts/deploy_wrapper.ts",
|
|
12
|
+
"test:networks": "ts-node scripts/test_network.ts",
|
|
13
|
+
"export-abi": "ts-node scripts/export_abi.ts",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"test": "cargo test",
|
|
16
|
+
"lint": "eslint scripts --ext .ts",
|
|
17
|
+
"lint:fix": "eslint scripts --ext .ts --fix",
|
|
18
|
+
"new-module": "bash scripts/new_module.sh"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"stylus",
|
|
22
|
+
"typescript",
|
|
23
|
+
"arbitrum",
|
|
24
|
+
"blockchain"
|
|
25
|
+
],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^20.0.0",
|
|
30
|
+
"@types/yargs": "^17.0.32",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
32
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
33
|
+
"eslint": "^8.0.0",
|
|
34
|
+
"jest": "^29.0.0",
|
|
35
|
+
"ts-jest": "^29.0.0",
|
|
36
|
+
"typescript": "^5.3.0",
|
|
37
|
+
"yargs": "^17.7.2"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"abitype": "^1.0.8",
|
|
41
|
+
"dotenv": "^16.0.0",
|
|
42
|
+
"ethers": "^6.15.0",
|
|
43
|
+
"prettier": "^3.6.2",
|
|
44
|
+
"toml": "^3.0.0",
|
|
45
|
+
"ts-node": "^10.9.2",
|
|
46
|
+
"viem": "^1.19.9"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import deployStylusContract from "./deploy_contract";
|
|
2
|
+
import { getDeploymentConfig, printDeployedAddresses } from "./utils/";
|
|
3
|
+
import { DeployOptions } from "./utils/type";
|
|
4
|
+
import { config as dotenvConfig } from "dotenv";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
|
|
8
|
+
const envPath = path.resolve(__dirname, "../.env");
|
|
9
|
+
if (fs.existsSync(envPath)) {
|
|
10
|
+
dotenvConfig({ path: envPath });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Define your deployment logic here
|
|
15
|
+
*/
|
|
16
|
+
export default async function deployScript(deployOptions: DeployOptions) {
|
|
17
|
+
const config = getDeploymentConfig(deployOptions);
|
|
18
|
+
|
|
19
|
+
console.log(`š” Using endpoint: ${config.chain?.rpcUrl}`);
|
|
20
|
+
if (config.chain) {
|
|
21
|
+
console.log(`š Network: ${config.chain?.name}`);
|
|
22
|
+
console.log(`š Chain ID: ${config.chain?.id}`);
|
|
23
|
+
}
|
|
24
|
+
console.log(`š Using private key: ${config.privateKey.substring(0, 10)}...`);
|
|
25
|
+
console.log(`š Deployment directory: ${config.deploymentDir}`);
|
|
26
|
+
console.log(`\n`);
|
|
27
|
+
|
|
28
|
+
// Deploy a single contract
|
|
29
|
+
await deployStylusContract({
|
|
30
|
+
contract: "your-contract",
|
|
31
|
+
constructorArgs: [config.deployerAddress!],
|
|
32
|
+
...deployOptions,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/// Deploy your contract with a custom name
|
|
36
|
+
// await deployStylusContract({
|
|
37
|
+
// contract: "your-contract",
|
|
38
|
+
// constructorArgs: [config.deployerAddress],
|
|
39
|
+
// name: "my-contract",
|
|
40
|
+
// ...deployOptions,
|
|
41
|
+
// });
|
|
42
|
+
|
|
43
|
+
// Print the deployed addresses
|
|
44
|
+
console.log("\n\n");
|
|
45
|
+
printDeployedAddresses(config.deploymentDir, config.chain?.id);
|
|
46
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDeploymentConfig,
|
|
3
|
+
ensureDeploymentDirectory,
|
|
4
|
+
executeCommand,
|
|
5
|
+
extractDeploymentInfo,
|
|
6
|
+
saveDeployment,
|
|
7
|
+
// estimateGasPrice,
|
|
8
|
+
} from "./utils/";
|
|
9
|
+
import { exportStylusAbi } from "./export_abi";
|
|
10
|
+
import { DeployOptions } from "./utils/type";
|
|
11
|
+
import { buildDeployCommand } from "./utils/command";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Deploy a single contract using cargo stylus
|
|
15
|
+
* @param deployOptions - The deploy options
|
|
16
|
+
* @param additionalOptions - The additional options
|
|
17
|
+
* @returns void
|
|
18
|
+
*/
|
|
19
|
+
export default async function deployStylusContract(
|
|
20
|
+
deployOptions: DeployOptions,
|
|
21
|
+
) {
|
|
22
|
+
console.log(`\nš Deploying contract in: ${deployOptions.contract}`);
|
|
23
|
+
|
|
24
|
+
const config = getDeploymentConfig(deployOptions);
|
|
25
|
+
ensureDeploymentDirectory(config.deploymentDir);
|
|
26
|
+
|
|
27
|
+
console.log(`š Contract name: ${config.contractName}`);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Step 1: Deploy the contract using cargo stylus with contract address
|
|
31
|
+
// --contract-address='${config.contractAddress}' deactivated for now as it's not working. Issue https://github.com/OffchainLabs/cargo-stylus/issues/171
|
|
32
|
+
const deployCommand = await buildDeployCommand(config, deployOptions);
|
|
33
|
+
const deployOutput = await executeCommand(
|
|
34
|
+
deployCommand,
|
|
35
|
+
deployOptions.contract!,
|
|
36
|
+
"Deploying contract with cargo stylus",
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if (deployOptions.estimateGas) {
|
|
40
|
+
console.log(deployOutput);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Extract the actual deployed address from the output
|
|
45
|
+
const deploymentInfo = extractDeploymentInfo(deployOutput);
|
|
46
|
+
if (deploymentInfo) {
|
|
47
|
+
console.log(`š Contract deployed at address: ${deploymentInfo.address}`);
|
|
48
|
+
console.log("Transaction hash: ", deploymentInfo.txHash);
|
|
49
|
+
} else {
|
|
50
|
+
throw new Error("Failed to extract deployed address");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Save the deployed address to chain-specific deployment file
|
|
54
|
+
saveDeployment(config, deploymentInfo);
|
|
55
|
+
|
|
56
|
+
// Step 2: Export ABI using the shared function
|
|
57
|
+
await exportStylusAbi(
|
|
58
|
+
config.contractFolder,
|
|
59
|
+
config.contractName,
|
|
60
|
+
false,
|
|
61
|
+
config.chain?.id,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Step 3: Verify the contract
|
|
65
|
+
if (deployOptions.verify) {
|
|
66
|
+
try {
|
|
67
|
+
const output = await executeCommand(
|
|
68
|
+
`cargo stylus verify --endpoint=${config.chain?.rpcUrl} --deployment-tx=${deploymentInfo.txHash}`,
|
|
69
|
+
deployOptions.contract!,
|
|
70
|
+
"Verifying contract with cargo stylus",
|
|
71
|
+
);
|
|
72
|
+
console.log(output);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error(
|
|
75
|
+
`ā Verification failed in: ${deployOptions.contract}`,
|
|
76
|
+
error,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error(`ā Deployment failed in: ${deployOptions.contract}`, error);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { hideBin } from "yargs/helpers";
|
|
2
|
+
import yargs from "yargs";
|
|
3
|
+
import { DeployCommandOptions, DeployOptions } from "./utils/type";
|
|
4
|
+
import deployScript from "./deploy";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Entry point for the deploy script
|
|
8
|
+
* This script is used to deploy a single contract or all contracts in the stylus folder
|
|
9
|
+
*/
|
|
10
|
+
if (require.main === module) {
|
|
11
|
+
// Use yargs for argument parsing
|
|
12
|
+
const argv = yargs(hideBin(process.argv))
|
|
13
|
+
.usage("Usage: yarn deploy --name <contractName> --network <network>")
|
|
14
|
+
.option("network", {
|
|
15
|
+
alias: "net",
|
|
16
|
+
describe: "Network to deploy to",
|
|
17
|
+
type: "string",
|
|
18
|
+
demandOption: false,
|
|
19
|
+
})
|
|
20
|
+
.option("estimate-gas", {
|
|
21
|
+
alias: "eg",
|
|
22
|
+
describe: "Estimate gas for the deployment",
|
|
23
|
+
type: "boolean",
|
|
24
|
+
demandOption: false,
|
|
25
|
+
})
|
|
26
|
+
.option("max-fee", {
|
|
27
|
+
alias: "mf",
|
|
28
|
+
describe: "Max fee per gas gwei",
|
|
29
|
+
type: "string",
|
|
30
|
+
demandOption: false,
|
|
31
|
+
})
|
|
32
|
+
.help()
|
|
33
|
+
.parseSync() as DeployCommandOptions;
|
|
34
|
+
|
|
35
|
+
deployScript(argv as DeployOptions).catch((error) => {
|
|
36
|
+
console.error("Fatal error:", error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
|
39
|
+
}
|