> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sei.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Using the OpenZeppelin Contract Wizard with Sei EVM

> Learn how to use the OpenZeppelin Contract Wizard to create secure, standard-compliant smart contracts for Sei EVM, with step-by-step guidance and best practices.

export const AddSeiButton = ({network = 'mainnet', label = 'Add Sei to MetaMask'}) => {
  const SEI_MAINNET_CHAIN_PARAMS = {
    chainId: '0x531',
    chainName: 'Sei Network',
    rpcUrls: ['https://evm-rpc.sei-apis.com'],
    nativeCurrency: {
      name: 'Sei',
      symbol: 'SEI',
      decimals: 18
    },
    blockExplorerUrls: ['https://seiscan.io']
  };
  const SEI_TESTNET_CHAIN_PARAMS = {
    chainId: '0x530',
    chainName: 'Sei Testnet',
    rpcUrls: ['https://evm-rpc-testnet.sei-apis.com'],
    nativeCurrency: {
      name: 'Sei',
      symbol: 'SEI',
      decimals: 18
    },
    blockExplorerUrls: ['https://testnet.seiscan.io']
  };
  const chainParams = network === 'testnet' ? SEI_TESTNET_CHAIN_PARAMS : SEI_MAINNET_CHAIN_PARAMS;
  const [status, setStatus] = useState(null);
  const [isHovered, setIsHovered] = useState(false);
  const [isBusy, setIsBusy] = useState(false);
  const addOrSwitchSeiNetwork = async params => {
    if (typeof window === 'undefined' || !window.ethereum) {
      throw new Error('MetaMask is not installed');
    }
    const ethereum = window.ethereum;
    try {
      await ethereum.request({
        method: 'wallet_switchEthereumChain',
        params: [{
          chainId: params.chainId
        }]
      });
    } catch (switchError) {
      if (switchError && switchError.code === 4902) {
        await ethereum.request({
          method: 'wallet_addEthereumChain',
          params: [params]
        });
      } else {
        throw switchError;
      }
    }
  };
  const onClick = async e => {
    e.preventDefault();
    setIsBusy(true);
    setStatus(null);
    try {
      await addOrSwitchSeiNetwork(chainParams);
      setStatus({
        type: 'success',
        message: `${chainParams.chainName} added or switched.`
      });
    } catch (err) {
      const message = err && err.message ? err.message : 'Failed to add or switch network.';
      setStatus({
        type: 'error',
        message
      });
    } finally {
      setIsBusy(false);
    }
  };
  return <span className="inline-flex flex-col items-start gap-1">
      <button type="button" onClick={onClick} disabled={isBusy} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} className="inline-flex items-center gap-1 px-3 py-1.5 text-white transition-colors min-w-[160px]" style={{
    backgroundColor: isHovered ? 'var(--sei-maroon-200)' : 'var(--sei-maroon-100)',
    color: '#ffffff',
    fontFamily: 'var(--sei-font-mono)',
    textTransform: 'uppercase',
    letterSpacing: '0.04em',
    fontSize: '10px',
    opacity: isBusy ? 0.7 : 1,
    cursor: isBusy ? 'default' : 'pointer'
  }}>
        {isBusy ? 'Adding…' : label}
      </button>
      {status && <span className={status.type === 'error' ? 'text-red-600 dark:text-red-400' : 'text-green-600 dark:text-green-400'} style={{
    fontSize: '11px'
  }}>
          {status.message}
        </span>}
    </span>;
};

