diff --git a/app/academy/[...slug]/page.tsx b/app/academy/[...slug]/page.tsx index f681c9bb852..71d3cf3d5f0 100644 --- a/app/academy/[...slug]/page.tsx +++ b/app/academy/[...slug]/page.tsx @@ -38,7 +38,7 @@ import posthog from 'posthog-js'; import ToolboxMdxWrapper from "@/components/toolbox/academy/wrapper/ToolboxMdxWrapper" import CrossChainTransfer from "@/components/toolbox/console/primary-network/CrossChainTransfer" -import AvalancheGoDocker from '@/components/toolbox/console/layer-1/AvalancheGoDockerL1'; +import AvalancheGoDocker from '@/components/toolbox/console/layer-1/L1NodeSetupDocker'; import CreateChain from "@/components/toolbox/console/layer-1/create/CreateChain" import ConvertSubnetToL1 from "@/components/toolbox/console/layer-1/create/ConvertSubnetToL1" import GenesisBuilder from '@/components/toolbox/console/layer-1/create/GenesisBuilder'; diff --git a/app/console/layer-1/create/steps.ts b/app/console/layer-1/create/steps.ts index ef5e5a8e6fd..ba6c305fcc6 100644 --- a/app/console/layer-1/create/steps.ts +++ b/app/console/layer-1/create/steps.ts @@ -1,6 +1,6 @@ import { type StepDefinition } from "@/components/console/step-flow"; import CreateChain from "@/components/toolbox/console/layer-1/create/CreateChain"; -import AvalancheGoDockerL1 from "@/components/toolbox/console/layer-1/AvalancheGoDockerL1"; +import AvalancheGoDockerL1 from "@/components/toolbox/console/layer-1/L1NodeSetupDocker"; import ConvertSubnetToL1 from "@/components/toolbox/console/layer-1/create/ConvertSubnetToL1"; import ManagedTestnetNodes from "@/components/toolbox/console/testnet-infra/ManagedTestnetNodes"; diff --git a/app/console/layer-1/l1-node-setup/page.tsx b/app/console/layer-1/l1-node-setup/page.tsx index 0ddac18c9dd..3d7eded363e 100644 --- a/app/console/layer-1/l1-node-setup/page.tsx +++ b/app/console/layer-1/l1-node-setup/page.tsx @@ -1,9 +1,9 @@ "use client"; -import L1NodeSetup from "@/components/toolbox/console/layer-1/AvalancheGoDockerL1"; +import L1NodeSetupDocker from "@/components/toolbox/console/layer-1/L1NodeSetupDocker"; export default function Page() { return ( - + ); } diff --git a/components/toolbox/components/ToolContainer.tsx b/components/toolbox/components/ToolContainer.tsx new file mode 100644 index 00000000000..e8e9753152e --- /dev/null +++ b/components/toolbox/components/ToolContainer.tsx @@ -0,0 +1,36 @@ +"use client" + +import { ConsoleToolMetadata } from "@/types/consoleTool" +import type { ReactNode } from "react" +import { CheckWalletRequirements } from "./CheckWalletRequirements" + +interface ToolContainerProps { + consoleToolMetadata: ConsoleToolMetadata + children: ReactNode +} + +// simplified container does not use color themes currently + +export function ToolContainer({ + consoleToolMetadata, + children, +}: ToolContainerProps) { + + return ( + +
+

{consoleToolMetadata.title}