export const SandboxEmbed = props => {
  const {src, kind = 'codesandbox', title, description, height, label} = props || ({});
  const KINDS = {
    codesandbox: {
      name: 'CodeSandbox',
      host: 'codesandbox.io',
      defaultHeight: 500
    },
    remix: {
      name: 'Remix IDE',
      host: 'remix.ethereum.org',
      defaultHeight: 620
    },
    stackblitz: {
      name: 'StackBlitz',
      host: 'stackblitz.com',
      defaultHeight: 500
    }
  };
  const meta = KINDS[kind] || KINDS.codesandbox;
  const parsedHeight = Number(height);
  const frameHeight = Number.isFinite(parsedHeight) && parsedHeight > 0 ? parsedHeight : meta.defaultHeight;
  const allowAttr = 'clipboard-read; clipboard-write';
  const [loaded, setLoaded] = useState(false);
  const [btnHover, setBtnHover] = useState(false);
  const HAIRLINE = 'rgba(128, 128, 128, 0.25)';
  const surfaceStyle = {
    backgroundColor: 'rgba(128, 128, 128, 0.08)'
  };
  const monoStyle = {
    fontFamily: 'var(--sei-font-mono)'
  };
  const cardClass = 'not-prose w-full rounded-lg border overflow-hidden my-4';
  const headerClass = 'flex items-center justify-between gap-3 px-4 py-2.5 border-b';
  const buttonStyle = {
    backgroundColor: btnHover ? 'var(--sei-maroon-200)' : 'var(--sei-maroon-100)',
    color: '#ffffff',
    fontFamily: 'var(--sei-font-mono)',
    textTransform: 'uppercase',
    letterSpacing: '0.04em',
    fontSize: '10px',
    cursor: 'pointer'
  };
  const PlayIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
			<path d="M8 5v14l11-7z" />
		</svg>;
  const ExternalIcon = () => <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
			<path d="M14 5h5v5" />
			<path d="M19 5l-9 9" />
			<path d="M19 14v5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h5" />
		</svg>;
  return <div className={cardClass} style={{
    borderColor: HAIRLINE
  }}>
			<div className={headerClass} style={{
    ...surfaceStyle,
    borderBottomColor: HAIRLINE
  }}>
				<div className="flex flex-col min-w-0">
					<span className="text-sm font-medium text-neutral-900 dark:text-white truncate" style={monoStyle}>
						{title || meta.name}
					</span>
					<span className="text-xs text-neutral-500 dark:text-neutral-500">{meta.name}</span>
				</div>
				<div className="flex items-center gap-3 shrink-0">
					{src ? <a href={src} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1 text-xs text-neutral-500 hover:text-neutral-800 dark:text-neutral-400 dark:hover:text-neutral-200 transition-colors">
							Open <ExternalIcon />
						</a> : null}
					{!loaded && src ? <button type="button" onClick={() => setLoaded(true)} onMouseEnter={() => setBtnHover(true)} onMouseLeave={() => setBtnHover(false)} className="inline-flex items-center gap-1.5 px-3 py-1.5 transition-colors" style={buttonStyle}>
							<PlayIcon />
							{label || 'Load editor'}
						</button> : null}
				</div>
			</div>

			{description ? <div className="px-4 pt-3 pb-1 text-sm text-neutral-600 dark:text-neutral-400">{description}</div> : null}

			{!src ? <div className="px-4 py-6 text-sm text-red-600 dark:text-red-400" style={monoStyle}>
					SandboxEmbed: missing required `src`.
				</div> : loaded ? <iframe src={src} title={title || meta.name} className="w-full block border-0" style={{
    height: frameHeight + 'px',
    backgroundColor: 'rgba(128, 128, 128, 0.05)'
  }} allow={allowAttr} loading="lazy" allowFullScreen /> : <button type="button" onClick={() => setLoaded(true)} className="w-full flex flex-col items-center justify-center gap-2 text-neutral-500 dark:text-neutral-400 hover:text-neutral-800 dark:hover:text-neutral-200 transition-colors" style={{
    height: frameHeight + 'px',
    cursor: 'pointer',
    ...surfaceStyle
  }}>
					<PlayIcon />
					<span className="text-sm" style={monoStyle}>Click to load {meta.name}</span>
					<span className="text-xs">Loads {meta.host} in an embedded editor</span>
				</button>}
		</div>;
};

The OpenZeppelin Contract Wizard is a powerful interactive tool that simplifies the creation of secure, standard-compliant smart contracts for Sei EVM. It provides a user-friendly interface for generating production-ready contract code based on OpenZeppelin's battle-tested libraries. Explore and create your custom smart contracts using the embedded wizard below.

<iframe src="https://wizard.openzeppelin.com/embed" style={{ width: "100%", minHeight: "700px", border: "0", background: "white" }} loading="lazy" title="OpenZeppelin Contract Wizard" />

## Benefits of Using the Wizard