+ {consoleToolMetadata.description && ( +
+ {consoleToolMetadata.description} +
+ )} +
+ +
+ {children} +
+
+ ) +} + diff --git a/components/toolbox/console/layer-1/AvalancheGoDockerL1.tsx b/components/toolbox/console/layer-1/L1NodeSetupDocker.tsx similarity index 95% rename from components/toolbox/console/layer-1/AvalancheGoDockerL1.tsx rename to components/toolbox/console/layer-1/L1NodeSetupDocker.tsx index 14768f87c2d..0f26d85fdb8 100644 --- a/components/toolbox/console/layer-1/AvalancheGoDockerL1.tsx +++ b/components/toolbox/console/layer-1/L1NodeSetupDocker.tsx @@ -3,7 +3,7 @@ import { useWalletStore } from "@/components/toolbox/stores/walletStore"; import { useState, useEffect } from "react"; import { networkIDs } from "@avalabs/avalanchejs"; -import { Container } from "../../components/Container"; +import { ToolContainer } from "../../components/ToolContainer"; import { getBlockchainInfo, getSubnetInfo } from "../../coreViem/utils/glacier"; import InputSubnetId from "../../components/InputSubnetId"; import BlockchainDetailsDisplay from "../../components/BlockchainDetailsDisplay"; @@ -19,8 +19,15 @@ import { AddToWalletStep } from "../../components/AddToWalletStep"; import { ConfigureNodeType } from "../../components/ConfigureNodeType"; import { generateDockerCommand } from "./create/config"; import { SUBNET_EVM_VM_ID } from "@/constants/console"; +import { ConsoleToolMetadata, BaseConsoleToolProps, withConsoleToolMetadata } from "@/types/consoleTool"; -export default function AvalanchegoDocker() { +const l1NodeSetupDockerMetadata: ConsoleToolMetadata = { + title: "L1 Node Setup with Docker", + description: "This will start a Docker container running an RPC or validator node that tracks your L1.", + walletRequirements: [], +} + +function L1NodeSetupDockerBase({onSuccess}: BaseConsoleToolProps) { const [chainId, setChainId] = useState(""); const [subnetId, setSubnetId] = useState(""); const [subnet, setSubnet] = useState(null); @@ -151,11 +158,9 @@ export default function AvalanchegoDocker() { const isCustomVM = blockchainInfo && blockchainInfo.vmId !== SUBNET_EVM_VM_ID; return ( - <> - +

Set up Instance

@@ -382,14 +387,14 @@ export default function AvalanchegoDocker() {
- {chainAddedToWallet && ( - <> - - - - )} - -
- + {chainAddedToWallet && ( + <> + + + + )} + ); }; + +export default withConsoleToolMetadata(L1NodeSetupDockerBase, l1NodeSetupDockerMetadata); diff --git a/components/toolbox/console/layer-1/create/ConvertSubnetToL1.tsx b/components/toolbox/console/layer-1/create/ConvertSubnetToL1.tsx index 051ef5a41ed..bb52d324a36 100644 --- a/components/toolbox/console/layer-1/create/ConvertSubnetToL1.tsx +++ b/components/toolbox/console/layer-1/create/ConvertSubnetToL1.tsx @@ -5,18 +5,24 @@ import { useWalletStore } from "@/components/toolbox/stores/walletStore"; import { useState, useEffect } from "react"; import { Button } from "@/components/toolbox/components/Button"; import { type ConvertToL1Validator } from "@/components/toolbox/components/ValidatorListInput"; -import { Container } from "@/components/toolbox/components/Container"; +import { ToolContainer } from "@/components/toolbox/components/ToolContainer"; import { ValidatorListInput } from "@/components/toolbox/components/ValidatorListInput"; import InputChainId from "@/components/toolbox/components/InputChainId"; import SelectSubnet, { SubnetSelection } from "@/components/toolbox/components/SelectSubnet"; import { Callout } from "fumadocs-ui/components/callout"; import { EVMAddressInput } from "@/components/toolbox/components/EVMAddressInput"; import { getPChainBalance } from "@/components/toolbox/coreViem/methods/getPChainbalance"; -import { CheckWalletRequirements } from "@/components/toolbox/components/CheckWalletRequirements"; +import { ConsoleToolMetadata, BaseConsoleToolProps, withConsoleToolMetadata } from "@/types/consoleTool"; import { WalletRequirementsConfigKey } from "@/components/toolbox/hooks/useWalletRequirements"; import useConsoleNotifications from "@/hooks/useConsoleNotifications"; -export default function ConvertSubnetToL1() { +const convertSubnetToL1Metadata: ConsoleToolMetadata = { + title: "Convert Subnet to L1", + description: "This will convert your Subnet to an L1.", + walletRequirements: [WalletRequirementsConfigKey.PChainBalance], +} + +function ConvertSubnetToL1Base({onSuccess}: BaseConsoleToolProps) { const { subnetId: storeSubnetId, chainID: storeChainID, @@ -80,19 +86,16 @@ export default function ConvertSubnetToL1() { try { const txID = await convertSubnetToL1Tx; setConvertToL1TxId(txID); + onSuccess?.(); } finally { setIsConverting(false); } } return ( - - +
- -
-
+ ); }; + +export default withConsoleToolMetadata(ConvertSubnetToL1Base, convertSubnetToL1Metadata); diff --git a/components/toolbox/console/layer-1/create/CreateChain.tsx b/components/toolbox/console/layer-1/create/CreateChain.tsx index 54194476b24..1ad15db0884 100644 --- a/components/toolbox/console/layer-1/create/CreateChain.tsx +++ b/components/toolbox/console/layer-1/create/CreateChain.tsx @@ -4,7 +4,6 @@ import { useCreateChainStore } from "@/components/toolbox/stores/createChainStor import { useState } from "react"; import { Button } from "@/components/toolbox/components/Button"; import { Input } from "@/components/toolbox/components/Input"; -import { Container } from "@/components/toolbox/components/Container"; import { useWalletStore } from "@/components/toolbox/stores/walletStore"; import GenesisBuilder from '@/components/toolbox/console/layer-1/create/GenesisBuilder'; import { Step, Steps } from "fumadocs-ui/components/steps"; @@ -12,12 +11,13 @@ import generateName from 'boring-name-generator' import { RadioGroup } from "@/components/toolbox/components/RadioGroup"; import InputSubnetId from "@/components/toolbox/components/InputSubnetId"; import { SUBNET_EVM_VM_ID } from "@/constants/console"; -import { CheckWalletRequirements } from "@/components/toolbox/components/CheckWalletRequirements"; +import { ToolContainer } from "@/components/toolbox/components/ToolContainer"; + +import { ConsoleToolMetadata, BaseConsoleToolProps, withConsoleToolMetadata } from "@/types/consoleTool"; import { WalletRequirementsConfigKey } from "@/components/toolbox/hooks/useWalletRequirements"; import useConsoleNotifications from "@/hooks/useConsoleNotifications"; - const generateRandomName = () => { //makes sure the name doesn't contain a dash const firstLetterUppercase = (word: string) => word.charAt(0).toUpperCase() + word.slice(1); @@ -28,8 +28,13 @@ const generateRandomName = () => { throw new Error("Could not generate a name with a dash after 1000 attempts"); } +const createChainMetadata: ConsoleToolMetadata = { + title: "Create Chain", + description: "Create a Subnet and add a new blockchain with custom parameters and genesis data.", + walletRequirements: [WalletRequirementsConfigKey.PChainBalance], +} -export default function CreateChain() { +function CreateChainBase({onSuccess}: BaseConsoleToolProps) { const { subnetId, setChainID, @@ -103,109 +108,106 @@ export default function CreateChain() { setChainID(txID); setChainName(localChainName); setLocalChainName(generateRandomName()); - + onSuccess?.(); } finally { setIsCreatingChain(false); } } return ( - - - - -

Step 1: Create a Subnet

-

- Every chain needs to be associated with a Subnet. If you don't have a Subnet, create one here. If you already have a Subnet, skip to the next step. -

-
- - - -
-
- -

Step 2: Create a Chain

-

- Enter the parameters for your new chain. -

- - - + + + +

Step 1: Create a Subnet

+

+ Every chain needs to be associated with a Subnet. If you don't have a Subnet, create one here. If you already have a Subnet, skip to the next step. +

+
-

Virtual Machine

-

- Select what Virtual Machine (VM) your chain will use. -

- { - const shouldShow = value === "true"; - setShowVMIdInput(shouldShow); - // Reset to standard EVM when switching to uncustomized - if (!shouldShow) { - setVmId(SUBNET_EVM_VM_ID); - } - }} - idPrefix={`show-vm-id`} - className="mb-4" - items={[ - { value: "false", label: "Uncustomized EVM" }, - { value: "true", label: "Customized EVM or alternative VM (Experts only)" } - ]} - /> - {showVMIdInput && ( - - )} - - - - - - - +
+
+ +

Step 2: Create a Chain

+

+ Enter the parameters for your new chain. +

+ + + + + +

Virtual Machine

+

+ Select what Virtual Machine (VM) your chain will use. +

+ { + const shouldShow = value === "true"; + setShowVMIdInput(shouldShow); + // Reset to standard EVM when switching to uncustomized + if (!shouldShow) { + setVmId(SUBNET_EVM_VM_ID); + } + }} + idPrefix={`show-vm-id`} + className="mb-4" + items={[ + { value: "false", label: "Uncustomized EVM" }, + { value: "true", label: "Customized EVM or alternative VM (Experts only)" } + ]} + /> + {showVMIdInput && ( + + )} + + + + +
+
+
); }; + +export default withConsoleToolMetadata(CreateChainBase, createChainMetadata); \ No newline at end of file diff --git a/types/consoleTool.ts b/types/consoleTool.ts new file mode 100644 index 00000000000..1f17bb51099 --- /dev/null +++ b/types/consoleTool.ts @@ -0,0 +1,34 @@ +import { WalletRequirementsConfigKey } from "@/components/toolbox/hooks/useWalletRequirements"; + +// Console tool metadata interface +export interface ConsoleToolMetadata { + /** Display name of the tool */ + title: string; + /** Brief description of what the tool does */ + description: string; + /** Wallet requirements including if the tool is only available on testnet */ + walletRequirements: WalletRequirementsConfigKey[]; +} + +// Props interface for console tools +export interface BaseConsoleToolProps { + /** Function to call when the tool succeeds. This can be used to navigate the user to the next step. */ + onSuccess?: () => void; +} + +// Base console tool component type (before wrapping with metadata) +type BaseConsoleToolComponent = React.ComponentType; + +// Console Tool with Metadata +export type ConsoleToolComponent = BaseConsoleToolComponent & { + /** Required metadata for all console tools */ + metadata: ConsoleToolMetadata; +}; + +// Utility type to ensure a component has the required metadata +export function withConsoleToolMetadata( + BaseComponent: BaseConsoleToolComponent, + metadata: ConsoleToolMetadata +): ConsoleToolComponent { + return Object.assign(BaseComponent, { metadata }); +} \ No newline at end of file