* **Security First**: All generated contracts use audited, industry-standard implementations from OpenZeppelin
* **Time-Saving**: Eliminate boilerplate code and common setup configurations
* **Customizable**: Tailor contracts to your specific requirements through an intuitive UI
* **Educational**: Learn best practices by examining professionally structured contract code
* **Up-to-Date**: Always generates code compatible with the latest Solidity versions and standards

## Available Contract Types

| Contract Type    | Description                    | Common Use Cases                                                 |
| ---------------- | ------------------------------ | ---------------------------------------------------------------- |
| ERC20            | Standard fungible token        | Cryptocurrencies, utility tokens, governance tokens              |
| ERC721           | Non-fungible token (NFT)       | Digital collectibles, art, real estate, certifications           |
| ERC1155          | Multi-token standard           | Gaming assets, mixed fungible/non-fungible collections           |
| Governor         | On-chain governance            | DAO voting systems, protocol management                          |
| Stablecoin       | Price-stable cryptocurrency    | Trading pairs, remittances, reducing volatility, payment systems |
| Real-World-Asset | Tokenized physical assets      | Real estate, commodities, securities, debt instruments, invoices |
| Account          | Programmable Wallet (ERC-4337) | Account abstraction, Multi signature wallets, EOA Delegation     |
| Custom           | Specialized contracts          | Access control, payment systems, timelock functions              |

## Step-by-Step Guide

1. **Access the Wizard**: Use the embedded widget from OpenZeppelin above or visit [wizard.openzeppelin.com](https://wizard.openzeppelin.com/)
2. **Select Contract Type**: Choose the standard that matches your project needs (ERC20, ERC721, etc.)
3. **Configure Basic Settings**:
   * Set token name and symbol
   * Choose Solidity version
   * Select access control mechanism (Ownable, Roles, etc.)
4. **Add Security Features**:
   * Pausable functionality
   * Permit extensions
   * Flash minting capabilities
   * Voting mechanisms
5. **Customize Token Behavior**:
   * Premint options
   * Burning capabilities
   * Token transfer rules
   * Supply management
6. **Review Generated Code**: The code updates in real-time as you make selections
7. **Copy and Implement**: Use the "Copy to clipboard" button to export your contract code
8. **Deploy**: The generated code is ready for compilation and deployment

## Tips for Effective Use

* **Start Simple**: Begin with minimal features and add complexity incrementally
* **Understand Each Option**: Hover over the question icons (?) for detailed explanations
* **Review Dependencies**: Note which OpenZeppelin libraries your contract imports
* **Consider Gas Costs**: More features generally mean higher deployment and operation costs
* **Customize Post-Generation**: The wizard provides a starting point—most projects will require additional customization

## Try it: deploy from the browser

Once the wizard generates your contract, you can compile and deploy it to Sei testnet without any local setup. The Remix sandbox below is preloaded with a sample OpenZeppelin ERC-20 — replace it with your generated code, compile under **Solidity Compiler**, then **Deploy & Run** with **Environment** set to **Injected Provider — MetaMask**.

<AddSeiButton network="testnet" label="Add Sei testnet" />

<SandboxEmbed kind="remix" src="https://remix.ethereum.org/?#activate=solidity,fileManager&code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVApwcmFnbWEgc29saWRpdHkgXjAuOC4yNDsKCmltcG9ydCAiQG9wZW56ZXBwZWxpbi9jb250cmFjdHMvdG9rZW4vRVJDMjAvRVJDMjAuc29sIjsKCmNvbnRyYWN0IERlbW9Ub2tlbiBpcyBFUkMyMCB7CiAgICBjb25zdHJ1Y3RvcigpIEVSQzIwKCJEZW1vIFRva2VuIiwgIkRFTU8iKSB7CiAgICAgICAgX21pbnQobXNnLnNlbmRlciwgMV8wMDBfMDAwICogMTAgKiogZGVjaW1hbHMoKSk7CiAgICB9Cn0" title="OpenZeppelin ERC-20 · deploy to Sei testnet" description="Remix IDE preloaded with a sample OpenZeppelin ERC-20. Paste in your wizard output, compile, and deploy to Sei testnet." />

## Learn More

* [OpenZeppelin Contracts Documentation](https://docs.openzeppelin.com/contracts/)
* [OpenZeppelin GitHub Repository](https://github.com/OpenZeppelin/openzeppelin-contracts)
* [OpenZeppelin Community Forum](https://forum.openzeppelin.com/)
