diff --git a/.circleci/config.yml b/.circleci/config.yml index d87d65749..dcbd2db1d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -66,48 +66,48 @@ jobs: # NEXT_PUBLIC_ALGOLIA_INDEX_NAME pnpm run index:docs - breadcrumbs: - description: Check breadcrumbs in documentation - executor: ubuntu - steps: - - checkout - - setup-node - - run: - name: Run breadcrumb check - command: pnpm check-breadcrumbs + # breadcrumbs: + # description: Check breadcrumbs in documentation + # executor: ubuntu + # steps: + # - checkout + # - setup-node + # - run: + # name: Run breadcrumb check + # command: pnpm check-breadcrumbs - lint: - description: Lint Markdown files and validate metadata - executor: ubuntu - steps: - - checkout - - setup-node - - run: - name: Get changed files - command: | - if [ -n "$CIRCLE_PULL_REQUEST" ]; then - PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | rev | cut -d'/' -f1 | rev) - CHANGED_FILES=$(curl -s "https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PR_NUMBER/files" | jq -r '.[].filename' | grep '\.mdx$' || true) - echo "export CHANGED_FILES=\"$CHANGED_FILES\"" >> $BASH_ENV - fi - - run: - name: Lint Markdown files - command: pnpm lint - - run: - name: "Metadata Validation (Warning Only)" - command: | - echo "Running metadata validation (warnings will not block PR)..." - pnpm validate-pr-metadata || true + # lint: + # description: Lint Markdown files and validate metadata + # executor: ubuntu + # steps: + # - checkout + # - setup-node + # - run: + # name: Get changed files + # command: | + # if [ -n "$CIRCLE_PULL_REQUEST" ]; then + # PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | rev | cut -d'/' -f1 | rev) + # CHANGED_FILES=$(curl -s "https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PR_NUMBER/files" | jq -r '.[].filename' | grep '\.mdx$' || true) + # echo "export CHANGED_FILES=\"$CHANGED_FILES\"" >> $BASH_ENV + # fi + # - run: + # name: Lint Markdown files + # command: pnpm lint + # - run: + # name: "Metadata Validation (Warning Only)" + # command: | + # echo "Running metadata validation (warnings will not block PR)..." + # pnpm validate-pr-metadata || true - links: - description: Check broken links in documentation - executor: ubuntu - steps: - - checkout - - setup-node - - run: - name: Run link checker - command: pnpm link-checker + # links: + # description: Check broken links in documentation + # executor: ubuntu + # steps: + # - checkout + # - setup-node + # - run: + # name: Run link checker + # command: pnpm link-checker developer-metrics: description: Monthly Metrics Report @@ -152,11 +152,11 @@ workflows: branches: only: main - pr-workflow: - jobs: - - breadcrumbs - - links - - lint + # pr-workflow: + # jobs: + # - breadcrumbs + # - links + # - lint monthly-workflow: when: equal: [build_monthly, <>] diff --git a/.husky/install.sh b/.husky/install.sh deleted file mode 100755 index c7c1318e5..000000000 --- a/.husky/install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -# Add hooks here -npx husky add .husky/pre-push 'pnpm fix' \ No newline at end of file diff --git a/.husky/pre-push b/.husky/pre-push deleted file mode 100755 index 0739a3de4..000000000 --- a/.husky/pre-push +++ /dev/null @@ -1,31 +0,0 @@ -echo "🔍 Running automatic fixes before pushing..." - -# Try multiple ways to run pnpm -if command -v pnpm >/dev/null 2>&1; then - # Direct pnpm if available in PATH - pnpm fix -elif [ -f "$(npm root -g)/pnpm/bin/pnpm.cjs" ]; then - # Try global NPM installation path - "$(npm root -g)/pnpm/bin/pnpm.cjs" fix -elif command -v npx >/dev/null 2>&1; then - # Fallback to npx if available - npx --no-install pnpm fix -else - echo "⚠️ Could not find pnpm. Skipping automatic fixes..." - exit 0 # Don't fail the push, just continue -fi - -# Check if there are any changes after running fixes -if [ -n "$(git status --porcelain)" ]; then - echo "🔄 Changes detected after running fixes. Committing them automatically..." - - # Stage all changes - git add . - - # Create a commit with a descriptive message - git commit -m "Auto-fix: Update breadcrumbs, spelling dictionary and other automated fixes" - - echo "✅ Changes committed automatically. Continuing with push..." -else - echo "✅ No changes needed. Continuing with push..." -fi \ No newline at end of file diff --git a/.remarkrc.mjs b/.remarkrc.mjs deleted file mode 100644 index 2622554f7..000000000 --- a/.remarkrc.mjs +++ /dev/null @@ -1,33 +0,0 @@ -import remarkLintNoBlockedCharacters from './utils/plugins/remark/remark-lint-no-blocked-characters.mjs' - -export default { - plugins: [ - remarkLintNoBlockedCharacters, - "remark-gfm", - "remark-frontmatter", - "remark-preset-lint-consistent", - "remark-preset-lint-recommended", - "remark-lint-table-cell-padding", - "remark-lint-table-pipe-alignment", - "remark-lint-table-pipes", - "@double-great/remark-lint-alt-text", - [ - "remark-lint-heading-style", - "atx" - ], - [ - "remark-lint-unordered-list-marker-style", - "*" - ], - [ - "remark-lint-frontmatter-schema", - { - schemas: { - "./utils/schemas/page.schema.yaml": [ - "./pages/**/*.mdx" - ] - } - } - ] - ] -} diff --git a/pages/app-developers/bridging/basics.mdx b/app-developers/bridging/basics.mdx similarity index 90% rename from pages/app-developers/bridging/basics.mdx rename to app-developers/bridging/basics.mdx index 12ac5f3a8..fae3f193f 100644 --- a/pages/app-developers/bridging/basics.mdx +++ b/app-developers/bridging/basics.mdx @@ -3,16 +3,6 @@ title: Bridging basics description: >- Learn about the fundamentals of sending data and tokens between Ethereum and OP Mainnet. -lang: en-US -content_type: guide -topic: bridging-basics -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet -is_imported_content: 'false' --- # Bridging basics diff --git a/pages/app-developers/bridging/custom-bridge.mdx b/app-developers/bridging/custom-bridge.mdx similarity index 91% rename from pages/app-developers/bridging/custom-bridge.mdx rename to app-developers/bridging/custom-bridge.mdx index 9e105a09f..81e433a5f 100644 --- a/pages/app-developers/bridging/custom-bridge.mdx +++ b/app-developers/bridging/custom-bridge.mdx @@ -1,20 +1,8 @@ --- title: Custom bridges description: Important considerations when building custom bridges for OP Mainnet. -lang: en-US -content_type: guide -topic: custom-bridges -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Custom bridges @@ -22,11 +10,11 @@ Custom token bridges are any bridges other than the [Standard Bridge](./standard You may find yourself in a position where you need to build a custom token bridge because the Standard Bridge doesn't completely support your use case. This guide provides important information you should be aware of when building a custom bridge. - + Custom bridges can bring a significant amount of complexity and risk to any project. Before you commit to a custom bridge, be sure that the [Standard Bridge](./standard-bridge) definitely does not support your use case. [Building a custom bridged token](/app-developers/tutorials/bridging/standard-bridge-custom-token) is often sufficient for projects that need more flexibility. - + ## Guidelines diff --git a/pages/app-developers/bridging/messaging.mdx b/app-developers/bridging/messaging.mdx similarity index 97% rename from pages/app-developers/bridging/messaging.mdx rename to app-developers/bridging/messaging.mdx index e96057054..94a5a1cca 100644 --- a/pages/app-developers/bridging/messaging.mdx +++ b/app-developers/bridging/messaging.mdx @@ -3,30 +3,18 @@ title: Sending data between L1 and L2 description: >- Learn how bridging works between L1 and L2, how to use it, and what to watch out for. -lang: en-US -content_type: guide -topic: sending-data-between-l1-and-l2 -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Sending data between L1 and L2 Smart contracts on L1 (Ethereum) can interact with smart contracts on L2 (OP Mainnet) through a process called "bridging". This page explains how bridging works, how to use it, and what to watch out for. - + This is a high-level overview of the bridging process. For a step-by-step tutorial on how to send data between L1 and L2, check out the [Solidity tutorial](/app-developers/tutorials/bridging/cross-dom-solidity). - + ## Understanding contract calls @@ -129,9 +117,9 @@ contract MyContract { } ``` - + You can find the addresses of the `L1CrossDomainMessenger` and the `L2CrossDomainMessenger` contracts on OP Mainnet and OP Sepolia on the [Contract Addresses](/superchain/addresses) page. - + ## Communication speed @@ -202,10 +190,10 @@ L1 to L2 execution also triggers contract execution on L2. The `OptimismPortal` contract charges you for this L2 execution by burning a dynamic amount of L1 gas during your L1 to L2 transaction, depending on the gas limit you requested on L2. The amount of L1 gas charged increases when more people are sending L1 to L2 transactions (and decreases when fewer people are sending L1 to L2 transactions). - + Since the gas amount charged is dynamic, the gas burn can change from block to block. You should always add a buffer of at least 20% to the gas limit for your L1 to L2 transaction to avoid running out of gas. - + ### For L2 to L1 transactions diff --git a/pages/app-developers/bridging/standard-bridge.mdx b/app-developers/bridging/standard-bridge.mdx similarity index 98% rename from pages/app-developers/bridging/standard-bridge.mdx rename to app-developers/bridging/standard-bridge.mdx index 0f5a934cc..688f4c77b 100644 --- a/pages/app-developers/bridging/standard-bridge.mdx +++ b/app-developers/bridging/standard-bridge.mdx @@ -3,20 +3,8 @@ title: Using the Standard Bridge description: >- Learn the basics of using the Standard Bridge to move tokens between Layer 1 and Layer 2. -lang: en-US -content_type: guide -topic: using-the-standard-bridge -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Using the Standard Bridge @@ -29,9 +17,9 @@ The Standard Bridge is fully permissionless and supports standard ERC-20 tokens. Other bridging systems also exist that provide different features and security properties. You may wish to explore some of these options to find the bridge that works best for you and your application. - + The Standard Bridge **does not** support [**fee on transfer tokens**](https://github.com/d-xo/weird-erc20#fee-on-transfer) or [**rebasing tokens**](https://github.com/d-xo/weird-erc20#balance-modifications-outside-of-transfers-rebasingairdrops) because these types of tokens may cause bridge accounting errors. - + ## Design @@ -87,14 +75,14 @@ The process for bridging a native token involves a few steps. * `uint32 _minGasLimit`: Gas to use to complete the transfer on the receiving side. * `bytes calldata _extraData`: Optional identify extra data. - + Users can also trigger the [`bridgeERC20`](https://github.com/ethereum-optimism/optimism/blob/2e647210882d961f04055e656590d90ad98c9934/packages/contracts-bedrock/src/universal/StandardBridge.sol#L168-L191) function instead of `bridgeERC20To` to avoid needing to specify the `address _to` parameter. Doing so will automatically set the `address _to` parameter to the `msg.sender`. **The `bridgeERC20` function can be potentially dangerous for users with [smart contract wallets](https://web.archive.org/web/20231012141406/https://blockworks.co/news/what-are-smart-contract-wallets) as some smart contract wallets cannot be deployed at the same address on every blockchain.** To help users avoid potentially losing access to tokens by accident, the `bridgeERC20` function will always revert when triggered from a smart contract. Smart contract wallet users and other smart contracts should therefore use the `bridgeERC20To` function instead. - + {

The Standard Bridge locks the transferred tokens

} @@ -203,11 +191,11 @@ The Standard Bridge contracts can also be used to bridge ETH from Ethereum to OP The ETH bridging process is generally less complex than the ERC-20 bridging process. Users simply need to trigger and send ETH to the [`bridgeETH`](https://github.com/ethereum-optimism/optimism/blob/2e647210882d961f04055e656590d90ad98c9934/packages/contracts-bedrock/src/universal/StandardBridge.sol#L143-L150) or [`bridgeETHTo`](https://github.com/ethereum-optimism/optimism/blob/2e647210882d961f04055e656590d90ad98c9934/packages/contracts-bedrock/src/universal/StandardBridge.sol#L152-L166) functions on either blockchain. - + Users can also deposit ETH from Ethereum to OP Mainnet by sending a basic ETH transfer from an EOA to the `L1StandardBridgeProxy`. This works because the `L1StandardBridgeProxy` contains a [`receive`](https://github.com/ethereum-optimism/optimism/blob/2e647210882d961f04055e656590d90ad98c9934/packages/contracts-bedrock/src/universal/StandardBridge.sol#L119-L121) function. You can find the mainnet and testnet addresses on the [Contract Addresses](/superchain/addresses) page. - + ## Tutorials diff --git a/pages/app-developers/building-apps.mdx b/app-developers/building-apps.mdx similarity index 93% rename from pages/app-developers/building-apps.mdx rename to app-developers/building-apps.mdx index 60b17ba1a..06627e051 100644 --- a/pages/app-developers/building-apps.mdx +++ b/app-developers/building-apps.mdx @@ -1,20 +1,8 @@ --- title: Building apps on the Superchain description: Learn the basics of building apps on the Superchain. -lang: en-US -content_type: guide -topic: building-apps-on-the-superchain -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet - - testnet -is_imported_content: 'false' --- -import { Steps } from 'nextra/components' # Building apps on the Superchain diff --git a/app-developers/get-started.mdx b/app-developers/get-started.mdx new file mode 100644 index 000000000..bcaae70b2 --- /dev/null +++ b/app-developers/get-started.mdx @@ -0,0 +1,10 @@ +--- +title: Build interoperable apps on Superchain devnet +description: >- + Learn about deploying contracts, cross-chain messaging, and tutorials to help + you build applications on the Superchain. +--- + + + + diff --git a/app-developers/interop.mdx b/app-developers/interop.mdx new file mode 100644 index 000000000..57e719fba --- /dev/null +++ b/app-developers/interop.mdx @@ -0,0 +1,7 @@ +--- +title: Getting started with Interop +description: Learn the basics of interoperability on the Superchain. +--- + + + diff --git a/app-developers/starter-kit.mdx b/app-developers/starter-kit.mdx new file mode 100644 index 000000000..56223ba9d --- /dev/null +++ b/app-developers/starter-kit.mdx @@ -0,0 +1,9 @@ +--- +title: Deploying a SuperchainERC20 (Starter Kit) +description: >- + Learn how to quickly build and deploy a SuperchainERC20 token across the + Superchain using the SuperchainERC20 Starter Kit. +--- + + + diff --git a/pages/app-developers/testing-apps.mdx b/app-developers/testing-apps.mdx similarity index 96% rename from pages/app-developers/testing-apps.mdx rename to app-developers/testing-apps.mdx index cc5346324..2f1d54d74 100644 --- a/pages/app-developers/testing-apps.mdx +++ b/app-developers/testing-apps.mdx @@ -1,15 +1,6 @@ --- title: Testing apps for the Superchain description: Learn best practices for testing apps on the Superchain. -lang: en-US -content_type: guide -topic: testing-apps-for-the-superchain -personas: - - app-developer -categories: - - mainnet - - testnet -is_imported_content: 'false' --- # Testing apps for the Superchain diff --git a/pages/app-developers/tools.mdx b/app-developers/tools.mdx similarity index 93% rename from pages/app-developers/tools.mdx rename to app-developers/tools.mdx index 6ab674e72..0f6ba5ccf 100644 --- a/pages/app-developers/tools.mdx +++ b/app-developers/tools.mdx @@ -1,19 +1,8 @@ --- title: App developer tools description: Learn about app developer tools for the OP Stack. -lang: en-US -content_type: guide -topic: app-developer-tools -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # App developer tools @@ -23,17 +12,17 @@ If you are already familiar with [building on the OP Stack](/stack/getting-start ## Connecting - + } /> } /> } /> - + ## Building - + } /> } /> @@ -63,11 +52,11 @@ If you are already familiar with [building on the OP Stack](/stack/getting-start } /> } /> - + ## Data and dashboards - + } /> } /> @@ -77,4 +66,4 @@ If you are already familiar with [building on the OP Stack](/stack/getting-start } /> } /> - + diff --git a/pages/app-developers/tools/build/account-abstraction.mdx b/app-developers/tools/build/account-abstraction.mdx similarity index 95% rename from pages/app-developers/tools/build/account-abstraction.mdx rename to app-developers/tools/build/account-abstraction.mdx index 0b02511f6..5e21967cc 100644 --- a/pages/app-developers/tools/build/account-abstraction.mdx +++ b/app-developers/tools/build/account-abstraction.mdx @@ -3,25 +3,14 @@ title: Account abstraction description: >- This guide explains how to use account abstraction to remove friction from your app experience -lang: en-US -content_type: guide -topic: account-abstraction -personas: - - app-developer -categories: - - account-abstraction - - paymasters - - transactions -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Account abstraction - + This page includes providers that meet specific [inclusion criteria](#inclusion-criteria), as outlined below. Please visit the [community account abstractions page](https://github.com/ethereum-optimism/developers/blob/main/community/tools/account-abstraction.md) for an additional listing of third-party account abstraction tools. - + [ERC-4337](https://www.erc4337.io/docs/paymasters/introduction), also known as Account Abstraction, enables more opportunities for apps and wallet developers to innovate on user experiences, including the ability to: @@ -36,9 +25,9 @@ The OP Stack includes support for the `eth_sendRawTransactionConditional` RPC me If used by the chain operator, also see the supplemental [op-txproxy](/operators/chain-operators/tools/op-txproxy) service which may apply additional restrictions prior to reaching the block builder. - + As of today, this endpoint is not enabled by default in the stack. The operator must explicitly configure this. - + ## Superchain paymaster diff --git a/pages/app-developers/tools/build/analytics-tools.mdx b/app-developers/tools/build/analytics-tools.mdx similarity index 96% rename from pages/app-developers/tools/build/analytics-tools.mdx rename to app-developers/tools/build/analytics-tools.mdx index d3bd68ee2..dfb6f57dd 100644 --- a/pages/app-developers/tools/build/analytics-tools.mdx +++ b/app-developers/tools/build/analytics-tools.mdx @@ -3,15 +3,6 @@ title: Analytics tools description: >- Learn about platforms you can use to gather analytics and setup customizations about OP Mainnet. -lang: en-US -content_type: guide -topic: analytics-tools -personas: - - app-developer -categories: - - monitoring - - analytics -is_imported_content: 'false' --- # Analytics tools diff --git a/pages/app-developers/tools/build/block-explorers.mdx b/app-developers/tools/build/block-explorers.mdx similarity index 96% rename from pages/app-developers/tools/build/block-explorers.mdx rename to app-developers/tools/build/block-explorers.mdx index 16bc43960..fa2f04992 100644 --- a/pages/app-developers/tools/build/block-explorers.mdx +++ b/app-developers/tools/build/block-explorers.mdx @@ -3,28 +3,16 @@ title: Block explorers description: >- Learn about different block explorers you can use to interact with contracts and view transaction history for OP Mainnet and OP Sepolia. -lang: en-US -content_type: guide -topic: block-explorers -personas: - - app-developer -categories: - - testnet - - monitoring - - analytics - - testnet-tooling -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Block explorers This reference guide lists different block explorers you can use to interact with contract source code and view transaction history for OP Mainnet and OP Sepolia. - + This page includes providers that meet specific [inclusion criteria](#inclusion-criteria), as outlined below. Please visit the [community block explorers page](https://github.com/ethereum-optimism/developers/blob/main/community/tools/block-explorers.md) for an additional listing of third-party block explorers. - + ## Blockscout diff --git a/pages/app-developers/tools/build/faucets.mdx b/app-developers/tools/build/faucets.mdx similarity index 96% rename from pages/app-developers/tools/build/faucets.mdx rename to app-developers/tools/build/faucets.mdx index e764af9de..c7b5af0c5 100644 --- a/pages/app-developers/tools/build/faucets.mdx +++ b/app-developers/tools/build/faucets.mdx @@ -3,20 +3,8 @@ title: Testnet faucets description: >- Learn how to get testnet ETH on test networks like Sepolia and OP Sepolia for development and testing purposes. -lang: en-US -content_type: guide -topic: testnet-faucets -personas: - - app-developer -categories: - - testnet-tooling - - sepolia - - op-sepolia - - testnet -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Testnet faucets @@ -25,14 +13,14 @@ Here you'll find a list of active faucets that you can try out. Different faucets use different authentication methods, so you may have to try a few before you find one that works for you. Faucets can occasionally also run out of ETH, so if you're having trouble getting ETH from a faucet, try another one. - + This page includes providers that meet specific [inclusion criteria](#inclusion-criteria), as outlined below. Please visit the [community faucets page](https://github.com/ethereum-optimism/developers/blob/main/community/tools/faucets.md) for an additional listing of third-party faucets. - + - + Tokens on test networks like Sepolia or OP Sepolia have no value and are only meant for testing. Optimists only take what they need so that others can use faucets too! - + ## Superchain faucet diff --git a/pages/app-developers/tools/build/nft-tools.mdx b/app-developers/tools/build/nft-tools.mdx similarity index 97% rename from pages/app-developers/tools/build/nft-tools.mdx rename to app-developers/tools/build/nft-tools.mdx index 66e7db469..b0ce62ca4 100644 --- a/pages/app-developers/tools/build/nft-tools.mdx +++ b/app-developers/tools/build/nft-tools.mdx @@ -1,19 +1,8 @@ --- title: OP Mainnet NFT tools description: Learn the basics of creating an NFT on OP Mainnet. -lang: en-US -content_type: guide -topic: op-mainnet-nft-tools -personas: - - app-developer -categories: - - monitoring - - analytics - - mainnet -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # OP Mainnet NFT tools @@ -37,9 +26,9 @@ These tools are available on OP Mainnet: ## Feature comparison - + This list was last updated early February 2024, but new features are implemented all the time. - + | | NiftyKit | NFT-Inator | Mintplex | Zero Code NFT | thirdweb | Crossmint | | ------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/pages/app-developers/tools/build/oracles.mdx b/app-developers/tools/build/oracles.mdx similarity index 98% rename from pages/app-developers/tools/build/oracles.mdx rename to app-developers/tools/build/oracles.mdx index fb818d167..5d25d79ea 100644 --- a/pages/app-developers/tools/build/oracles.mdx +++ b/app-developers/tools/build/oracles.mdx @@ -3,25 +3,14 @@ title: Oracles description: >- Learn about different oracles and how you can use them to access offchain data onchain as well as random number generation. -lang: en-US -content_type: guide -topic: oracles -personas: - - app-developer -categories: - - monitoring - - analytics - - interoperability -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Oracles - + This page includes providers that meet specific [inclusion criteria](#inclusion-criteria), as outlined below. Please visit the [community oracles page](https://github.com/ethereum-optimism/developers/blob/main/community/tools/oracles.md) for an additional listing of third-party Oracles. - + This reference guide lists different Oracles you can use when building on Optimism. [Oracles](https://ethereum.org/en/developers/docs/oracles/) provide offchain data onchain. This allows code running on a blockchain to access a wide variety of information. For example, a [stablecoin](https://ethereum.org/en/stablecoins/) that accepts ETH as collateral needs to know the ETH/USD exchange rate: diff --git a/app-developers/tools/connect/networks.mdx b/app-developers/tools/connect/networks.mdx new file mode 100644 index 000000000..5cb425534 --- /dev/null +++ b/app-developers/tools/connect/networks.mdx @@ -0,0 +1,9 @@ +--- +title: Networks +description: >- + Learn about networks in the Optimism ecosystem. This guide provides detailed + information and resources about networks. +--- + + + diff --git a/pages/app-developers/tools/connect/rpc-providers.mdx b/app-developers/tools/connect/rpc-providers.mdx similarity index 98% rename from pages/app-developers/tools/connect/rpc-providers.mdx rename to app-developers/tools/connect/rpc-providers.mdx index 449ef2452..583002b55 100644 --- a/pages/app-developers/tools/connect/rpc-providers.mdx +++ b/app-developers/tools/connect/rpc-providers.mdx @@ -2,22 +2,8 @@ title: Superchain RPC directory description: >- Find public RPC endpoints and production RPC providers across all Superchain networks. -lang: en-US -content_type: guide -topic: rpc-node-providers -personas: - - app-developer -categories: - - infrastructure - - chain-operator - - developers - - superchain - - registry -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { Tabs } from 'nextra/components' # Superchain RPC Directory diff --git a/pages/app-developers/tools/data-and-dashboards/data-glossary.mdx b/app-developers/tools/data-and-dashboards/data-glossary.mdx similarity index 98% rename from pages/app-developers/tools/data-and-dashboards/data-glossary.mdx rename to app-developers/tools/data-and-dashboards/data-glossary.mdx index d9d6ecf0c..2da33304f 100644 --- a/pages/app-developers/tools/data-and-dashboards/data-glossary.mdx +++ b/app-developers/tools/data-and-dashboards/data-glossary.mdx @@ -2,14 +2,6 @@ title: Data glossary description: >- This glossary explains various data terms. -lang: en-US -content_type: guide -topic: data-glossary -personas: - - app-developer -categories: - - data-glossary -is_imported_content: 'false' --- # Data glossary diff --git a/pages/app-developers/tools/supersim.mdx b/app-developers/tools/supersim.mdx similarity index 91% rename from pages/app-developers/tools/supersim.mdx rename to app-developers/tools/supersim.mdx index 735f54051..93b5cc728 100644 --- a/pages/app-developers/tools/supersim.mdx +++ b/app-developers/tools/supersim.mdx @@ -1,25 +1,14 @@ --- title: Supersim Multichain Development Environment description: Learn how to use the Supersim local dev environment tool designed to simulate the Optimism Superchain. -lang: en-US -content_type: guide -topic: tools -personas: - - app-developer -categories: - - protocol - - devops-tooling - - supersim -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Supersim Multichain Development Environment - + Interop is currently in active development and not yet ready for production use. The information provided here may change. Check back regularly for the most up-to-date information. - + [Supersim](https://github.com/ethereum-optimism/Supersim) is a local development environment tool designed to simulate the Optimism Superchain for developers building multi-chain applications. It provides a simplified way to test and develop applications that interact with multiple chains within the Superchain ecosystem. diff --git a/pages/app-developers/transactions.mdx b/app-developers/transactions.mdx similarity index 82% rename from pages/app-developers/transactions.mdx rename to app-developers/transactions.mdx index e38926b58..9526afb57 100644 --- a/pages/app-developers/transactions.mdx +++ b/app-developers/transactions.mdx @@ -3,28 +3,17 @@ title: Transaction guides description: >- Guide to understanding and working with transactions on OP Stack, including fee estimation, gas parameters, and troubleshooting. -lang: en-US -content_type: guide -topic: transaction-guides -personas: - - app-developer -categories: - - mainnet - - transactions - - gas -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Transaction guides This section provides information on transactions in OP Mainnet, including fee estimation, gas parameters, transaction statuses, and troubleshooting. You'll find guides to help you understand and work with these topics. - + } /> } /> } /> } /> } /> - + diff --git a/pages/app-developers/transactions/estimates.mdx b/app-developers/transactions/estimates.mdx similarity index 95% rename from pages/app-developers/transactions/estimates.mdx rename to app-developers/transactions/estimates.mdx index 19b283548..3352b1cad 100644 --- a/pages/app-developers/transactions/estimates.mdx +++ b/app-developers/transactions/estimates.mdx @@ -1,25 +1,14 @@ --- title: Estimating transaction fees on OP Mainnet description: Learn how to properly estimate the total cost of a transaction on OP Mainnet. -lang: en-US -content_type: guide -topic: estimating-transaction-fees-on-op-mainnet -personas: - - app-developer -categories: - - gas - - cross-chain-messaging - - infrastructure -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Estimating transaction fees on OP Mainnet - + Check out the guide on understanding [Transaction Fees on OP Mainnet](./fees) for an in-depth explanation of how OP Mainnet transaction fees work. - + It's important to properly estimate the cost of a transaction on OP Mainnet before submitting it to the network. Here you'll learn how to estimate both of the components that make up the total cost of an OP Mainnet transaction, the [execution gas fee](./fees#execution-gas-fee) and the [L1 data fee](./fees#l1-data-fee). @@ -27,10 +16,10 @@ Make sure to read the guide on [Transaction Fees on OP Mainnet](./fees) for a de ## Execution gas fee - + Estimating the execution gas fee on OP Mainnet is just like estimating the execution gas fee on Ethereum. Steps are provided here for reference and convenience, but you can use the same tooling that you'd use to estimate the execution gas fee for a transaction on Ethereum. - + A transaction's execution gas fee is exactly the same fee that you would pay for the same transaction on Ethereum. This fee is equal to the amount of gas used by the transaction multiplied by the gas price attached to the transaction. @@ -58,11 +47,11 @@ Make sure to check out the guide on [Setting Transaction Gas Parameters on OP Ma ## L1 data fee - + The Viem library provides a convenient method for estimating the L1 data fee for a transaction. Check out the tutorial on [Estimating Transaction Costs on OP Mainnet](/app-developers/tutorials/transactions/sdk-estimate-costs) to learn how to use the Viem library to estimate the L1 data fee for your transaction. Keep reading if you'd like to learn how to estimate the L1 data fee without the Viem library. - + The L1 data fee is a fee paid to the Sequencer for the cost of publishing your transaction to Ethereum. This fee is paid in ETH and is calculated based on the size of your transaction in bytes and the current gas price on Ethereum. @@ -72,12 +61,12 @@ Unlike the execution gas fee, the L1 data fee is an **intrinsic** fee for every This fee is automatically charged based on the size of your transaction and the current Ethereum gas price. You currently cannot specify a custom L1 data fee for your transaction. - + The L1 data fee is paid based on the current Ethereum gas price as tracked within the [`GasPriceOracle`](https://github.com/ethereum-optimism/optimism/blob/233ede59d16cb01bdd8e7ff662a153a4c3178bdd/packages/contracts/contracts/L2/predeploys/OVM_GasPriceOracle.sol) smart contract. This gas price is updated automatically by the OP Mainnet protocol. Your transaction will be charged the Ethereum gas price seen by the protocol at the time that your transaction is included in an OP Mainnet block. This means that the L1 data fee for your transaction may differ from your estimated L1 data fee. - + @@ -92,10 +81,10 @@ For instance, Ethers.js provides the [`ethers.utils.serializeTransaction`](https Once you have serialized your transaction, you can estimate the L1 data fee by calling the [`getL1Fee`](https://github.com/ethereum-optimism/optimism/blob/233ede59d16cb01bdd8e7ff662a153a4c3178bdd/packages/contracts/contracts/L2/predeploys/OVM_GasPriceOracle.sol#L109-L124) method on the [`GasPriceOracle`](https://github.com/ethereum-optimism/optimism/blob/233ede59d16cb01bdd8e7ff662a153a4c3178bdd/packages/contracts/contracts/L2/predeploys/OVM_GasPriceOracle.sol) smart contract available on OP Mainnet and all OP Stack chains. This method takes the serialized transaction as input and returns the L1 data fee in wei using the formula described in the [Transaction Fees on OP Mainnet](./fees#l1-data-fee) guide. - + Fee estimation is typically performed before the transaction is signed. As a result, the `getL1Fee` method assumes that your input is an **unsigned** Ethereum transaction. - + diff --git a/app-developers/transactions/fees.mdx b/app-developers/transactions/fees.mdx new file mode 100644 index 000000000..6147839d9 --- /dev/null +++ b/app-developers/transactions/fees.mdx @@ -0,0 +1,7 @@ +--- +title: TransactionFees +description: Learn about fees in the Optimism ecosystem. This guide provides detailed information and resources about fees. +--- + + + diff --git a/pages/app-developers/transactions/parameters.mdx b/app-developers/transactions/parameters.mdx similarity index 94% rename from pages/app-developers/transactions/parameters.mdx rename to app-developers/transactions/parameters.mdx index d8288d256..67facf7e6 100644 --- a/pages/app-developers/transactions/parameters.mdx +++ b/app-developers/transactions/parameters.mdx @@ -1,19 +1,8 @@ --- title: Setting transaction gas parameters on OP Mainnet description: Learn how to set gas parameters for transactions on OP Mainnet. -lang: en-US -content_type: guide -topic: setting-transaction-gas-parameters-on-op-mainnet -personas: - - app-developer -categories: - - gas - - infrastructure - - transactions -is_imported_content: 'false' --- -import { Steps } from 'nextra/components' # Setting transaction gas parameters on OP Mainnet diff --git a/pages/app-developers/transactions/statuses.mdx b/app-developers/transactions/statuses.mdx similarity index 94% rename from pages/app-developers/transactions/statuses.mdx rename to app-developers/transactions/statuses.mdx index be32e3e74..e7fea44aa 100644 --- a/pages/app-developers/transactions/statuses.mdx +++ b/app-developers/transactions/statuses.mdx @@ -1,17 +1,6 @@ --- title: Transaction statuses on OP Mainnet description: Learn about the statuses transactions can have on OP Mainnet. -lang: en-US -content_type: guide -topic: transaction-statuses-on-op-mainnet -personas: - - app-developer -categories: - - infrastructure - - monitoring - - analytics - - transactions -is_imported_content: 'false' --- # Transaction statuses on OP Mainnet diff --git a/pages/app-developers/transactions/troubleshooting.mdx b/app-developers/transactions/troubleshooting.mdx similarity index 95% rename from pages/app-developers/transactions/troubleshooting.mdx rename to app-developers/transactions/troubleshooting.mdx index 57f0ebe3b..e0b72dd84 100644 --- a/pages/app-developers/transactions/troubleshooting.mdx +++ b/app-developers/transactions/troubleshooting.mdx @@ -1,17 +1,6 @@ --- title: Troubleshooting transactions description: Learn how to troubleshoot common problems with transactions. -lang: en-US -content_type: guide -topic: transactions -personas: - - app-developer -categories: - - gas - - infrastructure - - monitoring - - transactions -is_imported_content: 'false' --- # Troubleshooting transactions diff --git a/pages/app-developers/tutorials.mdx b/app-developers/tutorials.mdx similarity index 94% rename from pages/app-developers/tutorials.mdx rename to app-developers/tutorials.mdx index 987c1c352..2f3476c2f 100644 --- a/pages/app-developers/tutorials.mdx +++ b/app-developers/tutorials.mdx @@ -4,43 +4,33 @@ description: >- A collection of tutorials for app developers building on OP Stack, covering topics such as bridging tokens, deploying contracts, and estimating transaction costs. -lang: en-US -content_type: landing-page -topic: app-dev-tutorials -personas: - - app-developer -categories: - - mainnet - - testnet -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # App dev tutorials If you're a bit more familiar with the OP Stack and Ethereum, you can try walking through one of the tutorials put together by the Optimism community. They'll help you get a head start when building your first Optimistic project. ## Bridging - + } /> } /> } /> } /> } /> } /> - + ## Transactions - + } /> } /> } /> } /> - + ## Supersim - + } /> } /> } /> @@ -50,14 +40,14 @@ If you're a bit more familiar with the OP Stack and Ethereum, you can try walkin } /> } /> } /> - + ## Interop - + } /> } /> } /> } /> - + You can also [suggest a new tutorial](https://github.com/ethereum-optimism/docs/issues/new?assignees=\&labels=tutorial%2Cdocumentation%2Ccommunity-request\&projects=\&template=suggest_tutorial.yaml\&title=%5BTUTORIAL%5D+Add+PR+title) if you have something specific in mind. We'd love to grow this list! diff --git a/pages/app-developers/tutorials/bridging.mdx b/app-developers/tutorials/bridging.mdx similarity index 81% rename from pages/app-developers/tutorials/bridging.mdx rename to app-developers/tutorials/bridging.mdx index fd57707fc..d89b6651f 100644 --- a/pages/app-developers/tutorials/bridging.mdx +++ b/app-developers/tutorials/bridging.mdx @@ -1,28 +1,17 @@ --- title: Bridging tutorials description: A collection of app developer tutorials focused on bridging. -lang: en-US -content_type: tutorial -topic: bridging-tutorials -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Bridging tutorials This is a collection of app developer tutorials focused on bridging. - + } /> } /> } /> } /> } /> - + diff --git a/pages/app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx b/app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx similarity index 97% rename from pages/app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx rename to app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx index 4a6932a25..580773ff4 100644 --- a/pages/app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx +++ b/app-developers/tutorials/bridging/cross-dom-bridge-erc20.mdx @@ -3,21 +3,8 @@ title: Bridging ERC-20 tokens to OP Mainnet description: >- Learn how to use the @eth-optimism/viem package to transfer ERC-20 tokens between Layer 1 (Ethereum or Sepolia) and Layer 2 (OP Mainnet or OP Sepolia). -lang: en-US -content_type: tutorial -topic: bridging-erc-20-tokens-to-op-mainnet -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Bridging ERC-20 tokens to OP Mainnet @@ -28,12 +15,12 @@ It also provides some safety rails to prevent common mistakes that could cause t Behind the scenes, `@eth-optimism/viem` package uses the [Standard Bridge](/app-developers/bridging/standard-bridge) contracts to transfer tokens. Make sure to check out the [Standard Bridge guide](/app-developers/bridging/standard-bridge) if you want to learn more about how the bridge works under the hood. - + The Standard Bridge **does not** support [**fee on transfer tokens**](https://github.com/d-xo/weird-erc20#fee-on-transfer) or [**rebasing tokens**](https://github.com/d-xo/weird-erc20#balance-modifications-outside-of-transfers-rebasingairdrops) because they can cause bridge accounting errors. - + ## Supported networks @@ -77,24 +64,24 @@ Since the `@eth-optimism/viem` package is a [Node.js](https://nodejs.org/en/) li ``` - + Want to create a new wallet for this tutorial? If you have [`cast`](https://book.getfoundry.sh/getting-started/installation) installed you can run `cast wallet new` in your terminal to create a new wallet and get the private key. - + ## Get ETH on Sepolia and OP Sepolia This tutorial explains how to bridge tokens from Sepolia to OP Sepolia. You will need to get some ETH on both of these testnets. - + You can use [this faucet](https://sepoliafaucet.com) to get ETH on Sepolia. You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=op-docs&utm_medium=docs) to get ETH on OP Sepolia. - + ## Add a private key to your environment @@ -173,13 +160,13 @@ Let's set those up now. ```js file=/public/tutorials/cross-dom-bridge-erc20.js#L12-L13 hash=d4da7ec838773c9f0e4ca38f4ba70242 ``` - + If you're coming from the [Bridging Your Standard ERC-20 Token to OP Mainnet Using the Standard Bridge](./standard-bridge-standard-token) or [Bridging Your Custom ERC-20 Token to OP Mainnet Using the Standard Bridge](./standard-bridge-custom-token) tutorials, you can use the addresses of your own ERC-20 tokens here instead. - + ## Get L1 tokens @@ -282,14 +269,14 @@ You'll then receive the same number of tokens on L2 in return. ```js file=/public/tutorials/cross-dom-bridge-erc20.js#L130-L139 hash=5084d848deaf4b798706446a24e54a18 ``` - + Using a smart contract wallet? As a safety measure, `depositERC20` will fail if you try to deposit ETH from a smart contract wallet without specifying a `recipient`. Add the `recipient` option to the `depositERC20` call to fix this. Check out the [@eth-optimism/viem docs](https://github.com/ethereum-optimism/ecosystem/tree/main/packages/viem) for more info on the options you can pass to `depositERC20`. - + {

Wait for the deposit to be relayed

} @@ -356,10 +343,10 @@ Now you're going to repeat the process in reverse to bridge some tokens from L2 ```js file=/public/tutorials/cross-dom-bridge-erc20.js#L173-L174 hash=f1359ec27815a9fcf4964a877280da59 ``` - + This step can take a few minutes. Feel free to take a quick break while you wait. - + {

Check your token balance on L2

} diff --git a/pages/app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx b/app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx similarity index 95% rename from pages/app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx rename to app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx index df97cccb9..b1a3230ab 100644 --- a/pages/app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx +++ b/app-developers/tutorials/bridging/cross-dom-bridge-eth.mdx @@ -3,22 +3,8 @@ title: Bridging ETH to OP Mainnet with Viem description: >- Learn how to use Viem to transfer ETH between Layer 1 (Ethereum or Sepolia) and Layer 2 (OP Mainnet or OP Sepolia). -lang: en-US -content_type: tutorial -topic: bridging-eth-to-op-mainnet-with-viem -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet - - viem -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' # Bridging ETH to OP Mainnet with Viem @@ -66,19 +52,19 @@ Since Viem is a [Node.js](https://nodejs.org/en/) library, you'll need to create ``` - + Want to create a new wallet for this tutorial? If you have [`cast`](https://book.getfoundry.sh/getting-started/installation) installed you can run `cast wallet new` in your terminal to create a new wallet and get the private key. - + ## Get ETH on Sepolia This tutorial explains how to bridge ETH from Sepolia to OP Sepolia. You will need to get some ETH on Sepolia to follow along. - + You can use [this faucet](https://sepoliafaucet.com) to get ETH on Sepolia. - + ## Add a private key to your environment @@ -159,9 +145,9 @@ Now that you have some ETH on L1 you can deposit that ETH into the `OptimismPort ```js file=/public/tutorials/cross-dom-bridge-eth.js#L38-L39 hash=a77304eb0a056ba30aaa21eee60bcafa ``` - + We used `formatEther` method from `viem` to format the balance to ether. - + {

Create the deposit transaction

} @@ -207,11 +193,11 @@ Now that you have some ETH on L1 you can deposit that ETH into the `OptimismPort - + Using a smart contract wallet? As a safety measure, `depositETH` will fail if you try to deposit ETH from a smart contract wallet without specifying a `recipient`. Add the `recipient` option to the `depositETH` call to fix this. - + ## Withdraw ETH @@ -271,10 +257,10 @@ Now you're going to repeat the process in reverse to bridge some ETH from L2 to ```js file=/public/tutorials/cross-dom-bridge-eth.js#L94-L97 hash=15e6f754d2e9f11a03f400813efef383 ``` - + We're currently testing fault proofs on OP Sepolia, so withdrawal times reflect Mainnet times. - + {

Finalize the withdrawal

} @@ -303,12 +289,12 @@ Now you're going to repeat the process in reverse to bridge some ETH from L2 to ## Important Considerations - + * Challenge period: The 7-day withdrawal challenge Period is crucial for security. * Gas costs: Withdrawals involve transactions on both L2 and L1, each incurring gas fees. * Private Key handling: Use secure key management practices in real applications. * RPC endpoint security: Keep your API key (or any RPC endpoint) secure. - + ## Next Steps diff --git a/pages/app-developers/tutorials/bridging/cross-dom-solidity.mdx b/app-developers/tutorials/bridging/cross-dom-solidity.mdx similarity index 96% rename from pages/app-developers/tutorials/bridging/cross-dom-solidity.mdx rename to app-developers/tutorials/bridging/cross-dom-solidity.mdx index 6816cd613..428b868f2 100644 --- a/pages/app-developers/tutorials/bridging/cross-dom-solidity.mdx +++ b/app-developers/tutorials/bridging/cross-dom-solidity.mdx @@ -3,22 +3,8 @@ title: Communicating between OP Stack and Ethereum in Solidity description: >- Learn how to write Solidity contracts on OP Stack and Ethereum that can talk to each other. -lang: en-US -content_type: tutorial -topic: communicating-between-op-stack-and-ethereum-in-solidity -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet - - viem -is_imported_content: 'false' --- -import { Steps, Callout, Tabs } from 'nextra/components' # Communicating between OP Stack and Ethereum in Solidity @@ -30,10 +16,10 @@ You won't actually be deploying any smart contracts as part of this tutorial. Instead, you'll reuse existing contracts that have already been deployed to OP Stack and Ethereum. Later in the tutorial you'll learn exactly how these contracts work so you can follow the same pattern to deploy your own contracts. - + Just looking to bridge tokens between OP Stack and Ethereum? Check out the tutorial on [Bridging ERC-20 Tokens to OP Stack With the viem](./cross-dom-bridge-erc20). - + ## Message passing basics @@ -53,10 +39,10 @@ Read more about message passing in the guide to [Sending Data Between L1 and L2] This tutorial explains how to send messages from Sepolia to OP Sepolia. You will need to get some ETH on both of these testnets. - + You can use [this faucet](https://sepoliafaucet.com/) to get ETH on Sepolia. You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=op-docs&utm_medium=docs) to get ETH on OP Sepolia. - + ## Review the contracts You're about to use two contracts that have already been deployed to Sepolia and OP Sepolia, the `Greeter` contracts. @@ -91,11 +77,11 @@ You can use any greeting you'd like. It will take a few minutes for your message to reach L2. Feel free to take a quick break while you wait. - + You can use Viem to programmatically check the status of any message between L1 and L2. Later on in this tutorial you'll learn how to use Viem and the `waitToProve` function to wait for various message statuses. This same function can be used to wait for a message to be relayed from L1 to L2. - + {

Check the L2 Greeter

} @@ -104,11 +90,11 @@ Open up the [L2 `Greeter` contract on OP Sepolia Etherscan](https://sepolia-opti Paste your address into the field next to the "greeting" function and click the "Query" button. You should see the message you sent from L1. - + Haven't seen your message yet? You might need to wait a little longer. L2 transactions triggered on L1 are typically processed within one minute but can occasionally be slightly delayed. - + @@ -131,11 +117,11 @@ Open up the [L2 `Greeter` contract on OP Sepolia Etherscan](https://sepolia-opti Put a greeting into the field next to the "sendGreeting" function and click the "Write" button. You can use any greeting you'd like. - + Copy the transaction hash from the transaction you just sent. You'll need this for the next few steps. Feel free to keep this tab open so you can easily copy the transaction hash later. - + {

Create a demo project folder

} @@ -208,10 +194,10 @@ You first need to wait until the message is ready to prove. ```js file=/public/tutorials/cross-dom-solidity.js#L22-L30 hash=0e460f24fc394acdcdb7f06df0188e31 ``` - + This step can take a few minutes. Feel free to take a quick break while you wait. - + {

Prove the message on L1

} @@ -231,9 +217,9 @@ The final step to sending messages from L2 to L1 is to relay the messages on L1. This can only happen after the fault proof period has elapsed. On OP Stack, this takes 7 days. - + We're currently testing fault proofs on OP Sepolia, so withdrawal times reflect Mainnet times. - + ```js file=/public/tutorials/cross-dom-solidity.js#L46-L50 hash=8c08d1f4c6a7f5d1754a411b3590530d ``` @@ -323,11 +309,11 @@ Finally, it sets the greeting in the `greetings` mapping. ```solidity file=/public/tutorials/cross-dom-solidity.sol#L40-L52 hash=f50a94e77ecb2f76b9fe278b058a79e4 ``` - + The two `require` statements in this function are important! Without them, anyone could call this function and set the greeting to whatever they want. You can follow a similar pattern in your own smart contracts. - + ## Conclusion diff --git a/pages/app-developers/tutorials/bridging/standard-bridge-custom-token.mdx b/app-developers/tutorials/bridging/standard-bridge-custom-token.mdx similarity index 94% rename from pages/app-developers/tutorials/bridging/standard-bridge-custom-token.mdx rename to app-developers/tutorials/bridging/standard-bridge-custom-token.mdx index 673bd2c9d..0ebaf62f3 100644 --- a/pages/app-developers/tutorials/bridging/standard-bridge-custom-token.mdx +++ b/app-developers/tutorials/bridging/standard-bridge-custom-token.mdx @@ -1,22 +1,8 @@ --- title: Bridging your custom ERC-20 token using the Standard Bridge description: Learn how to bridge your custom ERC-20 token using the standard bridge. -lang: en-US -content_type: tutorial -topic: bridging-your-custom-erc-20-token-using-the-standard-bridge -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { WipCallout } from '@/components/WipCallout' # Bridging your custom ERC-20 token using the Standard Bridge @@ -27,9 +13,9 @@ This tutorial explains how you can create a custom token that conforms to the [` A custom token allows you to do things like trigger extra logic whenever a token is deposited. If you don't need extra functionality like this, consider following the tutorial on [Bridging Your Standard ERC-20 Token Using the Standard Bridge](./standard-bridge-standard-token) instead. - + The Standard Bridge **does not** support [**fee on transfer tokens**](https://github.com/d-xo/weird-erc20#fee-on-transfer) or [**rebasing tokens**](https://github.com/d-xo/weird-erc20#balance-modifications-outside-of-transfers-rebasingairdrops) because they can cause bridge accounting errors. - + ## About OptimismMintableERC20s @@ -48,10 +34,10 @@ This tutorial will show you how to create a custom token that implements this in This tutorial explains how to create a bridged ERC-20 token on OP Sepolia. You will need to get some ETH on both of these testnets. - + You can use [this faucet](https://sepoliafaucet.com/) to get ETH on Sepolia. You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=op-docs\&utm_medium=docs) to get ETH on OP Sepolia. - + ## Add OP Sepolia to your wallet diff --git a/pages/app-developers/tutorials/bridging/standard-bridge-standard-token.mdx b/app-developers/tutorials/bridging/standard-bridge-standard-token.mdx similarity index 94% rename from pages/app-developers/tutorials/bridging/standard-bridge-standard-token.mdx rename to app-developers/tutorials/bridging/standard-bridge-standard-token.mdx index 31b973271..efe8a94ad 100644 --- a/pages/app-developers/tutorials/bridging/standard-bridge-standard-token.mdx +++ b/app-developers/tutorials/bridging/standard-bridge-standard-token.mdx @@ -1,21 +1,8 @@ --- title: Bridging Your Standard ERC-20 Token Using the Standard Bridge description: Learn how to bridge your standard ERC-20 token using the standard bridge. -lang: en-US -content_type: tutorial -topic: bridging-your-standard-erc-20-token-using-the-standard-bridge -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Bridging Your Standard ERC-20 Token Using the Standard Bridge @@ -26,9 +13,9 @@ This tutorial explains how to use the [`OptimismMintableERC20Factory`](https://g Tokens created by this factory contract are compatible with the Standard Bridge system and include basic logic for deposits, transfers, and withdrawals. If you want to include specialized logic within your L2 token, see the tutorial on [Bridging Your Custom ERC-20 Token Using the Standard Bridge](./standard-bridge-custom-token) instead. - + The Standard Bridge **does not** support [**fee on transfer tokens**](https://github.com/d-xo/weird-erc20#fee-on-transfer) or [**rebasing tokens**](https://github.com/d-xo/weird-erc20#balance-modifications-outside-of-transfers-rebasingairdrops) because they can cause bridge accounting errors. - + ## About OptimismMintableERC20s @@ -46,10 +33,10 @@ This tutorial will show you how to use the [`OptimismMintableERC20Factory`](http This tutorial explains how to create a bridged ERC-20 token on OP Sepolia. You will need to get some ETH on both of these testnets. - + You can use [this faucet](https://sepoliafaucet.com) to get ETH on Sepolia. You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=op-docs\&utm_medium=docs) to get ETH on OP Sepolia. - + ## Get an L1 ERC-20 token address diff --git a/pages/app-developers/tutorials/interop.mdx b/app-developers/tutorials/interop.mdx similarity index 82% rename from pages/app-developers/tutorials/interop.mdx rename to app-developers/tutorials/interop.mdx index 5e15bc68b..e82dfccbe 100644 --- a/pages/app-developers/tutorials/interop.mdx +++ b/app-developers/tutorials/interop.mdx @@ -1,29 +1,18 @@ --- title: Interop tutorials description: A collection of app developer tutorials focused on interop. -lang: en-US -content_type: tutorial -topic: interop-tutorials -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Interop tutorials This is a collection of app developer tutorials focused on interop. - + } /> } /> } /> } /> } /> } /> - + diff --git a/app-developers/tutorials/interop/bridge-crosschain-eth.mdx b/app-developers/tutorials/interop/bridge-crosschain-eth.mdx new file mode 100644 index 000000000..26bef72fd --- /dev/null +++ b/app-developers/tutorials/interop/bridge-crosschain-eth.mdx @@ -0,0 +1,7 @@ +--- +title: Bridge Crosschain Eth +description: Learn how to bridge native cross-chain ETH transfers. +--- + + + diff --git a/app-developers/tutorials/interop/contract-calls.mdx b/app-developers/tutorials/interop/contract-calls.mdx new file mode 100644 index 000000000..7287bbc6e --- /dev/null +++ b/app-developers/tutorials/interop/contract-calls.mdx @@ -0,0 +1,7 @@ +--- +title: Contract Calls +description: Learn how to make crosschain contract calls using ping pong. +--- + + + diff --git a/app-developers/tutorials/interop/deploy-superchain-erc20.mdx b/app-developers/tutorials/interop/deploy-superchain-erc20.mdx new file mode 100644 index 000000000..511e5fdee --- /dev/null +++ b/app-developers/tutorials/interop/deploy-superchain-erc20.mdx @@ -0,0 +1,7 @@ +--- +title: Deploy Superchain Erc20 +description: Learn how to issue assets on SuperchainERC20. +--- + + + diff --git a/app-developers/tutorials/interop/event-contests.mdx b/app-developers/tutorials/interop/event-contests.mdx new file mode 100644 index 000000000..7c73c508c --- /dev/null +++ b/app-developers/tutorials/interop/event-contests.mdx @@ -0,0 +1,7 @@ +--- +title: Event Contests +description: Learn how to deploy crosschain event composability using contests. +--- + + + diff --git a/app-developers/tutorials/interop/event-reads.mdx b/app-developers/tutorials/interop/event-reads.mdx new file mode 100644 index 000000000..d3ace649b --- /dev/null +++ b/app-developers/tutorials/interop/event-reads.mdx @@ -0,0 +1,7 @@ +--- +title: Event Reads +description: Learn how to make crosschain event reads using tic-tac-toe. +--- + + + diff --git a/app-developers/tutorials/interop/transfer-superchainERC20.mdx b/app-developers/tutorials/interop/transfer-superchainERC20.mdx new file mode 100644 index 000000000..b4d3f572b --- /dev/null +++ b/app-developers/tutorials/interop/transfer-superchainERC20.mdx @@ -0,0 +1,9 @@ +--- +title: Transfer SuperchainERC20 +description: >- + Learn how to transfer a SuperchainERC20 between chains using + L2ToL2CrossDomainMessenger. +--- + + + diff --git a/pages/app-developers/tutorials/supersim.mdx b/app-developers/tutorials/supersim.mdx similarity index 89% rename from pages/app-developers/tutorials/supersim.mdx rename to app-developers/tutorials/supersim.mdx index d48fa17b4..acf0e5e97 100644 --- a/pages/app-developers/tutorials/supersim.mdx +++ b/app-developers/tutorials/supersim.mdx @@ -1,31 +1,24 @@ --- title: Supersim guides and tutorials description: A collection of guides and tutorials to understanding and working with Supersim. -lang: en-US -content_type: tutorial -topic: supersim-guides-and-tutorials -personas: app-developer -categories: ['supersim', 'devnets', 'cli'] -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Supersim guides and tutorials This is a collection of guides and tutorials to understanding and working with Supersim, including getting started, CLI reference, and chain environment. ## General - + } /> } /> } /> } /> - + ## Tutorials - + } /> } /> } /> @@ -34,4 +27,4 @@ This is a collection of guides and tutorials to understanding and working with S } /> } /> } /> - + diff --git a/pages/app-developers/tutorials/supersim/chain-env.mdx b/app-developers/tutorials/supersim/chain-env.mdx similarity index 76% rename from pages/app-developers/tutorials/supersim/chain-env.mdx rename to app-developers/tutorials/supersim/chain-env.mdx index 77d49dc39..ef0b2c58f 100644 --- a/pages/app-developers/tutorials/supersim/chain-env.mdx +++ b/app-developers/tutorials/supersim/chain-env.mdx @@ -3,27 +3,17 @@ title: Chain environment tutorials description: >- A collection of tutorials on understanding and configuring your chain environment using Supersim. -lang: en-US -content_type: tutorial -topic: chain-environment-tutorials -personas: - - app-developer -categories: - - supersim - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Chain environment tutorials These tutorials are for understanding and configuring your chain environment using Supersim. - + } /> } /> } /> - + diff --git a/pages/app-developers/tutorials/supersim/chain-env/chain-a.mdx b/app-developers/tutorials/supersim/chain-env/chain-a.mdx similarity index 94% rename from pages/app-developers/tutorials/supersim/chain-env/chain-a.mdx rename to app-developers/tutorials/supersim/chain-env/chain-a.mdx index 67055f51f..86ef199f7 100644 --- a/pages/app-developers/tutorials/supersim/chain-env/chain-a.mdx +++ b/app-developers/tutorials/supersim/chain-env/chain-a.mdx @@ -1,20 +1,8 @@ --- title: OPChainA (chainID 901) description: Learn network details and contract addresses for OPChainA (chainID 901). -lang: en-US -content_type: tutorial -topic: opchaina-chainid-901 -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - supersim - - devnets -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # OPChainA (chainID 901) diff --git a/pages/app-developers/tutorials/supersim/chain-env/chain-b.mdx b/app-developers/tutorials/supersim/chain-env/chain-b.mdx similarity index 94% rename from pages/app-developers/tutorials/supersim/chain-env/chain-b.mdx rename to app-developers/tutorials/supersim/chain-env/chain-b.mdx index 2d611269b..8dcadf2ec 100644 --- a/pages/app-developers/tutorials/supersim/chain-env/chain-b.mdx +++ b/app-developers/tutorials/supersim/chain-env/chain-b.mdx @@ -1,20 +1,8 @@ --- title: OPChainB (chainID 902) description: Learn network details and contract addresses for OPChainB (chainID 902). -lang: en-US -content_type: tutorial -topic: opchainb-chainid-902 -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - supersim - - devnets -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # OPChainB (chainID 902) diff --git a/pages/app-developers/tutorials/supersim/chain-env/included-contracts.mdx b/app-developers/tutorials/supersim/chain-env/included-contracts.mdx similarity index 91% rename from pages/app-developers/tutorials/supersim/chain-env/included-contracts.mdx rename to app-developers/tutorials/supersim/chain-env/included-contracts.mdx index 11bae1c64..17a8a2a02 100644 --- a/pages/app-developers/tutorials/supersim/chain-env/included-contracts.mdx +++ b/app-developers/tutorials/supersim/chain-env/included-contracts.mdx @@ -1,20 +1,8 @@ --- title: Included contracts description: Learn about the Supersim included contracts. -lang: en-US -content_type: tutorial -topic: included-contracts -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - supersim - - devnets -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Included contracts diff --git a/pages/app-developers/tutorials/supersim/deposit-transactions.mdx b/app-developers/tutorials/supersim/deposit-transactions.mdx similarity index 93% rename from pages/app-developers/tutorials/supersim/deposit-transactions.mdx rename to app-developers/tutorials/supersim/deposit-transactions.mdx index 50d223cf5..b70f9aebe 100644 --- a/pages/app-developers/tutorials/supersim/deposit-transactions.mdx +++ b/app-developers/tutorials/supersim/deposit-transactions.mdx @@ -1,22 +1,8 @@ --- title: Deposit transactions description: Learn about using deposit transactions with `supersim`. -lang: en-US -content_type: tutorial -topic: deposit-transactions -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - supersim - - devnets - - mainnet - - transactions -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Deposit transactions diff --git a/pages/app-developers/tutorials/supersim/getting-started.mdx b/app-developers/tutorials/supersim/getting-started.mdx similarity index 71% rename from pages/app-developers/tutorials/supersim/getting-started.mdx rename to app-developers/tutorials/supersim/getting-started.mdx index 53604732b..ead2554b7 100644 --- a/pages/app-developers/tutorials/supersim/getting-started.mdx +++ b/app-developers/tutorials/supersim/getting-started.mdx @@ -3,25 +3,15 @@ title: Getting started guides description: >- A collection of guides for installing dependencies and getting started with Supersim. -lang: en-US -content_type: tutorial -topic: getting-started-guides -personas: - - app-developer -categories: - - supersim - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Getting started guides This is a collection of guides for installing dependencies and getting started with Supersim. - + } /> } /> - + diff --git a/pages/app-developers/tutorials/supersim/getting-started/first-steps.mdx b/app-developers/tutorials/supersim/getting-started/first-steps.mdx similarity index 93% rename from pages/app-developers/tutorials/supersim/getting-started/first-steps.mdx rename to app-developers/tutorials/supersim/getting-started/first-steps.mdx index e6c402f16..1932aa0cb 100644 --- a/pages/app-developers/tutorials/supersim/getting-started/first-steps.mdx +++ b/app-developers/tutorials/supersim/getting-started/first-steps.mdx @@ -1,21 +1,8 @@ --- title: First steps description: Take your first steps with Supersim. -lang: en-US -content_type: tutorial -topic: first-steps -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - supersim - - devnets - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # First steps @@ -40,9 +27,9 @@ import { Callout, Steps } from 'nextra/components' * Send the Ether to `OptimismPortal` contract of the respective L2 (on chain 900) - + For chain 901, the contract is `0x37a418800d0c812A9dE83Bc80e993A6b76511B57`. - + * Initiate a bridge transaction on the L1: @@ -54,9 +41,9 @@ import { Callout, Steps } from 'nextra/components' * Call `bridgeETH` function on the `L1StandardBridgeProxy` / `L1StandardBridge` contract of the respective L2 on L1 (chain 900) - + For chain 901, the contract is `0x8d515eb0e5F293B16B6bBCA8275c060bAe0056B0`. - + * Initiate a bridge transaction on the L1: diff --git a/pages/app-developers/tutorials/supersim/getting-started/installation.mdx b/app-developers/tutorials/supersim/getting-started/installation.mdx similarity index 87% rename from pages/app-developers/tutorials/supersim/getting-started/installation.mdx rename to app-developers/tutorials/supersim/getting-started/installation.mdx index 298686a89..668afb04b 100644 --- a/pages/app-developers/tutorials/supersim/getting-started/installation.mdx +++ b/app-developers/tutorials/supersim/getting-started/installation.mdx @@ -1,18 +1,8 @@ --- title: Installation description: Learn how to install Supersim. -lang: en-US -content_type: tutorial -topic: installation -personas: - - app-developer -categories: - - supersim - - devnets -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Installation diff --git a/pages/app-developers/tutorials/supersim/reference.mdx b/app-developers/tutorials/supersim/reference.mdx similarity index 69% rename from pages/app-developers/tutorials/supersim/reference.mdx rename to app-developers/tutorials/supersim/reference.mdx index c31b7a550..e5e168d0d 100644 --- a/pages/app-developers/tutorials/supersim/reference.mdx +++ b/app-developers/tutorials/supersim/reference.mdx @@ -1,25 +1,15 @@ --- title: CLI reference guides description: A collection of guides for using the Superchain CLI with Supersim. -lang: en-US -content_type: tutorial -topic: cli-reference-guides -personas: - - app-developer -categories: - - supersim - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # CLI reference guides This is a collection of guides for using the Superchain CLI with Supersim. - + } /> } /> - + diff --git a/pages/app-developers/tutorials/supersim/reference/fork.mdx b/app-developers/tutorials/supersim/reference/fork.mdx similarity index 96% rename from pages/app-developers/tutorials/supersim/reference/fork.mdx rename to app-developers/tutorials/supersim/reference/fork.mdx index f27eb500d..f5982c8b9 100644 --- a/pages/app-developers/tutorials/supersim/reference/fork.mdx +++ b/app-developers/tutorials/supersim/reference/fork.mdx @@ -1,21 +1,8 @@ --- title: Fork mode description: Learn how to fork Supersim. -lang: en-US -content_type: tutorial -topic: fork-mode -personas: - - app-developer -categories: - - supersim - - devnets - - mainnet - - testnet - - cli -is_imported_content: "false" --- -import { Callout, Steps } from "nextra/components" # Fork mode diff --git a/pages/app-developers/tutorials/supersim/reference/vanilla.mdx b/app-developers/tutorials/supersim/reference/vanilla.mdx similarity index 96% rename from pages/app-developers/tutorials/supersim/reference/vanilla.mdx rename to app-developers/tutorials/supersim/reference/vanilla.mdx index 2bf85face..69b303249 100644 --- a/pages/app-developers/tutorials/supersim/reference/vanilla.mdx +++ b/app-developers/tutorials/supersim/reference/vanilla.mdx @@ -1,19 +1,8 @@ --- title: Vanilla mode description: Learn how to use Supersim in vanilla mode (non-forked). -lang: en-US -content_type: tutorial -topic: vanilla-mode -personas: - - app-developer -categories: - - supersim - - devnets - - cli -is_imported_content: "false" --- -import { Callout, Steps } from "nextra/components" # Vanilla mode diff --git a/pages/app-developers/tutorials/transactions.mdx b/app-developers/tutorials/transactions.mdx similarity index 73% rename from pages/app-developers/tutorials/transactions.mdx rename to app-developers/tutorials/transactions.mdx index cc14d04a5..d205acf7a 100644 --- a/pages/app-developers/tutorials/transactions.mdx +++ b/app-developers/tutorials/transactions.mdx @@ -1,27 +1,15 @@ --- title: Transaction tutorials description: A collection of app developer tutorials focused on transactions. -lang: en-US -content_type: tutorial -topic: transaction-tutorials -personas: - - app-developer -categories: - - transactions - - mainnet - - testnet - - devnets -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Transaction tutorials This is a collection of app developer tutorials focused on transactions. - + } /> } /> } /> - + diff --git a/pages/app-developers/tutorials/transactions/sdk-estimate-costs.mdx b/app-developers/tutorials/transactions/sdk-estimate-costs.mdx similarity index 94% rename from pages/app-developers/tutorials/transactions/sdk-estimate-costs.mdx rename to app-developers/tutorials/transactions/sdk-estimate-costs.mdx index 44b244094..966b85fb2 100644 --- a/pages/app-developers/tutorials/transactions/sdk-estimate-costs.mdx +++ b/app-developers/tutorials/transactions/sdk-estimate-costs.mdx @@ -1,21 +1,8 @@ --- title: Estimating transaction costs on OP Stack description: Learn how to use viem to estimate the cost of a transaction on OP Stack. -lang: en-US -content_type: tutorial -topic: estimating-transaction-costs-on-op-stack -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - mainnet - - testnet -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' # Estimating transaction costs on OP Stack @@ -23,9 +10,9 @@ In this tutorial, you'll learn how to use [viem](https://viem.sh/op-stack/) to e You'll learn how to estimate the [execution gas fee](/app-developers/transactions/fees#execution-gas-fee) and the [L1 data fee](/app-developers/transactions/fees#l1-data-fee) independently. You'll also learn how to estimate the total cost of the transaction all at once. - + Check out the full explainer on [OP Stack transaction fees](/app-developers/transactions/fees) for more information on how OP Mainnet charges fees under the hood. - + ## Supported networks @@ -64,28 +51,28 @@ Since Viem is a [Node.js](https://nodejs.org/en/) library, you'll need to create ``` - + Want to create a new wallet for this tutorial? If you have [`cast`](https://book.getfoundry.sh/getting-started/installation) installed you can run `cast wallet new` in your terminal to create a new wallet and get the private key. - + ## Get ETH on Sepolia This tutorial explains how to bridge ETH from Sepolia to OP Sepolia. You will need to get some ETH on Sepolia to follow along. - + You can use [this faucet](https://sepoliafaucet.com) to get ETH on Sepolia. - + ## Get ETH on OP Sepolia This tutorial explains how estimate transaction costs on OP Sepolia. You will need to get some ETH on OP Sepolia in order to run the code in this tutorial. - + You can use the [Superchain faucet](https://console.optimism.io/faucet?utm_source=op-docs&utm_medium=docs) to get ETH on OP Sepolia. - + ## Add a private key to your environment @@ -198,9 +185,9 @@ Here you'll estimate the cost of a simple transaction that sends a small amount ``` - + Estimates will never be entirely accurate due to network conditions and gas price fluctuation, but they should be close to the actual costs. - + ## Next steps diff --git a/pages/app-developers/tutorials/transactions/sdk-trace-txns.mdx b/app-developers/tutorials/transactions/sdk-trace-txns.mdx similarity index 95% rename from pages/app-developers/tutorials/transactions/sdk-trace-txns.mdx rename to app-developers/tutorials/transactions/sdk-trace-txns.mdx index fd9084bba..53a27f581 100644 --- a/pages/app-developers/tutorials/transactions/sdk-trace-txns.mdx +++ b/app-developers/tutorials/transactions/sdk-trace-txns.mdx @@ -3,20 +3,8 @@ title: Tracing deposits and withdrawals description: >- Learn how to use the viem library to trace deposits and withdrawals between L1 and L2. -lang: en-US -content_type: tutorial -topic: tracing-deposits-and-withdrawals -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Tracing deposits and withdrawals diff --git a/pages/app-developers/tutorials/transactions/send-tx-from-eth.mdx b/app-developers/tutorials/transactions/send-tx-from-eth.mdx similarity index 94% rename from pages/app-developers/tutorials/transactions/send-tx-from-eth.mdx rename to app-developers/tutorials/transactions/send-tx-from-eth.mdx index f201098f7..f5214ba24 100644 --- a/pages/app-developers/tutorials/transactions/send-tx-from-eth.mdx +++ b/app-developers/tutorials/transactions/send-tx-from-eth.mdx @@ -3,20 +3,8 @@ title: Triggering OP Stack transactions from Ethereum description: >- Learn how to force transaction inclusion without the OP Stack Sequencer using Viem. -lang: en-US -content_type: tutorial -topic: triggering-op-stack-transactions-from-ethereum -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - devnets - - testnet -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Triggering OP Stack transactions from Ethereum @@ -56,19 +44,19 @@ You're going to use the `viem` package for this tutorial. Since Viem is a [Node. ``` - + Want to create a new wallet for this tutorial? If you have [`cast`](https://book.getfoundry.sh/getting-started/installation) installed you can run `cast wallet new` in your terminal to create a new wallet and get the private key. - + ## Get ETH on Sepolia and OP Sepolia This tutorial explains how to bridge tokens from Sepolia to OP Sepolia. You will need to get some ETH on both of these testnets. - + You can use [this faucet](https://sepoliafaucet.com) to get ETH on Sepolia. You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=op-docs&utm_medium=docs) to get ETH on OP Sepolia. - + ## Add a private key to your environment diff --git a/components/AddressTable.tsx b/components/AddressTable.tsx deleted file mode 100644 index b1ab80366..000000000 --- a/components/AddressTable.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import type { ReactElement } from 'react' -import { CHAIN_CONSTANTS, LEGACY_CONTRACT_NAMES } from '@/utils/constants' - -export interface TableAddresses { - [contract: string]: string -} - -export function AddressTable({ - chain, - explorer, - legacy, - addresses -}: { - chain: string, - explorer: string, - legacy: boolean - addresses: TableAddresses -}): ReactElement { - // Filter out legacy (or non-legacy) contracts. - const filtered: TableAddresses = Object.keys(addresses) - .filter(key => LEGACY_CONTRACT_NAMES.includes(key) === legacy) - .reduce((acc, key) => { - acc[key] = addresses[key] - return acc - }, {}) - - return ( - - - - - - - - - { - Object.entries(filtered) - .map(([contract, address]) => { - return ( - - - - - ) - }) - } - -
Contract NameContract Address
- - {contract} - - - - - {address} - - (opens in a new tab) - -
- ) -} diff --git a/components/AskAIButton.tsx b/components/AskAIButton.tsx deleted file mode 100644 index 344e20d17..000000000 --- a/components/AskAIButton.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { RiSparkling2Fill } from '@remixicon/react'; -import { useFeature } from '@growthbook/growthbook-react'; -import { useEffect, useState } from 'react'; - -const AskAIButton = () => { - const [mounted, setMounted] = useState(false); - const enableDocsAIWidget = useFeature('enable_docs_ai_widget').on; - - useEffect(() => { - setMounted(true); - }, []); - - // Don't render anything until client-side - if (!mounted) { - return null; - } - - if (!enableDocsAIWidget) { - return null; - } - - return ( - - ); -}; - -export { AskAIButton }; diff --git a/components/AutorelayCallout.tsx b/components/AutorelayCallout.tsx deleted file mode 100644 index 383b645d4..000000000 --- a/components/AutorelayCallout.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/** - * The AutorelayCallout function renders a callout component with a message about autorelays - * - * @param {Props} props - Expected to be empty, ignored. - * @returns {ReactElement} The AutorelayCallout component, a callout that explains about autorelays. - */ -import type { ReactElement } from 'react'; -import { Callout } from 'nextra/components' - -// nx-w-full nx-flex nx-mt-6 -// nx-mt-6 nx-justify-center nx-items-center nx-bg-white dark:nx-bg-black" - -// import { Callout } from 'vocs/components' - -export function AutorelayCallout(): ReactElement { - return ( - - Normally we expect Superchain blockchains to run an autorelayer and relay your messages automatically. - However, for performance reasons or reliability, you might decide to submit the executing message manually. - See below to learn how to do that. - - ); -} diff --git a/components/Footer.tsx b/components/Footer.tsx deleted file mode 100644 index 041b4777c..000000000 --- a/components/Footer.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { Link } from 'nextra-theme-docs'; -export function Footer() { - return ( -
-
-
-
-
-
- - - - -
-
- -
-

Tools

-
    -
  • Superchain Faucet
  • -
  • Gas Tracker
  • -
  • Service Status
  • -
  • Changelog
  • -
  • Devnets
  • -
-
- -
-

Resources

-
    -
  • Developer Support
  • -
  • Superchain Dev Discord
  • -
  • Get Launch Support
  • -
  • Glossary
  • -
  • Contribute to the OP Stack
  • -
  • Protocol Specs
  • -
-
- -
-

Ecosystem

-
    -
  • Ecosystem Packages
  • -
  • Ecosystem Contributions
  • -
  • Superchain Registry
  • -
-
-
- -
- -
-

Follow Us

- -
-
-
- -
-
- Community Agreement - Terms of Service - Privacy Policy - Code of Conduct -
-
© {new Date().getFullYear()} Optimism Foundation. All rights reserved.
-
-
-
- ); -} \ No newline at end of file diff --git a/components/L1ContractTable.tsx b/components/L1ContractTable.tsx deleted file mode 100644 index 050fb562c..000000000 --- a/components/L1ContractTable.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import type { ReactElement } from 'react' -import { useEffect, useState } from 'react' -import { AddressTable, TableAddresses } from '@/components/AddressTable' - -const ADDRESSES_URL = 'https://raw.githubusercontent.com/ethereum-optimism/superchain-registry/main/superchain/extra/addresses/addresses.json'; - -export function L1ContractTable({ - chain, - explorer, - legacy -}: { - chain: string, - explorer: string, - legacy: boolean -}): ReactElement { - const [addresses, setAddresses] = useState | null>(null) - const [loading, setLoading] = useState(true) - const [error, setError] = useState(null) - - useEffect(() => { - async function fetchAddresses() { - try { - const response = await fetch(ADDRESSES_URL) - if (!response.ok) { - throw new Error('Failed to fetch addresses') - } - const data = await response.json() - setAddresses(data) - } catch (err) { - setError(err.message) - console.error('Error fetching addresses:', err) - } finally { - setLoading(false) - } - } - - fetchAddresses() - }, []) - - if (loading) { - return
Loading...
- } - - if (error) { - return
Error: {error}
- } - - return ( - { - return chainid === chain - })?.[1] as TableAddresses - } - /> - ) -} diff --git a/components/L2ContractTable.tsx b/components/L2ContractTable.tsx deleted file mode 100644 index e9d9f499f..000000000 --- a/components/L2ContractTable.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import type { ReactElement } from 'react' -import { AddressTable } from '@/components/AddressTable' -import { PREDEPLOYS } from '@/utils/constants' - -export function L2ContractTable({ - chain, - legacy -}: { - chain: string, - legacy: boolean -}): ReactElement { - return ( - - ) -} diff --git a/components/ScrollDispatcher/index.tsx b/components/ScrollDispatcher/index.tsx deleted file mode 100644 index 27e9df798..000000000 --- a/components/ScrollDispatcher/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import AlgoliaContext from "@/utils/contexts/AlgoliaContext"; -import React, { ReactNode, useContext, useEffect } from "react"; -import * as aa from "search-insights"; - -export default function ScrollDispatcher({ - children, -}: Readonly<{ - children: ReactNode; -}>) { - const { queryID, objectID } = useContext(AlgoliaContext); - - const onScroll = () => { - const bottom = - Math.ceil(window.innerHeight + window.scrollY) >= - document.documentElement.scrollHeight; - - if (bottom && queryID && objectID) { - aa.default("convertedObjectIDsAfterSearch", { - index: "docs", - eventName: "Converted Search", - queryID: queryID, - objectIDs: [objectID], - }); - } - }; - - useEffect(() => { - window.addEventListener("scroll", onScroll); - - return () => { - window.removeEventListener("scroll", onScroll); - }; - }, [queryID, objectID]); - - return
{children}
; -} diff --git a/components/Search/docsearch.tsx b/components/Search/docsearch.tsx deleted file mode 100644 index 902a5c34c..000000000 --- a/components/Search/docsearch.tsx +++ /dev/null @@ -1,347 +0,0 @@ -import { Transition } from "@headlessui/react"; -import cn from "clsx"; -import { useRouter } from "next/router"; -import { useMounted } from "nextra/hooks"; -import { InformationCircleIcon, SpinnerIcon } from "nextra/icons"; -import type { - ReactNode, - CompositionEvent, - KeyboardEvent, - ReactElement, -} from "react"; -import { - Fragment, - useCallback, - useEffect, - useRef, - useState, - useContext, -} from "react"; -import { Input } from "./input"; -import Link from "next/link"; -import * as aa from "search-insights"; -import AlgoliaContext from "@/utils/contexts/AlgoliaContext"; - -type SearchResult = { - children: ReactNode; - id: string; - prefix?: ReactNode; - route: string; -}; - -type SearchProps = { - className?: string; - overlayClassName?: string; - value: string; - onChange: (newValue: string) => void; - onActive?: (active: boolean) => void; - loading?: boolean; - error?: boolean; - results: SearchResult[]; -}; - -const INPUTS = ["input", "select", "button", "textarea"]; - -export function DocSearch({ - className, - overlayClassName, - value, - onChange, - onActive, - loading, - error, - results, -}: SearchProps): ReactElement { - const [show, setShow] = useState(false); - const [active, setActive] = useState(0); - const router = useRouter(); - const input = useRef(null); - const ulRef = useRef(null); - const [focused, setFocused] = useState(false); - // Trigger the search after the Input is complete for languages like Chinese - const [composition, setComposition] = useState(true); - const { queryID, setObjectID } = useContext(AlgoliaContext); - - useEffect(() => { - setActive(0); - }, [value]); - - useEffect(() => { - const down = (e: globalThis.KeyboardEvent): void => { - const activeElement = document.activeElement as HTMLElement; - const tagName = activeElement?.tagName.toLowerCase(); - if ( - !input.current || - !tagName || - INPUTS.includes(tagName) || - activeElement?.isContentEditable - ) - return; - if ( - e.key === "/" || - (e.key === "k" && - (e.metaKey /* for Mac */ || /* for non-Mac */ e.ctrlKey)) - ) { - e.preventDefault(); - // prevent scrolling to the top - input.current.focus({ preventScroll: true }); - } else if (e.key === "Escape") { - setShow(false); - input.current.blur(); - } - }; - - window.addEventListener("keydown", down); - return () => { - window.removeEventListener("keydown", down); - }; - }, []); - - const finishSearch = (i: number) => { - input.current?.blur(); - - const result = results[i]; - - aa.default("clickedObjectIDsAfterSearch", { - index: "docs", - eventName: "Search Option Clicked", - queryID: queryID, - objectIDs: [result.id], - positions: [results.indexOf(result) + 1], - }); - - setObjectID(result.id); - onChange(""); - setShow(false); - }; - - const handleActive = useCallback( - (e: { currentTarget: { dataset: DOMStringMap } }) => { - const { index } = e.currentTarget.dataset; - setActive(Number(index)); - }, - [] - ); - - const handleKeyDown = useCallback( - function (e: KeyboardEvent) { - switch (e.key) { - case "ArrowDown": { - if (active + 1 < results.length) { - const el = ulRef.current?.querySelector( - `li:nth-of-type(${active + 2}) > a` - ); - if (el) { - e.preventDefault(); - handleActive({ currentTarget: el }); - el.focus(); - } - } - break; - } - case "ArrowUp": { - if (active - 1 >= 0) { - const el = ulRef.current?.querySelector( - `li:nth-of-type(${active}) > a` - ); - if (el) { - e.preventDefault(); - handleActive({ currentTarget: el }); - el.focus(); - } - } - break; - } - case "Enter": { - const result = results[active]; - if (result && composition) { - void router.push(result.route); - finishSearch(active); - } - break; - } - case "Escape": { - setShow(false); - input.current?.blur(); - break; - } - } - }, - [active, results, router, finishSearch, handleActive, composition] - ); - - const mounted = useMounted(); - const renderList = show && Boolean(value); - - const icon = ( - - { - onChange(""); - }} - > - {value && focused - ? "ESC" - : mounted && - (navigator.userAgent.includes("Macintosh") ? ( - <> - K - - ) : ( - "CTRL K" - ))} - - - ); - const handleComposition = useCallback( - (e: CompositionEvent) => { - setComposition(e.type === "compositionend"); - }, - [] - ); - - return ( -
- {renderList && ( -
setShow(false)} - /> - )} - - { - const { value } = e.target; - onChange(value); - setShow(Boolean(value)); - }} - onFocus={() => { - onActive?.(true); - setFocused(true); - }} - onBlur={() => { - setFocused(false); - }} - onCompositionStart={handleComposition} - onCompositionEnd={handleComposition} - type="search" - placeholder={"Search"} - onKeyDown={handleKeyDown} - suffix={icon} - /> - - -
-
    - {error ? ( - - - {"Error"} - - ) : loading ? ( - - - {"Loading"} - - ) : results.length > 0 ? ( - results.map(({ route, prefix, children, id }, i) => ( - - {prefix} -
  • - finishSearch(i)} - onKeyDown={handleKeyDown} - > - {children} - -
  • -
    - )) - ) : ( - - No results found. - - )} -
-
- Algolia logo -
-
-
-
- ); -} diff --git a/components/Search/highlight-matches.tsx b/components/Search/highlight-matches.tsx deleted file mode 100644 index 0dc35b091..000000000 --- a/components/Search/highlight-matches.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import escapeStringRegexp from "escape-string-regexp"; -import type { ReactElement, ReactNode } from "react"; -import { memo } from "react"; - -type MatchArgs = { - value?: string; - match: string; -}; - -export const HighlightMatches = memo(function HighlightMatches({ - value, - match, -}: MatchArgs): ReactElement | null { - if (!value) { - return null; - } - const splitText = value.split(""); - const escapedSearch = escapeStringRegexp(match.trim()); - const regexp = new RegExp(escapedSearch.replaceAll(/\s+/g, "|"), "ig"); - let result; - let index = 0; - const content: (string | ReactNode)[] = []; - - while ((result = regexp.exec(value))) { - if (result.index === regexp.lastIndex) { - regexp.lastIndex++; - } else { - const before = splitText.splice(0, result.index - index).join(""); - const after = splitText - .splice(0, regexp.lastIndex - result.index) - .join(""); - content.push( - before, - - {after} - - ); - index = regexp.lastIndex; - } - } - - return ( -
- {content} - {splitText.join("")} -
- ); -}); diff --git a/components/Search/index.tsx b/components/Search/index.tsx deleted file mode 100644 index f1442cf1a..000000000 --- a/components/Search/index.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import type { Item as NormalItem } from "nextra/normalize-pages"; -import type { ReactElement } from "react"; -import { useContext, useEffect, useState } from "react"; -import { HighlightMatches } from "./highlight-matches"; -import { DocSearch } from "./docsearch"; -import algoliasearch from "algoliasearch"; -import AlgoliaContext from "@/utils/contexts/AlgoliaContext"; - -// Using environment variables for Algolia configuration -const client = algoliasearch( - process.env.NEXT_PUBLIC_ALGOLIA_APPLICATION_ID || "", - process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY || "" -); - -const index = client.initIndex(process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME || "docs"); - -type AlgoliaHits = { - hits: AlgoliaHit[]; - queryID?: string; -}; - -export type AlgoliaHit = { - objectID: string; - title: string; - description: string; - slug: string; -}; - -export function Search({ - className, - directories, -}: Readonly<{ - className?: string; - directories: NormalItem[]; -}>): ReactElement { - // Rest of your code remains the same - const [search, setSearch] = useState(""); - const [results, setResults] = useState([]); - - const { queryID, setQueryID } = useContext(AlgoliaContext); - - useEffect(() => { - async function fetchData() { - const hits: AlgoliaHits = await index.search(search, { - clickAnalytics: true, - }); - - setQueryID(hits.queryID); - - const mappedHits = hits?.hits.map((hit) => ({ - id: hit.objectID, - route: hit.slug, - children: ( - <> - -
- -
- - ), - })); - setResults(mappedHits); - } - - fetchData(); - }, [search, directories]); - - return ( - - ); -} \ No newline at end of file diff --git a/components/Search/input.tsx b/components/Search/input.tsx deleted file mode 100644 index e1094b37e..000000000 --- a/components/Search/input.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import cn from 'clsx' -import type { ComponentProps, ReactNode } from 'react' -import { forwardRef } from 'react' - -type InputProps = ComponentProps<'input'> & { suffix?: ReactNode } - -export const Input = forwardRef( - ({ className, suffix, ...props }, forwardedRef) => ( -
- - {suffix} -
- ) -) - -Input.displayName = 'Input' diff --git a/components/SuperchainContractTable.tsx b/components/SuperchainContractTable.tsx deleted file mode 100644 index e9ad34c32..000000000 --- a/components/SuperchainContractTable.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import type { ReactElement } from 'react'; -import { useEffect, useState } from 'react'; -import { AddressTable, TableAddresses } from '@/components/AddressTable'; -import toml from 'toml'; - -const CONFIG_URL = 'https://raw.githubusercontent.com/ethereum-optimism/superchain-registry/main/superchain/configs/mainnet/superchain.toml'; - -export function SuperchainContractTable({ - chain, - explorer, -}: { - chain: string; - explorer: string; -}): ReactElement { - const [config, setConfig] = useState | null>(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - useEffect(() => { - async function fetchAddresses() { - try { - const response = await fetch(CONFIG_URL); - if (!response.ok) { - throw new Error('Failed to fetch config'); - } - const text = await response.text(); - const data = toml.parse(text); - setConfig(data); - } catch (err) { - setError(err.message); - console.error('Error fetching or parsing config:', err); - } finally { - setLoading(false); - } - } - - fetchAddresses(); - }, []); - - if (loading) { - return
Loading...
; - } - - if (error) { - return
Error: {error}
; - } - -// Helper function to recursively extract Ethereum addresses with renamed keys -function extractAddresses(obj: Record, prefix = ''): TableAddresses { - const addresses: TableAddresses = {}; - for (const [key, value] of Object.entries(obj)) { - if (typeof value === 'string' && /^0x[a-fA-F0-9]{40}$/.test(value)) { - // Rename specific keys - let newKey = `${prefix}${key}`; - if (key === 'protocol_versions_addr') newKey = 'ProtocolVersions'; - if (key === 'superchain_config_addr') newKey = 'SuperchainConfig'; - if (key === 'op_contracts_manager_proxy_addr') newKey = 'OPContractsManagerProxy'; - addresses[newKey] = value; - } else if (typeof value === 'object' && value !== null) { - Object.assign(addresses, extractAddresses(value, `${key}.`)); // Recurse into nested objects - } - } - return addresses; -} - - - const addresses = extractAddresses(config || {}); - - return ( - - ); -} diff --git a/components/TokenListTable.tsx b/components/TokenListTable.tsx deleted file mode 100644 index 0fc3b0a82..000000000 --- a/components/TokenListTable.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import type { ReactElement } from 'react' -import tokenlist from '@eth-optimism/tokenlist' - -const explorers = { - '1': 'https://etherscan.io', - '5': 'https://goerli.etherscan.io', - '10': 'https://optimistic.etherscan.io', - '420': 'https://goerli-optimism.etherscan.io', - '11155111': 'https://sepolia.etherscan.io/', - '11155420': 'https://sepolia-optimism.etherscan.io/', -} - -export function TokenListTable({ - l1, - l2, -}: { - l1: string, - l2: string -}): ReactElement { - return ( - - - - - - - - - - - { - tokenlist.tokens - .filter((token) => { - // Find all of the L1 tokens - return token.chainId === parseInt(l1) - }) - .sort((a, b) => { - // Sort alphabetically by symbol - return a.symbol.localeCompare(b.symbol) - }) - .reduce((acc, token) => { - // Remove duplicate L1 tokens by address - if (acc.some((other) => { - return other.address === token.address - })) { - return acc - } else { - return acc.concat(token) - } - }, []) - .map((token) => { - // Find the corresponding L2 token - return { - token, - pair: tokenlist.tokens - .find((other) => { - return ( - other.chainId === parseInt(l2) && - other.symbol === token.symbol - ) - }) - } - }) - .filter(({ pair }) => { - // Make sure the L2 token exists (it may not) - return pair !== undefined - }) - .map(({ token, pair }) => { - return ( - - - - - - - ) - }) - } - -
NameSymbolL1 TokenL2 Token
- {token.name} - - {token.symbol} - - - - {token.address} - - (opens in a new tab) - - - - - {pair.address} - - (opens in a new tab) - -
- ) -} diff --git a/components/WipCallout.tsx b/components/WipCallout.tsx deleted file mode 100644 index cebce8d24..000000000 --- a/components/WipCallout.tsx +++ /dev/null @@ -1,111 +0,0 @@ -/** - * The WipCallout function renders a custom callout component with optional context text for - * displaying maintenance messages. - * @param {Props} props - An object containing the optional `context` property, a string used - * to customize the message displayed in the callout. - * @returns {ReactElement} The WipCallout component, representing a custom callout message. - */ -import type { ReactElement } from 'react'; -import { useState } from 'react'; - -interface Props { - context?: string; -} -export function WipCallout({ context }: Props): ReactElement { - const [closeCallout, setCloseCallout] = useState(false); - return ( -
-
- {context ? ( - context - ) : ( -
- Please do not rely on the content of this page as it is currently - undergoing maintenance. Code samples and solutions may not function - as expected. Please check back for an update or{' '} - - sign up to help us revise this page - - . We welcome your contribution! ❤️ -
- )} -
- -
- ); -} - -export function InteropCallout({ context }: Props): ReactElement { - const [closeCallout, setCloseCallout] = useState(false); - return ( -
-
- {context ? ( - context - ) : ( -
- Interop is currently in active development and not - yet ready for production use. The information provided here may - change frequently. We recommend checking back regularly for the most up-to-date - information. -
- )} -
- -
- ); -} - -interface BetaCalloutProps extends Props { - featureName: string; -} - -function BetaCallout({ context, featureName }: BetaCalloutProps): ReactElement { - return ( -
-
- {context ? ( - context - ) : ( -
- The {featureName} feature is currently in Beta within - the MIT-licensed OP Stack. Beta features are built and reviewed by - the Optimism Collective's core contributors, and provide developers - with early access to highly requested configurations. These features - may experience stability issues, and we encourage feedback from our - early users. -
- )} -
-
- ); -} - -export function AltCallout(props: Props): ReactElement { - return ; -} - -export function CGTCallout(props: Props): ReactElement { - return ; -} diff --git a/components/calculator/ChainParametersForm.tsx b/components/calculator/ChainParametersForm.tsx deleted file mode 100644 index 12c794ecc..000000000 --- a/components/calculator/ChainParametersForm.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import type { ReactElement } from "react"; -import { useState } from "react"; -import { TextInput, SelectInput } from "./Inputs"; -import { ResultsParams, ResultsTable } from "./ResultsTable"; -import { - displayL1BaseFeeScalar, - displayL1BlobBaseFeeScalar, - calculateOverallL1DataAndStateCostsMargin, - calculateModeledDAPlusStateRevenueOnL2, - calculateTotalL1StateProposalCostsInETH, - determineDAInUse, - calculateImpliedDataGasFeePerTxUsingBlobs, - calculateImpliedDataGasFeePerTxUsingL1Calldata, - calculateImpliedDataGasFeePerTxUsingAltDAPlasmaMode, - resultsFeeScalarsAssumed, - impliedDataGasFee -} from "@/utils/calculator-helpers"; -import { Loader } from "./Loader"; - -type ComparableTransactionType = "Base" | "Zora" | "Mint" | "Mode"; -type DataAvailabilityType = "Ethereum" | "AltDA Plasma Mode"; - -export function ChainParametersForm(): ReactElement { - const [transactionsPerDay, setTransactionsPerDay] = useState(500000); - const [comparableTransactionType, setComparableTransactionType] = - useState("General OP Mainnet"); - const [dataAvailabilityType, setDataAvailabilityType] = useState("Ethereum"); - const [isFaultProofEnabled, setIsFaultProofEnabled] = useState("yes"); - const [targetDataFeeMargin, setTargetDataFeeMargin] = useState(5); - const [maxBlobsPerL1Transaction, setMaxBlobsPerL1Transaction] = useState(5); - const [maxChannelDuration, setMaxChannelDuration] = useState(5); - const [outputRootPostFrequency, setOutputRootPostFrequency] = useState(1 ); - const [isIncludeOutputRootCosts, setIsIncludeOutputRootCosts] = useState("yes"); - const [resultsParams, setResultsParams] = useState({}); - const [isLoading, setIsLoading] = useState(false); - const [showResult, setShowResult] = useState(false); - - const comparableTransactionTypeOptions = [ - "General OP Mainnet", - "Base", - "Zora", - "Mint", - "Mode", - ]; - const dataAvailabilityTypeOptions = ["Ethereum", "AltDA Plasma Mode"]; - const booleanOptions = ["Yes", "No"]; - - const handleSubmit = async (e: any) => { - e.preventDefault(); - setIsLoading(true); - setShowResult(false) - - //e37 - const l1BlobBaseFeeScalar = await displayL1BlobBaseFeeScalar( - stringToBoolean(isIncludeOutputRootCosts), - stringToBoolean(isFaultProofEnabled), - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTransactionType, - dataAvailabilityType, - targetDataFeeMargin - ); - - //e38 - const l1BaseFeeScalar = await displayL1BaseFeeScalar( - isIncludeOutputRootCosts, - isFaultProofEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTransactionType, - targetDataFeeMargin, - dataAvailabilityType - ); - - // e58 - const overallL1DataAndStateCostsMargin = - await calculateOverallL1DataAndStateCostsMargin( - transactionsPerDay, - comparableTransactionType, - l1BlobBaseFeeScalar, - l1BaseFeeScalar, - dataAvailabilityType, - maxChannelDuration, - outputRootPostFrequency, - isFaultProofEnabled - ); - - //e56 - const totalL1StateProposalCostsInETH = - await calculateTotalL1StateProposalCostsInETH( - outputRootPostFrequency, - isFaultProofEnabled - ); - - // e118 - const modeledDAPlusStateRevenueOnL2 = - await calculateModeledDAPlusStateRevenueOnL2( - transactionsPerDay, - comparableTransactionType, - l1BlobBaseFeeScalar, - l1BaseFeeScalar - ); - - // e64 - const impliedDataGasFeePerTxUsingBlobs = - await calculateImpliedDataGasFeePerTxUsingBlobs( - isIncludeOutputRootCosts, - isFaultProofEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTransactionType, - dataAvailabilityType, - targetDataFeeMargin - ); - - // e67 - const impliedDataGasFeePerTxUsingL1Calldata = - await calculateImpliedDataGasFeePerTxUsingL1Calldata( - isIncludeOutputRootCosts, - isFaultProofEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTransactionType, - dataAvailabilityType, - targetDataFeeMargin - ); - - // e66 - const impliedDataGasFeePerTxUsingAltDAPlasmaMode = - await calculateImpliedDataGasFeePerTxUsingAltDAPlasmaMode( - isIncludeOutputRootCosts, - isFaultProofEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTransactionType, - dataAvailabilityType, - targetDataFeeMargin - ); - - const dataAvailabilityInUse = determineDAInUse(dataAvailabilityType); - - const assumedFeeScalarMessage = resultsFeeScalarsAssumed( - comparableTransactionType, // e15 - transactionsPerDay, // e14 - dataAvailabilityType, // E16 - targetDataFeeMargin, // E18 - isIncludeOutputRootCosts, // E24 - maxChannelDuration // E22 - ); - const impliedDataGasFeeMessage = await impliedDataGasFee(dataAvailabilityType) - - const data = { - dataAvailabilityType, // e16 - l1BlobBaseFeeScalar, // e37 - l1BaseFeeScalar, // e38 - overallL1DataAndStateCostsMargin, // e58 - totalL1StateProposalCostsInETH, // e56 - modeledDAPlusStateRevenueOnL2, // e118 - dataAvailabilityInUse, // F35 - impliedDataGasFeePerTxUsingBlobs, // e64 - impliedDataGasFeePerTxUsingL1Calldata, // e67 - impliedDataGasFeePerTxUsingAltDAPlasmaMode, // e66 - assumedFeeScalarMessage, - impliedDataGasFeeMessage, - }; - setResultsParams(data); - setIsLoading(false); - setShowResult(true) - }; - - const stringToBoolean = (value: string): boolean => { - return value === "yes" || value === "Yes" ? true : false; - } - - return ( -
-
-
-

Chain Inputs

- - - - - - - - - -
-
-

Advanced Inputs

- - - - - -
- -
- {isLoading && } - {!isLoading && showResult && } -
- ); -} diff --git a/components/calculator/Inputs/CheckboxInput.tsx b/components/calculator/Inputs/CheckboxInput.tsx deleted file mode 100644 index 113a3804f..000000000 --- a/components/calculator/Inputs/CheckboxInput.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; - -type Props = { - otherProps?: any; - className?: string; - label?: string; - description?:string; - handleToggle: (e: any) => void; -}; - -export const CheckboxInput: React.FC = React.memo( - ({ otherProps, label, description, className, handleToggle }) => { - function onCheckboxChange(e: any) { - const isChecked = e.target.checked; - handleToggle(isChecked); - } - return ( -
- {label && } -

{description}

- -
- ); - } -); -CheckboxInput.displayName = "CheckboxInput"; diff --git a/components/calculator/Inputs/SelectInput.tsx b/components/calculator/Inputs/SelectInput.tsx deleted file mode 100644 index c43bd8267..000000000 --- a/components/calculator/Inputs/SelectInput.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from "react"; - -type Props = { - className?: string; - label?: string; - data: any[]; - otherProps?: any; - description?: string; - labelClass?: string; - onSelect?: (e: any) => void; -}; - -export const SelectInput: React.FC = React.memo( - ({ className, labelClass, description, otherProps, label, data, onSelect }) => { - const handleSelect = (e: any) => { - const value = e.target.value - onSelect(value) - } - return ( -
- {label && ( - - )} -

- {description} -

-
- - {/* */} -
-
- ); - } -); -SelectInput.displayName = "SelectInput"; diff --git a/components/calculator/Inputs/TextInput.tsx b/components/calculator/Inputs/TextInput.tsx deleted file mode 100644 index 05d1b18c5..000000000 --- a/components/calculator/Inputs/TextInput.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react"; - -type Props = { - placeholder?: string; - className?: string; - type: "text" | "email" | "password" | "number"; - label?: string; - labelClass?: string; - otherProps?: any; - description?: string; - error?: string; - isDisabled?: boolean; - onInputChange?: (e: any) => void; -}; - -export const TextInput = ({ - label, - placeholder, - className, - type, - otherProps, - isDisabled, - description, - labelClass, - onInputChange, -}: Props) => { - const handleInputChange = (e: any) => { - const val = e.target.value; - onInputChange(val); - }; - return ( -
- {label && ( - - )} -

{description}

- - -
- ); -}; diff --git a/components/calculator/Inputs/index.ts b/components/calculator/Inputs/index.ts deleted file mode 100644 index 1447fe40e..000000000 --- a/components/calculator/Inputs/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -"use client"; - -export * from "./TextInput"; -export * from "./SelectInput"; -export * from "./CheckboxInput"; diff --git a/components/calculator/Loader.tsx b/components/calculator/Loader.tsx deleted file mode 100644 index 9e4ebbb85..000000000 --- a/components/calculator/Loader.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from "react"; - -export const Loader: React.FC = () => { - return ( -
- - - - - - - - - - - -
- ); - } - -Loader.displayName = "Loader"; diff --git a/components/calculator/ResultsTable.tsx b/components/calculator/ResultsTable.tsx deleted file mode 100644 index d81504347..000000000 --- a/components/calculator/ResultsTable.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { convertToMillionUnits } from "@/utils/calculator-helpers"; -import type { ReactElement } from "react"; - -export type ResultsParams = { - data: { - dataAvailabilityType: string; // e16 - l1BlobBaseFeeScalar: number; // e37 - l1BaseFeeScalar: number; // e38 - overallL1DataAndStateCostsMargin: number; // e58 - totalL1StateProposalCostsInETH: number; // e56 - modeledDAPlusStateRevenueOnL2: number; // e118 - dataAvailabilityInUse: string; // f35 - impliedDataGasFeePerTxUsingBlobs: number; // e64 - impliedDataGasFeePerTxUsingL1Calldata: number; // e67 - impliedDataGasFeePerTxUsingAltDAPlasmaMode: number; // e66, - assumedFeeScalarMessage: string; - impliedDataGasFeeMessage: string; - }; -}; - -export function ResultsTable({ - data -}: ResultsParams): ReactElement { - - const { - dataAvailabilityType, - l1BlobBaseFeeScalar, - l1BaseFeeScalar, - overallL1DataAndStateCostsMargin, - totalL1StateProposalCostsInETH, - modeledDAPlusStateRevenueOnL2, - dataAvailabilityInUse, - impliedDataGasFeePerTxUsingBlobs, - impliedDataGasFeePerTxUsingAltDAPlasmaMode, - impliedDataGasFeePerTxUsingL1Calldata, - assumedFeeScalarMessage, - impliedDataGasFeeMessage, - } = data; - - function calculateConstructionMessage( - _overallL1DataAndStateCostsMargin: number, // Corresponds to E58 - _totalL1StateProposalCostsInETH: number, // Corresponds to E56 - _modeledDAPlusStateRevenueOnL2: number // Corresponds to E118 - ): string { - const roundedE58IfNegative = - Math.round(_overallL1DataAndStateCostsMargin * -1000) / 1000; - const roundedE56 = - Math.round(_totalL1StateProposalCostsInETH * 1000) / 1000; - const roundedE58IfPositive = - Math.round(_overallL1DataAndStateCostsMargin * 1000) / 1000; - const marginPercentage = - Math.round(100 * (_overallL1DataAndStateCostsMargin / _modeledDAPlusStateRevenueOnL2) * 10) / 10; - const messageIfE58Negative = `This construction has ${roundedE58IfNegative} ETH / day of estimated State Output root costs, not covered by Data Margin (${roundedE56} ETH Total Output Root Cost / Day) at inputted Blob/L1 Gas Prices.`; - const messageIfE58Positive = `This construction is expected to have +${roundedE58IfPositive} ETH Margin on Data Costs (${marginPercentage}% Margin) at inputted L1 Gas Prices.`; - return _overallL1DataAndStateCostsMargin < 0 ? messageIfE58Negative : messageIfE58Positive - } - - function calculateDataGasFee( - _dataAvailabilityType: string, // Corresponds to E16 - _dataAvailabilityInUse: string, // Corresponds to F35 - _impliedDataGasFeePerTxUsingAltDAPlasmaMode: number, // Corresponds to E66 - _impliedDataGasFeePerTxUsingBlobs: number, // Corresponds to E64 - _impliedDataGasFeePerTxUsingL1Calldata: number // Corresponds to E67 - ): string { - let gasFee: number; - _dataAvailabilityType === "AltDA Plasma Mode" - ? (gasFee = _impliedDataGasFeePerTxUsingAltDAPlasmaMode) - : _dataAvailabilityInUse === "EIP-4844" - ? (gasFee = _impliedDataGasFeePerTxUsingBlobs) - : (gasFee = _impliedDataGasFeePerTxUsingL1Calldata); - - // Round the gas fee to 4 decimal places - const roundedGasFee = Math.round(gasFee * 10000) / 10000; - return `Implied Data Gas Fee per User Transaction: $${roundedGasFee}`; - } - - return ( -
-
-

- {calculateConstructionMessage( - overallL1DataAndStateCostsMargin, - totalL1StateProposalCostsInETH, - modeledDAPlusStateRevenueOnL2 - )} -

-

- {calculateDataGasFee( - dataAvailabilityType, - dataAvailabilityInUse, - impliedDataGasFeePerTxUsingAltDAPlasmaMode, - impliedDataGasFeePerTxUsingBlobs, - impliedDataGasFeePerTxUsingL1Calldata - )} -

-
-
-

Results

- -
-

- Fee Scalar Recommendations - Values to Set as Chain Inputs{" "} -

-

- Recommended fee scalar configurations to achieve your target Data - Margin, given the transaction type and volume are shown below{" "} -

-

- Note: This is an estimation,{" "} - - read how to determine scalar values using blobs - -

-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
DA Recommendation:{`${ - dataAvailabilityInUse === "EIP-4844" - ? `Blobs (EIP-4844)` - : dataAvailabilityInUse - }`}
Scalar TypeChain InputDecimal-Adjusted (6 decimals)
l1BlobBaseFeeScalar{l1BlobBaseFeeScalar}{convertToMillionUnits(l1BlobBaseFeeScalar)}
l1BaseFeeScalar{l1BaseFeeScalar}{convertToMillionUnits(l1BaseFeeScalar)}
-
-

- Using Blobs (EIP-4844), posting transaction data will be 99.7% - cheaper than using L1 Calldata{" "} -

-
-
-

- {assumedFeeScalarMessage} -

-

- {impliedDataGasFeeMessage} -

-
-
-
-
- ); -} diff --git a/pages/connect/contribute.mdx b/connect/contribute.mdx similarity index 66% rename from pages/connect/contribute.mdx rename to connect/contribute.mdx index 211af4798..5facc20bf 100644 --- a/pages/connect/contribute.mdx +++ b/connect/contribute.mdx @@ -3,28 +3,15 @@ title: Contribute description: >- Documentation covering Docs Contribute, Stack Contribute, Style Guide in the Contribute section of the OP Stack ecosystem. -lang: en-US -content_type: guide -topic: contribute -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator -categories: - - security-council - - blockspace-charters -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Contribute Documentation covering Docs Contribute, Stack Contribute, Style Guide in the Contribute section of the OP Stack ecosystem. - + - + diff --git a/pages/connect/contribute/docs-contribute.mdx b/connect/contribute/docs-contribute.mdx similarity index 95% rename from pages/connect/contribute/docs-contribute.mdx rename to connect/contribute/docs-contribute.mdx index 7783df705..e0f2d4e3c 100644 --- a/pages/connect/contribute/docs-contribute.mdx +++ b/connect/contribute/docs-contribute.mdx @@ -1,30 +1,17 @@ --- title: Contribute to Optimism Docs description: Learn about the different ways you can contribute to Optimism Docs. -lang: en-US -content_type: guide -topic: docs-contribute -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator -categories: - - security-council - - protocol -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Contribute to Optimism Docs Optimism Docs (docs.optimism.io) is an open-source project, and we welcome your contributions. Here's how you can help grow and support the Optimism Collective. - + We recently migrated our technical docs from community.optimism.io --> docs.optimism.io. So, if you contributed to either repo in 2023, don't forget to claim your [POAP token](#claim-your-gitpoap)! - + ## Ways to contribute @@ -95,9 +82,9 @@ We use GitPOAPs to recognize our contributors! GitPOAP automatically recognizes 3. Search for your GitHub username, ETH address, ENS names or any GitPOAP to check if you're eligible. 4. If your GitHub account is eligible, then you are able to mint a GitPOAP! - + You should only use self-custody wallets to claim POAPs. Do not use exchange accounts or other accounts you do not hold the private keys to, as these will not allow you to access and manage your POAPs. - + ## Still have questions? diff --git a/pages/connect/contribute/stack-contribute.mdx b/connect/contribute/stack-contribute.mdx similarity index 93% rename from pages/connect/contribute/stack-contribute.mdx rename to connect/contribute/stack-contribute.mdx index 1e9b88387..49857f8d1 100644 --- a/pages/connect/contribute/stack-contribute.mdx +++ b/connect/contribute/stack-contribute.mdx @@ -1,21 +1,8 @@ --- title: Contribute to the OP Stack description: Learn different ways you can contribute to the OP Stack. -lang: en-US -content_type: guide -topic: stack-contribute -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator -categories: - - security-council - - protocol -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Contribute to the OP Stack @@ -38,11 +25,11 @@ If you'd like to contribute to the current release of OP Stack codebase, rather To make your first contribution to the codebase, check out the [open issues](https://github.com/ethereum-optimism/optimism/issues) on the Optimism Monorepo. - + Only the software components included within the current release of the OP Stack codebase are considered in the scope of the OP Stack. Any usage of the OP Stack outside of the official, intended capabilities of the current release is considered [OP Stack Hacks](https://github.com/ethereum-optimism/developers/tree/main/docs) — unofficial modifications that are useful for experimentation but could have unforeseen results, such as security vulnerabilities, and are likely to cause your chain to no longer be interoperable with the [Optimism Superchain](https://app.optimism.io/superchain/?utm_source=op-docs&utm_medium=docs). Developer support for OP Stack Hacks is limited — when in doubt, stick to the capabilities of the current release! - + ## Bounty hunting diff --git a/pages/connect/contribute/style-guide.mdx b/connect/contribute/style-guide.mdx similarity index 97% rename from pages/connect/contribute/style-guide.mdx rename to connect/contribute/style-guide.mdx index b9046d0d8..06ed0658d 100644 --- a/pages/connect/contribute/style-guide.mdx +++ b/connect/contribute/style-guide.mdx @@ -3,21 +3,8 @@ title: Docs style guide description: >- This guide explains how to write technical content for Optimism Docs using a consistent voice, tone, and style. -lang: en-US -content_type: guide -topic: style-guide -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator -categories: - - security-council - - protocol -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Docs style guide @@ -88,13 +75,13 @@ See below for when to use title or sentence case. **Example**: I use Visual Studio on my local machine. * Use title case for all headers (H1, H2, H3) and when referring to buttons, tab names, page names, and links within the documentation. Note: The actual text on buttons, links, pages, or tabs need not be in title case—only the references within the docs. - + **Examples of Title Case:**
Domains For the Development Environment (header)
Select **Make Owner**.
Click **Clear Caches**.
Select the **Settings** tab.
-
+ * Use sentence case for body content and short phrases, even when the content is a link. Sentence case means you only capitalize the first letter of the sentence.
**Example:** If you're trying to figure out how to do something specific as a node operator, you might search our collection of [tutorials](/operators/node-operators/rollup-node) or [suggest a new one](https://github.com/ethereum-optimism/docs/issues). @@ -102,9 +89,9 @@ See below for when to use title or sentence case. * Use lowercase in code snippets by default, unless the code block uses capitalization (e.g., for the name of a function or variable) and you are referring to the function or variable elsewhere within the technical documentation.
**Examples**: Run `git add` or Import `useState` - + When in doubt, follow the code base because exact capitalization is necessary in order for the code to compile. - + ## Accessibility @@ -144,23 +131,23 @@ We aim to use consistent organization that is also user-centered and accessible. * Set the meta title by reusing the H1 page title, but since meta titles are not visually displayed on the page to users, the H1 page title is also required. - + **NOTE**
SEO guidelines suggest that meta page titles differ slightly from H1 page titles, but this is handled automatically by our site platform. So, please match H1 page titles to meta page titles for ease of documentation. -
+ * Set the language attribute for accessibility and usability (for screen readers) but also to make it easier to enable language localization support in the future. * Write meta descriptions as concise overviews (100-150 characters) of the most relevant content of the page. - + **Example Meta section of docs:**
—-
title: Supercharge Your App with Account Abstraction
lang: en-US
description: This guide explains how account abstraction enables users to utilize smart contracts to build, onboard, and scale apps.
—-
-
+ ### Page titles (H1) @@ -175,12 +162,12 @@ We aim to use consistent organization that is also user-centered and accessible. * Use an imperative verb for headings or subheadings in a document, and not a gerund (a verb ending in "ing"). Headings should be shown in H2 tags, and subheadings should be shown in H3 tags. * Outline the page content according to main topics first. Those will be your headings (tagged as H2). If there are subtopics that belong under a category, display those as subheaders (tagged as H3).
- + **Example**:
(H1) Supporting OP Mainnet in Your Wallet (H1 page title uses "ing"verb ending)
(H2) Connect to OP Mainnet (H2 does not use "ing"verb ending)
(H2) Locate Canonical Token Addresses (second H2 does not use "ing"verb ending)
-
+ * Use headings in a logical manner, and the site will automatically generate anchor links for H2 and H3 tags and place them in a Table of Contents (TOC) in the right column. @@ -193,33 +180,33 @@ We aim to use consistent organization that is also user-centered and accessible. * Add a "Before You Begin" section at the top of the document if there are tasks a user needs to complete before continuing with the current task, e.g. installing a module, downloading a software update, etc. * Use the title "Before You Begin" and format as H2. It should follow the page overview/intro section or table of contents. * Include all the tasks the user needs to complete, including links to aid in usability. Use a bulleted list for more than 2 prerequisite items. - + **Example**:
(H2) Before You Begin
You'll need to enable the ApacheSolr module. Visit the [ApacheSolr](https://drupal.org/project/apachesolr) page on [Drupal.org](http://drupal.org/) for more information.
-
+ ### Callouts * Use callouts to direct users to information necessary to complete a task or information of special importance. When adding a callout to a document, use sentence case. * Use the correct callout type based on the type of issue: a) info/general, b) warning, c) error. Our documentation platform supports 4 different callout types. * The default and info callouts are used to share non-sensitive, non-breaking info with users, such as suggestions or best practices that might make the installation or deployment easier. - + **Example**:
You can easily export your OP Profile data to reuse on other media platforms. -
+ * Warning callouts should be used to indicate important info, such as when a product or code will be deprecated. - + **Example**:
This API will be deprecated soon.
-
+ * Error callouts are reserved for critical issues that cannot be undone or can result in breaking changes, such as when data might be permanently deleted or lost. - + **Example**:
This is a dangerous action that permanently deletes your data and cannot be undone. Your data cannot be recovered by Optimism.
-
+ * Use callouts sparingly as too many can be confusing to readers. **As a general rule of thumb:** pages with more than 2 callouts likely needs revision and/or a discussion with an Optimism developer or product manager to ensure guide content accuracy. ### Code samples @@ -229,10 +216,10 @@ We aim to use consistent organization that is also user-centered and accessible. **Example**: This markdown or MDX file
- + js
console.log('hello, world')
-
+ will render this code snippet in `javascript` with proper syntax highlighting: @@ -259,7 +246,6 @@ console.log('hello, world') * **Example (imported)**: ``` -import Image from 'next/image' ... @@ -387,11 +373,11 @@ When writing tutorials or quick starts, steps should be written in parallel styl **Example**: - + Step 1: **Create** Your Site
Step 2: **Choose** Your Framework
Step 3: **Visit** the Dev Environment -
+ ### FAQs @@ -409,21 +395,21 @@ The heading level for FAQs will vary based on if it's an FAQ-only doc or if FAQs **Example of a simple FAQ** - + **Does Optimism Support ERC-721?**
Yes. We have complete and total support for ERC-721 standard.
-
+ **Example of an instructional FAQ** - + **How do I change my Optimism password?**
1. Select **Sites & Accounts** from the user account drop-down menu. 2. Click the **Account** tab. 3. Select **Change Password**. 4. Enter the information, and click **Save**. -
+ Include a category heading when you need to group related FAQ content (e.g., See the Optimism Glossary for a detailed example). Category headings are optional, but helpful, for longer FAQs. diff --git a/pages/connect/resources.mdx b/connect/resources.mdx similarity index 50% rename from pages/connect/resources.mdx rename to connect/resources.mdx index f79157f85..7a1fa1936 100644 --- a/pages/connect/resources.mdx +++ b/connect/resources.mdx @@ -3,26 +3,13 @@ title: Resources description: >- Documentation covering Glossary in the Resources section of the OP Stack ecosystem. -lang: en-US -content_type: guide -topic: resources -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator -categories: - - security-council - - blockspace-charters -is_imported_content: 'false' --- -import { Card, Cards } from 'nextra/components' # Resources Documentation covering Glossary in the Resources section of the OP Stack ecosystem. - + - + diff --git a/pages/connect/resources/glossary.mdx b/connect/resources/glossary.mdx similarity index 98% rename from pages/connect/resources/glossary.mdx rename to connect/resources/glossary.mdx index b10bdf0a4..be8643daf 100644 --- a/pages/connect/resources/glossary.mdx +++ b/connect/resources/glossary.mdx @@ -3,22 +3,8 @@ title: glossary description: >- Learn the meaning of important terminology used throughout the Optimism Developer Documentation. -lang: en-US -content_type: reference -topic: glossary -personas: - - app-developer - - protocol-developer - - chain-operator - - node-operator - - governance-participant -categories: - - security-council - - protocol -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Glossary @@ -360,14 +346,14 @@ CHANNEL_TIMEOUT]`. The acceptable L1 block range for these frames are any L1 blo time range. (Note that `channel_id.timestamp` must be lower than the L1 block timestamp of any L1 block in which frames of the channel are seen, or else these frames are ignored.) - + The purpose of channel timeouts is dual: * Avoid keeping old unclosed channel data around forever (an unclosed channel is a channel whose final frame was not sent). * Bound the number of L1 blocks we have to look back in order to decode [sequencer batches](#sequencer-batch) from channels. This is particularly relevant during L1 re-orgs. - + ### Data Availability @@ -392,11 +378,11 @@ L2 transaction derived from an L1 block (by the rollup driver). While transactio L1 contract to which [EOAs](#eoa-or-externally-owned-account) and contracts may send deposits. The deposits are emitted as log records (in Solidity, these are called *events*) for consumption by [rollup nodes](#rollup-node). - + The deposits are not stored in calldata because they can be sent by contracts, in which case the calldata is part of the *internal* execution between contracts, and this intermediate calldata is not captured in one of the [Merkle Patricia Trie roots](#merkle-patricia-trie) included in the L1 block. - + ### Deposited Transaction diff --git a/docs.json b/docs.json new file mode 100644 index 000000000..1b6017a62 --- /dev/null +++ b/docs.json @@ -0,0 +1,459 @@ +{ + "$schema": "https://mintlify.com/docs.json", + "theme": "mint", + "name": "Optimism Documentation", + "colors": { + "primary": "#FF0420", + "light": "#FF0420", + "dark": "#FF0420" + }, + "favicon": "/favicon.svg", + "navigation": { + "tabs": [ + { + "tab": "Get Started", + "groups": [ + { + "group": "Get Started", + "pages": [ + "index", + "get-started/interop", + "get-started/op-stack", + "get-started/superchain" + ] + } + ] + }, + { + "tab": "Superchain", + "groups": [ + { + "group": "Superchain", + "pages": [ + "superchain/superchain-explainer", + "superchain/addresses", + "superchain/networks", + "superchain/blockspace-charter", + "superchain/privileged-roles", + "superchain/standard-configuration", + "superchain/superchain-upgrades", + "superchain/superchain-registry", + "superchain/tokenlist" + ] + } + ] + }, + { + "tab": "Interoperability", + "groups": [ + { + "group": "Superchain Interoperability", + "pages": [ + "interop/get-started", + "interop/explainer", + "interop/compatible-tokens", + "interop/estimate-costs", + "interop/starter-kit", + "interop/superchain-eth-bridge", + "interop/superchain-erc20", + "interop/message-passing", + "interop/message-expiration", + "interop/predeploy", + "interop/reading-logs", + "interop/reorg", + "interop/interop-security", + "interop/op-supervisor" + ] + }, + { + "group": "Tools", + "pages": [ + "interop/tools/supersim", + "interop/tools/interop-devnet" + ] + }, + { + "group": "Tutorials", + "pages": [ + "interop/tutorials/transferring-superchain-erc20", + "interop/tutorials/deploying-superchain-erc20", + "interop/tutorials/bridge-crosschain-eth", + "interop/tutorials/relay-interop-messages-cast", + "interop/tutorials/relay-interop-messages-viem", + "interop/tutorials/crosschain-contract-calls", + "interop/tutorials/crosschain-event-reads", + "interop/tutorials/crosschain-event-composability", + "interop/tutorials/upgrade-superchain-erc20" + ] + } + ] + }, + { + "tab": "App Devs", + "groups": [ + { + "group": "App Developers", + "pages": [ + "app-developers/get-started", + "app-developers/superchain-erc20-starter-kit", + "app-developers/interop", + "app-developers/building-apps", + "app-developers/testing-apps", + { + "group": "Bridging", + "pages": [ + "app-developers/bridging/basics", + "app-developers/bridging/custom-bridge", + "app-developers/bridging/messaging", + "app-developers/bridging/standard-bridge" + ] + }, + { + "group": "Transactions", + "pages": [ + "app-developers/transactions/estimates", + "app-developers/transactions/fees", + "app-developers/transactions/parameters", + "app-developers/transactions/statuses", + "app-developers/transactions/troubleshooting" + ] + } + ] + }, + { + "group": "Tutorials", + "pages": [ + { + "group": "Bridging Tutorials", + "pages": [ + "app-developers/tutorials/bridging/cross-dom-bridge-erc20", + "app-developers/tutorials/bridging/cross-dom-bridge-eth", + "app-developers/tutorials/bridging/cross-dom-solidity", + "app-developers/tutorials/bridging/standard-bridge-custom-token", + "app-developers/tutorials/bridging/standard-bridge-standard-token" + ] + }, + { + "group": "Transaction Tutorials", + "pages": [ + "app-developers/tutorials/transactions/sdk-trace-txns", + "app-developers/tutorials/transactions/sdk-estimate-costs", + "app-developers/tutorials/transactions/send-tx-from-eth" + ] + }, + { + "group": "Supersim Tutorials", + "pages": [ + "app-developers/tutorials/supersim/chain-env/chain-a", + "app-developers/tutorials/supersim/chain-env/chain-b", + "app-developers/tutorials/supersim/chain-env/included-contracts", + "app-developers/tutorials/supersim/getting-started/first-steps", + "app-developers/tutorials/supersim/getting-started/installation", + "app-developers/tutorials/supersim/reference/fork", + "app-developers/tutorials/supersim/reference/vanilla", + "app-developers/tutorials/supersim/chain-env", + "app-developers/tutorials/supersim/deposit-transactions", + "app-developers/tutorials/supersim/getting-started", + "app-developers/tutorials/supersim/reference" + ] + }, + { + "group": "Interop Tutorials", + "pages": [ + "app-developers/tutorials/interop/bridge-crosschain-eth", + "app-developers/tutorials/interop/contract-calls", + "app-developers/tutorials/interop/deploy-superchain-erc20", + "app-developers/tutorials/interop/event-contests", + "app-developers/tutorials/interop/event-reads", + "app-developers/tutorials/interop/transfer-superchainERC20" + ] + } + ] + }, + { + "group": "Developer Tools", + "pages": [ + "app-developers/tools/superchain-dev-console", + "app-developers/tools/supersim-multichain-dev-env", + { + "group": "Connecting", + "pages": [ + "app-developers/tools/connect/networks", + "app-developers/tools/connect/rpc-providers" + ] + }, + { + "group": "Building", + "pages": [ + "app-developers/tools/build/account-abstraction", + "app-developers/tools/build/block-explorers", + "app-developers/tools/build/faucets", + "app-developers/tools/build/nft-tools", + "app-developers/tools/build/oracles" + ] + }, + { + "group": "Data and Dashboards", + "pages": [ + "app-developers/tools/data-and-dashboards/data-glossary" + ] + } + ] + } + ] + }, + { + "tab": "Operators", + "groups": [ + { + "group": "Chain Operators", + "pages": [ + "operators/chain-operators/architecture", + "operators/chain-operators/self-hosted", + { + "group": "Chain Configuration", + "pages": [ + "operators/chain-operators/configuration/index", + "operators/chain-operators/configuration/batcher", + "operators/chain-operators/configuration/proposer", + "operators/chain-operators/configuration/rollup" + ] + }, + { + "group": "Chain Management", + "pages": [ + "operators/chain-operators/management/best-practices", + "operators/chain-operators/management/blobs", + "operators/chain-operators/management/key-management", + "operators/chain-operators/management/operations", + "operators/chain-operators/management/snap-sync", + "operators/chain-operators/management/troubleshooting" + ] + }, + { + "group": "Chain Features", + "pages": [ + "operators/chain-operators/features/alt-da-mode", + "operators/chain-operators/features/bridged-usdc-standard", + "operators/chain-operators/features/preinstalls", + "operators/chain-operators/features/span-batches" + ] + }, + { + "group": "Deployment", + "pages": [ + "operators/chain-operators/deploy/genesis", + "operators/chain-operators/deploy/overview", + "operators/chain-operators/deploy/proposer-setup-guide", + "operators/chain-operators/deploy/sequencer-node", + "operators/chain-operators/deploy/smart-contracts", + "operators/chain-operators/deploy/spin-batcher", + "operators/chain-operators/deploy/validate-deployment" + ] + }, + { + "group": "Tutorials", + "pages": [ + "operators/chain-operators/tutorials/absolute-prestate", + "operators/chain-operators/tutorials/adding-derivation-attributes", + "operators/chain-operators/tutorials/adding-precompiles", + "operators/chain-operators/tutorials/chain-dev-net", + "operators/chain-operators/tutorials/create-l2-rollup", + "operators/chain-operators/tutorials/dispute-games", + "operators/chain-operators/tutorials/integrating-da-layer", + "operators/chain-operators/tutorials/migrating-permissions", + "operators/chain-operators/tutorials/modifying-predeploy-contracts" + ] + }, + { + "group": "Chain Tools", + "pages": [ + "operators/chain-operators/tools/chain-monitoring", + "operators/chain-operators/tools/explorer", + "operators/chain-operators/tools/fee-calculator", + "operators/chain-operators/tools/op-challenger", + "operators/chain-operators/tools/op-conductor", + "operators/chain-operators/tools/op-deployer", + "operators/chain-operators/tools/op-txproxy", + "operators/chain-operators/tools/op-validator", + "operators/chain-operators/tools/proxyd" + ] + } + ] + }, + { + "group": "Node Operators", + "pages": [ + "operators/node-operators/architecture", + "operators/node-operators/run-node-superchain", + { + "group": "Tutorials", + "pages": [ + "operators/node-operators/tutorials/node-from-docker", + "operators/node-operators/tutorials/node-from-source", + "operators/node-operators/tutorials/run-node-from-source" + ] + }, + { + "group": "Configuration", + "pages": [ + "operators/node-operators/configuration/base-config", + "operators/node-operators/configuration/consensus-config", + "operators/node-operators/configuration/execution-config" + ] + }, + { + "group": "Node Management", + "pages": [ + "operators/node-operators/management/blobs", + "operators/node-operators/management/metrics", + "operators/node-operators/management/genesis-history", + "operators/node-operators/management/snap-sync", + "operators/node-operators/management/snapshots", + "operators/node-operators/management/troubleshooting" + ] + }, + "operators/node-operators/network-upgrades", + "operators/node-operators/json-rpc", + "operators/node-operators/releases" + ] + } + ] + }, + { + "tab": "OP Stack", + "groups": [ + { + "group": "OP Stack", + "pages": [ + "stack/getting-started", + "stack/fact-sheet", + "stack/differences", + "stack/design-principles", + "stack/components", + "stack/public-devnets", + "stack/superchain-ops-upgrades", + "stack/opcm", + { + "group": "Smart Contracts", + "pages": [ + "stack/smart-contracts/smart-contracts", + "stack/smart-contracts/superchain-ops-guide", + "stack/smart-contracts/op-deployer-upgrade", + "stack/smart-contracts/upgrade-op-contracts" + ] + }, + { + "group": "Rollup", + "pages": [ + "stack/rollup/overview", + "stack/rollup/derivation-pipeline", + "stack/rollup/outages" + ] + }, + { + "group": "Fault Proofs", + "pages": [ + "stack/fault-proofs/explainer", + "stack/fault-proofs/fp-components", + "stack/fault-proofs/cannon", + "stack/fault-proofs/challenger", + "stack/fault-proofs/mips", + "stack/fault-proofs/fp-security" + ] + }, + { + "group": "Transactions", + "pages": [ + "stack/transactions/fees", + "stack/transactions/transaction-flow", + "stack/transactions/transaction-finality", + "stack/transactions/deposit-flow", + "stack/transactions/withdrawal-flow", + "stack/transactions/forced-transaction", + "stack/transactions/cross-domain" + ] + }, + { + "group": "Features", + "pages": [ + "stack/features/send-raw-transaction-conditional" + ] + }, + { + "group": "Security", + "pages": [ + "stack/security/faq", + "stack/security/pause", + "stack/security/audits-report", + "stack/security/faq-sec-model", + "stack/security/security-policy" + ] + } + ] + }, + { + "group": "Experimental", + "pages": [ + { + "group": "Beta Features", + "pages": [ + "stack/beta-features/alt-da-mode" + ] + }, + { + "group": "Research", + "pages": [ + "stack/research/block-time-research" + ] + } + ] + } + ] + } + ], + "global": { + "anchors": [ + { + "anchor": "Community Hub", + "href": "https://community.optimism.io/", + "icon": "users" + }, + { + "anchor": "GitHub", + "href": "https://github.com/ethereum-optimism", + "icon": "github" + }, + { + "anchor": "Discord", + "href": "https://discord.gg/optimism", + "icon": "discord" + } + ] + } + }, + "logo": { + "light": "/public/logos/logo-docs-light.svg", + "dark": "/public/logos/logo-docs-dark.svg" + }, + "navbar": { + "links": [ + { + "label": "Superchain Faucet", + "href": "https://console.optimism.io/faucet" + } + ], + "primary": { + "type": "button", + "label": "Get Started", + "href": "https://docs.optimism.io/get-started/interop" + } + }, + "footer": { + "socials": { + "twitter": "https://twitter.com/Optimism", + "github": "https://github.com/ethereum-optimism", + "discord": "https://discord.gg/optimism" + } + } +} \ No newline at end of file diff --git a/favicon.svg b/favicon.svg new file mode 100644 index 000000000..5231c04a5 --- /dev/null +++ b/favicon.svg @@ -0,0 +1,6 @@ + + + + O + + \ No newline at end of file diff --git a/get-started/interop.mdx b/get-started/interop.mdx new file mode 100644 index 000000000..90395a6fb --- /dev/null +++ b/get-started/interop.mdx @@ -0,0 +1,69 @@ +--- +title: Superchain Interoperability +description: Learn the basics of interoperability and how to get started building cross-chain applications. +--- + +# Superchain Interoperability + +Superchain interoperability is the next major scalability improvement to the OP Stack which enables a network of chains, the Superchain, to feel like a single blockchain. This revolutionary approach unlocks 1-block latency and trust-minimized cross-chain composability. + +## What is Superchain Interoperability? + +Superchain interoperability enables: + +* **Native asset transfers**: ETH and ERC-20 tokens move securely between chains via native minting and burning +* **Cross-chain composability**: Smart contracts can compose with data across multiple chains +* **Horizontal scalability**: Applications can scale across multiple chains seamlessly + +## Key Benefits + + + + Eliminates liquidity fragmentation by enabling native asset transfers without wrapping or liquidity pools + + + + Users experience seamless cross-chain interactions without complex bridging processes + + + + Build applications that can leverage resources and data from multiple chains + + + + Horizontal scaling across multiple chains while maintaining security + + + +## Getting Started + + + + Understand how Superchain interoperability works by reading our [comprehensive explainer](/interop/explainer) + + + + Get hands-on experience with our [SuperchainERC20 starter kit](/interop/starter-kit) + + + + Learn about [cross-chain transaction costs](/interop/estimate-costs) and how to optimize them + + + + Start building with our [development tools and tutorials](/interop/tutorials) + + + +## Next Steps + +Ready to start building? Check out these resources: + +* [Superchain Interoperability Explainer](/interop/explainer) - Deep dive into the technical details +* [Compatible Tokens Guide](/interop/compatible-tokens) - Learn about SuperchainERC20 tokens +* [Development Tools](/interop/tools) - Discover tools for building cross-chain applications +* [Tutorials](/interop/tutorials) - Step-by-step guides for common use cases + + + Superchain interop is in active development. Some features may be experimental or subject to change. + diff --git a/get-started/op-stack.mdx b/get-started/op-stack.mdx new file mode 100644 index 000000000..1516fd567 --- /dev/null +++ b/get-started/op-stack.mdx @@ -0,0 +1,117 @@ +--- +title: Getting started with the OP Stack +description: Learn the basics of OP Stack development and how to build on Optimism. +--- + +# Getting Started with the OP Stack + +The OP Stack is the standardized, shared, and open-source development stack that powers Optimism and makes it easy to spin up your own production-ready Layer 2 blockchain. Whether you're building applications or deploying your own chain, the OP Stack provides the foundation you need. + +## What is the OP Stack? + +The OP Stack is a modular collection of software components that work together to create Layer 2 blockchains. It includes: + +* **Execution Layer**: Processes transactions and manages state +* **Consensus Layer**: Handles block production and validation +* **Data Availability**: Ensures transaction data is available +* **Settlement Layer**: Finalizes transactions on Ethereum + +## Choose Your Path + + + + Start building decentralized applications on existing OP Stack chains + + + + Launch your own OP Stack chain for your project or organization + + + + Operate infrastructure by running your own OP Stack node + + + + Help build the future of the OP Stack protocol + + + +## Development Options + + + + Build on **OP Mainnet** for production applications with real users and value. + + * Network: Production-ready Layer 2 + * Security: Secured by Ethereum mainnet + * Ecosystem: Full ecosystem of tools and services + + + + Use **OP Sepolia** for testing and development without real costs. + + * Network: Test environment + * Faucets: Free test ETH available + * Perfect for: Development and testing + + + + Run your own local OP Stack chain for rapid development and testing. + + * Tools: Supersim, Anvil, Hardhat + * Speed: Instant transactions + * Control: Full control over chain behavior + + + +## Quick Start Guide + + + + Install Node.js, your preferred IDE, and essential development tools + + + + Select from popular frameworks like Hardhat, Foundry, or Remix + + + + Use the [Superchain Faucet](https://console.optimism.io/faucet) to get test ETH + + + + Deploy a simple smart contract to get familiar with the process + + + + Learn about cross-chain messaging, account abstraction, and more + + + +## Key Features + +* **EVM Compatibility**: Full compatibility with Ethereum tooling and smart contracts +* **Low Fees**: Significantly lower transaction costs than Ethereum mainnet +* **Fast Finality**: Near-instant transaction confirmation +* **Ethereum Security**: Inherits security from Ethereum's consensus +* **Modular Design**: Customizable components for specific needs + +## Next Steps + + + + Understand the technical architecture of the OP Stack + + + + Discover tools and services for building on OP Stack + + + + Follow step-by-step tutorials for common use cases + + + + + The OP Stack is continuously evolving. Check our [roadmap and updates](/stack/protocol-specs) to stay current with new features and improvements. + diff --git a/get-started/superchain.mdx b/get-started/superchain.mdx new file mode 100644 index 000000000..a76c30ed2 --- /dev/null +++ b/get-started/superchain.mdx @@ -0,0 +1,154 @@ +--- +title: Superchain Overview +description: Learn about the Optimism Superchain, its components, features, and how to get started. +--- + +# Superchain Overview + +The Superchain is a network of OP Stack chains that share a unified bridging protocol, governance system, and development stack. It represents the next evolution of Layer 2 scaling, creating a cohesive ecosystem where chains can interoperate seamlessly. + +## What is the Superchain? + +The Superchain is more than just a collection of blockchains—it's a unified network that enables: + +* **Shared Security**: All chains inherit security from Ethereum +* **Native Interoperability**: Chains can communicate with minimal latency +* **Unified Governance**: Coordinated upgrades and standards +* **Developer Experience**: Consistent tooling across all chains + +## Superchain Components + + + + Individual Layer 2 blockchains built using the OP Stack framework + + + + Native cross-chain communication and asset transfers + + + + Coordinated decision-making across the network + + + + Common protocols and specifications for consistency + + + +## Current Superchain Networks + +The Superchain includes several production chains: + + + + The flagship Optimism chain with the largest ecosystem + + * **Focus**: General-purpose applications + * **Ecosystem**: DeFi, NFTs, gaming, and more + * **Network ID**: 10 + + + + Coinbase's Layer 2 focused on bringing billions onchain + + * **Focus**: Consumer applications and onchain economy + * **Backed by**: Coinbase + * **Network ID**: 8453 + + + + Creator-focused chain for NFTs and digital art + + * **Focus**: NFT creation and trading + * **Features**: Creator tools and monetization + * **Network ID**: 7777777 + + + + DeFi-focused chain with yield optimization + + * **Focus**: Decentralized finance + * **Features**: DeFi protocols and yield farming + * **Network ID**: 34443 + + + +## Benefits of Building on Superchain + + + + Tap into the combined liquidity and user base of all Superchain networks + + + + Build applications that work seamlessly across multiple chains + + + + Benefit from common tooling, standards, and best practices + + + + Have a voice in the future direction of the Superchain + + + +## Getting Started + +Choose your approach to building on the Superchain: + + + + Build applications on established Superchain networks + + + + Create a new OP Stack chain and join the Superchain + + + + Build applications that leverage multiple chains + + + + Help build the future of the Superchain + + + +## Key Features + +* **Unified Bridging**: Native asset transfers between chains +* **Shared Sequencing**: Coordinated block production (coming soon) +* **Fault Proof System**: Shared security and dispute resolution +* **Governance**: Collective decision-making via the Optimism Collective +* **Developer Tools**: Consistent tooling across all chains + +## Future Roadmap + +The Superchain is continuously evolving with exciting features on the horizon: + +* **Shared Sequencing**: Single sequencer for atomic cross-chain transactions +* **Proof Aggregation**: Efficient batch proving for multiple chains +* **Governance Improvements**: Enhanced coordination mechanisms +* **New Chain Types**: Specialized chains for specific use cases + +## Resources + + + + Find contract addresses and network information + + + + Browse all available Superchain networks + + + + Understand the security guarantees and assumptions + + + + + The Superchain is rapidly evolving. Some features may be experimental or subject to change as the network matures. + diff --git a/pages/index.mdx b/index.mdx similarity index 50% rename from pages/index.mdx rename to index.mdx index 4eadb7c38..55c4c06ac 100644 --- a/pages/index.mdx +++ b/index.mdx @@ -1,81 +1,80 @@ --- title: Welcome to the Optimism Docs -lang: en-US description: Learn about the Optimism Collective, the Optimism Docs, and how to get started building with Optimism. -content_type: landing-page -topic: welcome-to-optimism-docs -personas: - - app-developer - - node-operator - - chain-operator - - partner - - protocol-developer - - auditor - - governance-participant -categories: - - architecture - - infrastructure - - system-components - - superchain - - op-stack - - layer2-scaling - - system-design - - development-networks -is_imported_content: 'false' --- -import { Cards, Card } from 'nextra/components' +{/* Optimism Logo +Optimism Logo */} -# Welcome to the Optimism Docs - -Welcome to the Optimism Docs, the unified home of the [Optimism Collective's](/connect/resources/glossary#optimism-collective) technical documentation and information about the [OP Stack](/stack/getting-started). -Information about the Optimism Collective's governance, community, and mission can be found on the [Optimism Community Hub](https://community.optimism.io/docs/governance/?utm_source=op-docs&utm_medium=docs). - -## Grow your app with Superchain interoperability! +## Grow your app with Superchain interoperability! Superchain interoperability is the next major scalability improvement to the OP Stack which enables a network of chains, the Superchain, to feel like a single blockchain. Superchain interoperability unlocks 1-block latency, trust minimized cross-chain composability and enables ETH and ERC-20 tokens to move securely between chains via native minting and burning as well as smart contracts to compose with data across multiple chains. Superchain interop is in active development. [Learn how you can leverage Superchain interoperability to tap into Superchain network effects](/interop/get-started). - - - } /> - } /> - } /> - + + + Start building cross-chain applications on the Superchain + + + Get started with SuperchainERC20 token development + + + Learn how Superchain interoperability works + + ## Builder guides Whether you're a developer building an app on OP Mainnet, a node operator running an OP Mainnet node, or a chain operator launching your own OP Stack chain, you'll find everything you need to get started right here. - - } /> - - } /> - - } /> - - } /> - + + + Build applications on Optimism and the Superchain + + + Deploy and operate your own OP Stack chain + + + Run and maintain Optimism nodes + + + Create applications that work across multiple chains + + ## Featured tools Check out these amazing tools, so you can get building with Optimism. - - } /> - - } /> - - } /> - - } /> - - } /> - - } /> - - + + + Get testnet ETH for development + + + Local multi-chain development environment + + + Web-based development tools + + + Test networks for development + + + Development tools and resources + + + Calculate transaction fees and parameters + + ## About Optimism @@ -83,10 +82,14 @@ The OP Stack is the standardized, shared, and open-source development stack that The Superchain is a network of OP Stack chains that share a bridging protocol, governance system, and more. We've got you covered with these detailed guides to help you learn all about Optimism's tech stack. - - } /> - - } /> - - } /> - + + + Learn about the OP Stack architecture + + + Discover the Superchain network + + + Understand cross-chain interoperability + + diff --git a/pages/interop/compatible-tokens.mdx b/interop/compatible-tokens.mdx similarity index 95% rename from pages/interop/compatible-tokens.mdx rename to interop/compatible-tokens.mdx index c5c1fecba..8345d8680 100644 --- a/pages/interop/compatible-tokens.mdx +++ b/interop/compatible-tokens.mdx @@ -3,32 +3,13 @@ title: Superchain interop compatible tokens description: >- Learn how different tokens can use Superchain interop to benefit from secure, low-latency, cross-chain composability. -lang: en-US -content_type: guide -topic: superchain-interop-compatible-tokens -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain-erc20 - - token-standard - - interoperable-assets - - token-bridge - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - + The SuperchainERC20 standard is ready for production use with active Mainnet deployments. Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + # Superchain interop compatible tokens diff --git a/pages/interop/estimate-costs.mdx b/interop/estimate-costs.mdx similarity index 93% rename from pages/interop/estimate-costs.mdx rename to interop/estimate-costs.mdx index 39aa11a6b..de2e4a6ca 100644 --- a/pages/interop/estimate-costs.mdx +++ b/interop/estimate-costs.mdx @@ -1,34 +1,19 @@ --- title: Estimating the cost of interop messages description: Estimate the gas cost of Superchain interop messages. -lang: en-US -content_type: guide -topic: interop-gas-estimate -personas: - - protocol-developer - - app-developer -categories: - - interoperability - - cross-chain-messaging - - superchain - - message-passing - - gas-cost -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Estimating the cost of interop messages - + As of May 2025, the cost of 100 interop messages is just a few cents. Unless OP Stack transaction costs increase significantly, interop costs should not be a primary consideration in your implementation decisions. To see the current cost of gas, go to a [block explorer](https://optimism.blockscout.com/) and look at a recent transaction. - + There are several factors that determine the cost of an [interop transaction](/interop/message-passing): diff --git a/pages/interop/explainer.mdx b/interop/explainer.mdx similarity index 95% rename from pages/interop/explainer.mdx rename to interop/explainer.mdx index 28c2c08bb..9b5f3059e 100644 --- a/pages/interop/explainer.mdx +++ b/interop/explainer.mdx @@ -1,31 +1,11 @@ --- title: Superchain interoperability explainer description: Learn the basics of Superchain interoperability. -lang: en-US -content_type: guide -topic: superchain-interoperability-explainer -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain - - architecture - - message-passing - - block-safety - - dependency-set -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import Image from 'next/image' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Superchain interoperability diff --git a/pages/interop/get-started.mdx b/interop/get-started.mdx similarity index 94% rename from pages/interop/get-started.mdx rename to interop/get-started.mdx index f9a44183e..1171e0517 100644 --- a/pages/interop/get-started.mdx +++ b/interop/get-started.mdx @@ -3,28 +3,16 @@ title: Build interoperable apps on Superchain devnet description: >- Learn about deploying contracts, cross-chain messaging, and tutorials to help you build applications on the Superchain. -lang: en-US -content_type: guide -topic: build-interoperable-apps-on-superchain-devnet -personas: - - app-developer -categories: - - cross-chain-messaging - - interoperability - - standard-bridge - - testnet -is_imported_content: 'false' --- -import { Cards, Card, Callout } from 'nextra/components' # Build interoperable apps on Superchain devnet Reimagine your app with Superchain Interop to deliver the unified UX your users expect. Hack on net-new, bold use cases on Interop devnet. - + Explore the [Superchain Dev Console](https://console.optimism.io/?utm_source=op-docs\&utm_medium=docs) to build, launch, and grow your app on the Superchain. Join the [Superchain Dev Discord](https://guild.xyz/superchain-devs) for questions. - + ## Connect to Superchain Interop @@ -57,7 +45,7 @@ The SuperchainERC20 Starter Kit allows you to focus on what to deploy, not how t ## Handy step-by-step guides - + } /> } /> @@ -65,7 +53,7 @@ The SuperchainERC20 Starter Kit allows you to focus on what to deploy, not how t } /> } /> - + ## Discover and build net-new use cases with Superchain Interop diff --git a/pages/interop/interop-security.mdx b/interop/interop-security.mdx similarity index 95% rename from pages/interop/interop-security.mdx rename to interop/interop-security.mdx index e1dfac811..df57eb97b 100644 --- a/pages/interop/interop-security.mdx +++ b/interop/interop-security.mdx @@ -1,31 +1,11 @@ --- title: Crosschain security measures for safe interoperability description: Learn more about crosschain security measures for safe interoperability -lang: en-US -content_type: guide -topic: crosschain-security-measures-for-safe-interoperability -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - security - - block-safety - - message-passing - - reorgs - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import Image from 'next/image' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Crosschain security measures for safe interoperability @@ -153,9 +133,9 @@ Currently, this adds [about 15 minutes](https://ethereum.org/en/roadmap/single-s Safe and Unsafe Security Diagram - + Even if a sequencer accepts unsafe initiating messages, the blocks it constructs that rely on them are considered unsafe until the blocks with those initiating messages are written to L1 and become safe. - + {/* ## What is stopping a sequencer from censoring a cross-chain message? diff --git a/pages/interop/message-expiration.mdx b/interop/message-expiration.mdx similarity index 89% rename from pages/interop/message-expiration.mdx rename to interop/message-expiration.mdx index ed5cc1ac5..a8f4d2003 100644 --- a/pages/interop/message-expiration.mdx +++ b/interop/message-expiration.mdx @@ -1,23 +1,6 @@ --- title: Message expiration description: What message expiration is, why it exists, and how to reemit a previously sent message if it has expired and was never relayed. -lang: en-US -content_type: guide -topic: message-expiration -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - security - - block-safety - - message-passing - - reorgs - - superchain -is_imported_content: 'false' --- # Message expiration diff --git a/pages/interop/message-passing.mdx b/interop/message-passing.mdx similarity index 91% rename from pages/interop/message-passing.mdx rename to interop/message-passing.mdx index 7b51dbedf..97c5dfaad 100644 --- a/pages/interop/message-passing.mdx +++ b/interop/message-passing.mdx @@ -1,36 +1,18 @@ --- title: Interop message passing overview description: Learn about cross-chain message passing in the Superchain. -lang: en-US -content_type: guide -topic: interop-message-passing-overview -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - message-passing - - cross-domain-messenger - - architecture - - block-safety - - superchain -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Interop message passing overview - + This is an explanation of how interop works. You can find a step by step tutorial [here](/interop/tutorials/message-passing). - + The low-level [`CrossL2Inbox`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol) contract handles basic message execution. It verifies whether an initiating message exists but does not check the message's destination, processing status, or other attributes. diff --git a/pages/interop/op-supervisor.mdx b/interop/op-supervisor.mdx similarity index 90% rename from pages/interop/op-supervisor.mdx rename to interop/op-supervisor.mdx index 515830534..65a100e02 100644 --- a/pages/interop/op-supervisor.mdx +++ b/interop/op-supervisor.mdx @@ -1,28 +1,10 @@ --- title: OP-Supervisor description: Learn the basics of OP-Supervisor. -lang: en-US -content_type: guide -topic: op-supervisor -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - infrastructure - - architecture - - op-supervisor - - message-validation - - superchain -is_imported_content: 'false' --- -import { Callout, Tabs, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # OP-Supervisor diff --git a/pages/interop/predeploy.mdx b/interop/predeploy.mdx similarity index 90% rename from pages/interop/predeploy.mdx rename to interop/predeploy.mdx index fdcbcb596..afc086fce 100644 --- a/pages/interop/predeploy.mdx +++ b/interop/predeploy.mdx @@ -1,30 +1,11 @@ --- title: Interoperability predeploys description: Learn how interoperability predeploys work. -lang: en-US -content_type: guide -topic: interoperability-predeploys -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - predeploys - - smart-contracts - - cross-domain-messenger - - superchain-token-bridge - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import Image from 'next/image' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Interoperability predeploys diff --git a/pages/interop/reading-logs.mdx b/interop/reading-logs.mdx similarity index 97% rename from pages/interop/reading-logs.mdx rename to interop/reading-logs.mdx index abfdfe851..db977d049 100644 --- a/pages/interop/reading-logs.mdx +++ b/interop/reading-logs.mdx @@ -1,17 +1,10 @@ --- title: Reading Logs with Superchain Interop -lang: en-US description: Learn how to reference logs from one chain on another within the Superchain. -topic: Cross-Chain Log Verification -personas: [ "Developer" ] -categories: [ "Documentation", "Interop" ] -content_type: documentation --- -import { Callout } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Reading Logs with Superchain Interop @@ -27,9 +20,9 @@ This enables developers to: * Build cross-chain applications that react to events happening across the Superchain. * Create novel applications that leverage data from multiple chains. - + When reading logs, you must reference logs created within the [expiry window of 7 days](/interop/message-expiration). - + ## Why use `CrossL2Inbox`? diff --git a/pages/interop/reorg.mdx b/interop/reorg.mdx similarity index 95% rename from pages/interop/reorg.mdx rename to interop/reorg.mdx index ba94642d2..198cb253f 100644 --- a/pages/interop/reorg.mdx +++ b/interop/reorg.mdx @@ -3,29 +3,11 @@ title: Interop reorg awareness description: >- How Superchain interop enables low-latency interop and avoids the double-spend problem. -lang: en-US -content_type: guide -topic: interop-reorg-awareness -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - reorgs - - block-safety - - security - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import Image from 'next/image' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Interop reorg awareness diff --git a/pages/interop/starter-kit.mdx b/interop/starter-kit.mdx similarity index 95% rename from pages/interop/starter-kit.mdx rename to interop/starter-kit.mdx index 5db0eddeb..a3d169266 100644 --- a/pages/interop/starter-kit.mdx +++ b/interop/starter-kit.mdx @@ -3,27 +3,13 @@ title: Deploying a SuperchainERC20 (Starter Kit) description: >- Learn how to quickly build and deploy a SuperchainERC20 token across the Superchain using the SuperchainERC20 Starter Kit. -lang: en-US -content_type: guide -topic: deploying-a-superchainerc20-starter-kit -personas: - - app-developer -categories: - - cross-chain-messaging - - standard-bridge - - mainnet - - superchain-erc20 -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import Image from 'next/image' -import { Tabs } from 'nextra/components' - + The SuperchainERC20 standard is ready for production use with active Mainnet deployments. Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + # Deploying a SuperchainERC20 (Starter Kit) @@ -136,9 +122,9 @@ Here's a breakdown of what's under the hood: * Before proceeding, ensure that your `deploy-config.toml` file is fully configured (see the [Modify Deploy Config Parameters](#modify-deploy-config-parameters) section setup details). * Also, confirm that the `[rpc_endpoints]` section in `foundry.toml` is properly set up by following the instructions in [Configure RPC urls](#configure-rpc-urls). - + Deployments are executed through the `SuperchainERC20Deployer.s.sol` script. This script deploys tokens across each specified chain in the deployment configuration using `Create2`, ensuring deterministic contract addresses for each deployment. The script targets the `L2NativeSuperchainERC20.sol` contract by default. If you need to modify the token being deployed, either update this file directly or point the script to a custom token contract of your choice. - + * To execute a token deployment run: diff --git a/pages/interop/superchain-erc20.mdx b/interop/superchain-erc20.mdx similarity index 93% rename from pages/interop/superchain-erc20.mdx rename to interop/superchain-erc20.mdx index d40513e31..ae17518ed 100644 --- a/pages/interop/superchain-erc20.mdx +++ b/interop/superchain-erc20.mdx @@ -1,44 +1,26 @@ --- title: SuperchainERC20 description: Learn about the basic details of the SuperchainERC20 implementation. -lang: en-US -content_type: guide -topic: superchainerc20 -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain-erc20 - - token-standard - - interoperable-assets - - token-bridge - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' - + The SuperchainERC20 standard is ready for production deployments. Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + - + SuperchainERC20s can be deployed on any chain, but will only be interoperable within the [Superchain interop cluster](/interop/explainer#superchain-interop-cluster). - + # SuperchainERC20 - + This tutorial provides a behind the scenes explanation of how `SuperchainERC20` tokens are transferred. * [See the tutorial](tutorials/transfer-superchainERC20) for how your application can transfer `SuperchainERC20` tokens. * For a sample UI that bridges a `SuperchainERC20` token, [see here](https://interop-alpha-app.superchain.tools/). - + The [`SuperchainERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol) contract implements [ERC-7802](https://ethereum-magicians.org/t/erc-7802-crosschain-token-interface/21508) to enable asset interoperability within the Superchain. @@ -130,11 +112,11 @@ Setting this up in advance ensures tokens will benefit from interop when it beco * Deploy the `SuperchainERC20` at the same address on every chain in the Superchain where you want your token to be available. If you do not deploy the contract to a specific destination chain, users will be unable to successfully move their tokens to that chain. - + To ensure security, you must either design the deployer to allow only a specific trusted ERC-20 contract, such as `SuperchainERC20`, to be deployed through it, or call `CREATE2` to deploy the contract directly from an EOA you control. This precaution is critical because if an unauthorized ERC-20 contract is deployed at the same address on any Superchain network, it could allow malicious actors to mint unlimited tokens and bridge them to the network where the original ERC-20 contract resides. - + diff --git a/pages/interop/superchain-eth-bridge.mdx b/interop/superchain-eth-bridge.mdx similarity index 94% rename from pages/interop/superchain-eth-bridge.mdx rename to interop/superchain-eth-bridge.mdx index 4ef057ab2..10128eec2 100644 --- a/pages/interop/superchain-eth-bridge.mdx +++ b/interop/superchain-eth-bridge.mdx @@ -1,36 +1,18 @@ --- title: Superchain ETH Bridge description: Learn basic details about Interoperable ETH. -lang: en-US -content_type: guide -topic: superchain-eth-bridge -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain-eth-bridge - - eth-bridging - - interoperable-assets - - cross-domain-messenger - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Superchain ETH Bridge - + This is an explanation of how interop ETH works. You can find a step by step tutorial [here](tutorials/bridge-crosschain-eth). - + InteroperableETH enables seamless ETH transfers across Superchain blockchains. It is implemented using three key contracts: diff --git a/pages/interop/tools/devnet.mdx b/interop/tools/devnet.mdx similarity index 89% rename from pages/interop/tools/devnet.mdx rename to interop/tools/devnet.mdx index 3c6f4a28e..d25f0056d 100644 --- a/pages/interop/tools/devnet.mdx +++ b/interop/tools/devnet.mdx @@ -1,34 +1,18 @@ --- title: Superchain interop devnet description: Details on the public Superchain interoperability devnet -lang: en-US -content_type: guide -topic: interop-devnet -personas: - - protocol-developer - - app-developer -categories: - - testnet - - protocol - - interoperability - - cross-chain-messaging - - devnet - - standard-bridge - - superchain-registry -is_imported_content: 'false' --- -import { Callout, Tabs, Steps } from 'nextra/components' # Superchain interop devnet - + NOTE: The current Interop devnet has been deprecated. This page will be updated once the next Interop devnet is live. - + - + Superchain interop devnet is currently in active development and may experience periods of instability, including potential outages, as the networks are regularly updated and improved. Developers should expect some level of unreliability when interacting with the devnet. The devnet is intended for testing and development purposes only, and should not be relied upon for mission-critical applications. - + The Superchain interop devnet is a temporary public network of two OP Stack Sepolia instances that support Superchain interop enabling native ETH and SuperchainERC20 cross-chain token transfers. As we iterate on Superchain interop, these networks will be deprecated once the next devnets are released. diff --git a/interop/tools/supersim.mdx b/interop/tools/supersim.mdx new file mode 100644 index 000000000..0815a0d30 --- /dev/null +++ b/interop/tools/supersim.mdx @@ -0,0 +1,9 @@ +--- +title: Supersim +description: >- + Learn how to use the Supersim local dev environment tool designed to simulate + the Optimism Superchain. +--- + + + diff --git a/pages/interop/tutorials/bridge-crosschain-eth.mdx b/interop/tutorials/bridge-crosschain-eth.mdx similarity index 94% rename from pages/interop/tutorials/bridge-crosschain-eth.mdx rename to interop/tutorials/bridge-crosschain-eth.mdx index 0c9e9cd69..2cc1800e4 100644 --- a/pages/interop/tutorials/bridge-crosschain-eth.mdx +++ b/interop/tutorials/bridge-crosschain-eth.mdx @@ -1,37 +1,18 @@ --- title: Transferring ETH description: Learn how to transfer ETH across the Superchain interop cluster -lang: en-US -content_type: tutorial -topic: bridging-native-cross-chain-eth-transfers -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - standard-bridge - - eth-bridging - - message-relaying - - cross-domain-messenger - - superchain -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' -import { AutorelayCallout } from '@/components/AutorelayCallout' - +Superchain interop is in active development. Some features may be experimental. # Transferring ETH - + This tutorial provides step-by-step instructions for how to send ETH from one chain in the Superchain interop cluster to another. For a conceptual overview, see the [interoperable ETH explainer](/interop/superchain-eth-bridge). - + ## Overview @@ -180,7 +161,7 @@ The tutorial uses these primary tools: ### Create the TypeScript project - + Messages are relayed automatically in the interop devnet. To create an executing message on the destination chain we use [the `@eth-optimism/viem` package](https://www.npmjs.com/package/@eth-optimism/viem). For that we need TypeScript code. diff --git a/pages/interop/tutorials/contract-calls.mdx b/interop/tutorials/contract-calls.mdx similarity index 94% rename from pages/interop/tutorials/contract-calls.mdx rename to interop/tutorials/contract-calls.mdx index 8e721130d..a27af300e 100644 --- a/pages/interop/tutorials/contract-calls.mdx +++ b/interop/tutorials/contract-calls.mdx @@ -1,25 +1,10 @@ --- title: Making crosschain contract calls (ping pong) description: Learn how to make crosschain contract calls using ping pong. -lang: en-US -content_type: tutorial -topic: making-crosschain-contract-calls-ping-pong -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Making crosschain contract calls (ping pong) diff --git a/pages/interop/tutorials/custom-superchain-erc20.mdx b/interop/tutorials/custom-superchain-erc20.mdx similarity index 96% rename from pages/interop/tutorials/custom-superchain-erc20.mdx rename to interop/tutorials/custom-superchain-erc20.mdx index 994f47df4..a09064751 100644 --- a/pages/interop/tutorials/custom-superchain-erc20.mdx +++ b/interop/tutorials/custom-superchain-erc20.mdx @@ -1,29 +1,13 @@ --- title: Custom SuperchainERC20 tokens description: Create SuperchainERC20 tokens with custom behaviors -lang: en-US -content_type: tutorial -topic: custom-superchainerc20-tokens -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain-erc20 - - token-standard - - superchain -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' - + The SuperchainERC20 standard is ready for production deployments. Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + # Custom SuperchainERC20 tokens diff --git a/pages/interop/tutorials/deploy-superchain-erc20.mdx b/interop/tutorials/deploy-superchain-erc20.mdx similarity index 94% rename from pages/interop/tutorials/deploy-superchain-erc20.mdx rename to interop/tutorials/deploy-superchain-erc20.mdx index e7d031631..193fe7fee 100644 --- a/pages/interop/tutorials/deploy-superchain-erc20.mdx +++ b/interop/tutorials/deploy-superchain-erc20.mdx @@ -1,32 +1,13 @@ --- title: Deploying a SuperchainERC20 description: Learn about the basic details of deploying assets on SuperchainERC20 -lang: en-US -content_type: tutorial -topic: deploying-a-superchainerc20 -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - interoperable-assets - - interoperability - - cross-chain-messaging - - superchain-erc20 - - token-standard - - token-deployment - - smart-contracts - - superchain -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { Steps } from 'nextra/components' - + The SuperchainERC20 standard is ready for production deployments. However, the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + # Deploying a SuperchainERC20 diff --git a/pages/interop/tutorials/event-contests.mdx b/interop/tutorials/event-contests.mdx similarity index 94% rename from pages/interop/tutorials/event-contests.mdx rename to interop/tutorials/event-contests.mdx index a408a332a..f89f86849 100644 --- a/pages/interop/tutorials/event-contests.mdx +++ b/interop/tutorials/event-contests.mdx @@ -1,34 +1,18 @@ --- title: Deploying crosschain event composability (contests) description: Learn how to deploy crosschain event composability using contests. -lang: en-US -content_type: tutorial -topic: deploying-crosschain-event-composability-contests -personas: - - protocol-developer - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - event-reading - - contests - - superchain -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Deploying crosschain event composability (contests) We showcase cross chain composability through the implementation of contests. Leveraging the same underlying mechanism powering [TicTacToe](event-reads), these contests can permissionlessly integrate with the events emitted by any contract in the Superchain. - + See the [frontend documentation](https://github.com/ethereum-optimism/supersim/tree/main/examples/contests) for how the contests UI is presented to the user. - + ## How it works diff --git a/pages/interop/tutorials/event-reads.mdx b/interop/tutorials/event-reads.mdx similarity index 95% rename from pages/interop/tutorials/event-reads.mdx rename to interop/tutorials/event-reads.mdx index fd00dcf4d..b103efbbb 100644 --- a/pages/interop/tutorials/event-reads.mdx +++ b/interop/tutorials/event-reads.mdx @@ -1,34 +1,18 @@ --- title: Making cross-chain event reads (tic-tac-toe) description: Learn how to make cross-chain event reads using tic-tac-toe. -lang: en-US -content_type: tutorial -topic: making-crosschain-event-reads-tic-tac-toe -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - event-reading - - superchain -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Making cross-chain event reads (tic-tac-toe) This guide reviews a horizontally scalable implementation of TicTacToe. This [implementation](https://github.com/ethereum-optimism/supersim/blob/main/contracts/src/tictactoe/TicTacToe.sol) allows players to play each other from any chain without cross-chain calls, instead relying on cross-chain event reading. Since superchain interop can allow for event reading with a 1-block latency, the experience is the **same as a single-chain implementation**. - + Check out the [frontend documentation](https://github.com/ethereum-optimism/supersim/tree/main/examples/tictactoe) to see how the game UI is presented to the player. - + ## How it works diff --git a/pages/interop/tutorials/message-passing.mdx b/interop/tutorials/message-passing.mdx similarity index 96% rename from pages/interop/tutorials/message-passing.mdx rename to interop/tutorials/message-passing.mdx index 128cdfeb9..96f8927d6 100644 --- a/pages/interop/tutorials/message-passing.mdx +++ b/interop/tutorials/message-passing.mdx @@ -3,29 +3,10 @@ title: Interop message passing tutorial description: >- Learn to implement cross-chain communication in the Superchain by building a message passing system using the L2ToL2CrossDomainMessenger contract. -lang: en-US -content_type: tutorial -topic: interop-message-passing-tutorial -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - message-relaying - - cross-domain-messenger - - smart-contracts - - testnet - - superchain -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' - +Superchain interop is in active development. Some features may be experimental. # Interop message passing tutorial @@ -73,11 +54,11 @@ message passing system that enables different chains to interact with each other * A `GreetingSender` contract that sends cross-chain messages to update the greeting * A TypeScript application to relay messages between chains - + This tutorial provides step-by-step instructions for implementing cross-chain messaging. For a conceptual overview, see the [Message Passing Explainer](/interop/message-passing). - + In this tutorial, you will learn how to use the [`L2ToL2CrossDomainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/L2ToL2CrossDomainMessenger.sol) contract to pass messages between interoperable blockchains. diff --git a/pages/interop/tutorials/message-passing/manual-relay.mdx b/interop/tutorials/message-passing/manual-relay.mdx similarity index 95% rename from pages/interop/tutorials/message-passing/manual-relay.mdx rename to interop/tutorials/message-passing/manual-relay.mdx index 09e8735ce..84e4d886d 100644 --- a/pages/interop/tutorials/message-passing/manual-relay.mdx +++ b/interop/tutorials/message-passing/manual-relay.mdx @@ -2,34 +2,14 @@ title: Relay transactions manually description: >- Learn to relay transactions directly by sending the correct transaction. -lang: en-US -content_type: tutorial -topic: interop-cast-manual-relay-tutorial -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - message-relaying - - cross-domain-messenger - - smart-contracts - - testnet - - superchain -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { InteropCallout } from '@/components/WipCallout' -import { AutorelayCallout } from '@/components/AutorelayCallout' # Relay transactions manually - +Superchain interop is in active development. Some features may be experimental. - +Messages are relayed automatically in the interop devnet. ## Overview diff --git a/pages/interop/tutorials/transfer-superchainERC20.mdx b/interop/tutorials/transfer-superchainERC20.mdx similarity index 93% rename from pages/interop/tutorials/transfer-superchainERC20.mdx rename to interop/tutorials/transfer-superchainERC20.mdx index 81c6dd05b..432212b46 100644 --- a/pages/interop/tutorials/transfer-superchainERC20.mdx +++ b/interop/tutorials/transfer-superchainERC20.mdx @@ -3,31 +3,13 @@ title: Transferring a SuperchainERC20 description: >- Learn how to transfer a SuperchainERC20 between chains using L2ToL2CrossDomainMessenger. -lang: en-US -content_type: tutorial -topic: transferring-a-superchainerc20 -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - superchain-erc20 - - token-transfers - - message-relaying - - superchain -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' -import { AutorelayCallout } from '@/components/AutorelayCallout' - + The SuperchainERC20 standard is ready for production deployments. Please note that the OP Stack interoperability upgrade, required for crosschain messaging, is currently still in active development. - + # Transferring SuperchainERC20 tokens @@ -40,10 +22,10 @@ Note that this tutorial provides step-by-step instructions for transferring `Sup ## Overview - + Always verify your addresses and amounts before sending transactions. Cross-chain transfers cannot be reversed. - +
About this tutorial diff --git a/pages/interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx b/interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx similarity index 98% rename from pages/interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx rename to interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx index 4262d38d6..b5e746a6f 100644 --- a/pages/interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx +++ b/interop/tutorials/upgrade-to-superchain-erc20/custom-bridge.mdx @@ -1,14 +1,8 @@ --- title: Building a custom bridge -lang: en-US description: Tutorial on how to create a custom interoperability bridge. The example is a bridge when the addresses of the ERC20 contracts are not the same. -topic: Interoperability -personas: [Developer] -categories: [Tutorial, Interop] -content_type: article --- -import { Steps, Callout, Tabs } from 'nextra/components' # Building a custom bridge @@ -31,12 +25,12 @@ However, if the original ERC20 contract is behind a proxy (so we can add [ERC780 * How to [transfer interop messages](/interop/tutorials/message-passing).
- + The code on the documentation site is sample code, *not* production code. This means that we ran it, and it works as advertised. However, it did not pass through the rigorous audit process that most Optimism code undergoes. You're welcome to use it, but if you need it for production purposes you should get it audited first. - + {/* @@ -87,13 +81,13 @@ Some steps depend on whether you want to deploy on [Supersim](/interop/tools/sup If you are going to use Supersim, [follow these instructions](/app-developers/tutorials/supersim/getting-started/installation) to install and run Supersim. - + Make sure to run Supersim with autorelay on. ```sh ./supersim --interop.autorelay true ``` - + ### Set up the ERC20 token on chain A diff --git a/pages/interop/tutorials/verify-messages.mdx b/interop/tutorials/verify-messages.mdx similarity index 97% rename from pages/interop/tutorials/verify-messages.mdx rename to interop/tutorials/verify-messages.mdx index ccd773307..91fc499f5 100644 --- a/pages/interop/tutorials/verify-messages.mdx +++ b/interop/tutorials/verify-messages.mdx @@ -2,23 +2,8 @@ title: Verifying log entries description: >- Learn how to verify log entries on a different chain using CrossL2Inbox. -lang: en-US -content_type: tutorial -topic: verify-message -personas: - - protocol-developer - - chain-operator - - app-developer -categories: - - protocol - - interoperability - - cross-chain-messaging - - message-relaying - - superchain -is_imported_content: 'false' --- -import { Callout, Steps, Tabs } from 'nextra/components' # Verifying log entries @@ -27,9 +12,9 @@ This lets developers use interoperability with applications on a different chain To demonstrate this functionality, this guide uses an [attestation](https://attest.org/) from one chain on another. - + Because of [message expiration](/interop/message-expiration), this solution can only validate log messages emitted in the last seven days (on the Superchain, other interop clusters may vary). - + ## Overview diff --git a/lib/growthbook.ts b/lib/growthbook.ts deleted file mode 100644 index 7df2b35da..000000000 --- a/lib/growthbook.ts +++ /dev/null @@ -1,11 +0,0 @@ -// lib/growthbook.ts -import { GrowthBook } from '@growthbook/growthbook-react'; - -export const growthbook = new GrowthBook({ - apiHost: process.env.NEXT_PUBLIC_GROWTHBOOK_API_HOST || '', - clientKey: process.env.NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY || '' -}); - -if (process.env.NEXT_PUBLIC_GROWTHBOOK_API_HOST && process.env.NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY) { - growthbook.init(); -} diff --git a/logo/dark.svg b/logo/dark.svg new file mode 100644 index 000000000..ee10a4a3a --- /dev/null +++ b/logo/dark.svg @@ -0,0 +1,5 @@ + + + Optimism + + \ No newline at end of file diff --git a/logo/light.svg b/logo/light.svg new file mode 100644 index 000000000..ec6799db1 --- /dev/null +++ b/logo/light.svg @@ -0,0 +1,5 @@ + + + Optimism + + \ No newline at end of file diff --git a/lychee.toml b/lychee.toml deleted file mode 100644 index 0ad13b998..000000000 --- a/lychee.toml +++ /dev/null @@ -1,56 +0,0 @@ -############################# Display ############################# -# Use error level to only show failed requests -verbose = "error" -# Don't show interactive progress bar while checking links. -no_progress = true -# Don't show the source file of links -no_show_source = false - -############################# Requests ############################ -# URL remapping rules. -remap = [ - # Handle resource files without adding .mdx extension - "file:///pages/(.*?)\\.(pdf|png|jpg|jpeg|gif|svg|json)$ file:///./pages/$1.$2", - # Handle URL-encoded anchors (%23) for mdx files - "file:///([^%\\.]+)%23(.*) file:///./pages/$1.mdx#$2", - # Handle regular anchors (#) for mdx files - "file:///([^#\\.]+)#(.*) file:///./pages/$1.mdx#$2", - # Handle regular mdx files without anchors - "file:///([^#%\\.]+)$ file:///./pages/$1.mdx", -] - -# Base URL or website root directory to check relative URLs -base = "." - -############################# Exclusions ########################## -# Exclude loopback IP address range and localhost from checking. -exclude_loopback = true -# Exclude all mail addresses from checking. -exclude_mail = true -# Exclude RPC URLs from checking -exclude = [ - 'https://mainnet.optimism.io', - 'https://mainnet-sequencer.optimism.io', - 'https://sepolia.optimism.io', - 'https://sepolia-sequencer.optimism.io', - 'https://archive.org', - 'https://web.archive.org', - 'https://mainnet.base.org', - 'https://sepolia.base.org', - 'https://optimism.easscan.org', - '\.(pdf|zip|png|jpg|jpeg|gif|svg|json)$' -] - -# Accept all status codes except 404 -accept = [ - "100..=399", - "401..=403", - "405..=999" -] - -# Use compact format for cleaner output -format = "compact" - -############################# Anchors ############################# -# Enable checking for anchors in local files -check_anchors = true \ No newline at end of file diff --git a/netlify.toml b/netlify.toml index 1b26ae741..6b4ea3694 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,7 +1,11 @@ [build] - command = "pnpm install --no-frozen-lockfile && pnpm build" - publish = ".next" + command = "echo 'No build needed for Mintlify'" + publish = "." [build.environment] - NODE_VERSION = "20.11.0" - NPM_FLAGS = "--no-frozen-lockfile" \ No newline at end of file + NODE_VERSION = "20" + +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 \ No newline at end of file diff --git a/next-env.d.ts b/next-env.d.ts deleted file mode 100644 index a4a7b3f5c..000000000 --- a/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/next-sitemap.config.js b/next-sitemap.config.js deleted file mode 100644 index 6f7627d0c..000000000 --- a/next-sitemap.config.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import('next-sitemap').IConfig} */ -module.exports = { - siteUrl: process.env.SITE_URL || 'https://docs.optimism.io/', - generateRobotsTxt: true, // (optional) - generateIndexSitemap: true, - // ...other options -} diff --git a/next.config.mjs b/next.config.mjs deleted file mode 100644 index 0bbf778c3..000000000 --- a/next.config.mjs +++ /dev/null @@ -1,49 +0,0 @@ -import nextra from 'nextra' -import remarkCodeImport from 'remark-code-import' - -const withNextra = nextra({ - theme: 'nextra-theme-docs', - themeConfig: './theme.config.tsx', - defaultShowCopyCode: true, - mdxOptions: { - remarkPlugins: [ - remarkCodeImport, - ] - }, -}) - -export default { - ...withNextra(), - eslint: { - ignoreDuringBuilds: true, - }, - - async headers() { - return [ - { - source: '/:path*', - headers: [ - { - key: 'X-DNS-Prefetch-Control', - value: 'on' - }, - { - key: 'Strict-Transport-Security', - value: 'max-age=31536000; includeSubDomains; preload' - }, - { - key: 'X-Content-Type-Options', - value: 'nosniff' - }, - { - key: 'X-Frame-Options', - value: 'DENY' - } - ], - }, - ] - }, - - // Don't put redirects here - // they go in public/_redirects -} diff --git a/pages/notices/blob-fee-bug.mdx b/notices/blob-fee-bug.mdx similarity index 95% rename from pages/notices/blob-fee-bug.mdx rename to notices/blob-fee-bug.mdx index 645ec7dec..c0d459539 100644 --- a/pages/notices/blob-fee-bug.mdx +++ b/notices/blob-fee-bug.mdx @@ -1,21 +1,8 @@ --- title: Superchain testnets' blob fee bug description: Learn about the blob fee bug that effects OP Stack testnets on the Superchain and how to fix it. -lang: en-US -content_type: guide -topic: l1-cost-blob-schedule-bug -personas: - - chain-operator - - node-operator -categories: - - security - - protocol - - infrastructure -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' -import Image from 'next/image' # Superchain testnets' blob fee bug @@ -60,9 +47,9 @@ The following chains are in the Superchain Registry and are not opted into the h ### Update to the latest release - + You must configure your op-node to utilize the activation timestamp outlined in step 2 at the same time as upgrading your node binary. This is to ensure that the hardfork is activated uniformly across the network. If the Pectra Blob Schedule flag is not set, your node will either not start or automatically apply the hardfork at startup causing the node to fork from the rest of the network. - + The following `op-node/v1.12.2` adds a kill-switch to op-node to print an error at startup if the Pectra Blob Schedule Fix time is not set for a Sepolia or Holesky chain. The check only happens if the chain's genesis is before the Holesky/Sepolia Pectra activation time. The check can be disabled with a hidden flag. @@ -75,11 +62,11 @@ The following chains are in the Superchain Registry and are not opted into the h ### Update the hardfork activation time - + If you are operating a node for an OP Chain that has opted into the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md), the Pectra Blob Schedule Fix activation date is part of the op-node node. So, no action is needed for the sequencer after upgrading to the latest release, assuming you're using the network flags. That is: `OP Sepolia`, `Soneium Minato`, `Zora Sepolia`, `Unichain Sepolia`, `Base Sepolia`, `Mode Sepolia`, `Metal Sepolia`, `Creator Chain Sepolia`, `Ink Sepolia`, and `Ethernity Sepolia`. - + For chains that are not opted into the hardfork activation inheritance behavior, you will need to manually set the hardfork activation time. This can be done one of two ways: diff --git a/pages/notices/custom-gas-tokens-deprecation.mdx b/notices/custom-gas-tokens-deprecation.mdx similarity index 96% rename from pages/notices/custom-gas-tokens-deprecation.mdx rename to notices/custom-gas-tokens-deprecation.mdx index 0f8fb839e..bb528c667 100644 --- a/pages/notices/custom-gas-tokens-deprecation.mdx +++ b/notices/custom-gas-tokens-deprecation.mdx @@ -3,16 +3,6 @@ title: Preparing for custom gas tokens deprecation description: >- This page outlines the details of the Custom Gas Tokens deprecation and points towards alternatives -lang: en-US -content_type: guide -topic: custom-gas-tokens-deprecation -personas: - - app-developer - - chain-operator -categories: - - security - - automated-pause -is_imported_content: 'false' --- ## Deprecation of Custom Gas Tokens diff --git a/pages/notices/holocene-changes.mdx b/notices/holocene-changes.mdx similarity index 95% rename from pages/notices/holocene-changes.mdx rename to notices/holocene-changes.mdx index 30e67ede1..7c5db6ae5 100644 --- a/pages/notices/holocene-changes.mdx +++ b/notices/holocene-changes.mdx @@ -1,28 +1,15 @@ --- title: Preparing for Holocene breaking changes description: Learn how to prepare for Holocene upgrade breaking changes. -lang: en-US -content_type: guide -topic: holocene-changes -personas: - - chain-operator - - node-operator -categories: - - security - - automated-pause - - protocol - - infrastructure -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Preparing for Holocene breaking changes This page outlines breaking changes related to the Holocene network upgrade for chain operators, and node operators. If you experience difficulty at any stage of this process, please reach out to [developer support](https://github.com/ethereum-optimism/developers/discussions). - + The Holocene upgrade for the Sepolia Superchain will be activated at **Tue Nov 26 at 15:00:00 UTC** (`1732633200`). The Holocene upgrade for the Unichain Sepolia will be activated at **Wed Dec 18 at 22:00:00 UTC** (`1734559200`). @@ -32,7 +19,7 @@ If you experience difficulty at any stage of this process, please reach out to [ The Holocene upgrade for the Mainnet Superchain is scheduled for **Thu 9 Jan 2025 18:00:01 UTC**, [governance approval](https://vote.optimism.io/proposals/20127877429053636874064552098716749508236019236440427814457915785398876262515). The Holocene upgrade for the Soneium Mainnet will be activated at **Mon Feb 03 at 09:00:00 UTC** (`1738573200`). - + ## What's included in Holocene @@ -82,11 +69,11 @@ These following steps are necessary for every node operator: ### Configure the Holocene activation date - + If you are operating a node for an OP Chain that has opted into the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md), the Holocene activation date is part of the `op-node` and `op-geth` nodes. So, no action is needed for the sequencer after upgrading to the latest release. Please skip to [Step 3: Verify Your Configuration](#verify-your-configuration). For Sepolia that is: `OP Sepolia`, `Base Sepolia`, `Mode Sepolia`, `Zora Sepolia`, and `Metal Sepolia`. - + For node operators of not included in the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md), you will need to manually configure the activation. This can be done one of two ways: diff --git a/pages/notices/pectra-changes.mdx b/notices/pectra-changes.mdx similarity index 96% rename from pages/notices/pectra-changes.mdx rename to notices/pectra-changes.mdx index bdf2fd0b1..0b7ebffa4 100644 --- a/pages/notices/pectra-changes.mdx +++ b/notices/pectra-changes.mdx @@ -1,25 +1,12 @@ --- title: Preparing for Pectra breaking changes description: Learn how to prepare for Pectra upgrade breaking changes. -lang: en-US -content_type: guide -topic: pectra-changes -personas: - - chain-operator - - node-operator -categories: - - security - - automated-pause - - protocol - - infrastructure -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Preparing for Pectra breaking changes - + Please note that this notice page was updated March 11th, 2025. There was a bug found in previous op-node releases where the L1 Block's blob base fee (for the sake of computing the L1 fees) is calculated with pre-Prague=Cancun blob schedule parameters, instead of using the Prague parameters. This bug has been fixed in the latest release of op-node. This is not a critical issue on any OP Sepolia chain. However, when L1 blob base fees rise to 100 Mwei or higher on Sepolia, there is a temporary liveness risk, because we'd be overcharge L1 fees. Essentially, our L1 cost computation now overcharges by an exponential of 1.5, BBF\_Cancun = `BBF_Prague^1.5` (where BBF=blob base fee). @@ -27,7 +14,7 @@ import { Steps, Callout } from 'nextra/components' You must update your Sepolia nodes to the latest release of op-node and schedule a hardfork activation time to avoid this issue on your network. There are new instructions in the node operator section to help you mitigate this issue. See this notice page for more information: [Superchain testnets' blob fee bug](/notices/blob-fee-bug). - + This page outlines breaking changes related to the Ethereum Pectra (Prague-Electra) hard fork for chain operators and node operators on OP Stack chains. The OP Stack is dividing the Pectra upgrade into two parts: @@ -36,7 +23,7 @@ This page outlines breaking changes related to the Ethereum Pectra (Prague-Elect If you experience difficulty at any stage of this process, please reach out to [developer support](https://github.com/ethereum-optimism/developers/discussions). - + This page will be updated continuously with information on upgrade runbooks and timelines as they come. Here's the tentative L1 Pectra hard fork times per the ACDC that happened on Feb 6th: L1 Client testnet releases out by Feb 13 (ACDE): @@ -44,7 +31,7 @@ If you experience difficulty at any stage of this process, please reach out to [ * Holesky slot: `1740434112` (Mon, Feb 24 at 21:55:12 UTC) * Sepolia slot: `1741159776` (Wed, Mar 5 at 07:29:36 UTC) * +30 day mainnet slot: `1744154711` (Tue, Apr 8 at 23:25:11 UTC) - + ## What's included in Pectra? @@ -68,17 +55,17 @@ Node operators will need to upgrade to the respective releases before the activa ### Update to the latest release - + Full node operators, meaning those who are running op-geth with `gc-mode=full`, will need to reference the [`op-geth v1.101411.8`release notes](https://github.com/ethereum-optimism/op-geth/releases/tag/v1.101411.8) to handle an intermediate upgrade step before upgrading to the latest release. Archive node operators, `gc-mode=archive`, can skip this step and upgrade directly to the latest release. - + * `op-node` at [`v1.12.0`](https://github.com/ethereum-optimism/optimism/releases/tag/op-node%2Fv1.12.0) * `op-geth` at [`v1.101503.0`](https://github.com/ethereum-optimism/op-geth/releases/tag/v1.101503.0) * `op-reth` at [`v1.2.0`](https://github.com/paradigmxyz/reth/releases/tag/v1.2.0) also includes L1 Pectra support. - + Schedule your hardfork activation time when upgrading your op-node binaries to ensure your network uses the correct fee calculation. Please review the Superchain Registry [configurations](https://github.com/ethereum-optimism/superchain-registry/tree/main/superchain/configs/sepolia) to determine if your network needs to coordinate this independently from the Superchain activation time. - + For node operators of not included in the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md), you will need to manually configure the activation. This can be done one of two ways: @@ -109,9 +96,9 @@ The following sections are how chain operators can prepare the first part of the ## For fault proof enabled chains - + The following instructions assume your chain is on the latest contract release `op-contracts/v1.8.0` and has Holocene activated. - + All fault proof enabled chains (both permisionless and permissioned fault proof systems) need to update their `op-challenger` binary to [`op-challenger/v1.3.2`](https://github.com/ethereum-optimism/optimism/releases/tag/op-challenger%2Fv1.3.2). diff --git a/pages/notices/pectra-fees.mdx b/notices/pectra-fees.mdx similarity index 96% rename from pages/notices/pectra-fees.mdx rename to notices/pectra-fees.mdx index 0f5e51c4d..0b53bf137 100644 --- a/pages/notices/pectra-fees.mdx +++ b/notices/pectra-fees.mdx @@ -1,21 +1,14 @@ --- title: L1 Pectra user fees and chain profitability description: L1 Pectra affect on user fees and chain profitability analysis -lang: en-US -content_type: notice -topic: pectra-fees -personas: - chain-operator - node-operator -categories: - security - protocol - infrastructure - l1-contracts -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Pectra impact on user fees and chain profitability @@ -33,9 +26,9 @@ Since the Ecotone upgrade, the Optimism protocol prices L2 transactions using a Please review your [Ecotone scalar chain configuration](/operators/chain-operators/management/blobs). - + If your chain uses a zero blob base fee scalar, meaning it is configured to price for calldata only, you may need to update the base fee scalar and/or the blob base fee scalar. Otherwise, no action is necessary. - + The impact and recommended actions for each of the possible configurations are summarized in the following table, and explained in more detail below: diff --git a/pages/notices/superchain-withdrawal-pause-test.mdx b/notices/superchain-withdrawal-pause-test.mdx similarity index 81% rename from pages/notices/superchain-withdrawal-pause-test.mdx rename to notices/superchain-withdrawal-pause-test.mdx index 441103149..25142b608 100644 --- a/pages/notices/superchain-withdrawal-pause-test.mdx +++ b/notices/superchain-withdrawal-pause-test.mdx @@ -1,28 +1,15 @@ --- title: Superchain withdrawal pause test description: Notice about the Superchain withdrawal pause test. -lang: en-US -content_type: notice -topic: superchain-pause-test -personas: - - chain-operator - - node-operator -categories: - - security - - protocol - - infrastructure - - l1-contracts -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Superchain withdrawal pause test - + * Sepolia Superchain withdrawal pause test was successfully completed on **April 14th 2025**. * Mainnet Superchain withdrawal pause test will happen **May 14th 2025**. - + The Optimism Collective will be testing improved incident response features on the Sepolia Superchain. diff --git a/pages/notices/upgrade-13.mdx b/notices/upgrade-13.mdx similarity index 95% rename from pages/notices/upgrade-13.mdx rename to notices/upgrade-13.mdx index d09bb5760..f124ffc30 100644 --- a/pages/notices/upgrade-13.mdx +++ b/notices/upgrade-13.mdx @@ -1,25 +1,12 @@ --- title: Upgrade 13 OPCM and incident response improvements description: Learn how to prepare for Isthmus upgrade breaking changes. -lang: en-US -content_type: notice -topic: upgrade-13 -personas: - - chain-operator - - node-operator -categories: - - security - - protocol - - infrastructure - - l1-contracts -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Upgrade 13: OPCM and incident response improvements - + Upgrade execution timelines are being publicly tracked in this [release management project board](https://github.com/orgs/ethereum-optimism/projects/117/views/12). * OP Sepolia, Ink Sepolia, and Minato Sepolia are executing their upgrades **March 21st** @@ -27,7 +14,7 @@ import { Steps, Callout } from 'nextra/components' * Unichain Sepolia is executing its upgrade on **April 1nd**. * Unichain Mainnet is executing its upgrade on **April 8th**. * Other Optimism governed chains' upgrades will be tracked in the release management project board. - + This page outlines changes related to the Upgrade 13 network upgrade for chain operators, node operators, and users of OP Stack chains. The upgrade proposal is available [here](https://gov.optimism.io/t/upgrade-proposal-13-opcm-and-incident-response-improvements/9739) and the governance vote is available [here](https://vote.optimism.io/proposals/84511922734478887667300419900648701566511387783615524992018614345859900443455). @@ -84,9 +71,9 @@ Several components have been updated to improve incident response capabilities: * Added support for "bond refunding" to automatically distribute bonds back to their original depositors if the game is invalidated - + If adopted and deployed, this proposal will cause a one-time invalidation of all pending withdrawal proofs created on L1. Users should complete any pending withdrawals before the upgrade is executed and avoid creating new withdrawal proofs that would not become executable in time. - + ### DeputyPauseModule (Superchain pause improvements) @@ -106,9 +93,9 @@ As this is an L1 contracts-only upgrade, no action is required to upgrade your n ## For bridges and users - + All withdrawals that are not finalized before the Fault Proofs upgrade executes will need to be reproven after the upgrade is complete. You may want to consider waiting until after the upgrade is complete to begin a withdrawal during this 7-day window. - + Users should be aware of the following impacts: diff --git a/pages/notices/upgrade-14.mdx b/notices/upgrade-14.mdx similarity index 95% rename from pages/notices/upgrade-14.mdx rename to notices/upgrade-14.mdx index 0e42e8dc7..ceb472406 100644 --- a/pages/notices/upgrade-14.mdx +++ b/notices/upgrade-14.mdx @@ -1,31 +1,18 @@ --- title: Upgrade 14 MT-Cannon and Isthmus L1 Contracts description: Learn how to prepare for upgrade 14 breaking changes. -lang: en-US -content_type: notice -topic: upgrade-14 -personas: - - chain-operator - - node-operator -categories: - - security - - protocol - - infrastructure - - l1-contracts -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Upgrade 14: MT-Cannon and Isthmus L1 Contracts - + Upgrade execution timelines are being publicly tracked in this [release management project board](https://github.com/orgs/ethereum-optimism/projects/117/views/12) and are subject to change. Here are the following expected timelines: * OP Sepolia, Ink Sepolia, and Minato Sepolia upgrades are targeting **April 9th, 2025**. * OP Mainnet, Soneium Mainnet, Ink Mainnet are expected to execute Upgrade 14 on **April 25th, 2025**. * Other Optimism governed chains' upgrades will be tracked in the release management project board. - + This page outlines changes related to the Upgrade 14 network upgrade for chain operators, node operators, and users of OP Stack chains. The upgrade proposal is available [here](https://gov.optimism.io/t/upgrade-proposal-14-isthmus-l1-contracts-mt-cannon/9796) and the governance vote is available [here](https://vote.optimism.io/?utm_source=op-docs&utm_medium=docs). diff --git a/pages/notices/upgrade-15.mdx b/notices/upgrade-15.mdx similarity index 95% rename from pages/notices/upgrade-15.mdx rename to notices/upgrade-15.mdx index cec3d8073..5e257d9c7 100644 --- a/pages/notices/upgrade-15.mdx +++ b/notices/upgrade-15.mdx @@ -1,21 +1,8 @@ --- title: Upgrade 15 - Isthmus Hard Fork description: Learn how to prepare for Isthmus hard fork breaking changes. -lang: en-US -content_type: notice -topic: upgrade-15-changes -personas: - - chain-operator - - node-operator -categories: - - security - - automated-pause - - protocol - - infrastructure -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Upgrade 15: Isthmus Hard Fork @@ -23,10 +10,10 @@ This page outlines breaking changes related to the Isthmus network upgrade for c If you experience difficulty at any stage of this process, please reach out to developer support. - + The Isthmus hard fork for the Sepolia Superchain will be activated at **Thu Apr 17 16:00:00 UTC 2025** (`1744905600`) and the Mainnet Superchain will be activated at **Fri May 9 2025 16:00:01 UTC** (`1746806401`). This is for all chains who have opted into the [hard fork inheritance behavior](/superchain/superchain-registry#hard-fork-activation-inheritance-behavior). - + ## What's included in Isthmus @@ -51,9 +38,9 @@ Chains running permissionless fault proofs will need to deploy new dispute game ### Verify the new absolute prestate - + As of upgrade 14, the 64 bit multi-threaded version of cannon is utilized. - + The absolute prestate is generated with the [op-program/v1.6.0-rc.2](https://github.com/ethereum-optimism/optimism/tree/op-program/v1.6.0-rc.2). You can use this new absolute prestate (`0x03682932cec7ce0a3874b19675a6bbc923054a7b321efc7d3835187b172494b6`) for the following chains: @@ -113,17 +100,17 @@ These following steps are necessary for every node operator: ### Configure the Isthmus activation date - + If you are operating a node for an OP Chain that has opted into the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md) and are utilizing the network flags, the Isthmus activation date is part of the `op-node` and `op-geth` nodes. So, no action is needed for the sequencer after upgrading to the latest release. Please skip to [Step 3: Verify Your Configuration](#verify-your-configuration). The following chains are included but are subject to change: `Base Sepolia`, `Creator Chain Testnet`, `Ethernity Sepolia`, `Ink Sepolia`, `Lisk Sepolia`, `Metal Sepolia`, `Mode Sepolia`, `Minato (Soneium) Sepolia`, `OP Sepolia`, `Unichain Sepolia`, and `Zora Sepolia`. - + For node operators of not using the [hardfork activation inheritance behavior](https://github.com/ethereum-optimism/superchain-registry/blob/main/docs/hardfork-activation-inheritance.md), you will need to manually configure the activation. This can be done one of two ways: - + If you use custom genesis chain configuration, you need to set the `pragueTime` to the same value as the `isthmusTime`. It is not automatically set, this happens by default for chains using the network flags and also when using the override flags. - + * **Option 1:** Set the activation time in the `rollup.json` for `op-node`. You will still need to set the `override.isthmus` flag in `op-geth` if you use this option. Please note that the chain configuration file is subject to a stricter format and needs to contain the `chain_op_config` outlined in the `op-node/v1.11.0` [release notes](https://github.com/ethereum-optimism/optimism/releases/tag/op-node%2Fv1.11.0). * **Option 2:** Set the activation time via overrides (CLI) in both `op-node` and `op-geth`. These will need to be set on `op-node` and `op-geth` for the sequencer and all other nodes. diff --git a/pages/notices/upgrade-16.mdx b/notices/upgrade-16.mdx similarity index 96% rename from pages/notices/upgrade-16.mdx rename to notices/upgrade-16.mdx index 25eea0748..8cee1fc61 100644 --- a/pages/notices/upgrade-16.mdx +++ b/notices/upgrade-16.mdx @@ -1,20 +1,8 @@ --- title: Upgrade 16 - Protocol upgrade description: Learn how to prepare for the Upgrade 16 protocol changes. -lang: en-US -content_type: notice -topic: upgrade-16-changes -personas: - - chain-operator -categories: - - security - - protocol - - infrastructure - - interoperability -is_imported_content: 'false' --- -import { Steps, Callout } from 'nextra/components' # Upgrade 16: Protocol upgrade @@ -51,9 +39,9 @@ Chains running permissionless fault proofs will need to deploy new dispute game ### Verify the new absolute prestate - + As of upgrade 14, the 64 bit multi-threaded version of cannon is utilized. - + The absolute prestate is generated with the [op-program/v1.6.1-rc.1](https://github.com/ethereum-optimism/optimism/tree/op-program/v1.6.1-rc.1). You can use this new absolute prestate `0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8` for the following chains: @@ -103,9 +91,9 @@ Chains running permissionless fault proofs will need to deploy new dispute game ## For bridges and users - + All withdrawals that are not finalized before the Fault Proofs upgrade executes will need to be reproven after the upgrade is complete. You may want to consider waiting until after the upgrade is complete to begin a withdrawal during this 7-day window. - + Users should be aware of the following impacts: diff --git a/nouns.txt b/nouns.txt deleted file mode 100644 index 27f2e07a0..000000000 --- a/nouns.txt +++ /dev/null @@ -1,22 +0,0 @@ -Optimism -OP Mainnet -Ethereum -OP Stack -MetaMask -SuperchainERC20 -SuperchainERC20 Starter Kit -Supersim -ZK -Security Council -Sequencer PBS -Superchain Registry -Retro Funding -Alt-DA -Teleportr -Dev Console -Granite -Holocene -Monitorism -Kubernetes -Fault Proof System -Viem \ No newline at end of file diff --git a/pages/operators/chain-operators/architecture.mdx b/operators/chain-operators/architecture.mdx similarity index 94% rename from pages/operators/chain-operators/architecture.mdx rename to operators/chain-operators/architecture.mdx index 2a9d9a34d..2ab52b231 100644 --- a/pages/operators/chain-operators/architecture.mdx +++ b/operators/chain-operators/architecture.mdx @@ -1,26 +1,8 @@ --- title: Chain architecture description: Learn about the OP chain architecture. -lang: en-US -content_type: guide -topic: chain-architecture -personas: - - chain-operator - - protocol-developer -categories: - - mainnet - - testnet - - chain-configuration - - chain-deployment - - chain-operation - - node-management - - architecture -is_imported_content: 'false' --- -import Image from 'next/image' -import { Callout } from 'nextra/components' -import {OpProposerDescriptionShort} from '@/content/index.js' # Chain architecture @@ -107,9 +89,9 @@ replicas can help horizontally scale RPC requests. Replica Node Diagram - + To run a rollup, you need a minimum of one archive node. This is required by the proposer as the data that it needs can be older than the data available to a full node. Note that since the proposer doesn't care what archive node it points to, you can technically point it towards an archive node that isn't the sequencer. - + ## Ingress traffic diff --git a/pages/operators/chain-operators/configuration/batcher.mdx b/operators/chain-operators/configuration/batcher.mdx similarity index 97% rename from pages/operators/chain-operators/configuration/batcher.mdx rename to operators/chain-operators/configuration/batcher.mdx index f9678ba59..3492d3171 100644 --- a/pages/operators/chain-operators/configuration/batcher.mdx +++ b/operators/chain-operators/configuration/batcher.mdx @@ -1,21 +1,8 @@ --- title: Batcher configuration description: Learn the OP Stack batcher configurations. -lang: en-US -content_type: guide -topic: batcher-configuration -personas: - - chain-operator -categories: - - mainnet - - protocol - - data-availability - - sequencer - - gas-optimization -is_imported_content: 'false' --- -import { Callout, Tabs } from 'nextra/components' # Batcher configuration @@ -48,40 +35,34 @@ Include these high-level "policy" requirements when you set up or modify your `o ### Set your `OP_BATCHER_MAX_CHANNEL_DURATION` - + The default value inside `op-batcher`, if not specified, is still `0`, which means channel duration tracking is disabled. For very low throughput chains, this would mean to fill channels until close to the sequencing window and post the channel to `L1 SUB_SAFETY_MARGIN` L1 blocks before the sequencing window expires. - + To minimize costs, we recommend setting your `OP_BATCHER_MAX_CHANNEL_DURATION` to target 5 hours, with a value of `1500` L1 blocks. When non-zero, this parameter is the max time (in L1 blocks, which are 12 seconds each) between which batches will be submitted to the L1. If you have this set to 5 for example, then your batcher will send a batch to the L1 every 5\*12=60 seconds. When using blobs, because 130kb blobs need to be purchased in full, if your chain doesn't generate at least \~130kb of data in those 60 seconds, then you'll be posting only partially full blobs and wasting storage. * We do not recommend setting any values higher than targeting 5 hours, as batches have to be submitted within the sequencing window which defaults to 12 hours for OP chains, otherwise your chain may experience a 12 hour long chain reorg. 5 hours is the longest length of time we recommend that still sits snugly within that 12 hour window to avoid affecting stability. * If your chain fills up full blobs of data before the `OP_BATCHER_MAX_CHANNEL_DURATION` elapses, a batch will be submitted anyways - (e.g. even if the OP Mainnet batcher sets an `OP_BATCHER_MAX_CHANNEL_DURATION` of 5 hours, it will still be submitting batches every few minutes) - + While setting an`OP_BATCHER_MAX_CHANNEL_DURATION` of `1500` results in the cheapest fees, it also means that your [safe head](https://github.com/ethereum-optimism/specs/blob/main/specs/glossary.md#safe-l2-head) can stall for up to 5 hours. * This will negatively impact apps on your chain that rely on the safe head for operation. While many apps can likely operate simply by following the unsafe head, often Centralized Exchanges or third party bridges wait until transactions are marked safe before processing deposits and withdrawal. * Thus a larger gap between posting batches can result in significant delays in the operation of certain types of high-security applications. - + ### Configure your batcher to use multiple blobs - + When there's blob congestion, running with high blob counts can backfire, because you will have a harder time getting blobs included and then fees will bump, which always means a doubling of the priority fees. - + The `op-batcher` has the capabilities to send multiple blobs per single blob transaction. This is accomplished by the use of multi-frame channels, see the [specs](https://specs.optimism.io/protocol/derivation.html#frame-format?utm_source=op-docs&utm_medium=docs) for more technical details on channels and frames. A minimal batcher configuration (with env vars) to enable 6-blob batcher transactions is: ``` - - OP_BATCHER_BATCH_TYPE=1 # span batches, optional - - OP_BATCHER_DATA_AVAILABILITY_TYPE=blobs - - OP_BATCHER_TARGET_NUM_FRAMES=6 # 6 blobs per tx - - OP_BATCHER_TXMGR_MIN_BASEFEE=2.0 # 2 gwei, might need to tweak, depending on gas market - - OP_BATCHER_TXMGR_MIN_TIP_CAP=2.0 # 2 gwei, might need to tweak, depending on gas market - - OP_BATCHER_RESUBMISSION_TIMEOUT=240s # wait 4 min before bumping fees ``` This enables blob transactions and sets the target number of frames to 6, which translates to 6 blobs per transaction. @@ -113,9 +94,9 @@ There are two throttling knobs: **Configuration** - + Note that this feature requires the batcher to correctly follow the sequencer at all times, or it would set throttling parameters on a non-sequencer EL client. That means, active sequencer follow mode has to be enabled correctly by listing all the possible sequencers in the L2 rollup and EL endpoint flags. - + The batcher can be configured with the following new flags and default parameters: @@ -244,9 +225,9 @@ How frequently to poll L2 for new blocks. The default value is `6s`. #### data-availability-type - + Setting this flag to `auto` will allow the batcher to automatically switch between `calldata` and `blobs` based on the current L1 gas price. - + The data availability type to use for submitting batches to the L1. Valid options: `calldata`, `blobs`, and `auto`. The default value is `calldata`. diff --git a/pages/operators/chain-operators/configuration/overview.mdx b/operators/chain-operators/configuration/index.mdx similarity index 86% rename from pages/operators/chain-operators/configuration/overview.mdx rename to operators/chain-operators/configuration/index.mdx index edfff7fbb..51f156c1e 100644 --- a/pages/operators/chain-operators/configuration/overview.mdx +++ b/operators/chain-operators/configuration/index.mdx @@ -1,21 +1,8 @@ --- title: Chain Operator Configurations -lang: en-US description: Learn the how to configure an OP Stack chain. -content_type: landing-page -topic: chain-operator-configurations -personas: - - chain-operator - - node-operator -categories: - - mainnet - - testnet - - chain-configuration - - system-components -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Chain operator configurations diff --git a/pages/operators/chain-operators/configuration/proposer.mdx b/operators/chain-operators/configuration/proposer.mdx similarity index 98% rename from pages/operators/chain-operators/configuration/proposer.mdx rename to operators/chain-operators/configuration/proposer.mdx index ce33a2b94..d45ceb4e3 100644 --- a/pages/operators/chain-operators/configuration/proposer.mdx +++ b/operators/chain-operators/configuration/proposer.mdx @@ -1,23 +1,8 @@ --- title: Proposer Configuration -lang: en-US description: Learn the OP Stack proposer configurations. -content_type: guide -topic: proposer-configuration -personas: - - chain-operator -categories: - - mainnet - - testnet - - op-proposer - - state-commitment - - l2-output-submission - - dispute-game - - transaction-management -is_imported_content: 'false' --- -import { Tabs } from 'nextra/components' # Proposer configuration diff --git a/pages/operators/chain-operators/configuration/rollup.mdx b/operators/chain-operators/configuration/rollup.mdx similarity index 98% rename from pages/operators/chain-operators/configuration/rollup.mdx rename to operators/chain-operators/configuration/rollup.mdx index 55e5cce09..141e6ea84 100644 --- a/pages/operators/chain-operators/configuration/rollup.mdx +++ b/operators/chain-operators/configuration/rollup.mdx @@ -1,24 +1,8 @@ --- title: Rollup deployment configuration description: Learn about the OP Stack rollup deployment configurations. -lang: en-US -content_type: guide -topic: rollup-deployment-configuration -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-deployment - - network-parameters - - system-configuration - - hardfork-activation - - genesis-configuration - - protocol-upgrades -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Rollup deployment configuration @@ -29,19 +13,19 @@ You can see example deployment configuration files in the [deploy-config directory](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts-bedrock/deploy-config). This document highlights the deployment configurations and their values. - + The Rollup configuration is an active work in progress and will likely evolve significantly as time goes on. If something isn't working about your configuration, you can refer to the [source code](https://github.com/ethereum-optimism/optimism/blob/develop/op-chain-ops/genesis/config.go). - + - + Standard configuration is the set of requirements for an OP Stack chain to be considered a Standard Chain within the Superchain. These requirements are currently a draft, pending governance approval. For more details, please see this [governance thread](https://gov.optimism.io/t/season-6-draft-standard-rollup-charter/8135) and the actual requirements in the [OP Stack Configurability Specification](https://specs.optimism.io/protocol/configurability.html?utm_source=op-docs&utm_medium=docs). - + ## Deployment configuration values diff --git a/pages/operators/chain-operators/deploy/genesis.mdx b/operators/chain-operators/deploy/genesis.mdx similarity index 91% rename from pages/operators/chain-operators/deploy/genesis.mdx rename to operators/chain-operators/deploy/genesis.mdx index bffa42b8e..8662b9c7e 100644 --- a/pages/operators/chain-operators/deploy/genesis.mdx +++ b/operators/chain-operators/deploy/genesis.mdx @@ -1,24 +1,8 @@ --- title: Chain artifacts creation -lang: en-US description: Learn how to create genesis and rollup configuration files using op-deployer after L1 contract deployment. -content_type: guide -topic: genesis-creation -personas: - - chain-operator -categories: - - mainnet - - testnet - - op-deployer - - op-geth - - op-node - - op-contracts - - rollup-configuration - - genesis-configuration -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Overview @@ -101,9 +85,9 @@ If you encounter issues with the generated files: * Check that you're using the correct **L2 chain ID** in the generation commands * Ensure your `state.json` file is up-to-date with your latest deployment - + Never manually edit the generated genesis or rollup files unless you fully understand the implications. Incorrect configurations can lead to consensus failures or chain security issues. - + ## Next steps diff --git a/pages/operators/chain-operators/deploy/overview.mdx b/operators/chain-operators/deploy/overview.mdx similarity index 93% rename from pages/operators/chain-operators/deploy/overview.mdx rename to operators/chain-operators/deploy/overview.mdx index 551fe743b..5e495244a 100644 --- a/pages/operators/chain-operators/deploy/overview.mdx +++ b/operators/chain-operators/deploy/overview.mdx @@ -1,24 +1,8 @@ --- title: Deployment overview -lang: en-US description: Learn about the different components of deploying a standard OP Stack chain. -content_type: guide -topic: chain-deployment-overview -personas: - - chain-operator -categories: - - chain-deployment - - system-components - - op-deployer - - consensus-client - - execution-client - - batcher - - proposer - - op-challenger -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Deployment overview @@ -34,12 +18,12 @@ The OP Stack uses a set of smart contracts on the L1 blockchain to manage aspects of the Rollup. Each OP Stack chain has its own set of L1 smart contracts that are deployed when the chain is created. - + Standard OP Stack chains should only use governance approved and audited smart contracts. The monorepo has them tagged with the following pattern `op-contracts/vX.X.X` and you can review the release notes for details on the changes. Read more about the details in our [Smart Contract Release Section](/stack/smart-contracts/smart-contracts#official-releases). - + ## Sequencer node diff --git a/pages/operators/chain-operators/deploy/proposer-setup-guide.mdx b/operators/chain-operators/deploy/proposer-setup-guide.mdx similarity index 95% rename from pages/operators/chain-operators/deploy/proposer-setup-guide.mdx rename to operators/chain-operators/deploy/proposer-setup-guide.mdx index 734d9771a..eafa8dc8a 100644 --- a/pages/operators/chain-operators/deploy/proposer-setup-guide.mdx +++ b/operators/chain-operators/deploy/proposer-setup-guide.mdx @@ -1,22 +1,8 @@ --- title: Spinning up the proposer -lang: en-US description: Learn how to set up and configure an OP Stack proposer to post L2 state roots. -content_type: tutorial -topic: proposer-setup -personas: - - chain-operator -categories: - - testnet - - mainnet - - op-proposer - - state-commitment - - l2-output-submission - - withdrawal-verification -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Spinning up the proposer @@ -70,10 +56,10 @@ just # Binary will be available at ./bin/op-proposer ``` - + This uses `op-proposer/v1.10.0` which is compatible with op-node/v1.13.3 and op-geth/v1.101511.0 from [spinning up the sequencer guide](/operators/chain-operators/deploy/sequencer-node). Always check the [release notes](https://github.com/ethereum-optimism/optimism/releases) for compatibility. - + ### Verify installation @@ -115,10 +101,10 @@ GAME_FACTORY_ADDRESS=$(cat state.json | jq -r '.opChainDeployments[0].disputeGam echo "DisputeGameFactory Address: $GAME_FACTORY_ADDRESS" ``` - + The proposer only needs the `DisputeGameFactory` address to submit proposals. The `GAME_TYPE=0` represents the standard fault proof game type. - + ### 3. Set up environment variables diff --git a/pages/operators/chain-operators/deploy/sequencer-node.mdx b/operators/chain-operators/deploy/sequencer-node.mdx similarity index 97% rename from pages/operators/chain-operators/deploy/sequencer-node.mdx rename to operators/chain-operators/deploy/sequencer-node.mdx index 5aa70cd7f..a06571c88 100644 --- a/pages/operators/chain-operators/deploy/sequencer-node.mdx +++ b/operators/chain-operators/deploy/sequencer-node.mdx @@ -1,23 +1,8 @@ --- title: Spinning up the sequencer -lang: en-US description: Spin up a single sequencer node after verifying L1 smart-contract deployment. -content_type: tutorial -topic: spinning sequencer -personas: - - chain-operator - - node-operator - - protocol-developer -categories: - - chain-operation - - chain-deployment - - node-management - - sequencer-configuration - - op-stack -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' ## Overview @@ -78,12 +63,12 @@ The main components you'll need for sequencer deployment are: * **op-node**: Look for the latest `op-node/v*` release * **op-geth**: Look for the latest `op-geth/v*` [release](https://github.com/ethereum-optimism/op-geth/releases) - + The versions used in this guide (**op-node/v1.13.3** and **op-geth/v1.101511.0**) are verified compatible versions. According to the **op-node v1.13.3** [release notes](https://github.com/ethereum-optimism/optimism/releases/tag/op-node%2Fv1.13.3), this op-node version specifically corresponds to **op-geth v1.101511.0**. Always check the release notes to ensure you're using compatible versions. - + ## Software installation diff --git a/pages/operators/chain-operators/deploy/smart-contracts.mdx b/operators/chain-operators/deploy/smart-contracts.mdx similarity index 88% rename from pages/operators/chain-operators/deploy/smart-contracts.mdx rename to operators/chain-operators/deploy/smart-contracts.mdx index bc3af43be..f67b3cb1b 100644 --- a/pages/operators/chain-operators/deploy/smart-contracts.mdx +++ b/operators/chain-operators/deploy/smart-contracts.mdx @@ -1,24 +1,8 @@ --- title: Smart contract deployment -lang: en-US description: Learn how to deploy the OP Stack L1 smart contracts. -content_type: guide -topic: smart-contract-deployment -personas: - - chain-operator -categories: - - chain-deployment - - op-deployer - - op-geth - - op-node - - op-contracts - - rollup-configuration - - genesis-configuration - - deployment-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Overview @@ -26,11 +10,11 @@ This guide outlines the process for deploying the OP Stack L1 smart contracts us Deploying OP Stack L1 contracts is a critical step in setting up your rollup. - + Always deploy from official contract releases. You can find official release versions in the [smart contract overview](/stack/smart-contracts#official-releases). Contract changes are generally not considered backwards compatible. - + @@ -90,10 +74,10 @@ The OP Stack follows semantic versioning (X.Y.Z) for contract releases: Contract releases are tagged in the repository as `op-contracts/vX.Y.Z`. - + For standard chains intended to join the Superchain, always use the latest Optimism Governance approved release. You can find these in the [Superchain Registry](https://github.com/ethereum-optimism/superchain-registry). - + ## Version compatibility diff --git a/pages/operators/chain-operators/deploy/spin-batcher.mdx b/operators/chain-operators/deploy/spin-batcher.mdx similarity index 96% rename from pages/operators/chain-operators/deploy/spin-batcher.mdx rename to operators/chain-operators/deploy/spin-batcher.mdx index ec16cd85d..80ca0483f 100644 --- a/pages/operators/chain-operators/deploy/spin-batcher.mdx +++ b/operators/chain-operators/deploy/spin-batcher.mdx @@ -1,22 +1,8 @@ --- title: Spinning up the batcher -lang: en-US description: Learn how to set up and configure an OP Stack batcher to submit L2 transaction batches to L1. -content_type: tutorial -topic: batcher-setup -personas: - - chain-operator -categories: - - testnet - - mainnet - - op-batcher - - batch-submission - - l2-to-l1-data - - transaction-batching -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Spinning up the batcher @@ -58,10 +44,10 @@ To ensure you're using the latest compatible versions of OP Stack components, al Look for the latest `op-batcher/v*` release that's compatible with your sequencer setup. - + This guide uses `op-batcher/v1.13.1` which is compatible with op-node/v1.13.3 and op-geth/v1.101511.0 from the sequencer setup. Always check the [release notes](https://github.com/ethereum-optimism/optimism/releases) for compatibility information. - + ### Build from source @@ -152,10 +138,10 @@ If you prefer containerized deployment, you can use the official Docker images. 3. **Create docker-compose.yml:** - + This configuration assumes your sequencer is running in a Docker container named `sequencer-node` on the same `op-stack` network. Make sure your sequencer is running before starting the batcher. - + ```yaml version: '3.8' @@ -227,10 +213,10 @@ services: ``` - + The rest of this guide assumes you're using the **build-from-source** approach. If you chose Docker, refer to the collapsible section. - + ## Configuration setup @@ -280,9 +266,9 @@ BATCH_INBOX_ADDRESS=$(cat state.json | jq -r '.opChainDeployments[0].systemConfi echo "BatchInbox Address: $BATCH_INBOX_ADDRESS" ``` - + The batcher submits transaction batches to the `BatchInbox` contract on L1. This contract is responsible for accepting and storing L2 transaction data. - + ### 3. Set up environment variables @@ -321,9 +307,9 @@ BATCHER_RPC_PORT=8548 Get a private key from your wallet that will be used for submitting batches to L1. This account needs sufficient ETH to pay for L1 gas costs. - + The batcher account needs to be funded with ETH on L1 to pay for batch submission transactions. Monitor this account's balance regularly as it will consume ETH for each batch submission. - + ## Batcher configuration @@ -435,9 +421,9 @@ curl -X POST -H "Content-Type: application/json" \ $L1_RPC_URL ``` - + For detailed cost analysis and optimization strategies, refer to the [Fee calculation tools](/operators/chain-operators/tools/fee-calculator). - + ## Next steps diff --git a/pages/operators/chain-operators/deploy/validate-deployment.mdx b/operators/chain-operators/deploy/validate-deployment.mdx similarity index 92% rename from pages/operators/chain-operators/deploy/validate-deployment.mdx rename to operators/chain-operators/deploy/validate-deployment.mdx index 69ba6002b..bacde917f 100644 --- a/pages/operators/chain-operators/deploy/validate-deployment.mdx +++ b/operators/chain-operators/deploy/validate-deployment.mdx @@ -1,23 +1,8 @@ --- title: Validate your contract deployment -lang: en-US description: Learn how to validate your OP Stack deployment using op-validator -content_type: guide -topic: deployment-validation -personas: - - chain-operator -categories: - - standardization - - validation - - op-validator - - chain-deployment - - rollup-configuration - - genesis-configuration - - deployment-configuration -is_imported_content: 'false' --- -import { Steps } from 'nextra/components' # Overview diff --git a/pages/operators/chain-operators/features/alt-da-mode.mdx b/operators/chain-operators/features/alt-da-mode.mdx similarity index 95% rename from pages/operators/chain-operators/features/alt-da-mode.mdx rename to operators/chain-operators/features/alt-da-mode.mdx index 0bf3ff776..a8405ed8e 100644 --- a/pages/operators/chain-operators/features/alt-da-mode.mdx +++ b/operators/chain-operators/features/alt-da-mode.mdx @@ -1,35 +1,22 @@ --- title: How to run an Alt-DA mode chain description: Learn how to configure and run an Alt-DA mode chain within the OP Stack. -lang: en-US -content_type: guide -topic: run-alt-da-mode-chain -personas: - - chain-operator -categories: - - mainnet - - testnet - - alt-da - - data-availability - - chain-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # How to run an Alt-DA mode chain - + The Alt-DA Mode feature is currently in Beta within the MIT-licensed OP Stack. Beta features are built and reviewed by Optimism Collective core contributors, and provide developers with early access to highly requested configurations. These features may experience stability issues, and we encourage feedback from our early users. - + This guide provides a walkthrough for chain operators who want to run an Alt-DA Mode chain. See the [Alt-DA Mode Explainer](/stack/beta-features/alt-da-mode) for a general overview of this OP Stack configuration. An Alt-DA Mode OP Stack chain enables a chain operator to post and read data to any alternative data availability layer that has built a functioning OP Stack DA Server. - + This page includes providers that meet specific [inclusion criteria](#inclusion-criteria), as outlined below. - + ## Prerequisite @@ -43,9 +30,9 @@ You should use at least the following compatible op\* versions when running your ### Setup your DA server - + DA Servers are not built or maintained by Optimism Collective Core Contributors. DA servers are maintained by third parties and run at your own risk. Please reach out to the team who built the DA Server you are trying to run with any questions or issues. - + * Celestia's docs on how to run the [Celestia DA server](https://github.com/celestiaorg/op-plasma-celestia/blob/main/README.md) * EigenDA's docs on how to run the [EigenDA DA server](https://github.com/Layr-Labs/op-plasma-eigenda/blob/main/README.md) @@ -106,9 +93,9 @@ You should use at least the following compatible op\* versions when running your "gasPriceOracleBlobBaseFeeScalar": 0, // blobs aren't used for submitting the small data commitments ``` - + Some initial scalar values must be set early on in the deploy config in [Step 2](#configure-your-op-node). And then at a later point, chain operators can update the scalar values with an L1 transaction. - + ## For node operators (full and archive nodes) @@ -172,9 +159,9 @@ Replace either of the above configurations with: } ``` - + Only include fields in the new config that were present in your old config. - + ## Updating OP Stack runtime config parameters @@ -224,9 +211,9 @@ Update the following CLI parameters for both `op-node` and `op-batcher`: After making these changes, your system should be properly configured to use the new Alt-DA Mode. - + Remember to thoroughly test your configuration in testnet before going mainnet. - + ## Next steps diff --git a/pages/operators/chain-operators/features/bridged-usdc-standard.mdx b/operators/chain-operators/features/bridged-usdc-standard.mdx similarity index 89% rename from pages/operators/chain-operators/features/bridged-usdc-standard.mdx rename to operators/chain-operators/features/bridged-usdc-standard.mdx index 3c03aa62e..4073c445b 100644 --- a/pages/operators/chain-operators/features/bridged-usdc-standard.mdx +++ b/operators/chain-operators/features/bridged-usdc-standard.mdx @@ -1,24 +1,8 @@ --- title: Bridged USDC Standard on OP Stack -lang: en-US description: This guide explains how chain operators can deploy USDC on their OP Stack chain. -content_type: guide -topic: bridged-usdc-standard -personas: - - chain-operator -categories: - - mainnet - - testnet - - op-contracts - - l1-contracts - - l2-contracts - - standard-bridge - - custom-bridge - - superchain-erc20 -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Bridged USDC Standard on the OP Stack @@ -33,10 +17,10 @@ Bridged USDC Standard for the OP Stack allows for an efficient and modular solut Chain operators can use the Bridged USDC Standard for the OP Stack to get bridged USDC on their OP Stack chain while also providing the optionality for Circle to seamlessly upgrade bridged USDC to native USDC and retain existing supply, holders, and app integrations. - + Chain operators can deploy the Bridged USDC Standard for the OP Stack, providing immediate USDC availability for their users. Importantly, the Bridged USDC Standard allows for a seamless, in-place upgrade to native USDC if an agreement is later reached between the chain operator and Circle. - + ## Security diff --git a/pages/operators/chain-operators/features/preinstalls.mdx b/operators/chain-operators/features/preinstalls.mdx similarity index 94% rename from pages/operators/chain-operators/features/preinstalls.mdx rename to operators/chain-operators/features/preinstalls.mdx index 0267095bb..bf598d4d8 100644 --- a/pages/operators/chain-operators/features/preinstalls.mdx +++ b/operators/chain-operators/features/preinstalls.mdx @@ -1,23 +1,8 @@ --- title: OP Stack preinstalls description: Learn how to use preinstalls on your chain. -lang: en-US -content_type: guide -topic: op-stack-preinstalls -personas: - - chain-operator -categories: - - mainnet - - testnet - - preinstalls - - predeploys - - smart-contracts - - genesis-configuration - - chain-deployment -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # OP Stack preinstalls @@ -28,9 +13,9 @@ Whether hacking alone or starting the next big rollup, developers can start usin Preinstalls place these core smart contracts at their usual addresses in the L2 genesis state, to ensure that they're usable as soon as a chain is initialized. With these contracts preinstalled at set addresses, developers can also expect all these contracts to be present at set addresses on the Superchain. - + Preinstalls are automatically enabled for all new OP chains after Ecotone. - + ## Contracts and deployed addresses diff --git a/pages/operators/chain-operators/features/span-batches.mdx b/operators/chain-operators/features/span-batches.mdx similarity index 84% rename from pages/operators/chain-operators/features/span-batches.mdx rename to operators/chain-operators/features/span-batches.mdx index 1011acbea..d71b65baa 100644 --- a/pages/operators/chain-operators/features/span-batches.mdx +++ b/operators/chain-operators/features/span-batches.mdx @@ -1,24 +1,8 @@ --- title: Span Batches -lang: en-US description: Learn how to use and enable span batches on your chain. -content_type: guide -topic: span-batches -personas: - - chain-operator -categories: - - mainnet - - testnet - - op-node - - op-contracts - - rollup-configuration - - genesis-configuration - - deployment-configuration - - batch-submission -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Span batches diff --git a/pages/operators/chain-operators/management/best-practices.mdx b/operators/chain-operators/management/best-practices.mdx similarity index 93% rename from pages/operators/chain-operators/management/best-practices.mdx rename to operators/chain-operators/management/best-practices.mdx index 9243d8b4a..16b6935cf 100644 --- a/pages/operators/chain-operators/management/best-practices.mdx +++ b/operators/chain-operators/management/best-practices.mdx @@ -1,22 +1,8 @@ --- title: Chain operator best practices description: Learn some best practices for managing the OP Stack's off-chain components. -lang: en-US -content_type: guide -topic: chain-operator-best-practices -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-operation - - node-management - - security - - deployment-artifacts -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Chain operator best practices diff --git a/pages/operators/chain-operators/management/blobs.mdx b/operators/chain-operators/management/blobs.mdx similarity index 93% rename from pages/operators/chain-operators/management/blobs.mdx rename to operators/chain-operators/management/blobs.mdx index f11894f82..3ef155b5a 100644 --- a/pages/operators/chain-operators/management/blobs.mdx +++ b/operators/chain-operators/management/blobs.mdx @@ -1,33 +1,16 @@ --- title: Using Blobs description: Learn how to switch to using blobs for your chain. -lang: en-US -content_type: guide -topic: using-blobs -personas: - - chain-operator -categories: - - mainnet - - testnet - - data-availability - - ecotone - - blob-configuration - - fee-optimization - - batcher-configuration - - chain-operation -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { Tabs } from 'nextra/components' # Using Blobs This guide walks you through how to switch to using blobs for your chain after Ecotone is activated. - + This guide is intended for chains already upgraded to Ecotone. - + ## Switch to using blobs @@ -70,9 +53,9 @@ This guide walks you through how to switch to using blobs for your chain after E Check that the gas price oracle on L2 returns the expected values for `baseFeeScalar` and `blobBaseFeeScalar` (wait \~1 minute): - + This is checked on L2, so ensure you are using an RPC URL for your chain. You'll also need to provide a `gas-price` to geth when making this call. - + @@ -92,9 +75,9 @@ This guide walks you through how to switch to using blobs for your chain after E Now that the fee config has been updated, you should immediately configure your batcher! - + Your chain may be undercharging users during the time between updating the scalar values and updating the Batcher, so aim to do this immediately after. - + Steps to configure the batcher: @@ -121,9 +104,9 @@ blobs back to using calldata. to get a better estimate for scalar values on your chain. The following information is tuned to a network like OP Mainnet. - + Since the Pectra upgrade on L1, chains which exclusively use calldata DA need to scale up their BaseFeeScalar by 10/4. See [this notice](/notices/pectra-fees). - + Chains can update their fees to increase or decrease their margin. If using calldata, then `BaseFeeScalar` should be scaled to achieve the desired margin. For example, to increase your L1 Fee margin by 10%: @@ -141,9 +124,9 @@ blobs back to using calldata. Now that the fee config has been updated, you will want to immediately configure your batcher. - + Reminder, that your chain may be undercharging users during the time between updating the scalar values and updating the Batcher, so aim to do this immediately after. - + * Configure `OP_BATCHER_DATA_AVAILABILITY_TYPE=calldata`. The batcher will have to be restarted for it to take effect. * Ensure your `OP_BATCHER_MAX_CHANNEL_DURATION` is properly set to maximize savings. **NOTE:** While setting a high value here will lower costs, it will be less meaningful than for low throughput chains using blobs. See [OP Batcher Max Channel Configuration](/operators/chain-operators/configuration/batcher#set-your--op_batcher_max_channel_duration) for more details. diff --git a/pages/operators/chain-operators/management/key-management.mdx b/operators/chain-operators/management/key-management.mdx similarity index 84% rename from pages/operators/chain-operators/management/key-management.mdx rename to operators/chain-operators/management/key-management.mdx index 4c4f51b86..9810c62d9 100644 --- a/pages/operators/chain-operators/management/key-management.mdx +++ b/operators/chain-operators/management/key-management.mdx @@ -1,21 +1,8 @@ --- title: Key management -lang: en-US description: A guide for chain operators on managing private keys on their chain, covering hot and cold wallets, and the use of an HSM. -content_type: guide -topic: key-management -personas: - - chain-operator -categories: - - mainnet - - testnet - - key-management - - privileged-roles - - security -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Managing your keys @@ -37,10 +24,10 @@ Key Management Systems (KMS) that can work with your developer operations configurations. This can be used in conjunction with the `eth_signTransaction` RPC method. - + You can take a look at the signer client [source code](https://github.com/ethereum-optimism/optimism/blob/develop/op-service/signer/client.go) if you're interested in what's happening under the hood. - + ## Cold wallets @@ -49,7 +36,7 @@ These can be set up as multisig contracts, so they can be controlled by groups of community members and avoid a single point of failure. The signers behind a multisig should probably also use a hardware wallet. - + Refer to the [privileged roles](/superchain/privileged-roles) documentation for more information about these different addresses and their security concerns. - + diff --git a/pages/operators/chain-operators/management/operations.mdx b/operators/chain-operators/management/operations.mdx similarity index 95% rename from pages/operators/chain-operators/management/operations.mdx rename to operators/chain-operators/management/operations.mdx index 093945d07..e86e6a073 100644 --- a/pages/operators/chain-operators/management/operations.mdx +++ b/operators/chain-operators/management/operations.mdx @@ -1,20 +1,8 @@ --- title: Rollup operations -lang: en-US description: Learn basics of rollup operations, such as how to start and stop your rollup, get your rollup config, and how to add nodes. -content_type: guide -topic: rollup-operations -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-operation - - rollup-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Rollup operations This guide reviews the basics of rollup operations, such as how to start your rollup, stop your rollup, get your rollup config, and add nodes. @@ -84,7 +72,7 @@ Start the proposer using the appropriate command. Here's an example: | private-key | Private key for signing proposals | | l1-eth-rpc | L1 network RPC endpoint URL | - + Synchronization takes time `op-batcher` might have warning messages similar to: @@ -97,15 +85,15 @@ WARN [03-21|14:13:57.328] Error calculating L2 block range err="failed t This means that `op-node` is not yet synchronized up to the present time. Just wait until it is. - + ## Getting your rollup config Use this tool to get your rollup config from `op-node`. This will only work if your chain is **already** in the [superchain-registry](https://github.com/ethereum-optimism/superchain-registry/blob/main/chainList.json) and `op-node` has been updated to pull those changes in from the registry. - + This script will NOT work for chain operators trying to generate this data in order to submit it to the registry. - + ### Get your rollup config from `op-node` @@ -194,9 +182,9 @@ If you do it this way, you won't have to wait until the transactions are written If you already have peer to peer synchronization, add the new node to the `--p2p.static` list so it can synchronize. ### Start `op-geth` (using the same command line you used on the initial node) - + **Important:** Make sure to configure the `--rollup.sequencerhttp` flag to point to your sequencer node. This HTTP endpoint is crucial because `op-geth` will route `eth_sendRawTransaction` calls to this URL. The OP Stack does not currently have a public mempool, so configuring this is required if you want your node to support transaction submission. - + ### Start `op-node` (using the same command line you used on the initial node) diff --git a/pages/operators/chain-operators/management/snap-sync.mdx b/operators/chain-operators/management/snap-sync.mdx similarity index 89% rename from pages/operators/chain-operators/management/snap-sync.mdx rename to operators/chain-operators/management/snap-sync.mdx index 3f753a8ae..e182c3c16 100644 --- a/pages/operators/chain-operators/management/snap-sync.mdx +++ b/operators/chain-operators/management/snap-sync.mdx @@ -1,21 +1,8 @@ --- title: Using snap sync for chain operators -lang: en-US description: Learn how to use and enable snap sync on your OP chain. -content_type: guide -topic: snap-sync -personas: - - chain-operator -categories: - - mainnet - - testnet - - node-management - - chain-operation - - rollup-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Using snap sync for chain operators @@ -32,12 +19,12 @@ This means that performing a snap sync is significantly faster than performing a To enable snap sync, chain operators need to spin up a node which is exposed to the network and has transaction gossip disabled. - + For snap sync, all `op-geth` nodes should expose port `30303` TCP and `30303` UDP to easily find other op-geth nodes to sync from. * If you set the port with [`--discovery.port`](/operators/node-operators/configuration/execution-config#discoveryport), then you must open the port specified for UDP. * If you set [`--port`](/operators/node-operators/configuration/execution-config#port), then you must open the port specified for TCP. * The only exception is for sequencers and transaction ingress nodes. - + ### Setup a snap sync node diff --git a/pages/operators/chain-operators/management/troubleshooting.mdx b/operators/chain-operators/management/troubleshooting.mdx similarity index 93% rename from pages/operators/chain-operators/management/troubleshooting.mdx rename to operators/chain-operators/management/troubleshooting.mdx index f635b230f..86a958c58 100644 --- a/pages/operators/chain-operators/management/troubleshooting.mdx +++ b/operators/chain-operators/management/troubleshooting.mdx @@ -1,18 +1,6 @@ --- title: Troubleshooting chain operations -lang: en-US description: Learn solutions to common problems when troubleshooting chain operations. -content_type: guide -topic: chain-troubleshooting -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-deployment - - batcher-configuration - - chain-management -is_imported_content: 'false' --- # Troubleshooting: chain operations diff --git a/pages/operators/chain-operators/self-hosted.mdx b/operators/chain-operators/self-hosted.mdx similarity index 95% rename from pages/operators/chain-operators/self-hosted.mdx rename to operators/chain-operators/self-hosted.mdx index c7bc895a9..94dd91125 100644 --- a/pages/operators/chain-operators/self-hosted.mdx +++ b/operators/chain-operators/self-hosted.mdx @@ -1,23 +1,8 @@ --- title: How to start a self-hosted chain description: Learn how to start a self-hosted OP Chain with standard configuration. -lang: en-US -content_type: guide -topic: how-to-start-a-self-hosted-chain -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-deployment - - chain-configuration - - chain-operation - - node-management - - system-components -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # How to start a self-hosted chain @@ -41,9 +26,9 @@ There are two main steps to get started building your own self-hosted OP Chain: that are deployed when the chain is created. * **Preinstalls**: OP Chains come with [preinstalled core contracts](/operators/chain-operators/features/preinstalls), making them usable as soon as a chain is initialized on the OP Stack. - + You should only use governance approved and audited smart contracts. The monorepo has them tagged with the following pattern `op-contracts/vX.X.X` and you can review the release notes for details on the changes. - + {

Launch Your OP Stack Testnet Chain

} diff --git a/pages/operators/chain-operators/tools/chain-monitoring.mdx b/operators/chain-operators/tools/chain-monitoring.mdx similarity index 97% rename from pages/operators/chain-operators/tools/chain-monitoring.mdx rename to operators/chain-operators/tools/chain-monitoring.mdx index 17178ff4d..32bb7d882 100644 --- a/pages/operators/chain-operators/tools/chain-monitoring.mdx +++ b/operators/chain-operators/tools/chain-monitoring.mdx @@ -1,20 +1,8 @@ --- title: Chain monitoring options -lang: en-US description: Learn about onchain and offchain monitoring options for your OP Stack chain. -content_type: guide -topic: chain-monitoring -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-operation - - node-management -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Chain monitoring options diff --git a/pages/operators/chain-operators/tools/explorer.mdx b/operators/chain-operators/tools/explorer.mdx similarity index 87% rename from pages/operators/chain-operators/tools/explorer.mdx rename to operators/chain-operators/tools/explorer.mdx index bc422fcd2..c04bc51dd 100644 --- a/pages/operators/chain-operators/tools/explorer.mdx +++ b/operators/chain-operators/tools/explorer.mdx @@ -1,30 +1,17 @@ --- title: Block explorer -lang: en-US description: Learn how to deploy a Blockscout block explorer for your OP Stack chain. -content_type: guide -topic: block-explorer -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-operation - - node-management - - testnet-tooling -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Deploying a block explorer [Blockscout](https://www.blockscout.com/) is an open source block explorer that supports OP Stack chains. Keep reading for a quick overview on how to deploy Blockscout for your OP Stack chain. - + Check out the [Blockscout documentation](https://docs.blockscout.com) for up-to-date information on how to deploy and maintain a Blockscout instance. - + ## Dependencies @@ -35,11 +22,11 @@ Keep reading for a quick overview on how to deploy Blockscout for your OP Stack Blockscout needs access to an [archive node](https://www.alchemy.com/overviews/archive-nodes#archive-nodes) for your OP Stack chain to properly index transactions, blocks, and internal interactions. If using `op-geth`, you can run a node in archive mode with the `--gcmode=archive` flag. - + Archive nodes take up significantly more disk space than full nodes. You may need to have 2-4 terabytes of disk space available (ideally SSD) if you intend to run an archive node for a production OP Stack chain. 1-200 gigabytes of disk space may be sufficient for a development chain. - + ## Installation diff --git a/pages/operators/chain-operators/tools/fee-calculator.mdx b/operators/chain-operators/tools/fee-calculator.mdx similarity index 70% rename from pages/operators/chain-operators/tools/fee-calculator.mdx rename to operators/chain-operators/tools/fee-calculator.mdx index 9bfdc6448..b517e1dc3 100644 --- a/pages/operators/chain-operators/tools/fee-calculator.mdx +++ b/operators/chain-operators/tools/fee-calculator.mdx @@ -1,19 +1,8 @@ --- title: Fjord fee parameter calculator -lang: en-US description: Use the Fjord Fee Parameter Calculator to estimate and calculate fees for transactions. -content_type: guide -topic: fee-calculator -personas: - - chain-operator -categories: - - mainnet - - testnet - - fee-optimization -is_imported_content: 'false' --- -import { ChainParametersForm } from '@/components/calculator/ChainParametersForm' # Fjord fee parameter calculator @@ -28,4 +17,4 @@ The Fjord Fee Parameter Calculator helps you estimate transaction fees. Use this 2. The calculator will automatically update the fee estimates based on your inputs. 3. Adjust the parameters as needed to see how they affect the fee calculations. - +Use the fee parameter calculator to estimate transaction costs. diff --git a/pages/operators/chain-operators/tools/op-challenger.mdx b/operators/chain-operators/tools/op-challenger.mdx similarity index 96% rename from pages/operators/chain-operators/tools/op-challenger.mdx rename to operators/chain-operators/tools/op-challenger.mdx index 7d7f8c025..bb0add79d 100644 --- a/pages/operators/chain-operators/tools/op-challenger.mdx +++ b/operators/chain-operators/tools/op-challenger.mdx @@ -1,21 +1,8 @@ --- title: How to configure challenger for your chain description: Learn how to configure challenger for your OP Stack chain. -lang: en-US -content_type: tutorial -topic: configure-challenger-for-your-chain -personas: - - chain-operator -categories: - - mainnet - - testnet - - fault-proofs - - op-challenger - - chain-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # How to configure challenger for your chain @@ -37,9 +24,9 @@ This guide provides a walkthrough of setting up the configuration and monitoring git checkout op-challenger/vX.Y.Z ``` - + Chain operators need to specify the arguments and `op-program` server if `op-challenger` is running outside of Docker, but there's a Cannon server option which points to `op-program`'s executable. - + * Build challenger @@ -104,9 +91,9 @@ This guide provides a walkthrough of setting up the configuration and monitoring --safedb.path # Replace with your actual path ``` - + If this path is not set, the SafeDB feature will be disabled. - + 2. Ensuring Historical Data Availability: @@ -121,9 +108,9 @@ This guide provides a walkthrough of setting up the configuration and monitoring --safedb.path ``` - + Replace `` with the URL of your archive node and `` with the desired path for storing SafeDB data. - + #### `--private-key` @@ -157,9 +144,9 @@ This guide provides a walkthrough of setting up the configuration and monitoring --game-factory-address ``` - + These options vary based on which `--network` is specified. Chain operators always need to specify a way to load prestates and must also specify the cannon-server whenever the docker image isn't being used. - + #### `--datadir` @@ -179,9 +166,9 @@ This guide provides a walkthrough of setting up the configuration and monitoring * [https://example.com/prestates/0x031e3b504740d0b1264e8cf72b6dde0d497184cfb3f98e451c6be8b33bd3f808.json](https://example.com/prestates/0x031e3b504740d0b1264e8cf72b6dde0d497184cfb3f98e451c6be8b33bd3f808.json) * This file contains the cannon memory state. - + Challenger will refuse to interact with any games if it doesn't have the matching prestate. - + ### Execute challenger diff --git a/pages/operators/chain-operators/tools/op-conductor.mdx b/operators/chain-operators/tools/op-conductor.mdx similarity index 97% rename from pages/operators/chain-operators/tools/op-conductor.mdx rename to operators/chain-operators/tools/op-conductor.mdx index 4b9000a95..1efd305f1 100644 --- a/pages/operators/chain-operators/tools/op-conductor.mdx +++ b/operators/chain-operators/tools/op-conductor.mdx @@ -1,24 +1,8 @@ --- title: Conductor -lang: en-US description: Learn what the op-conductor is and how to use it to create a highly available and reliable sequencer. -content_type: tutorial -topic: op-conductor -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-operation - - node-management - - chain-configuration - - reorgs - - op-node - - sequencer -is_imported_content: 'false' --- -import { Callout, Tabs, Steps } from 'nextra/components' # Conductor @@ -293,12 +277,12 @@ It is configured via its [flags / environment variables](https://github.com/ethe #### --raft.bootstrap (`RAFT_BOOTSTRAP`) - + For bootstrapping a new cluster. This should only be used on the sequencer that is currently active and can only be started once with this flag, otherwise the flag has to be removed or the raft log must be deleted before re-bootstrapping the cluster. - + * **Usage:** If this node should bootstrap a new raft cluster * **Default Value:** false @@ -360,10 +344,10 @@ It is configured via its [flags / environment variables](https://github.com/ethe #### --paused (`PAUSED`) - + There is no configuration state, so if you unpause via RPC and then restart, it will start paused again. - + * **Usage:** Whether the conductor is paused * **Default Value:** false @@ -507,9 +491,9 @@ SequencerHealthy returns true if the sequencer is healthy. #### conductor_leader - + API related to consensus. - + Leader returns true if the server is the leader. @@ -531,9 +515,9 @@ Leader returns true if the server is the leader. #### conductor_leaderWithID - + API related to consensus. - + LeaderWithID returns the current leader's server info. @@ -555,9 +539,9 @@ LeaderWithID returns the current leader's server info. #### conductor_addServerAsVoter - + API related to consensus. - + AddServerAsVoter adds a server as a voter to the cluster. @@ -579,9 +563,9 @@ AddServerAsVoter adds a server as a voter to the cluster. #### conductor_addServerAsNonvoter - + API related to consensus. - + AddServerAsNonvoter adds a server as a non-voter to the cluster. non-voter The non-voter will not participate in the leader election. @@ -604,9 +588,9 @@ The non-voter will not participate in the leader election. #### conductor_removeServer - + API related to consensus. - + RemoveServer removes a server from the cluster. @@ -628,9 +612,9 @@ RemoveServer removes a server from the cluster. #### conductor_transferLeader - + API related to consensus. - + TransferLeader transfers leadership to another server (resigns). @@ -652,9 +636,9 @@ TransferLeader transfers leadership to another server (resigns). #### conductor_transferLeaderToServer - + API related to consensus. - + TransferLeaderToServer transfers leadership to a specific server. @@ -696,9 +680,9 @@ ClusterMembership returns the current cluster membership configuration. #### conductor_active - + API called by `op-node`. - + Active returns true if the op-conductor is active (not paused or stopped). @@ -720,9 +704,9 @@ Active returns true if the op-conductor is active (not paused or stopped). #### conductor_commitUnsafePayload - + API called by `op-node`. - + CommitUnsafePayload commits an unsafe payload (latest head) to the consensus layer. This method is typically called by the op-node to commit execution payload envelopes. diff --git a/pages/operators/chain-operators/tools/op-deployer.mdx b/operators/chain-operators/tools/op-deployer.mdx similarity index 98% rename from pages/operators/chain-operators/tools/op-deployer.mdx rename to operators/chain-operators/tools/op-deployer.mdx index 0c450d04c..6a1819652 100644 --- a/pages/operators/chain-operators/tools/op-deployer.mdx +++ b/operators/chain-operators/tools/op-deployer.mdx @@ -1,19 +1,8 @@ --- title: Deployer description: Learn how op-deployer can simplify deploying a standard OP Stack Chain. -lang: en-US -content_type: tutorial -topic: deployer -personas: - - chain-operator -categories: - - testnet - - chain-deployment - - op-deployer -is_imported_content: 'false' --- -import {Callout, Steps} from 'nextra/components' # Deployer @@ -60,9 +49,9 @@ op-deployer --version ## Deployment usage - + Deploying an OP Stack chain involves deploying multiple contracts, which can consume a substantial amount of gas. On testnets like Sepolia, costs may fluctuate significantly depending on network congestion. We recommend ensuring your deployer wallet has a buffer of **at least 1.5 to 3.5 ETH** , depending on gas prices and configuration. Always check current gas estimates before deploying. - + The base use case for `op-deployer` is deploying new OP Chains. This process is broken down into three steps: @@ -70,10 +59,10 @@ The base use case for `op-deployer` is deploying new OP Chains. This process is To get started with `op-deployer`, create an intent file that defines your desired chain configuration. Use the built-in `op-deployer` utility to generate this file: - + op-deployer uses a declarative intent file to determine how a new chain should be configured. Then, it runs through a deployment pipeline to actually deploy the chain. - + ```bash op-deployer init \ @@ -91,10 +80,10 @@ This command will create a directory called `.deployer` in your current working Your intent file will need to be modified to your parameters, but it will initially look something like this: - + Do not use the default addresses in the intent for a production chain! They are generated from the `test... junk` mnemonic. **Any funds they hold will be stolen on a live chain.** - + ```toml deploymentStrategy = "live" @@ -130,10 +119,10 @@ l2ContractsLocator = "tag://op-contracts/v1.7.0-beta.1+l2-contracts"# L2 smart c challenger = "0x7B51A480dAeE699CA3a4F68F9AAA434452112eF7" ``` - + Before you can use your intent file for a deployment, you will need to update all zero values to whatever is appropriate for your chain. For dev environments, it is ok to use all EOAs/hot-wallets. - + **Production setup** @@ -240,9 +229,9 @@ The `l1ContractsLocator` and `l2ContractsLocator` fields support several schemes e.g. `file:///packages/contracts-bedrock/forge-artifacts` * `http://` or `https://` - Points to a target directory containing contract artifacts. The URL should directly reference the directory containing the `forge-artifacts` directory, in this case, the bytecode will be downloaded from the URL specified. - + When using any scheme other than tag://, you must set configType to either custom or standard-overrides in your intent file. - + For example: @@ -269,9 +258,9 @@ You can also do chain by chain configurations in the `chains` table. ### `apply`: deploy your chain - + Hardware wallets are not supported, but you can use ephemeral hot wallets since this deployer key has no privileges. - + Now that you've created your intent file, you can apply it to your chain to deploy the L1 smart contracts: @@ -320,9 +309,9 @@ op-deployer verify \ * Navigate to your `state.json` file and locate the `implementationsDeployment` object. * Copy everything inside the `implementationsDeployment` object (without the object name itself) and paste it into your new `input.json` file. - + You don't need to specify a `--workdir`, op-deployer will automatically look for deployment artifacts from the deploy step, unless overridden. - + **Example:** @@ -336,9 +325,9 @@ op-deployer verify \ ### `inspect`: generate genesis files and chain information - + To add your chain to the [Superchain Registry](https://github.com/ethereum-optimism/superchain-registry) you will need to provide the chain artifacts. To get these chain artifacts, you will need to write the output of these commands to new files. - + Inspect the `state.json` file by navigating to your working directory. With the contracts deployed, generate the genesis and rollup configuration files by running the following commands: diff --git a/pages/operators/chain-operators/tools/op-txproxy.mdx b/operators/chain-operators/tools/op-txproxy.mdx similarity index 90% rename from pages/operators/chain-operators/tools/op-txproxy.mdx rename to operators/chain-operators/tools/op-txproxy.mdx index db35cbbef..936b9028a 100644 --- a/pages/operators/chain-operators/tools/op-txproxy.mdx +++ b/operators/chain-operators/tools/op-txproxy.mdx @@ -1,30 +1,16 @@ --- title: op-txproxy -lang: en-US description: A passthrough proxy service that can apply additional constraints on transactions prior to reaching the sequencer. -content_type: tutorial -topic: op-txproxy -personas: - - chain-operator -categories: - - mainnet - - testnet - - op-node - - proxyd - - docker - - chain-configuration -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # op-txproxy A [passthrough proxy](https://github.com/ethereum-optimism/infra/tree/main/op-txproxy) for the execution engine endpoint. This proxy does not forward all RPC traffic and only exposes a specific set of methods. Operationally, the ingress router should only re-route requests for these specific methods. - + [proxyd](./proxyd) as an ingress router supports the mapping of specific methods to unique backends. - + ## Methods ### **eth_sendRawTransactionConditional** @@ -51,21 +37,21 @@ Even though the op-geth implementation of this endpoint includes rate limits, it * Conditional values are valid (i.e min \< max) * Transaction targets are only 4337 Entrypoint contracts - + The motivating factor for this endpoint is to enable permissionless 4337 mempools, hence the restricted usage of this method to just [Entrypoint](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/core/EntryPoint.sol) transactions. Please open up an issue if you'd like this restriction to be optional via configuration to broaden usage of this endpoint. - + When the request passes validation, it is passed through to the configured backend URL `--sendRawTxConditional.backend ($OP_TXPROXY_SENDRAWTXCONDITIONAL_BACKENDS)` - + Per the [specification](/stack/features/send-raw-transaction-conditional), conditional transactions are not gossiped between peers. Thus, if you use replicas in an active/passive sequencer setup, this request must be broadcasted to all replicas. [proxyd](./proxyd) as an egress router for this method supports this broadcasting functionality. - + ## How it works diff --git a/pages/operators/chain-operators/tools/op-validator.mdx b/operators/chain-operators/tools/op-validator.mdx similarity index 93% rename from pages/operators/chain-operators/tools/op-validator.mdx rename to operators/chain-operators/tools/op-validator.mdx index 002287f1a..fc4ec6648 100644 --- a/pages/operators/chain-operators/tools/op-validator.mdx +++ b/operators/chain-operators/tools/op-validator.mdx @@ -1,23 +1,8 @@ --- title: op-validator description: Learn how to use op-validator to validate chain configurations and deployments. -lang: en-US -content_type: tutorial -topic: op-validator -personas: - - chain-operator - - protocol-developer -categories: - - tools - - op-validator - - chain-configuration - - chain-deployment - - chain-operation - - node-management -is_imported_content: 'false' --- -import {Callout, Steps} from 'nextra/components' # op-validator diff --git a/pages/operators/chain-operators/tools/proxyd.mdx b/operators/chain-operators/tools/proxyd.mdx similarity index 89% rename from pages/operators/chain-operators/tools/proxyd.mdx rename to operators/chain-operators/tools/proxyd.mdx index 32c9f10e8..dba91880c 100644 --- a/pages/operators/chain-operators/tools/proxyd.mdx +++ b/operators/chain-operators/tools/proxyd.mdx @@ -1,24 +1,8 @@ --- title: proxyd -lang: en-US description: Learn about the proxyd service and how to configure it for use in the OP Stack. -content_type: guide -topic: proxyd -personas: - - chain-operator - - protocol-developer -categories: - - mainnet - - testnet - - rpc - - node-management - - load-balancing - - chain-operation - - consensus-awareness -is_imported_content: 'false' --- -import { Steps } from 'nextra/components' # proxyd diff --git a/pages/operators/chain-operators/tutorials/absolute-prestate.mdx b/operators/chain-operators/tutorials/absolute-prestate.mdx similarity index 96% rename from pages/operators/chain-operators/tutorials/absolute-prestate.mdx rename to operators/chain-operators/tutorials/absolute-prestate.mdx index 6e1d988f0..cba223469 100644 --- a/pages/operators/chain-operators/tutorials/absolute-prestate.mdx +++ b/operators/chain-operators/tutorials/absolute-prestate.mdx @@ -1,20 +1,8 @@ --- title: Generating absolute prestate and preimage files description: A high-level guide on how to generate the absolute prestate and preimage necessary for running cannon/permissionless proofs. -lang: en-US -content_type: tutorial -topic: generating absolute prestate files -personas: -- chain-operator -categories: -- fault proofs -- cannon -- permissionless proofs -- proof system -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Overview @@ -39,10 +27,10 @@ This upgrade offers several advantages: * Enhanced fault proof VM capabilities * Support for the latest network upgrades - + Beginning with [Upgrade 14](/notices/upgrade-14), all chains should use the `64-bit` multi-threaded version of Cannon. The absolute prestate files for this version typically have the format `prestate-mt64.bin.gz`. - + ## Generating the absolute prestate @@ -117,7 +105,7 @@ This upgrade offers several advantages: The Superchain registry maintains official absolute prestate hashes for chains that are part of the registry. These prestates include the configurations of chains that were in the Superchain registry at the time the prestate was created. - + Important: A prestate listed in the Superchain registry may not be suitable for your chain if: * Your chain was added to the registry after the prestate was created @@ -126,7 +114,7 @@ These prestates include the configurations of chains that were in the Superchain Before using a prestate from the registry, verify that it contains the latest configuration for your chain. When in doubt, generating your own prestate with your specific chain configuration is the safest approach. - + You can find the latest prestate tags in the [Superchain registry](https://github.com/ethereum-optimism/superchain-registry/blob/main/validation/standard/standard-prestates.toml). @@ -242,9 +230,9 @@ After generating the absolute prestate and preimage files, you'll need to: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest ``` - + When using an HTTP URL, no volume mount is required. The challenger will download the prestate files as needed. - + ### Option 2: Using local files @@ -264,16 +252,16 @@ After generating the absolute prestate and preimage files, you'll need to: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest ``` - + When using local files, ensure your prestate files are in the mounted directory and properly named with their hash (e.g., `0x03eb07101fbdeaf3f04d9fb76526362c1eea2824e4c6e970bdb19675b72e4fc8.bin.gz`). - +
- + * Ensure you're using the latest op-challenger version, see the [release page](https://github.com/ethereum-optimism/optimism/release). * If your chain uses interoperability features, you'll need to add a `depsets.json` file to the `op-program/chainconfig/configs` directory. * This file contains dependency set configurations in the same format as the op-supervisor's configs. You can extract this from your existing op-supervisor setup. - + ## Next Steps diff --git a/pages/operators/chain-operators/tutorials/adding-derivation-attributes.mdx b/operators/chain-operators/tutorials/adding-derivation-attributes.mdx similarity index 96% rename from pages/operators/chain-operators/tutorials/adding-derivation-attributes.mdx rename to operators/chain-operators/tutorials/adding-derivation-attributes.mdx index cb0405b81..74838142d 100644 --- a/pages/operators/chain-operators/tutorials/adding-derivation-attributes.mdx +++ b/operators/chain-operators/tutorials/adding-derivation-attributes.mdx @@ -1,30 +1,16 @@ --- title: Adding attributes to the derivation function -lang: en-US description: Learn how to modify the derivation function for an OP Stack chain to track the amount of ETH being burned on L1. -content_type: tutorial -topic: adding-derivation-attributes -personas: - - chain-operator - - protocol-developer -categories: - - chain-operation - - chain-configuration - - chain-deployment - - node-management - - derivation -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Adding attributes to the derivation function - + OP Stack Hacks are explicitly things that you can do with the OP Stack that are *not* currently intended for production use. OP Stack Hacks are not for the faint of heart. You will not be able to receive significant developer support for OP Stack Hacks — be prepared to get your hands dirty and to work without support. - + ## Overview diff --git a/pages/operators/chain-operators/tutorials/adding-precompiles.mdx b/operators/chain-operators/tutorials/adding-precompiles.mdx similarity index 94% rename from pages/operators/chain-operators/tutorials/adding-precompiles.mdx rename to operators/chain-operators/tutorials/adding-precompiles.mdx index 2f4e8557c..aa79d13f0 100644 --- a/pages/operators/chain-operators/tutorials/adding-precompiles.mdx +++ b/operators/chain-operators/tutorials/adding-precompiles.mdx @@ -1,31 +1,16 @@ --- title: Adding a precompile -lang: en-US description: Learn how to run an EVM with a new precompile for OP Stack chain operations to speed up calculations that are not currently supported. -content_type: tutorial -topic: adding-precompiles -personas: - - chain-operator - - protocol-developer -categories: - - op-geth - - op-node - - chain-configuration - - chain-operation - - precompiles - - node-management -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Adding a precompile - + OP Stack Hacks are explicitly things that you can do with the OP Stack that are *not* currently intended for production use. OP Stack Hacks are not for the faint of heart. You will not be able to receive significant developer support for OP Stack Hacks — be prepared to get your hands dirty and to work without support. - + One possible use of OP Stack is to run an EVM with a new precompile for operations to speed up calculations that are not currently supported. In this tutorial, you'll make a simple precompile that returns a constant value if it's called with four or less bytes, or an error if it is called with more than that. diff --git a/pages/operators/chain-operators/tutorials/chain-dev-net.mdx b/operators/chain-operators/tutorials/chain-dev-net.mdx similarity index 95% rename from pages/operators/chain-operators/tutorials/chain-dev-net.mdx rename to operators/chain-operators/tutorials/chain-dev-net.mdx index ca05f63c3..57a078f16 100644 --- a/pages/operators/chain-operators/tutorials/chain-dev-net.mdx +++ b/operators/chain-operators/tutorials/chain-dev-net.mdx @@ -1,31 +1,15 @@ --- title: Running a Local Development Environment description: This tutorial walks you through spinning up an OP Stack devnet chain. -lang: en-US -content_type: tutorial -topic: running-a-local-development-environment -personas: - - chain-operator -categories: - - testnet - - local-devnet - - chain-deployment - - docker - - chain-configuration - - chain-operation - - node-management -is_imported_content: 'false' --- -import {Callout, Steps} from 'nextra/components' -import {WipCallout} from '@/components/WipCallout' # Running a Local Development Environment - + This guide is currently under active development. If you run into any issues, please open an issue on [Github](https://github.com/ethereum-optimism/optimism). - + This tutorial is **designed for developers** who want to learn about the OP Stack by spinning up a local OP Stack devnet. You'll perform the full deployment process, and **you'll end up with your very own OP Stack devnet**. @@ -38,10 +22,10 @@ You can use this devnet to experiment and perform tests, or you can choose to mo **The OP Stack is free and open source software licensed entirely under the MIT license**. You don't need permission from anyone to modify or deploy the stack in any configuration you want. - + Modifications to the OP Stack may prevent a chain from being able to benefit from aspects of the [Optimism Superchain](/superchain/superchain-explainer). Make sure to check out the [Superchain Explainer](/superchain/superchain-explainer) to learn more. - + ## Installing Dependencies @@ -154,13 +138,13 @@ can see: At this point your chain is up and running. Let's move on to the next section to learn how to interact with it. - + You can also use the Kurtosis Web UI to monitor and interact with your services by running: ```bash kurtosis web ``` This will open a browser window with a dashboard showing all your running enclaves and services. - + ## Interact with your network @@ -171,9 +155,9 @@ of the execution client services identified by `op-el`. ### Using pre-funded accounts on L2 - + Important: The setup script automatically pre-funds accounts on the L2 chain directly. You don't need to bridge funds from L1 to L2 to get started. - + Your network is configured to pre-fund development addresses on L2 using the `test test test test test test test test test test test junk` mnemonic. You can import one of the private keys from that mnemonic into your favorite wallet or use diff --git a/pages/operators/chain-operators/tutorials/create-l2-rollup.mdx b/operators/chain-operators/tutorials/create-l2-rollup.mdx similarity index 97% rename from pages/operators/chain-operators/tutorials/create-l2-rollup.mdx rename to operators/chain-operators/tutorials/create-l2-rollup.mdx index 0f7d88d13..2d374cfe7 100644 --- a/pages/operators/chain-operators/tutorials/create-l2-rollup.mdx +++ b/operators/chain-operators/tutorials/create-l2-rollup.mdx @@ -1,32 +1,16 @@ --- title: Creating your own L2 rollup testnet description: This tutorial walks you through spinning up an OP Stack testnet chain. -lang: en-US -content_type: tutorial -topic: creating-your-own-l2-rollup-testnet -personas: - - chain-operator -categories: - - mainnet - - testnet - - chain-deployment - - chain-configuration - - chain-operation - - node-management - - op-deployer -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { WipCallout } from '@/components/WipCallout' - +This feature is currently in development. # Creating your own L2 rollup testnet - + Please **be prepared to set aside approximately one hour** to get everything running properly and **make sure to read through the guide carefully**. You don't want to miss any important steps that might cause issues down the line. - + This tutorial is **designed for developers** who want to learn about the OP Stack by spinning up an OP Stack testnet chain. You'll walk through the full deployment process and teach you all of the components that make up the OP Stack, and **you'll end up with your very own OP Stack testnet**. @@ -39,10 +23,10 @@ You can use this testnet to experiment and perform tests, or you can choose to m **The OP Stack is free and open source software licensed entirely under the MIT license**. You don't need permission from anyone to modify or deploy the stack in any configuration you want. - + Modifications to the OP Stack may prevent a chain from being able to benefit from aspects of the [Optimism Superchain](/superchain/superchain-explainer). Make sure to check out the [Superchain Explainer](/superchain/superchain-explainer) to learn more. - + ## Software dependencies @@ -77,10 +61,10 @@ This means you won't have to manually export environment variables every time yo After [installing `direnv`](https://direnv.net/docs/installation.html), you will need to **make sure that [`direnv` is hooked into your shell](https://direnv.net/docs/hook.html)**. Make sure you've followed [the guide on the `direnv` website](https://direnv.net/docs/hook.html), then **close your terminal and reopen it** so that the changes take effect (or `source` your config file if you know how to do that). - + Make sure that you have correctly hooked `direnv` into your shell by modifying your shell configuration file (like `~/.bashrc` or `~/.zshrc`). If you haven't edited a config file then you probably haven't configured `direnv` properly (and things might not work later). - + ## Get access to a sepolia node @@ -101,11 +85,11 @@ You're going to be spinning up your OP Stack chain directly from source code ins Although this adds a few extra steps, it means you'll have an easier time modifying the behavior of the stack if you'd like to do so. If you want a summary of the various components you'll be using, take another look at the [What You're Going to Deploy](#what-youre-going-to-deploy) section above. - + You're using the home directory `~/` as the work directory for this tutorial for simplicity. You can use any directory you'd like but using the home directory will allow you to copy/paste the commands in this guide. If you choose to use a different directory, make sure you're using the correct directory in the commands throughout this tutorial. - + ### Build the Optimism monorepo @@ -126,11 +110,11 @@ cd optimism {

Check out the correct branch

} - + You will be using the `tutorials/chain` branch of the Optimism Monorepo to deploy an OP Stack testnet chain during this tutorial. This is a non-production branch that lags behind the `develop` branch. You should **NEVER** use the `develop` or `tutorials/chain` branches in production. - + ```bash git checkout tutorials/chain @@ -138,9 +122,9 @@ git checkout tutorials/chain {

Check your dependencies

} - + Don't skip this step! Make sure you have all of the required dependencies installed before continuing. - + Run the following script and double check that you have all of the required versions installed. If you don't have the correct versions installed, you may run into unexpected errors. @@ -237,10 +221,10 @@ cd ~/optimism {

Generate new addresses

} - + You should **not** use the `wallets.sh` tool for production deployments. If you are deploying an OP Stack based chain into production, you should likely be using a combination of hardware security modules and hardware wallets. - + ```bash ./packages/contracts-bedrock/scripts/getting-started/wallets.sh @@ -304,10 +288,10 @@ cd ~/optimism {

Load the variables with direnv

} - + You're about to use `direnv` to load environment variables from the `.envrc` file into your terminal. Make sure that you've [installed `direnv`](https://direnv.net/docs/installation.html) and that you've properly [hooked `direnv` into your shell](#configuring-direnv). - + Next you'll need to allow `direnv` to read this file and load the variables into your terminal using the following command. @@ -315,10 +299,10 @@ Next you'll need to allow `direnv` to read this file and load the variables into direnv allow ``` - + WARNING: `direnv` will unload itself whenever your `.envrc` file changes. **You *must* rerun the following command every time you change the `.envrc` file.** - + {

Confirm that the variables were loaded

} @@ -379,10 +363,10 @@ It's recommended to keep this file as-is for now so you don't run into any unexp If you're deploying an OP Stack chain to a network other than Sepolia, you may need to deploy a Create2 factory contract to the L1 chain. This factory contract is used to deploy OP Stack smart contracts in a deterministic fashion. - + This step is typically only necessary if you are deploying your OP Stack chain to custom L1 chain. If you are deploying your OP Stack chain to Sepolia, you can safely skip this step. - + @@ -442,10 +426,10 @@ The recommended flow for creating a genesis file and rollup configuration file o 2. **Generate** both the L2 genesis file (`genesis.json`) and the rollup configuration file (`rollup.json`) using op-deployer's `inspect` commands. 3. **Initialize** your off-chain components (e.g., execution client, consensus client). - + Using op-deployer for chain initialization is a requirement for all chains intending to be for chains who intend to be standard and join the superchain. This ensures standardization and compatibility across the OP Stack ecosystem. - + ### Prerequisites @@ -555,15 +539,15 @@ cd ~/op-geth {

Run op-geth

} - + You're using `--gcmode=archive` to run `op-geth` here because this node will act as your Sequencer. It's useful to run the Sequencer in archive mode because the `op-proposer` requires access to the full state. Feel free to run other (non-Sequencer) nodes in full mode if you'd like to save disk space. Just make sure at least one other archive node exists and the `op-proposer` points to it. - + - + It's important that you've already initialized the geth node at this point as per the previous section. Failure to do this will cause startup issues between `op-geth` and `op-node`. - + ```bash ./build/bin/geth \ @@ -632,7 +616,7 @@ Once you run this command, you should start seeing the `op-node` begin to sync L Once the `op-node` has caught up to the tip of the L1 chain, it'll begin to send blocks to `op-geth` for execution. At that point, you'll start to see blocks being created inside of `op-geth`. - + **By default, your `op-node` will try to use a peer-to-peer to speed up the synchronization process.** If you're using a chain ID that is also being used by others, like the default chain ID for this tutorial (42069), your `op-node` will receive blocks signed by other sequencers. These requests will fail and waste time and network resources. @@ -649,7 +633,7 @@ You can add the following options to the `op-node` command to enable peer-to-pee ``` You can alternatively also remove the [--p2p.static](/operators/node-operators/configuration/consensus-config#p2pstatic) option, but you may see failed requests from other chains using the same chain ID. - +
@@ -693,12 +677,12 @@ cd ~/optimism/op-batcher --private-key=$GS_BATCHER_PRIVATE_KEY ``` - + The [`--max-channel-duration=n`](/operators/chain-operators/configuration/batcher#set-your--op_batcher_max_channel_duration) setting tells the batcher to write all the data to L1 every `n` L1 blocks. When it is low, transactions are written to L1 frequently and other nodes can synchronize from L1 quickly. When it is high, transactions are written to L1 less frequently and the batcher spends less ETH. If you want to reduce costs, either set this value to 0 to disable it or increase it to a higher value. - +
diff --git a/pages/operators/chain-operators/tutorials/dispute-games.mdx b/operators/chain-operators/tutorials/dispute-games.mdx similarity index 94% rename from pages/operators/chain-operators/tutorials/dispute-games.mdx rename to operators/chain-operators/tutorials/dispute-games.mdx index 6a58e9a28..80b7c1393 100644 --- a/pages/operators/chain-operators/tutorials/dispute-games.mdx +++ b/operators/chain-operators/tutorials/dispute-games.mdx @@ -1,22 +1,8 @@ --- title: Deploying new dispute games with OPCM description: Learn how to deploy new dispute games to an OP Stack chain using OPCM -lang: en-US -content_type: tutorial -topic: deploying-dispute-games-opcm -personas: - - chain-operator - - protocol-developer -categories: - - fault proofs - - smart contracts upgrades - - OPCM upgrade - - OPCM contracts - - dispute game -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Deploying new dispute games with OPCM @@ -37,11 +23,11 @@ The OP Stack uses two types of dispute games: * **Permissioned dispute game**: Limited to specific proposer and challenger addresses * **Permissionless dispute game**: Open to anyone to propose or challenge - + In the Permissioned dispute game (PDG), the [challenger role](/superchain/privileged-roles#challenger) is a protocol-level permission assigned to specific addresses, allowing them to initiate or respond to disputes. This role is distinct from the op-challenger service, which is an off-chain monitoring service responsible for automatically detecting discrepancies and submitting challenges. While the op-challenger service typically operates using an address that has been assigned the challenger role, the protocol-level role itself can be independently assigned, regardless of whether the op-challenger service is in use. Refer to the [OP Stack configurability spec](https://specs.optimism.io/protocol/configurability.html) for more details. - + All chains deployed with `op-deployer` only initially include the permissioned dispute game. This guide explains how to add the permissionless game. @@ -103,9 +89,9 @@ For a permissionless game, you'll generally want to mirror most parameters from 3. Execute the addGameType function The following is a template for calling the addGameType function using Forge's cast: - + The most recommended way is to use a script to execute this call, rather than manual execution. - + ```bash # Retrieve existing values from chain for reference diff --git a/pages/operators/chain-operators/tutorials/integrating-da-layer.mdx b/operators/chain-operators/tutorials/integrating-da-layer.mdx similarity index 87% rename from pages/operators/chain-operators/tutorials/integrating-da-layer.mdx rename to operators/chain-operators/tutorials/integrating-da-layer.mdx index 85e21418f..21940844c 100644 --- a/pages/operators/chain-operators/tutorials/integrating-da-layer.mdx +++ b/operators/chain-operators/tutorials/integrating-da-layer.mdx @@ -1,29 +1,15 @@ --- title: Integrating a new DA layer with Alt-DA -lang: en-US description: Learn how to add support for a new DA Layer within the OP Stack. -content_type: tutorial -topic: integrating-da-layer -personas: - - chain-operator - - protocol-developer -categories: - - alt-da - - chain-configuration - - chain-deployment - - chain-operation - - node-management -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Integrating a new DA layer with Alt-DA - + The Alt-DA Mode feature is currently in Beta within the MIT-licensed OP Stack. Beta features are built and reviewed by Optimism Collective core contributors, and provide developers with early access to highly requested configurations. These features may experience stability issues, and we encourage feedback from our early users. - + [Alt-DA Mode](/stack/beta-features/alt-da-mode) enables seamless integration of any DA Layer, regardless of their commitment type, into the OP Stack. After a DA Server is built for a DA Layer, any chain operator can launch an OP Stack chain using that DA Layer for sustainably low costs. @@ -37,9 +23,9 @@ Our suggestion is for every DA Layer to build and maintain their own DA Server, * It must point to the data on your layer (like block height / hash). * It must be able to validate the data returned from the data (i.e., include a cryptographic commitment to the data like a hash, merkle proof, or polynomial commitment, this could be done against the block hash with a complex proof). - + See the [specs](https://specs.optimism.io/experimental/alt-da.html?highlight=input-commitment-submission?utm_source=op-docs&utm_medium=docs#input-commitment-submission) for more info on commitment submission. - + ### Claim your da\_layer byte diff --git a/pages/operators/chain-operators/tutorials/migrating-permissionless.mdx b/operators/chain-operators/tutorials/migrating-permissionless.mdx similarity index 96% rename from pages/operators/chain-operators/tutorials/migrating-permissionless.mdx rename to operators/chain-operators/tutorials/migrating-permissionless.mdx index e22ebcf62..5ecbece98 100644 --- a/pages/operators/chain-operators/tutorials/migrating-permissionless.mdx +++ b/operators/chain-operators/tutorials/migrating-permissionless.mdx @@ -1,23 +1,8 @@ --- title: Migrating to permissionless fault proofs on OP Stack description: A high-level guide for transitioning from permissioned to permissionless fault proofs on an OP Stack. -lang: en-US -content_type: tutorial -topic: migrating to permissionless fault proofs on OP Stack -personas: - - chain-operator -categories: - - fault proofs - - smart contracts upgrades - - Superchain-shared contracts - - proof system - - OPCM upgrade - - OPCM contracts - - dispute game -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Migrating to permissionless fault proofs on OP Stack @@ -139,11 +124,11 @@ You'll need to deploy two new dispute game contracts with the new absolute prest 1. `FaultDisputeGame` 2. `PermissionedDisputeGame` - + The initial prestate used for permissioned games doesn't include the necessary chain configuration for the Fault Proof System. The assumption is that the chain operator, the single permissioned actor, will not challenge their own games. So the absolute prestate on the initial `PermissionedDisputeGame` will never be used. When deploying a new chain, you must first deploy the L1 contracts and then generate the chain genesis file and rollup configuration files. These are inputs to the creation of the absolute prestate and this circular dependency is the reason chains cannot be deployed directly to the permissionless Fault Proof System. - + For chains not in the Superchain Registry, you need to build custom prestates with your chain's configuration: @@ -153,10 +138,10 @@ The prestate will typically be generated at: * `op-program/bin/prestate.bin.gz` (for intermediate versions) * `op-program/bin/prestate-mt64.bin.gz` (for chains upgraded to Cannon MT64, starting from [upgrade 14](/notices/upgrade-14#whats-included-in-upgrade-14)) - + Post-upgrade 14, chains are expected to use `prestate-mt64.bin.gz` due to the Fault Proof VM contract upgrade to `cannon-mt64`. The older `prestate.bin.gz` will eventually be deprecated but is temporarily retained until all chains complete the upgrade. - + ### Ensure sufficient funds for bonds @@ -375,9 +360,9 @@ Or via environment variable: OP_PROPOSER_GAME_TYPE=0 ``` - + This action requires all in-progress withdrawals to be re-proven against a new `FaultDisputeGame` created after this update occurs. - + ## Next steps diff --git a/pages/operators/chain-operators/tutorials/modifying-predeploys.mdx b/operators/chain-operators/tutorials/modifying-predeploys.mdx similarity index 91% rename from pages/operators/chain-operators/tutorials/modifying-predeploys.mdx rename to operators/chain-operators/tutorials/modifying-predeploys.mdx index b82454ccb..eab5c91b7 100644 --- a/pages/operators/chain-operators/tutorials/modifying-predeploys.mdx +++ b/operators/chain-operators/tutorials/modifying-predeploys.mdx @@ -1,30 +1,16 @@ --- title: Modifying predeployed contracts -lang: en-US description: Learn how to modify predeployed contracts for an OP Stack chain by upgrading the proxy. -content_type: tutorial -topic: modifying-predeploys -personas: - - chain-operator - - protocol-developer -categories: - - chain-operation - - chain-configuration - - chain-deployment - - node-management - - proxy -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Modifying predeployed contracts - + OP Stack Hacks are explicitly things that you can do with the OP Stack that are *not* currently intended for production use. OP Stack Hacks are not for the faint of heart. You will not be able to receive significant developer support for OP Stack Hacks — be prepared to get your hands dirty and to work without support. - + OP Stack blockchains have a number of [predeployed contracts](https://github.com/ethereum-optimism/optimism/blob/129032f15b76b0d2a940443a39433de931a97a44/packages/contracts-bedrock/src/constants.ts) that provide important functionality. Most of those contracts are proxies that can be upgraded using the `proxyAdminOwner` which was configured when the network was initially deployed. diff --git a/pages/operators/node-operators/architecture.mdx b/operators/node-operators/architecture.mdx similarity index 92% rename from pages/operators/node-operators/architecture.mdx rename to operators/node-operators/architecture.mdx index 64d943929..f0a05a692 100644 --- a/pages/operators/node-operators/architecture.mdx +++ b/operators/node-operators/architecture.mdx @@ -1,21 +1,6 @@ --- title: Node architecture -lang: en-US description: Learn about node architecture. -content_type: guide -topic: node-architecture -personas: - - node-operator -categories: - - architecture - - node-configuration - - infrastructure - - system-design - - execution-client - - consensus-client - - system-components - - rollup-node -is_imported_content: 'false' --- # Node architecture diff --git a/pages/operators/node-operators/configuration/base-config.mdx b/operators/node-operators/configuration/base-config.mdx similarity index 96% rename from pages/operators/node-operators/configuration/base-config.mdx rename to operators/node-operators/configuration/base-config.mdx index d953c5619..002be7e21 100644 --- a/pages/operators/node-operators/configuration/base-config.mdx +++ b/operators/node-operators/configuration/base-config.mdx @@ -1,28 +1,14 @@ --- title: Node base configuration -lang: en-US description: Learn the node base configuration and recommended flags for op-node, op-geth, and legacy geth. -content_type: guide -topic: node-base-configuration -personas: - - node-operator -categories: - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Node base configuration - + Always run `op-node` and `op-geth` in a one-to-one configuration. Don't run multiple `op-geth` instances behind one `op-node`, or vice versa. - + To configure your node, you will need to do the following: @@ -33,9 +19,9 @@ To configure your node, you will need to do the following: ## Configuring `op-geth` - + Although the Docker image for the Execution Engine is called `op-geth`, the actual binary is still called `geth` in order to minimize differences between `op-geth` and `go-ethereum`. You can see the difference [here](https://op-geth.optimism.io/?utm_source=op-docs&utm_medium=docs). - + `op-geth` stores its state in a database that requires initialization. Depending on the network you're running, initialization is done one of three ways: @@ -154,10 +140,10 @@ Following the [Ecotone upgrade](/operators/node-operators/network-upgrades#ecoto node operators must set an L1 beacon value to retrieve [blobs](/operators/node-operators/management/blobs) from a Beacon node. - + The `op-node` RPC should not be exposed publicly. If left exposed, it could accidentally expose admin controls to the public internet. - + ### Working base configuration @@ -191,9 +177,9 @@ The default port for the peer-to-peer network is `9222`. You will need to open t If you are running a node for an upgraded network like OP Mainnet (but not OP Sepolia), you will also need to run Legacy Geth in order to serve historical execution traces. Fundamentally, Legacy Geth is our old `l2geth` binary running against a preconfigured data directory. To configure Legacy Geth, follow the instructions above for using a preconfigured data directory, then execute the following command: - + It is imperative that you specify the `USING_OVM=true` environment variable in the command below. Failing to specify this will cause `l2geth` to return invalid execution traces, or panic at startup. - + ```bash USING_OVM=true \ diff --git a/pages/operators/node-operators/configuration/consensus-config.mdx b/operators/node-operators/configuration/consensus-config.mdx similarity index 98% rename from pages/operators/node-operators/configuration/consensus-config.mdx rename to operators/node-operators/configuration/consensus-config.mdx index 58f4f1dae..62a7d9b29 100644 --- a/pages/operators/node-operators/configuration/consensus-config.mdx +++ b/operators/node-operators/configuration/consensus-config.mdx @@ -1,31 +1,15 @@ --- title: Consensus layer configuration options (op-node) -lang: en-US description: Learn additional configuration and command line options for op-node and the Consensus-Layer. -content_type: reference -topic: consensus-layer-configuration -personas: - - node-operator -categories: - - consensus-client - - node-configuration - - infrastructure - - system-configuration - - node-management - - metrics - - rollup-configuration -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { Tabs } from 'nextra/components' # Consensus layer configuration options (op-node) - + You can configure your node using the command line options below (also called flags). There are also sub-commands, which can be used to invoke functionality such as the console or blockchain import/export. - + This page list all configuration options for `op-node`. `op-node` implements most rollup-specific functionality as Consensus-Layer, similar to a L1 beacon-node. The following options are from the `--help` in [v1.7.5](https://github.com/ethereum-optimism/optimism/releases/tag/op-node/v1.7.5). @@ -162,9 +146,9 @@ The kind of RPC provider, used to inform optimal transactions receipts fetching, `OP_NODE_L1_RPC_KIND=standard` - + For details on additional values, see [RPC Receipts](https://github.com/ethereum-optimism/optimism/blob/844cc20084a2e9716631b4092ce7eca4804a8e0a/op-service/sources/receipts_rpc.go#L239-L322). - + ### l1.runtime-config-reload-interval @@ -180,11 +164,11 @@ Poll interval for reloading the runtime config, useful when config events are no Trust the L1 RPC, sync faster at risk of malicious/buggy RPC providing bad or inconsistent L1 data. The default value is `false`. - + If you're running an Erigon Ethereum execution client for your L1 provider you will need to include `--l1.trustrpc`. At the time of writing, Erigon doesn't support the `eth_getProof` that we prefer to use to load L1 data for some processing in `op-node`. The trustrpc flag makes it use something else that erigon supports, but the `op-node` can't verify for correctness. - + `--l1.trustrpc=` @@ -796,9 +780,9 @@ Number of L1 blocks to keep distance from the L1 head as a sequencer for picking `OP_NODE_SEQUENCER_L1_CONFS=4` - + The maximum value for `sequencer.l1-confs` cannot exceed the sequencer drift, currently set to 30 minutes (1800 seconds or 150 blocks). Setting a value higher than this limit will prevent the sequencer from producing blocks within the sequence window. - + ### sequencer.max-safe-lag @@ -840,9 +824,9 @@ Number of L1 blocks to keep distance from the L1 head before deriving L2 data fr `OP_NODE_VERIFIER_L1_CONFS=0` - + While `verifier.l1-confs` has no strict limit, it's recommended to keep this value within 12-13 minutes (typically 10-20 blocks) for optimal performance. Exceeding this range may impact the verifier's data processing efficiency. - + ## Miscellaneous @@ -857,10 +841,10 @@ Show help. The default value is `false`. ### --version, -v - + Nodes built from source do not output the correct version numbers that are reported on the GitHub release page. - + Print the version. The default value is `false`. diff --git a/pages/operators/node-operators/configuration/execution-config.mdx b/operators/node-operators/configuration/execution-config.mdx similarity index 99% rename from pages/operators/node-operators/configuration/execution-config.mdx rename to operators/node-operators/configuration/execution-config.mdx index 4c75d1d07..28775b4b0 100644 --- a/pages/operators/node-operators/configuration/execution-config.mdx +++ b/operators/node-operators/configuration/execution-config.mdx @@ -1,31 +1,15 @@ --- title: Execution layer configuration options (op-geth) -lang: en-US description: Learn additional configuration and command line options for op-geth and the Execution-Layer. -content_type: reference -topic: execution-layer-configuration -personas: - - node-operator -categories: - - execution-client - - node-configuration - - infrastructure - - gas-configuration - - system-configuration - - node-management - - rpc -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { Tabs } from 'nextra/components' # Execution layer configuration options (op-geth) - + You can configure your node using the command line options below (also called flags). There are also sub-commands, which can be used to invoke functionality such as the console or blockchain import/export. - + This page list all configuration options for `op-geth`. `op-geth` implements the Execution-Layer, with minimal changes for a secure Ethereum-equivalent application environment. The following are options from [v1.101308.0](https://github.com/ethereum-optimism/op-geth/releases/tag/v1.101308.0) @@ -1250,10 +1234,10 @@ Hash of the block to full sync to (dev testing feature). #### version - + Nodes built from source do not output the correct version numbers that are reported on the GitHub release page. - + Print the version. This option is typically used to display the version of the software. diff --git a/pages/operators/node-operators/json-rpc.mdx b/operators/node-operators/json-rpc.mdx similarity index 98% rename from pages/operators/node-operators/json-rpc.mdx rename to operators/node-operators/json-rpc.mdx index 556e69099..1f6b0d3d2 100644 --- a/pages/operators/node-operators/json-rpc.mdx +++ b/operators/node-operators/json-rpc.mdx @@ -1,35 +1,18 @@ --- title: JSON-RPC API -lang: en-US description: Learn about the different OP Mainnet components with an RPC API. -content_type: reference -topic: json-rpc-api -personas: - - node-operator -categories: - - api - - node-configuration - - infrastructure - - rpc - - execution-client - - consensus-client - - node-management - - peer-management-service -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' -import { Tabs } from 'nextra/components' # JSON-RPC API There are several OP Mainnet components with an RPC API, which are reviewed in this guide. - + Use [`eth_gasPrice`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gasprice) instead of `rollup_gasPrices` for the L2 gas price. For the L1 gas price, you can call the [`GasPriceOracle`'s `l1BaseFee` function](https://optimistic.etherscan.io/address/0x420000000000000000000000000000000000000F#readProxyContract#F11). If you want to estimate the cost of a transaction, you can [use the SDK](/app-developers/tutorials/transactions/sdk-estimate-costs). - + ## op-node @@ -38,11 +21,11 @@ There are several OP Mainnet components with an RPC API, which are reviewed in t The following examples show you how to make requests with [`curl`](https://curl.se/) and [`cast`](https://book.getfoundry.sh/cast/). - + Protip: piping these commands in to [`jq`](https://jqlang.github.io/jq/) will give you nicely formatted JSON responses. `$ cast rpc optimism_syncStatus --rpc-url http://localhost:9545 | jq` - + ### optimism @@ -267,9 +250,9 @@ Sample success output: Get the software version. - + At the moment, building from source will not give you the correct version, but our docker images will. - + diff --git a/pages/operators/node-operators/management/blobs.mdx b/operators/node-operators/management/blobs.mdx similarity index 92% rename from pages/operators/node-operators/management/blobs.mdx rename to operators/node-operators/management/blobs.mdx index 42cfd532a..647f2c84f 100644 --- a/pages/operators/node-operators/management/blobs.mdx +++ b/operators/node-operators/management/blobs.mdx @@ -1,25 +1,8 @@ --- title: Using blobs -lang: en-US description: Learn how to handle blobs for your node. -content_type: guide -topic: using-blobs -personas: - - node-operator -categories: - - blob-configuration - - data-availability - - node-configuration - - system-configuration - - consensus-client - - execution-client - - network-upgrades - - infrastructure -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { Tabs } from 'nextra/components' # Using blobs @@ -48,10 +31,10 @@ the activation dates can be set in the `rollup.json` (set `ecotone_time`) or set the activation time via overrides (CLI) in both `op-node` and `op-geth`. These will need to be set on `op-node` and `op-geth` for the sequencer and all other nodes. - + Even if the ecotone activation is configured via the `rollup.json`, it still needs to be configured separately on `op-geth` via command line flag. - + diff --git a/pages/operators/node-operators/management/metrics.mdx b/operators/node-operators/management/metrics.mdx similarity index 97% rename from pages/operators/node-operators/management/metrics.mdx rename to operators/node-operators/management/metrics.mdx index 432001df1..9c5a906f2 100644 --- a/pages/operators/node-operators/management/metrics.mdx +++ b/operators/node-operators/management/metrics.mdx @@ -1,21 +1,6 @@ --- title: Node Metrics and Monitoring -lang: en-US description: Learn about the different metrics you can use to monitor the health of your node. -content_type: guide -topic: node-metrics-and-monitoring -personas: - - node-operator -categories: - - monitoring - - analytics - - node-management - - infrastructure - - stability-monitoring - - system-configuration - - consensus-client - - execution-client -is_imported_content: 'false' --- # Node metrics and monitoring diff --git a/pages/operators/node-operators/management/regenesis-history.mdx b/operators/node-operators/management/regenesis-history.mdx similarity index 90% rename from pages/operators/node-operators/management/regenesis-history.mdx rename to operators/node-operators/management/regenesis-history.mdx index 251359299..79f60a542 100644 --- a/pages/operators/node-operators/management/regenesis-history.mdx +++ b/operators/node-operators/management/regenesis-history.mdx @@ -1,24 +1,8 @@ --- title: Accessing pre-regenesis history -lang: en-US description: Learn how to use access pre-regenesis history using the Etherscan CSV exporting tool. -content_type: guide -topic: pre-regenesis-history -personas: - - node-operator -categories: - - node-management - - infrastructure - - system-configuration - - network-upgrades - - analytics - - transaction-lifecycle - - execution-client - - transaction-flow -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Accessing pre-regenesis history diff --git a/pages/operators/node-operators/management/snap-sync.mdx b/operators/node-operators/management/snap-sync.mdx similarity index 90% rename from pages/operators/node-operators/management/snap-sync.mdx rename to operators/node-operators/management/snap-sync.mdx index 05c6a954b..6712383e4 100644 --- a/pages/operators/node-operators/management/snap-sync.mdx +++ b/operators/node-operators/management/snap-sync.mdx @@ -1,25 +1,8 @@ --- title: Using snap sync for node operators -lang: en-US description: Learn how to use and enable snap sync on your node. -content_type: guide -topic: using-snap-sync-for-node-operators -personas: - - node-operator -categories: - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client - - network-upgrades - - performance-tooling -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' -import { Tabs } from 'nextra/components' # Using snap sync for node operators @@ -35,12 +18,12 @@ This means that performing a Snap Sync is significantly faster than performing a ## Enable snap sync for your node - + For snap sync, all `op-geth` nodes should expose port `30303` TCP and `30303` UDP to easily find other op-geth nodes to sync from. * If you set the port with [`--discovery.port`](/operators/node-operators/configuration/execution-config#discoveryport), then you must open the port specified for UDP. * If you set [`--port`](/operators/node-operators/configuration/execution-config#port), then you must open the port specified for TCP. * The only exception is for sequencers and transaction ingress nodes. - + Choose one of the following options to enable snap sync: diff --git a/pages/operators/node-operators/management/snapshots.mdx b/operators/node-operators/management/snapshots.mdx similarity index 89% rename from pages/operators/node-operators/management/snapshots.mdx rename to operators/node-operators/management/snapshots.mdx index 0bb8d7730..5cfe9468a 100644 --- a/pages/operators/node-operators/management/snapshots.mdx +++ b/operators/node-operators/management/snapshots.mdx @@ -1,33 +1,17 @@ --- title: Snapshots -lang: en-US description: Find download links for data directories and database snapshots for running your own node. -content_type: guide -topic: node-snapshots -personas: - - node-operator -categories: - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client - - network-upgrades - - deployment-artifacts -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Node snapshots This page contains download links for data directories and node snapshots that can be used to more easily run your own node. Data directories and node snapshots are not required but can significantly simplify the node operation process. - + Data directories and node snapshots are **not required** for nodes using [snap sync](snap-sync) but are still required for archive nodes and in instances when you need to trace the entire chain. - + ## About the Bedrock migration @@ -37,21 +21,21 @@ Migrated OP Mainnet databases can be generated manually or pre-migrated database ## Snapshots - + Always verify snapshots by comparing the sha256sum of the downloaded file to the sha256sum listed on this page. Check the sha256sum of the downloaded file by running `sha256sum ` in a terminal. - + - + Using [aria2](https://aria2.github.io/) to download snapshots can significantly speed up the download process. - + ### OP Mainnet (full node) - + [Allnodes](https://www.allnodes.com) provides more recent full node snapshots for OP Mainnet and Testnet. You can find them [here](https://www.publicnode.com/snapshots#optimism). **Please note:** Allnodes is a 3rd party provider, and the Optimism Foundation hasn't verified the snapshots. - + | Snapshot Date | Size | Download Link | sha256sum | | ------------- | ----- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | @@ -59,9 +43,9 @@ Migrated OP Mainnet databases can be generated manually or pre-migrated database ### OP Mainnet (archive node) - + You can also download access the [Optimism Foundation datadir explorer](https://datadirs.optimism.io/?utm_source=op-docs\&utm_medium=docs) to find other snapshots. - + | Snapshot Date | Size | Download Link | sha256sum | | ----------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | diff --git a/pages/operators/node-operators/management/troubleshooting.mdx b/operators/node-operators/management/troubleshooting.mdx similarity index 92% rename from pages/operators/node-operators/management/troubleshooting.mdx rename to operators/node-operators/management/troubleshooting.mdx index 559f508fa..7d000ab10 100644 --- a/pages/operators/node-operators/management/troubleshooting.mdx +++ b/operators/node-operators/management/troubleshooting.mdx @@ -1,24 +1,8 @@ --- title: Node Troubleshooting -lang: en-US description: Learn solutions to common problems to troubleshoot your node. -content_type: troubleshooting -topic: node-troubleshooting -personas: - - node-operator -categories: - - node-management - - infrastructure - - system-configuration - - node-configuration - - execution-client - - consensus-client - - stability-monitoring - - security-monitoring-response -is_imported_content: 'false' --- -import {Callout} from 'nextra/components' # Node Troubleshooting diff --git a/pages/operators/node-operators/network-upgrades.mdx b/operators/node-operators/network-upgrades.mdx similarity index 95% rename from pages/operators/node-operators/network-upgrades.mdx rename to operators/node-operators/network-upgrades.mdx index a262de2c4..e0f82e3ec 100644 --- a/pages/operators/node-operators/network-upgrades.mdx +++ b/operators/node-operators/network-upgrades.mdx @@ -1,24 +1,8 @@ --- title: Network upgrades -lang: en-US description: Learn more about Superchain network activations. -content_type: guide -topic: network-upgrades -personas: - - node-operator -categories: - - protocol-upgrades - - hardfork-activation - - node-configuration - - system-configuration - - infrastructure - - execution-client - - consensus-client -is_imported_content: 'false' --- -import Image from 'next/image' -import { Steps, Callout } from 'nextra/components' # Network upgrade overview @@ -47,11 +31,11 @@ Network upgrades follow this general process in which the features included in the upgrade are put into a release version cut from the `develop` branch and then the software is deployed on production networks. - + "Baking" on a network means the node software has been deployed and is live. Engineers take this time to observe the behavior of the software on production networks. - + Node Software Release Timeline diff --git a/pages/operators/node-operators/releases.mdx b/operators/node-operators/releases.mdx similarity index 84% rename from pages/operators/node-operators/releases.mdx rename to operators/node-operators/releases.mdx index 95079c349..266e18d7e 100644 --- a/pages/operators/node-operators/releases.mdx +++ b/operators/node-operators/releases.mdx @@ -1,33 +1,17 @@ --- title: Node software releases -lang: en-US description: Off chain node software release information and how to stay up to date. -content_type: guide -topic: node-software-releases -personas: - - node-operator -categories: - - node-configuration - - infrastructure - - system-configuration - - deployment-artifacts - - node-management - - execution-client - - consensus-client - - docker -is_imported_content: 'false' --- -import { Callout } from 'nextra/components' # Node software releases This page gives information on the off chain node software release information. - + Our latest releases, notes, and changelogs can be found on GitHub. `op-node` releases can be found [here](https://github.com/ethereum-optimism/optimism/releases) and `op-geth` releases can be found [here](https://github.com/ethereum-optimism/op-geth/releases). - + ## Production releases diff --git a/pages/operators/node-operators/rollup-node.mdx b/operators/node-operators/rollup-node.mdx similarity index 93% rename from pages/operators/node-operators/rollup-node.mdx rename to operators/node-operators/rollup-node.mdx index 9bc58e2be..94b39a39b 100644 --- a/pages/operators/node-operators/rollup-node.mdx +++ b/operators/node-operators/rollup-node.mdx @@ -1,24 +1,8 @@ --- title: How to run a node in the Superchain -lang: en-US description: Learn how to run an OP Stack rollup node in the Superchain. -content_type: guide -topic: run-rollup-node -personas: - - node-operator -categories: - - rollup-node - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client - - monitoring -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # How to run a node in the Superchain @@ -36,9 +20,9 @@ Before building your node, you will learn fundamental aspects of OP Stack rollup * **Node Architecture**: OP Stack rollup nodes use the rollup node and execution client and can also support legacy geth for pre-bedrock historical execution requests. For more details, see the [Node Architecture](/operators/node-operators/architecture) guide. * **Network Upgrades**: Network upgrades for OP Stack rollup nodes are generally [activated by timestamps](/operators/node-operators/network-upgrades#activations). Failing to upgrade your node before the timestamp causes a chain divergence, requiring you to resync your node to reconcile the chain. Follow the established [Node Upgrade Process](/operators/node-operators/network-upgrades#upgrade-process) to avoid chain divergence. - + If you are building an archive node on OP Mainnet, then you'll need a [node snapshot](/operators/node-operators/management/snapshots). This is **not required** for nodes using [snap sync](/operators/node-operators/management/snap-sync). - + {

Build Your OP Stack Node

} @@ -64,9 +48,9 @@ OP Stack rollup nodes can be configured for individual needs. The following step * Enable [snap sync](/operators/node-operators/management/snap-sync) for your node to significantly improve the experience and speed of syncing an OP Stack node. This is an **optional** feature but highly recommended for node providers. - + Additional configuration options exist for [`op-geth`](/operators/node-operators/configuration/execution-config) and [`op-node`](/operators/node-operators/configuration/consensus-config), respectively. - +
## Run your node @@ -78,9 +62,9 @@ Now, you will run your node and set your node debugging log level for more granu You will now run your node from source for your Superchain network. Here are your options. - + The tutorial [Building a Node from Source](/operators/node-operators/tutorials/node-from-source) is a **pre-requisite** to running your node from source and must be completed first. - + * **Option 1:** Follow the [Running an OP Sepolia Node from Source](/operators/node-operators/tutorials/run-node-from-source) tutorial. * **Option 2:** Follow the [Running an OP Mainnet Node from Source](/operators/node-operators/tutorials/run-node-from-source) tutorial, if you plan to run a full node or archive node. @@ -104,9 +88,9 @@ It is important to regularly monitor your node, and you can optionally configure {

Setup Prometheus & Grafana

} - + The following steps are intended for `go-ethereum`, so it must be tweaked to work for rollup nodes running within the Superchain. - + * Setup [influxdb](https://geth.ethereum.org/docs/monitoring/dashboards#setting-up-influxdb) to hold metrics data. * Setup [prometheus](https://geth.ethereum.org/docs/monitoring/dashboards#setting-up-prometheus) to read your endpoint. @@ -122,11 +106,11 @@ It is important to regularly monitor your node, and you can optionally configure ## Node operator tutorials - + Got an idea for a new tutorial? We'd love to hear it. Head over to GitHub to [suggest a new tutorial](https://github.com/ethereum-optimism/docs/issues/new?assignees=\&labels=tutorial%2Cdocumentation%2Ccommunity-request\&projects=\&template=suggest_tutorial.yaml\&title=%5BTUTORIAL%5D+Add+PR+title). - + | Tutorial Name | Description | Difficulty Level | | ----------------------------------------------------------------------- | ------------------------------------------------------ | ---------------- | diff --git a/pages/operators/node-operators/tutorials/node-from-docker.mdx b/operators/node-operators/tutorials/node-from-docker.mdx similarity index 93% rename from pages/operators/node-operators/tutorials/node-from-docker.mdx rename to operators/node-operators/tutorials/node-from-docker.mdx index b17efcac6..50625b67d 100644 --- a/pages/operators/node-operators/tutorials/node-from-docker.mdx +++ b/operators/node-operators/tutorials/node-from-docker.mdx @@ -1,24 +1,8 @@ --- title: Running a Node With Docker -lang: en-US description: Learn how to run a node using Docker. -content_type: guide -topic: run-node-with-docker -personas: - - node-operator -categories: - - docker - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client - - monitoring -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Running a node with Docker diff --git a/pages/operators/node-operators/tutorials/node-from-source.mdx b/operators/node-operators/tutorials/node-from-source.mdx similarity index 94% rename from pages/operators/node-operators/tutorials/node-from-source.mdx rename to operators/node-operators/tutorials/node-from-source.mdx index 0caf296f6..8bde9fd7c 100644 --- a/pages/operators/node-operators/tutorials/node-from-source.mdx +++ b/operators/node-operators/tutorials/node-from-source.mdx @@ -1,21 +1,8 @@ --- title: Building a Superchain node from source -lang: en-US description: Learn how to build your own node without relying on images from Optimism. -content_type: guide -topic: build-node-from-source -personas: - - node-operator -categories: - - node-management - - execution-client - - consensus-client - - deployment-artifacts - - smart-contracts -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Building a Superchain node from source @@ -79,10 +66,10 @@ Read through the [Releases page](https://github.com/ethereum-optimism/optimism/r git checkout ``` - + Make sure to read the Releases page carefully to determine the correct branch to check out. Some releases may only be required for the OP Sepolia testnet. - + {

Build op-node

} @@ -120,10 +107,10 @@ Read through the [Releases page](https://github.com/ethereum-optimism/op-geth/re git checkout ``` - + Make sure to read the Releases page carefully to determine the correct branch to check out. Some releases may only be required for the OP Sepolia testnet. - + {

Build op-geth

} diff --git a/pages/operators/node-operators/tutorials/run-node-from-source.mdx b/operators/node-operators/tutorials/run-node-from-source.mdx similarity index 96% rename from pages/operators/node-operators/tutorials/run-node-from-source.mdx rename to operators/node-operators/tutorials/run-node-from-source.mdx index 07e9f9def..f99c0deaa 100644 --- a/pages/operators/node-operators/tutorials/run-node-from-source.mdx +++ b/operators/node-operators/tutorials/run-node-from-source.mdx @@ -1,24 +1,8 @@ --- title: Running a Superchain node from source -lang: en-US description: Learn how to run a Superchain node from source code for full nodes and archive nodes. -content_type: guide -topic: run-node-from-source -personas: - - node-operator -categories: - - node-configuration - - infrastructure - - system-configuration - - node-management - - execution-client - - consensus-client - - deployment-artifacts - - performance-tooling -is_imported_content: 'false' --- -import { Callout, Steps } from 'nextra/components' # Running a Superchain node from source @@ -49,9 +33,9 @@ Below are the storage needs as of June 2025: Based on these trends, node operators should plan for future storage needs and choose SSDs that can handle these increasing requirements. - + Geth supports a "freezer" feature to store older chain data on HDDs, saving SSD space. Configure this for OP Mainnet using the `--datadir.ancient` flag. See [Geth docs](https://geth.ethereum.org/docs/fundamentals/databases) and [OP docs](/operators/node-operators/configuration/execution-config#datadirancient) for details. - + ## Superchain nodes @@ -102,9 +86,9 @@ You can still start `op-geth` without yet running `op-node`, but the `op-geth` i {

Start op-geth

} - + If you want to run an archive node, you will need to set `--gcmode=archive`. If you want to run an OP Mainnet archive node, please refer to the [OP Mainnet archive nodes](#op-mainnet-archive-nodes) section. - + Use the following command to start `op-geth` in a default configuration. The JSON-RPC API will become available on port 8545. Refer to the `op-geth` [configuration documentation](/operators/node-operators/configuration/execution-config) for more detailed information about available options. @@ -158,15 +142,15 @@ Once you've started `op-geth`, you can start `op-node`. Use the following command to start `op-node` in a default configuration. Refer to the `op-node` [configuration documentation](/operators/node-operators/configuration/consensus-config) for more detailed information about available options. - + The `op-node` RPC should not be exposed publicly. If left exposed, it could accidentally expose admin controls to the public internet. - + - + Sync mode is set to `--syncmode=execution-layer` to enable [snap sync](/operators/node-operators/management/snap-sync) and remove the need to initialize the node with a data directory. - + ```bash ./bin/op-node \ @@ -180,11 +164,11 @@ Once you've started `op-geth`, you can start `op-node`. --l2.enginekind=geth ``` - + Some L1 nodes, like Erigon, do not support the `eth_getProof` RPC method that the `op-node` uses to load L1 data for certain processing steps. If you are using an L1 node that does not support `eth_getProof`, you will need to include the `--l1.trustrpc` flag when starting `op-node`. Note that this flag will cause `op-node` to trust the L1 node to provide correct data as it will no longer be able to independently verify the data it receives. - +
### Synchronization verification @@ -243,10 +227,10 @@ There are two stages on `op-geth` for snap sync: #### Full sync - + For OP Mainnet you will need access to the migrated database to run a full node with full sync. You can [migrate your own data directory](https://web.archive.org/web/20240110231645/https://blog.oplabs.co/reproduce-bedrock-migration/) or follow the options available for [archive nodes](#get-the-migrated-data-directory). - + Initial full synchronization can take several days or weeks to complete. During this time, you will initially observe `op-node` deriving blocks from Ethereum without sending these blocks to `op-geth`. This means that `op-node` is requesting blocks from Ethereum one-by-one and determining the corresponding OP Mainnet blocks that were published to Ethereum. @@ -276,9 +260,9 @@ INFO [06-26|14:02:12.982] Starting work on payload id=0x5542117d ## OP Mainnet archive nodes - + You only need an archive node if you need the historical state. Most node operators should default to full nodes. - + ### Get the migrated data directory diff --git a/package.json b/package.json deleted file mode 100644 index 97163bd87..000000000 --- a/package.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "op-docs", - "version": "0.0.1", - "description": "Optimism Docs", - "type": "module", - "scripts": { - "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs && pnpm check-redirects && pnpm validate-metadata && pnpm link-checker", - "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm fix-redirects && pnpm fix-links", - "spellcheck:lint": "cspell lint \"**/*.mdx\"", - "prepare": "husky", - "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", - "breadcrumbs": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/create-breadcrumbs.ts", - "check-breadcrumbs": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/breadcrumbs.ts", - "check-redirects": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/redirects.ts", - "fix-redirects": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/fix-redirects.ts", - "link-checker": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/link-checker.ts", - "fix-links": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/fix-broken-links.ts", - "validate-metadata": "CHANGED_FILES=$(git diff --name-only --cached) NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-validator.ts", - "validate-pr-metadata": "NODE_NO_WARNINGS=1 node --loader ts-node/esm utils/metadata-validator.ts --pr", - "dev": "next dev", - "build": "next build", - "start": "next start", - "postbuild": "next-sitemap" - }, - "dependencies": { - "@eth-optimism/contracts-ts": "^0.17.0", - "@eth-optimism/tokenlist": "^9.0.9", - "@feelback/react": "^0.3.4", - "@growthbook/growthbook-react": "^1.3.1", - "@headlessui/react": "^2.1.8", - "@remixicon/react": "^4.6.0", - "algoliasearch": "^4.23.3", - "clsx": "^2.1.1", - "dotenv": "^16.4.7", - "escape-string-regexp": "^5.0.0", - "glob": "^11.0.1", - "js-yaml": "^4.1.0", - "next": "14.2.21", - "next-sitemap": "^4.2.3", - "nextra": "2.13.2", - "nextra-theme-docs": "2.13.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "search-insights": "^2.15.0", - "toml": "^3.0.0", - "viem": "^2.21.18" - }, - "devDependencies": { - "@double-great/remark-lint-alt-text": "^1.0.0", - "@eth-optimism/core-utils": "^0.13.1", - "@eth-optimism/sdk": "^3.1.6", - "@types/dotenv": "^8.2.3", - "@types/glob": "^8.1.0", - "@types/js-yaml": "^4.0.9", - "@types/node": "18.11.10", - "cspell": "^8.1.3", - "eslint": "^8.53.0", - "eslint-plugin-mdx": "^2.2.0", - "ethers": "^5", - "globby": "^11.0.4", - "gray-matter": "^4.0.3", - "husky": "^9.1.7", - "remark": "^15.0.1", - "remark-code-import": "^1.2.0", - "remark-frontmatter": "^5.0.0", - "remark-gfm": "^3.0.1", - "remark-lint-frontmatter-schema": "^3.15.4", - "remark-lint-heading-style": "^3.1.2", - "remark-lint-list-item-indent": "^3.1.2", - "remark-lint-table-cell-padding": "^4.1.3", - "remark-lint-table-pipe-alignment": "^3.1.3", - "remark-lint-table-pipes": "^4.1.2", - "remark-lint-unordered-list-marker-style": "^3.1.2", - "remark-preset-lint-consistent": "^5.1.2", - "remark-preset-lint-recommended": "^6.1.3", - "ts-node": "10.9.2", - "typescript": "^5.3.2", - "unified-lint-rule": "^2.1.2", - "unist-util-visit": "^5.0.0" - }, - "pnpm": { - "patchedDependencies": { - "remark-lint-frontmatter-schema@3.15.4": "patches/remark-lint-frontmatter-schema@3.15.4.patch", - "remark-code-import@1.2.0": "patches/remark-code-import@1.2.0.patch", - "nextra@2.13.2": "patches/nextra@2.13.2.patch" - } - } -} \ No newline at end of file diff --git a/pages/404.mdx b/pages/404.mdx deleted file mode 100644 index 00ddf00f1..000000000 --- a/pages/404.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Page Not Found -lang: en-US -description: 404 page not found and directs users to submit a GitHub issue. -content_type: guide -topic: 404-page-not-found -personas: - - app-developer - - node-operator - - chain-operator - - partner - - protocol-developer - - auditor - - governance-participant -categories: - - troubleshooting -is_imported_content: 'false' ---- - -# Page Not Found - -![404 Error Warning.](/img/icons/404-page.svg) - -## Let's find our way back.
Visit the [homepage](index) to get started. - -#### Please help by [submitting an issue](https://github.com/ethereum-optimism/docs/issues/new/choose) for the broken link. ❤️ - diff --git a/pages/500.mdx b/pages/500.mdx deleted file mode 100644 index 296199875..000000000 --- a/pages/500.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Internal Server Error -lang: en-US -description: 500 internal server error and directs users to submit a git issue. -content_type: guide -topic: 500-internal-server-error -personas: - - app-developer - - node-operator - - chain-operator - - partner - - protocol-developer - - auditor - - governance-participant -categories: - - troubleshooting -is_imported_content: 'false' ---- - -# Unexpected Error - -![500 Error Warning.](/img/icons/500-page.svg) - -## Something isn't quite right. Let's start again on the [homepage](index). - -#### Please help by [submitting an issue](https://github.com/ethereum-optimism/docs/issues/new/choose) about what led you to this page. ❤️ diff --git a/pages/_app.tsx b/pages/_app.tsx deleted file mode 100644 index b32bfeab1..000000000 --- a/pages/_app.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import '../styles/global.css'; - -import { useEffect, useState } from 'react'; -import { useRouter } from 'next/router'; -import * as gtag from '../utils/gtag'; -import * as aa from 'search-insights'; -import AlgoliaContext from '@/utils/contexts/AlgoliaContext'; -import ScrollDispatcher from '@/components/ScrollDispatcher'; -import { CustomGrowthBookProvider } from '../providers/GrowthbookProvider'; - -export default function App({ Component, pageProps }) { - const [queryID, setQueryID] = useState(null); - const [objectID, setObjectID] = useState(null); - - const router = useRouter(); - useEffect(() => { - const handleRouteChange = (url) => { - gtag.pageview(url); - }; - router.events.on('routeChangeComplete', handleRouteChange); - return () => { - router.events.off('routeChangeComplete', handleRouteChange); - }; - }, [router.events]); - - // Initialize Algolia insights with environment variables - aa.default('init', { - appId: process.env.NEXT_PUBLIC_ALGOLIA_APPLICATION_ID || '', - apiKey: process.env.NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY || '' - }); - - return ( - - - - - - - - ); -} \ No newline at end of file diff --git a/pages/_document.tsx b/pages/_document.tsx deleted file mode 100644 index 487353b6b..000000000 --- a/pages/_document.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' - -import { GA_TRACKING_ID } from '../utils/gtag' - -export default class MyDocument extends Document { - render() { - return ( - - - {/* Global Site Tag (gtag.js) - Google Analytics */} - - )} - - ); - } -}; - -export default config; diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 532f0a431..000000000 --- a/tsconfig.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": false, - "forceConsistentCasingInFileNames": true, - "noEmit": false, - "incremental": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "baseUrl": "./", - "outDir": "./dist", - "paths": { - "@/components/*": ["components/*"], - "@/content/*": ["content/*"], - "@/utils/*": ["utils/*"], - "@/pages/*": ["pages/*"], - "@/message/*": ["messages/*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"], - "ts-node": { - "esm": true, - "experimentalSpecifierResolution": "node" - } -} \ No newline at end of file diff --git a/utils/algolia-indexer.ts b/utils/algolia-indexer.ts deleted file mode 100644 index b44029bd7..000000000 --- a/utils/algolia-indexer.ts +++ /dev/null @@ -1,132 +0,0 @@ -import fs from 'fs/promises'; -import matter from 'gray-matter'; -import algoliasearch, { SearchIndex } from 'algoliasearch'; -const globby = require("globby"); - -interface PageObject { - objectID?: string; - slug: string; - section: string; - content: string; - [key: string]: unknown; -} - -interface AlgoliaConfig { - appId: string; - apiKey: string; - indexName: string; -} - -// Configuration -const CONFIG = { - excludeFiles: [ - '!**.json', - '!pages/404.mdx', - '!pages/500.mdx', - '!pages/_app.mdx' - ], - maxContentSize: 9500, - algolia: { - appId: process.env.ALGOLIA_APPLICATION_ID || '', - apiKey: process.env.ALGOLIA_WRITE_API_KEY || '', - indexName: process.env.ALGOLIA_INDEX_NAME || '' - } as AlgoliaConfig -}; - -const sanitizeContent = (content: string, maxBytes: number): string => { - const encoder = new TextEncoder(); - const decoder = new TextDecoder('utf-8'); - const encoded = encoder.encode(content); - return decoder.decode(encoded.slice(0, maxBytes)); -}; - -const processPage = async (filePath: string): Promise => { - try { - const fileContents = await fs.readFile(filePath, 'utf8'); - const { data, content } = matter(fileContents); - const slug = `/${filePath.replace('pages/', '').replace('.mdx', '')}`; - - return content.split(/^(?=#+ )/m) - .filter(Boolean) - .map(section => ({ - ...data, - slug, - section: slug, - content: sanitizeContent(section, CONFIG.maxContentSize) - })); - } catch (error) { - console.error(`Error processing ${filePath}:`, error); - return []; - } -}; - -class AlgoliaManager { - private client: ReturnType; - private index: SearchIndex; - - constructor(config: AlgoliaConfig) { - this.validateConfig(config); - this.client = algoliasearch(config.appId, config.apiKey); - this.index = this.client.initIndex(config.indexName); - } - - private validateConfig(config: AlgoliaConfig): void { - if (!config.appId || !config.apiKey || !config.indexName) { - throw new Error('Missing required Algolia configuration'); - } - } - - async testConnection(): Promise { - try { - const indices = await this.client.listIndices(); - console.log('[Algolia] Connection successful. Available indices:', indices); - } catch (error) { - console.error('[Algolia] Connection failed:', error); - throw error; - } - } - -async updateIndex(objects: PageObject[]): Promise { - try { - console.log(`[Algolia] Starting index update with ${objects.length} records`); - - const response = await this.index.replaceAllObjects(objects, { - safe: true, - autoGenerateObjectIDIfNotExist: true - }); - - console.log(`[Algolia] Index update initiated. Task IDs:`, response.taskIDs); - - await Promise.all( - response.taskIDs.map(taskID => this.index.waitTask(taskID)) - ); - - console.log('[Algolia] Index update completed successfully'); - } catch (error) { - console.error('[Algolia] Index update failed:', error); - throw error; - } -} -} - -const main = async () => { - try { - - const pagePaths = await globby(['pages/', ...CONFIG.excludeFiles]); - console.log(`[Processing] Found ${pagePaths.length} pages to index`); - - const processingResults = await Promise.all(pagePaths.map(processPage)); - const indexObjects = processingResults.flat(); - - const algolia = new AlgoliaManager(CONFIG.algolia); - await algolia.testConnection(); - await algolia.updateIndex(indexObjects); - - } catch (error) { - console.error('[Main] Fatal error:', error); - process.exit(1); - } -}; - -// Execute -main(); \ No newline at end of file diff --git a/utils/breadcrumbs.ts b/utils/breadcrumbs.ts deleted file mode 100644 index 921655513..000000000 --- a/utils/breadcrumbs.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { fileURLToPath } from 'url' -import path from 'path' -import fs from 'fs' -import matter from 'gray-matter'; - -// Get current file path in ESM -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) - -const rootDir = path.join(__dirname, '..', 'pages'); -const warnings: string[] = []; - -// ANSI color codes -const YELLOW = '\x1b[33m'; -const RESET = '\x1b[0m'; -const BOLD = '\x1b[1m'; - -interface FileInfo { - title: string; - url: string; - description?: string; - content: string; -} - -// Pages to exclude from checks -const excludedPages = [ - '400.mdx', - '500.mdx', - 'index.mdx', - '404.mdx', - 'console', - 'block-explorer', - 'bridge', - 'sdk', - 'faucet', - 'gas', - 'bug-bounty', - 'live-support', - 'governance', - 'changelog', - 'experimental' -]; - -async function getContentFiles(folderPath: string): Promise { - const files = await fs.promises.readdir(folderPath, { withFileTypes: true }); - const fileInfos: FileInfo[] = []; - const folderName = path.basename(folderPath); - - for (const file of files) { - if (file.name.startsWith('_') || - file.name.startsWith('.') || - excludedPages.includes(file.name)) { - continue; - } - - const filePath = path.join(folderPath, file.name); - - if (file.isFile() && (file.name.endsWith('.md') || file.name.endsWith('.mdx'))) { - try { - const content = await fs.promises.readFile(filePath, 'utf-8'); - const { data: frontMatter } = matter(content); - const fileName = path.basename(file.name, path.extname(file.name)); - const fileTitle = frontMatter.title || fileName; - const relativeUrl = `/${path.relative(rootDir, filePath)}`.replace(/\.(md|mdx)$/, ''); - - fileInfos.push({ - title: fileTitle, - url: relativeUrl, - description: frontMatter.description, - content: content - }); - } catch (error) { - console.error(`Error processing file ${file.name}:`, error); - } - } - } - - return fileInfos; -} - -async function getBreadcrumbCards(breadcrumbPath: string): Promise> { - try { - const content = await fs.promises.readFile(breadcrumbPath, 'utf-8'); - const cardMatches = content.match(/]*href="([^"]+)"[^>]*>/g) || []; - return new Set( - cardMatches.map(match => { - const hrefMatch = match.match(/href="([^"]+)"/); - return hrefMatch ? hrefMatch[1] : ''; - }).filter(Boolean) - ); - } catch (error) { - return new Set(); - } -} - -async function checkDirectory(dirPath: string): Promise { - const entries = await fs.promises.readdir(dirPath, { withFileTypes: true }); - - for (const entry of entries) { - if (entry.isDirectory() && !entry.name.startsWith('_') && !entry.name.startsWith('.')) { - const folderPath = path.join(dirPath, entry.name); - const breadcrumbPath = path.join(dirPath, `${entry.name}.mdx`); - - // Get all content files in the folder - const files = await getContentFiles(folderPath); - - // Get existing cards in breadcrumb - const existingCards = await getBreadcrumbCards(breadcrumbPath); - - // Check for missing pages - files.forEach(({ title, url }) => { - if (!existingCards.has(url)) { - warnings.push( - `Page "${title}" at ${url} needs to be added to the breadcrumb file ${entry.name}.mdx` - ); - } - }); - - // Recursively check subdirectories - await checkDirectory(folderPath); - } - } -} - -async function main() { - console.log('Starting breadcrumb check process...'); - console.log('Root directory:', rootDir); - - try { - // Process main sections: builders, chain, connect, stack - const mainSections = ['app-developers', 'operators', 'superchain', 'stack']; - for (const section of mainSections) { - const sectionPath = path.join(rootDir, section); - try { - await fs.promises.access(sectionPath); - await checkDirectory(sectionPath); - console.log(`Completed checking ${section} section`); - } catch (error) { - console.log(`Skipping ${section} - directory not found`); - } - } - - if (warnings.length > 0) { - console.log(`${YELLOW}${BOLD}Missing pages in breadcrumb navigation:${RESET}`); - warnings.forEach(warning => console.log(`${YELLOW}- ${warning}${RESET}`)); - process.exit(1); - } else { - console.log('All pages are properly referenced in breadcrumb files.'); - } - } catch (error) { - console.log(`${YELLOW}${BOLD}Error checking breadcrumbs:${RESET}`, error); - process.exit(1); - } -} - -main().catch(error => { - console.error('Error in main process:', error); - process.exit(1); -}); diff --git a/utils/calculator-helpers.ts b/utils/calculator-helpers.ts deleted file mode 100644 index c2c9fcb26..000000000 --- a/utils/calculator-helpers.ts +++ /dev/null @@ -1,1083 +0,0 @@ -import { transactionTypes } from "./transaction-types"; - -const L1GasBaseFee = - "https://raw.githubusercontent.com/ethereum-optimism/op-analytics/refs/heads/main/reference_data/market_data/outputs/suggest_base_fee.txt"; // E76 -const ethToUsdRate = - "https://raw.githubusercontent.com/ethereum-optimism/op-analytics/refs/heads/main/reference_data/market_data/outputs/ethusd.txt"; // E77 -const blobBaseFee = - "https://raw.githubusercontent.com/ethereum-optimism/op-analytics/refs/heads/main/reference_data/market_data/outputs/blob_base_fee.txt"; // E78 - -// transactionsPerDay === E14: number -// comparableTxnType === E15: string -// dataAvailabilityType === E16: string -// isFaultProofsEnabled === E17: boolean -// targetDataMargin === E18: number -// maxChannelDuration === E22: number -// outputRootPostFrequency === E23: number -// isStateEnabled: boolean, === E24: string - -// ModeledExpectedStateCostsOnL1: number === e120 == n40 == e56 -// ModeledDACostsOnL1: number === e119 == e55 -// ModeledDAPlusStateRevenueOnL2: number === e118 - -function calculateBlobTransactionCost( - dataAvailabilityType: string, // E16: string - altDATransactionCost: number, // E98: number - blobDataFee: number, // E64: number - l1CalldataFee: number, // E67: number - l1CalldataCost: number, // E96: number - blobCost: number // E94: number -): number { - return dataAvailabilityType === "AltDA Plasma Mode" - ? altDATransactionCost - : blobDataFee > l1CalldataFee - ? l1CalldataCost - : blobCost; -} // output = E37 - -function calculateAltDAOrL1TransactionCost( - dataAvailabilityType: string, //E16 - altDAPlasmaModeCost: number, // F98 - blobDataFee: number, // E64 - l1CalldataFee: number, // E67 - l1CalldataAltCost: number, // F96 - blobAltCost: number // F94 -): number { - if (dataAvailabilityType === "AltDA Plasma Mode") { - return altDAPlasmaModeCost; - } else { - return blobDataFee > l1CalldataFee ? l1CalldataAltCost : blobAltCost; - } -} // output = E38 - -export function resultsFeeScalarsAssumed( - comparableTxnType: string, // e15 - transactionsPerDay: number, // e14 - dataAvailabilityType: string, // E16 - targetDataMargin: number, // E18 - isStateEnabled: string, // E24 - maxChannelDuration: number // E22 -): string { - const n25: number = calculateBlobLevelImpliedBlobFullness( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ) // n25 - - const n26: number = calculateImpliedBlobsPerL1Tx( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); // n26 - const mode = - dataAvailabilityType === "AltDA Plasma Mode" - ? "AltDA Plasma Mode, " - : `${Math.round(n25 * 100)}% Blob Fullness and ${ - Math.round(n26 * 10) / 10 - } Blobs per L1 Tx (Avg), `; - const state = isStateEnabled === "Yes" ? " & State" : ""; - return `Fee Scalars Assume: ${mode}Target a ${Math.round( - targetDataMargin - )}% Margin on DA${state}, ${ - Math.round(maxChannelDuration * 100000) / 100000 - } hour Max Submission Window.`; -} // output = G41 - -export async function impliedDataGasFee( - dataAvailabilityType: string, // E16 -): Promise { - const blobgasBaseFee: number = await getBlobBaseFee()// E78 - const l1BaseFee: number = await getL1GasBaseFee(); // E76 - const ethToUsdRate: number = await getEthToUsdRate() // E77 - const mode = - dataAvailabilityType === "AltDA Plasma Mode" - ? "AltDA Plasma Mode, " - : `${Math.round(blobgasBaseFee * 100) / 100} gwei Blobgas Base Fee, `; - return `Implied Data Gas Fee Assumes: ${mode}${ - Math.round(l1BaseFee * 10) / 10 - } gwei L1 Base Fee, ${Math.round(ethToUsdRate)} ETH/USD`; -} // output = G42 - -export function convertToMillionUnits(value: number): number { - return value / 1000000; -} - -export async function getEthToUsdRate(): Promise { - try { - const response = await fetch(ethToUsdRate); - if (!response.ok) { - throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`); - } - const rateText = await response.text(); - const rate = parseFloat(rateText); - if (isNaN(rate)) { - throw new Error(`Failed to parse ETH to USD rate: ${rateText}`); - } - return rate; - } catch (error) { - console.error('Error fetching ETH to USD rate:', error); - throw error; - } -} - -export const determineDAInUse = (dataAvailabilityType: string): string => { - return dataAvailabilityType === "AltDA Plasma Mode" - ? "AltDA Plasma Mode" - : dataAvailabilityType === "L1 Calldata" - ? "L1 Calldata" - : "EIP-4844"; -}; - -// =INDEX($A$20:$G$32,MATCH('Chain Estimator'!$E$15,$A$20:$A$32,0),MATCH($B8,$A$20:$G$20,0)) -const getAvgEstimatedSizePerTx = (comparableTxnType: string) => { - if (!transactionTypes[comparableTxnType]) { - throw new Error(`Invalid transaction type: ${comparableTxnType}`); - } - const output = transactionTypes[comparableTxnType].AvgEstimatedSizePerTx; - console.log("c8::", output); - return output; -}; // c8 done - -// =(N22*N5)/(C8*'Chain Estimator'!E14) -const calculateImpliedCTSL1Data = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n22 = calculateImpliedBlobsPerDay( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const n5 = Total_Blobgas_Per_Blob; - const output = (n22 * n5) / (c8 * transactionsPerDay); ; - console.log("c10::", output); - return output; -}; // c10 done - -// =(C8*'Chain Estimator'!E14*C13 + N11*N27)/(C8*'Chain Estimator'!E14) -const calculateImpliedCTSL1Gas = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const c13 = getEstimatedSizeCalldataGasRatio(comparableTxnType); - const n27 = calculateImpliedL1Txs( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const numerator = - c8 * transactionsPerDay * c13 + Avg_Compressed_Overhead_Gas_Per_Blob * n27; - const denominator = c8 * transactionsPerDay; - const output = numerator / denominator; - console.log("c11::", output); - return output; -}; // c11 done - -// =INDEX($A$20:$G$32,MATCH('Chain Estimator'!$E$15,$A$20:$A$32,0),MATCH($B12,$A$20:$G$20,0)) -const getEstimatedSizeBlobgasRatio = (comparableTxnType: string) => { - const output = transactionTypes[comparableTxnType].EstimatedSizeBlobgasRatio; - console.log("c12::", output); - return output; -}; // c12 done - -const getEstimatedSizeCalldataGasRatio = (comparableTxnType: string) => { - const output = - transactionTypes[comparableTxnType].EstimatedSizeCalldataGasRatio; - console.log("c13::", output); - return output; -}; // c13 done - -// =24/'Chain Estimator'!E22 -const calculateImpliedMinimumBlobsPerDay = ( - maxChannelDuration: number -) => { - const output = 24 / maxChannelDuration; - console.log("n19::", output); - return output; -}; // n19 - -// =(N5-N10-N6)*C12 -const calculateImpliedEstimatedSizePerBlob = ( - comparableTxnType: string -): number => { - const c12 = getEstimatedSizeBlobgasRatio(comparableTxnType); - const output = - (Total_Blobgas_Per_Blob - - Avg_Compressed_Overhead_Bytes_Per_Blob - - Overhead_Blobgas_per_Blob) * - c12; - console.log("n20::", output); - return output; -}; // n20 done - -// =MIN(N20/C8,'Chain Estimator'!E14/(24/'Chain Estimator'!E22)) -const calculateImpliedL2TxsPerBlob = ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const n20 = calculateImpliedEstimatedSizePerBlob(comparableTxnType); - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const value1 = n20 / c8; - const value2 = transactionsPerDay / (24 / maxChannelDuration); - const output = Math.min(value1, value2); - console.log("n21::", output); - return output; -}; // n21 done - -// ='Chain Estimator'!E14/N21 -const calculateImpliedBlobsPerDay = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const output = - transactionsPerDay / - calculateImpliedL2TxsPerBlob( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); - console.log("n22::", output); - return output; -}; // n22 done - -// =N20*N22*(C11/16)+(N11*N22) -const calculateImpliedCalldataGasUsedIfL1 = ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const n20 = calculateImpliedEstimatedSizePerBlob(comparableTxnType); - const n22 = calculateImpliedBlobsPerDay( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const c11 = calculateImpliedCTSL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const output = - n20 * n22 * (c11 / 16) + (Avg_Compressed_Overhead_Gas_Per_Blob * n22); - console.log("n23::", output); - return output; -}; // n23 done - -// =MIN(N9,(C8*'Chain Estimator'!E14)*('Chain Estimator'!E22/24)/N20) -const calculateL1TxLevelImpliedBlobFullness = ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const c8 = getEstimatedSizeCalldataGasRatio(comparableTxnType); - const n20 = calculateImpliedEstimatedSizePerBlob(comparableTxnType); - const result = (c8 * transactionsPerDay * (maxChannelDuration / 24)) / n20; - const output = Math.min(Max_No_Of_Blobs_Per_L1_Transaction, result); - console.log("n24::", output); - return output; -}; // n24 done - -// =(N21*C8)/N20 -const calculateBlobLevelImpliedBlobFullness = ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const n21 = calculateImpliedL2TxsPerBlob( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const n20 = calculateImpliedEstimatedSizePerBlob(comparableTxnType); - const output = (n21 * c8) / n20; - console.log("n25::", output); - return output; -}; // n25 done - -// =ROUND(MAX(N24/1,1),0) -const calculateImpliedBlobsPerL1Tx = ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const n24 = calculateL1TxLevelImpliedBlobFullness( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); - const maxValue = Math.max(n24, 1); - const output = Math.round(maxValue); - console.log("n26::", output); - return output; -}; // n26 done - -// =N22/N26 -const calculateImpliedL1Txs = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n22 = calculateImpliedBlobsPerDay( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const n26 = calculateImpliedBlobsPerL1Tx( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); - const output = n22 / n26; - console.log("n27::", output); - return output; -}; // n27 done - -// =N27*N7 -const calculateTotalBlobCommitmentL1Gas = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n27 = calculateImpliedL1Txs( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const output = n27 * L1_Gas_per_Blob_Commitment; - console.log("n30::", output); - return output; -}; // n30 done - -// =N22*N8 -const calculateTotalAltDAPlasmaModeCommitmentL1Gas = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n22 = calculateImpliedBlobsPerDay( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const output = n22 * L1_Gas_Per_AltDA_Plasma_Mode_Commitment; - console.log("n31::", output); - return output; -}; // n31 done - -// N22 * N5 -const calculateTotalBlobgas = ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n22 = calculateImpliedBlobsPerDay( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const output = n22 * Total_Blobgas_Per_Blob; - console.log("n32::", output) - return output; -}; // n32 - -// =IF('Chain Estimator'!E23=0,0,24/'Chain Estimator'!E23) -const calculateImpliedStateProposalsPerDay = ( - outputRootPostFrequency: number -) => { - const output = - outputRootPostFrequency === 0 ? 0 : 24 / outputRootPostFrequency; - console.log("n33::", output); - return output; -}; // n33 done - -// =N33*IF('Chain Estimator'!E17="Yes",N16,N12) -const calculateTotalStateProposalL1Gas = ( - outputRootPostFrequency: number, - isFaultProofsEnabled: boolean -): number => { - const n33 = calculateImpliedStateProposalsPerDay(outputRootPostFrequency); - const output = - n33 * - (isFaultProofsEnabled - ? Avg_Total_Gas_Used_Per_L1_Fault_Proof_State_Proposal - : Avg_Total_Gas_Used_Per_L1_State_Proposal); - console.log("n34::", output); - return output; -}; // n34 done - -// =IF('Chain Estimator'!E24="Yes",1,0)*N34 -const calculateTotalStateProposalL1GasCoveredByUsers = ( - isStateEnabled: boolean, - outputRootPostFrequency: number, - isFaultProofsEnabled: boolean -) => { - const n34 = calculateTotalStateProposalL1Gas( - outputRootPostFrequency, - isFaultProofsEnabled - ); - const output = (isStateEnabled ? 1 : 0) * n34; - console.log("n35::", output); - return output; -}; // n35 done - -// =N30*'Chain Estimator'!E76/1000000000 -const calculateTotalBlobCommitmentCostsInETH = async ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n30 = calculateTotalBlobCommitmentL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const e76 = await getL1GasBaseFee(); - const output = (n30 * e76) / 1000000000; - console.log("n36::", output) - return output; -} // n36 - -// =N31*'Chain Estimator'!E76/1000000000 -const calculateTotalAltDAPlasmaModeCommitmentCostsInETH = async ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n31 = calculateTotalAltDAPlasmaModeCommitmentL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const e76 = await getL1GasBaseFee(); - const output = n31 * e76 / 1000000000; - console.log("n37::", output) - return output; -} // n37 done - -// =N32*'Chain Estimator'!E78/1000000000 -const calculateTotalBlobgasCostsInETH = async ( - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -) => { - const n32 = calculateTotalBlobgas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const e78 = await getBlobBaseFee(); - const output = (n32 * e78) / 1000000000; - console.log("n38::", output); - return output; -} // n38 - -// =N23*'Chain Estimator'!E76/1000000000 -const calculateTotalL1CalldataCostsInETHIfL1 = async ( - comparableTxnType: string, - transactionsPerDay: number, - maxChannelDuration: number -) => { - const n23 = calculateImpliedCalldataGasUsedIfL1( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ) - const e76 = await getL1GasBaseFee(); - const output = (n23 * e76) / 1000000000; - console.log("n39::", output); - return output; -} // n39 - -const _calculateL1BlobBaseFeeScalar = ( - determinedDAInUse: string, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number -) => { - let output = 0; - const c10 = calculateImpliedCTSL1Data( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const n25 = calculateBlobLevelImpliedBlobFullness( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ); - const e18 = _targetDataMarginInPercentage(targetDataMargin); - if (determinedDAInUse === "EIP-4844") { - output = (c10 / n25 / (1 - e18)) * 1000000; - } - - console.log("_calculateL1BlobBaseFeeScalar:::", output); - return Math.round(output); -}; - -async function getL1GasBaseFee(): Promise { - try { - const response = await fetch(L1GasBaseFee); - if (!response.ok) { - throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`); - } - const baseFeeText = await response.text(); - console.log("L1GasBaseFee_response::", baseFeeText); - const output = parseFloat(baseFeeText); - if (isNaN(output)) { - throw new Error(`Failed to parse L1 Gas Base Fee: ${baseFeeText}`); - } - console.log("e76:::", output); - return output; - } catch (error) { - console.error('Error fetching L1 Gas Base Fee:', error); - throw error; - } -} - -const getBlobBaseFee = async (): Promise => { - try { - const response = await fetch(blobBaseFee); - if (!response.ok) { - throw new Error(`Network response was not ok: ${response.status} ${response.statusText}`); - } - const feeText = await response.text(); - console.log("BlobBaseFee_response::", feeText); - const output = parseFloat(feeText); - if (isNaN(output)) { - throw new Error(`Failed to parse Blob Base Fee: ${feeText}`); - } - console.log("e78:::", output); - return output; - } catch (error) { - console.error('Error fetching Blob Base Fee:', error); - throw error; - } -}; - -// =ROUND((('Advanced Inputs'!C10/'Advanced Inputs'!N25/(1-E18))*1000000),0) -const calculateL1BlobBaseFeeScalarUsingBlob = ( - determinedDAInUse: string, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number -) => { - const output = _calculateL1BlobBaseFeeScalar( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - console.log("e94:::", output); - return output; -}; // e94 done - -const calculateL1BlobBaseFeeScalarUsingL1Calldata = ( - determinedDAInUse: string, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number -) => { - const output = _calculateL1BlobBaseFeeScalar( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - console.log("e96::", output); - return output; -}; // e96 done - -const calculateL1BlobBaseFeeScalarUsingPlasmaMode = ( - determinedDAInUse: string, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number -) => { - const output = _calculateL1BlobBaseFeeScalar( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - console.log("e98::", output); - return output; -}; // e98 done - -const calculateL1BaseFeeScalarUsingBlobs = ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number -) => { - const n30 = calculateTotalBlobCommitmentL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const n35 = calculateTotalStateProposalL1GasCoveredByUsers( - isStateEnabled, - outputRootPostFrequency, - isFaultProofsEnabled - ); - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const e18 = _targetDataMarginInPercentage(targetDataMargin); - const numerator = n30 + n35; - const denominator = transactionsPerDay * (16 * c8); - const result = numerator / denominator / (1 - e18); - return Math.round(result * 1000000); -}; // f94 done - -const calculateL1BaseFeeScalarUsingL1Calldata = ( - targetDataMargin: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -): number => { - const e18 = _targetDataMarginInPercentage(targetDataMargin); - const c11 = calculateImpliedCTSL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const value = c11 / 16 / (1 - e18); - const output = Math.round(value * 1000000); - console.log("f96::", output) - return output -}; // f96 done - -const calculateL1BaseFeeScalarUsingPlasmaMode = ( - targetDataMargin: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - isStateEnabled: boolean, - outputRootPostFrequency: number, - isFaultProofsEnabled: boolean -) => { - const n31 = calculateTotalAltDAPlasmaModeCommitmentL1Gas( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const n35 = calculateTotalStateProposalL1GasCoveredByUsers( - isStateEnabled, - outputRootPostFrequency, - isFaultProofsEnabled - ); - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const e18 = _targetDataMarginInPercentage(targetDataMargin); - const value = (n31 + n35) / (transactionsPerDay * (16 * c8)) / (1 - e18); - const output = Math.round(value * 1000000); - console.log("f98::", output); - return output; -}; // f98 done - -const _targetDataMarginInPercentage = (targetDataMargin: number): number => { - return targetDataMargin / 100; -}; - -const _getCalculateImpliedDataGasFeePerTxParams = async ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number, - dataAvailabilityType: string -) => { - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const f94 = calculateL1BaseFeeScalarUsingBlobs( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const f96 = calculateL1BaseFeeScalarUsingL1Calldata( - targetDataMargin, - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const e76 = await getL1GasBaseFee(); - const determinedDAInUse = determineDAInUse(dataAvailabilityType); - const e94 = calculateL1BlobBaseFeeScalarUsingBlob( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const e96 = calculateL1BlobBaseFeeScalarUsingL1Calldata( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const e78 = await getBlobBaseFee(); - const e77 = await getEthToUsdRate(); - return { c8, e76, e77, e78, e94, e96, f94, f96 }; -}; - -const _getBaseFeeScalarCalculationParams = async ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number, - dataAvailabilityType: string -) => { - const determinedDAInUse = determineDAInUse(dataAvailabilityType); - const e98 = calculateL1BlobBaseFeeScalarUsingPlasmaMode( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const e64 = await calculateImpliedDataGasFeePerTxUsingBlobs( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - dataAvailabilityType, - targetDataMargin - ); - const e67 = await calculateImpliedDataGasFeePerTxUsingL1Calldata( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - dataAvailabilityType, - targetDataMargin - ); - const e96 = calculateL1BlobBaseFeeScalarUsingL1Calldata( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const e94 = calculateL1BlobBaseFeeScalarUsingBlob( - determinedDAInUse, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const f94 = calculateL1BaseFeeScalarUsingBlobs( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin - ); - const f96 = calculateL1BaseFeeScalarUsingL1Calldata( - targetDataMargin, - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const f98 = calculateL1BaseFeeScalarUsingPlasmaMode( - targetDataMargin, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - isStateEnabled, - outputRootPostFrequency, - isFaultProofsEnabled - ); - return { e98, e64, e67, e96, e94, f94, f96, f98 }; -}; - -export const calculateImpliedDataGasFeePerTxUsingBlobs = async ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - dataAvailabilityType: string, - targetDataMargin: number -) => { - const { c8, f94, e76, e77, e78, e94 } = - await _getCalculateImpliedDataGasFeePerTxParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - const value = (c8 * (16 * f94 * e76 + e94 * e78)) / 1000000 / 1000000000; - const output = value * e77; - console.log("e64::", output) - return output -}; // e64 done - -// =('Advanced Inputs'!C8*(16*F98*E76+E98*E78)/1000000/1000000000)*E77 -export const calculateImpliedDataGasFeePerTxUsingAltDAPlasmaMode = async ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - dataAvailabilityType: string, - targetDataMargin: number -) => { - const { c8, e76, e77, e78} = - await _getCalculateImpliedDataGasFeePerTxParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - const { f98, e98 } = await _getBaseFeeScalarCalculationParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - - const part1 = 16 * f98 * e76; - const part2 = e98 * e78; - const sum = part1 + part2; - const result = sum / 1000000 / 1000000000; - const output = c8 * result * e77; - console.log("e66::", output); - return output; -}; // e66 - -export const calculateImpliedDataGasFeePerTxUsingL1Calldata = async ( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - dataAvailabilityType: string, - targetDataMargin: number -) => { - const { c8, f96, e76, e77, e78, e96 } = - await _getCalculateImpliedDataGasFeePerTxParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - const value = (c8 * (16 * f96 * e76 + e96 * e78)) / 1000000 / 1000000000; - const output = value * e77; - console.log("e67::", output); - return output; -}; // e67 done - -// =N34*'Chain Estimator'!E76/1000000000 -export const calculateTotalL1StateProposalCostsInETH = async ( - outputRootPostFrequency: number, - isFaultProofsEnabled: boolean -) => { - const n34 = calculateTotalStateProposalL1Gas( - outputRootPostFrequency, - isFaultProofsEnabled - ); - const e76 = await getL1GasBaseFee(); - const output = (n34 * e76) / 1000000000; - console.log("n40::", output) - return output; -}; // n40 done - -export async function displayL1BlobBaseFeeScalar( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - dataAvailabilityType: string, - targetDataMargin: number -) { - const { e98, e64, e67, e96, e94 } = await _getBaseFeeScalarCalculationParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - return calculateBlobTransactionCost( - dataAvailabilityType, - e98, - e64, - e67, - e96, - e94 - ); -} // e37 done - -export async function displayL1BaseFeeScalar( - isStateEnabled: boolean, - isFaultProofsEnabled: boolean, - outputRootPostFrequency: number, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string, - targetDataMargin: number, - dataAvailabilityType: string -) { - const { f98, e64, e67, f96, f94 } = await _getBaseFeeScalarCalculationParams( - isStateEnabled, - isFaultProofsEnabled, - outputRootPostFrequency, - transactionsPerDay, - maxChannelDuration, - comparableTxnType, - targetDataMargin, - dataAvailabilityType - ); - return calculateAltDAOrL1TransactionCost(dataAvailabilityType, f98, e64, e67, f96, f94); -} // e38 done - -// =E118-(E56+E55) | OverallL1DataAndStateCostsMargin -export const calculateOverallL1DataAndStateCostsMargin = async ( - transactionsPerDay: number, - comparableTxnType: string, - displayL1BlobBaseFeeScalar: number, - displayL1BaseFeeScalar: number, - dataAvailabilityType: string, - maxChannelDuration: number, - outputRootPostFrequency: number, - isFaultProofsEnabled: boolean -) => { - const e118 = await calculateModeledDAPlusStateRevenueOnL2(transactionsPerDay, comparableTxnType, displayL1BlobBaseFeeScalar, displayL1BaseFeeScalar) - const e55 = await calculateModeledDACostsOnL1( - dataAvailabilityType, - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const e56 = await calculateTotalL1StateProposalCostsInETH( - outputRootPostFrequency, - isFaultProofsEnabled - ) - const output = e118 - (e56 + e55); - console.log("e58::", output); - return output; -} // e58 - -// =(E14*'Advanced Inputs'!C8*(16*G38*E76/1000000000+G37*E78/1000000000)) -export const calculateModeledDAPlusStateRevenueOnL2 = async ( - transactionsPerDay: number, - comparableTxnType: string, - displayL1BlobBaseFeeScalar: number, - displayL1BaseFeeScalar: number -) => { - const c8 = getAvgEstimatedSizePerTx(comparableTxnType); - const g38 = convertToMillionUnits(displayL1BaseFeeScalar); - const g37 = convertToMillionUnits(displayL1BlobBaseFeeScalar); - const e76 = await getL1GasBaseFee(); - const e78 = await getBlobBaseFee(); - const part1 = (16 * g38 * e76) / 1000000000; - const part2 = (g37 * e78) / 1000000000; - const output = transactionsPerDay * c8 * (part1 + part2); - console.log("e118::", output) - return output -} // e118 - -async function calculateModeledDACostsOnL1( - dataAvailabilityType: string, - transactionsPerDay: number, - maxChannelDuration: number, - comparableTxnType: string -): Promise { - let output = 0; - const f35 = determineDAInUse(dataAvailabilityType); - const n36 = await calculateTotalBlobCommitmentCostsInETH( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ); - const n37 = await calculateTotalAltDAPlasmaModeCommitmentCostsInETH( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const n38 = await calculateTotalBlobgasCostsInETH( - transactionsPerDay, - maxChannelDuration, - comparableTxnType - ) - const n39 = await calculateTotalL1CalldataCostsInETHIfL1( - comparableTxnType, - transactionsPerDay, - maxChannelDuration - ) - if (dataAvailabilityType === "AltDA Plasma Mode") { - output = n37; - } else if (f35 === "EIP-4844") { - output = n36 + n38; - } else { - output = n39; - } - console.log("e119::", output) - return output -} // e119 - - -export const Total_Blobgas_Per_Blob = 131072; // N5 -export const Overhead_Blobgas_per_Blob = 1028; // N6 -export const L1_Gas_per_Blob_Commitment = 21000.0; // N7 -export const L1_Gas_Per_AltDA_Plasma_Mode_Commitment = 21532.0; // N8 -export const Max_No_Of_Blobs_Per_L1_Transaction = 5; // N9 -export const Avg_Compressed_Overhead_Bytes_Per_Blob = 406; // N10 -export const Avg_Compressed_Overhead_Gas_Per_Blob = 6385; // N11 -export const Avg_Total_Gas_Used_Per_L1_State_Proposal = 86847.5; // N12 -export const FastLZ_Intercept = -42585600; // N13 -export const FastLZ_Coefficient = 836500; // N14 -export const FatLZ_Min_Transaction_Size = 100; // N15 -export const Avg_Total_Gas_Used_Per_L1_Fault_Proof_State_Proposal = 420926.0; // N16 \ No newline at end of file diff --git a/utils/constants.ts b/utils/constants.ts deleted file mode 100644 index 40165a5dc..000000000 --- a/utils/constants.ts +++ /dev/null @@ -1,52 +0,0 @@ -export const PREDEPLOYS = { - 'L2ToL1MessagePasser': '0x4200000000000000000000000000000000000016', - 'L2CrossDomainMessenger': '0x4200000000000000000000000000000000000007', - 'L2StandardBridge': '0x4200000000000000000000000000000000000010', - 'L2ERC721Bridge': '0x4200000000000000000000000000000000000014', - 'SequencerFeeVault': '0x4200000000000000000000000000000000000011', - 'OptimismMintableERC20Factory': '0x4200000000000000000000000000000000000012', - 'OptimismMintableERC721Factory': '0x4200000000000000000000000000000000000017', - 'L1Block': '0x4200000000000000000000000000000000000015', - 'GasPriceOracle': '0x420000000000000000000000000000000000000F', - 'L1MessageSender': '0x4200000000000000000000000000000000000001', - 'DeployerWhitelist': '0x4200000000000000000000000000000000000002', - 'LegacyERC20ETH': '0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000', - 'L1BlockNumber': '0x4200000000000000000000000000000000000013', - 'LegacyMessagePasser': '0x4200000000000000000000000000000000000000', - 'ProxyAdmin': '0x4200000000000000000000000000000000000018', - 'BaseFeeVault': '0x4200000000000000000000000000000000000019', - 'L1FeeVault': '0x420000000000000000000000000000000000001A', - 'GovernanceToken': '0x4200000000000000000000000000000000000042', - 'SchemaRegistry': '0x4200000000000000000000000000000000000020', - 'EAS': '0x4200000000000000000000000000000000000021' -} - -export const LEGACY_CONTRACT_NAMES = [ - 'AddressManager', - 'DeployerWhitelist', - 'L1MessageSender', - 'LegacyERC20ETH', - 'LegacyMessagePasser', - 'L1BlockNumber', -] - -export const CHAIN_CONSTANTS = { - 1: { - explorer: 'https://etherscan.io', - }, - 5: { - explorer: 'https://goerli.etherscan.io', - }, - 10: { - explorer: 'https://optimistic.etherscan.io', - }, - 420: { - explorer: 'https://goerli-optimism.etherscan.io', - }, - 11155111: { - explorer: 'https://sepolia.etherscan.io', - }, - 11155420: { - explorer: 'https://sepolia-optimism.etherscan.io', - }, -} diff --git a/utils/contexts/AlgoliaContext.ts b/utils/contexts/AlgoliaContext.ts deleted file mode 100644 index 57998d3dd..000000000 --- a/utils/contexts/AlgoliaContext.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createContext } from "react" - -const AlgoliaContext = createContext(null) - -export default AlgoliaContext diff --git a/utils/create-breadcrumbs.ts b/utils/create-breadcrumbs.ts deleted file mode 100644 index 20ac55836..000000000 --- a/utils/create-breadcrumbs.ts +++ /dev/null @@ -1,259 +0,0 @@ -import * as fs from 'fs/promises'; -import * as path from 'path'; -import matter from 'gray-matter'; - -const rootDir = path.join(process.cwd(), 'pages'); - -interface FileInfo { - title: string; - url: string; - description?: string; - content: string; -} - -// Pages to exclude -const excludedPages = [ - '400.mdx', - '500.mdx', - 'index.mdx', - '404.mdx', - '_app.tsx', - '_document.tsx', - '_meta.json' -]; - -function toTitleCase(str: string): string { - return str.split('-') - .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) - .join(' '); -} - -function extractFirstParagraph(content: string): string { - // Remove frontmatter - content = content.replace(/^---[\s\S]*?---/, ''); - - // Remove import statements - content = content.replace(/^import[\s\S]*?\n/gm, ''); - - // Remove HTML/MDX tags - content = content.replace(/<[^>]+>/g, ' '); - - // Remove markdown links but keep text - content = content.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1'); - - // Remove headers - content = content.replace(/^#.+$/gm, ''); - - const paragraphs = content.split(/\n\n+/); - const firstParagraph = paragraphs.find(p => { - const cleaned = p.trim(); - return cleaned.length > 30 && // Minimum length - !cleaned.startsWith('import') && - !cleaned.startsWith('export'); - }); - - if (firstParagraph) { - const cleaned = firstParagraph.replace(/\s+/g, ' ').trim(); - return cleaned.length > 150 ? cleaned.slice(0, 147) + '...' : cleaned; - } - - return ''; -} - -async function generateFolderDescription(folderName: string, files: FileInfo[]): Promise { - if (files.length === 0) { - return `Documentation for ${toTitleCase(folderName)} is coming soon.`; - } - - // Try to find overview or introduction file - const overviewFile = files.find(file => - file.url.toLowerCase().includes('overview') || - file.url.toLowerCase().includes('introduction') - ); - - if (overviewFile && overviewFile.content) { - const desc = extractFirstParagraph(overviewFile.content); - if (desc) return desc; - } - - // Generate description from files if no overview is found - const topics = files.map(file => toTitleCase(path.basename(file.url))).join(', '); - return `Documentation covering ${topics} in the ${toTitleCase(folderName)} section of the OP Stack ecosystem.`; -} - -async function getContentFiles(folderPath: string): Promise { - const files = await fs.readdir(folderPath, { withFileTypes: true }); - const fileInfos: FileInfo[] = []; - const folderName = path.basename(folderPath); - - for (const file of files) { - if (file.name.startsWith('_') || - file.name.startsWith('.') || - excludedPages.includes(file.name)) { - continue; - } - - const filePath = path.join(folderPath, file.name); - - if (file.isFile() && (file.name.endsWith('.md') || file.name.endsWith('.mdx'))) { - try { - const content = await fs.readFile(filePath, 'utf-8'); - const { data: frontMatter } = matter(content); - const fileName = path.basename(file.name, path.extname(file.name)); - const fileTitle = frontMatter.title || toTitleCase(fileName); - const relativeUrl = `/${path.relative(rootDir, filePath)}`.replace(/\.(md|mdx)$/, ''); - - fileInfos.push({ - title: fileTitle, - url: relativeUrl, - description: frontMatter.description, - content: content - }); - } catch (error) { - console.error(`Error processing file ${file.name}:`, error); - } - } - } - - return fileInfos; -} - -async function getExistingBreadcrumbContent(breadcrumbPath: string): Promise<{ - existingContent: string; - existingCards: Set; -} | null> { - try { - const content = await fs.readFile(breadcrumbPath, 'utf-8'); - const cardMatches = content.match(/]*href="([^"]+)"[^>]*>/g) || []; - const existingCards = new Set( - cardMatches.map(match => { - const hrefMatch = match.match(/href="([^"]+)"/); - return hrefMatch ? hrefMatch[1] : ''; - }).filter(Boolean) - ); - return { existingContent: content, existingCards }; - } catch (error) { - return null; - } -} - -async function createOrUpdateBreadcrumb(parentPath: string, folderName: string): Promise { - const folderPath = path.join(parentPath, folderName); - const breadcrumbPath = path.join(parentPath, `${folderName}.mdx`); - - // Get current files in the folder - const files = await getContentFiles(folderPath); - - // Check existing breadcrumb - const existing = await getExistingBreadcrumbContent(breadcrumbPath); - - if (existing) { - // If breadcrumb exists, only add new cards - const newCards: string[] = []; - let content = existing.existingContent; - - files.forEach(({ title: fileTitle, url }) => { - if (!existing.existingCards.has(url)) { - newCards.push(` `); - } - }); - - if (newCards.length > 0) { - // Find the closing tag and insert new cards before it - const cardsSectionEnd = content.lastIndexOf(''); - if (cardsSectionEnd !== -1) { - content = content.slice(0, cardsSectionEnd) + - '\n' + newCards.join('\n') + '\n' + - content.slice(cardsSectionEnd); - - await fs.writeFile(breadcrumbPath, content); - console.log(`Added ${newCards.length} new cards to: ${folderName}.mdx`); - } - } else { - console.log(`No new cards needed for: ${folderName}.mdx`); - } - } else { - // If breadcrumb doesn't exist, create new one - const title = toTitleCase(folderName); - const description = await generateFolderDescription(folderName, files); - - let content = `--- -title: ${title} -description: ${description} -lang: en-US ---- - -import { Card, Cards } from 'nextra/components' - -# ${title} - -${description} - -`; - - if (files.length > 0) { - content += '\n'; - files.forEach(({ title: fileTitle, url }) => { - content += ` \n`; - }); - content += ''; - } else { - content += 'Documentation for this section is coming soon.'; - } - - await fs.writeFile(breadcrumbPath, content); - console.log(`Created new breadcrumb file: ${folderName}.mdx`); - } -} - -async function processSubfolders(parentPath: string): Promise { - try { - const entries = await fs.readdir(parentPath, { withFileTypes: true }); - - for (const entry of entries) { - if (!entry.isDirectory() || entry.name.startsWith('_')) { - continue; - } - - const folderName = entry.name; - console.log(`Processing folder: ${folderName}`); - - try { - await createOrUpdateBreadcrumb(parentPath, folderName); - } catch (error) { - console.error(`Error processing breadcrumb for ${folderName}:`, error); - } - } - } catch (error) { - console.error('Error processing folders:', error); - } -} - -const main = async (): Promise => { - console.log('Starting breadcrumb update process...'); - console.log('Root directory:', rootDir); - - try { - // Process main sections: builders, chain, connect, stack - const mainSections = ['app-developers', 'operators', 'superchain', 'stack']; - for (const section of mainSections) { - const sectionPath = path.join(rootDir, section); - try { - await fs.access(sectionPath); - await processSubfolders(sectionPath); - console.log(`Completed processing ${section} section`); - } catch (error) { - console.log(`Skipping ${section} - directory not found`); - } - } - console.log('Finished updating all breadcrumbs.'); - } catch (error) { - console.error('Error in main process:', error); - process.exit(1); - } -}; - -main().catch(error => { - console.error('Error in main process:', error); - process.exit(1); -}); \ No newline at end of file diff --git a/utils/fix-broken-links.ts b/utils/fix-broken-links.ts deleted file mode 100644 index e3c2e76a1..000000000 --- a/utils/fix-broken-links.ts +++ /dev/null @@ -1,636 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { promisify } from 'util'; -import readline from 'readline'; - -const readFile = promisify(fs.readFile); -const writeFile = promisify(fs.writeFile); -const readdir = promisify(fs.readdir); -const stat = promisify(fs.stat); - -const colors = { - reset: '\x1b[0m', - red: '\x1b[31m', - green: '\x1b[32m', - yellow: '\x1b[33m', - blue: '\x1b[34m', - cyan: '\x1b[36m', - brightRed: '\x1b[91m', - brightYellow: '\x1b[93m', - brightGreen: '\x1b[92m', - bold: '\x1b[1m', -}; - -interface BrokenLink { - sourcePath: string; - linkPath: string; - lineNumber: number; - originalText?: string; -} - -interface FixedLink { - sourcePath: string; - oldLinkPath: string; - newLinkPath: string; - lineNumber: number; -} - -interface AutoFixResult { - fixed: FixedLink[]; - unfixable: BrokenLink[]; -} - -interface AuditReport { - timestamp: string; - totalFiles: number; - totalLinks: number; - brokenLinks: BrokenLink[]; - fixedLinks?: FixedLink[]; - summary: { - totalBrokenLinks: number; - totalFixedLinks?: number; - affectedFiles: number; - fixedFiles?: number; - }; - elapsedTime: string; -} - -const config = { - rootDir: path.resolve(process.cwd(), 'pages'), - fileExtensions: ['.mdx', '.md', '.tsx', '.jsx', '.ts', '.js'], - excludePatterns: [ - /\.(jpg|jpeg|png|gif|svg|webp|bmp|ico)($|\?)/i, - /\.(pdf|doc|docx|xls|xlsx|ppt|pptx)($|\?)/i, - /\.(css|scss|less|sass)($|\?)/i, - /\.(js|jsx|ts|tsx|json)($|\?)/i, - /^(https?|ftp|mailto):/i, - /^#/, - ], - autoFix: true, // Enable auto-fixing - interactiveMode: false, // Disable interactive confirmation for fixes - fixOptions: { - maxEditDistance: 2, // Max Levenshtein distance for suggesting similar paths - checkCaseInsensitive: true, // Check for case mismatches - checkExtensions: true, // Try alternative extensions - deleteOrphanedLinks: false, // Option to delete links that can't be fixed - }, - backupFiles: false, // Don't create backups before fixing -}; - -async function runLinkFixer(): Promise { - const startTime = Date.now(); - - try { - const allFiles = await findAllDocFiles(); - - const { allLinks, brokenLinks } = await checkLinks(allFiles); - - let fixedLinks: FixedLink[] = []; - let remainingBrokenLinks: BrokenLink[] = brokenLinks; - - if (config.autoFix && brokenLinks.length > 0) { - const fixResult = await fixBrokenLinks(brokenLinks, allFiles); - fixedLinks = fixResult.fixed; - remainingBrokenLinks = fixResult.unfixable; - } - - const duration = ((Date.now() - startTime) / 1000).toFixed(2); - const report = generateReport(allFiles.length, allLinks, remainingBrokenLinks, fixedLinks, duration); - - displayReport(report); - - } catch (error) { - console.error(`${colors.red}❌ Error running link fixer:${colors.reset}`, error); - process.exit(1); - } -} - -async function findAllDocFiles(dir = config.rootDir): Promise { - const entries = await readdir(dir, { withFileTypes: true }); - - const files = await Promise.all( - entries.map(async (entry) => { - const filePath = path.join(dir, entry.name); - - if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') { - return findAllDocFiles(filePath); - } - - if (entry.isFile() && config.fileExtensions.some(ext => entry.name.endsWith(ext))) { - return [filePath]; - } - - return []; - }) - ); - - return files.flat(); -} - -async function checkLinks(files: string[]): Promise<{ - allLinks: string[]; - brokenLinks: BrokenLink[]; -}> { - const allLinks: string[] = []; - const brokenLinks: BrokenLink[] = []; - const existingPaths = new Set(); - const pathToFileMap: Map = new Map(); - - // Build a map of normalized paths to the actual files they represent - for (const file of files) { - const relativePath = path.relative(config.rootDir, file); - - const pathWithoutExt = removeExtension(relativePath); - const normalizedPath = normalizeFilePath(pathWithoutExt); - - existingPaths.add(normalizedPath); - pathToFileMap.set(normalizedPath, relativePath); - - if (pathWithoutExt.endsWith('/index') || pathWithoutExt === 'index') { - const dirPath = pathWithoutExt.replace(/index$/, '').replace(/\/$/, ''); - if (dirPath) { - const normalizedDirPath = normalizeFilePath(dirPath); - existingPaths.add(normalizedDirPath); - pathToFileMap.set(normalizedDirPath, relativePath); - } - } - } - - for (const file of files) { - const fileContent = await readFile(file, 'utf8'); - const relativePath = path.relative(config.rootDir, file); - - const extractedLinks = extractLinks(fileContent); - allLinks.push(...extractedLinks.links); - - for (const { link, lineNumber, originalText } of extractedLinks.linkDetails) { - if (shouldSkipLink(link)) continue; - - const normalizedLink = normalizeLink(link); - const resolvedLink = resolveLink(normalizedLink, relativePath); - - if (!existingPaths.has(resolvedLink)) { - brokenLinks.push({ - sourcePath: relativePath, - linkPath: link, - lineNumber, - originalText - }); - } - } - } - - return { allLinks, brokenLinks }; -} - -function extractLinks(content: string): { - links: string[], - linkDetails: Array<{link: string, lineNumber: number, originalText: string}> -} { - const links: string[] = []; - const linkDetails: Array<{link: string, lineNumber: number, originalText: string}> = []; - - let cleanContent = content; - try { - const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/); - if (frontmatterMatch) { - cleanContent = content.slice(frontmatterMatch[0].length); - } - } catch (error) { - // Ignore frontmatter errors - } - - const lines = cleanContent.split('\n'); - - let inComment = false; - const isCommentLine = (line: string): boolean => { - const trimmedLine = line.trim(); - - if (trimmedLine.startsWith('//')) return true; - - if (trimmedLine.startsWith('/*')) { - inComment = true; - return true; - } - - if (inComment && trimmedLine.includes('*/')) { - inComment = false; - return true; - } - - if (inComment) return true; - - if (trimmedLine.startsWith('')) { - return true; - } - inComment = true; - return true; - } - - if (inComment && trimmedLine.includes('-->')) { - inComment = false; - return true; - } - - return false; - }; - - lines.forEach((line, index) => { - const lineNum = index + 1; - - if (isCommentLine(line)) return; - - let lineMatch; - - // Extract Markdown links - [text](link) - const markdownLinkRegex = /\[([^\[\]]+)\]\(([^)]+)\)/g; - while ((lineMatch = markdownLinkRegex.exec(line)) !== null) { - const linkText = lineMatch[1]; - const fullLinkPart = lineMatch[2]; - const link = fullLinkPart.split(' ')[0].trim(); - links.push(link); - linkDetails.push({ - link, - lineNumber: lineNum, - originalText: lineMatch[0] - }); - } - - // Extract JSX/HTML links - href="link" or href='link' or href={link} - const jsxLinkRegexSingleQuote = /href=['"]([^'"]+)['"]/g; - const jsxLinkRegexDoubleQuote = /href=["']([^"']+)["']/g; - const jsxLinkRegexCurly = /href=\{['"]?([^'"}\s]+)['"]?\}/g; - - [jsxLinkRegexSingleQuote, jsxLinkRegexDoubleQuote, jsxLinkRegexCurly].forEach(regex => { - while ((lineMatch = regex.exec(line)) !== null) { - const link = lineMatch[1].trim(); - links.push(link); - linkDetails.push({ - link, - lineNumber: lineNum, - originalText: lineMatch[0] - }); - } - }); - }); - - return { links, linkDetails }; -} - -function shouldSkipLink(link: string): boolean { - if (!link.trim()) return true; - - return config.excludePatterns.some(pattern => pattern.test(link)); -} - -function normalizeLink(link: string): string { - let normalizedLink = link; - - normalizedLink = normalizedLink.split(/[?#]/)[0]; - - if (normalizedLink.startsWith('./')) { - normalizedLink = normalizedLink.substring(2); - } - - return normalizedLink; -} - -function resolveLink(link: string, sourcePath: string): string { - if (link.startsWith('/')) { - return normalizeFilePath(link.substring(1)); - } - - const sourceDir = path.dirname(sourcePath); - if (sourceDir === '.') { - return normalizeFilePath(link); - } - - let resolvedPath; - if (link.startsWith('../')) { - const relativeParent = path.resolve(sourceDir, '..'); - const relativePath = path.relative(config.rootDir, relativeParent); - resolvedPath = path.join(relativePath, link.substring(3)); - } else { - resolvedPath = path.join(sourceDir, link); - } - - return normalizeFilePath(resolvedPath); -} - -function normalizeFilePath(filePath: string): string { - let normalizedPath = filePath.replace(/^\.\//, ''); - - normalizedPath = normalizedPath.replace(/\\/g, '/'); - - normalizedPath = normalizedPath.replace(/\/$/, ''); - - return normalizedPath; -} - -function removeExtension(filePath: string): string { - const extname = path.extname(filePath); - if (config.fileExtensions.includes(extname)) { - return filePath.substring(0, filePath.length - extname.length); - } - return filePath; -} - -async function fixBrokenLinks(brokenLinks: BrokenLink[], allFiles: string[]): Promise { - console.log(`\n${colors.bold}${colors.blue}🔧 Attempting to fix ${brokenLinks.length} broken links...${colors.reset}`); - - const existingPaths = new Map(); - const caseInsensitivePaths = new Map(); - - // Build a map of all valid paths - for (const file of allFiles) { - const relativePath = path.relative(config.rootDir, file); - const pathWithoutExt = removeExtension(relativePath); - const normalizedPath = normalizeFilePath(pathWithoutExt); - - existingPaths.set(normalizedPath, relativePath); - - if (config.fixOptions.checkCaseInsensitive) { - caseInsensitivePaths.set(normalizedPath.toLowerCase(), normalizedPath); - } - - // Handle index files (can be referenced by their directory) - if (pathWithoutExt.endsWith('/index') || pathWithoutExt === 'index') { - const dirPath = pathWithoutExt.replace(/index$/, '').replace(/\/$/, ''); - if (dirPath) { - const normalizedDirPath = normalizeFilePath(dirPath); - existingPaths.set(normalizedDirPath, relativePath); - - if (config.fixOptions.checkCaseInsensitive) { - caseInsensitivePaths.set(normalizedDirPath.toLowerCase(), normalizedDirPath); - } - } - } - } - - const fixedLinks: FixedLink[] = []; - const unfixableLinks: BrokenLink[] = []; - - // Group by source file for efficiency - const linksBySource = new Map(); - brokenLinks.forEach(link => { - if (!linksBySource.has(link.sourcePath)) { - linksBySource.set(link.sourcePath, []); - } - linksBySource.get(link.sourcePath)!.push(link); - }); - - const rl = config.interactiveMode ? readline.createInterface({ - input: process.stdin, - output: process.stdout - }) : null; - - // Process each source file - // Use Array.from to work around TS iteration issues with Maps - for (const [sourcePath, links] of Array.from(linksBySource.entries())) { - const absoluteSourcePath = path.join(config.rootDir, sourcePath); - let fileContent = await readFile(absoluteSourcePath, 'utf8'); - let fileModified = false; - - console.log(`\n${colors.cyan}Processing: ${sourcePath}${colors.reset}`); - - // Process each broken link in the file - for (const brokenLink of links) { - const normalizedLink = normalizeLink(brokenLink.linkPath); - const resolvedBrokenLink = resolveLink(normalizedLink, sourcePath); - - let fixSuggestion: string | null = null; - - // Try case-insensitive matching - if (config.fixOptions.checkCaseInsensitive) { - const lowerCaseLink = resolvedBrokenLink.toLowerCase(); - if (caseInsensitivePaths.has(lowerCaseLink)) { - fixSuggestion = caseInsensitivePaths.get(lowerCaseLink)!; - } - } - - // Try different extensions if enabled - if (!fixSuggestion && config.fixOptions.checkExtensions) { - for (const ext of config.fileExtensions) { - const withExt = `${resolvedBrokenLink}${ext}`; - const normalizedWithExt = normalizeFilePath(removeExtension(withExt)); - if (existingPaths.has(normalizedWithExt)) { - fixSuggestion = normalizedWithExt; - break; - } - } - } - - // Try to find similar paths using Levenshtein distance - if (!fixSuggestion) { - let closestMatch: string | null = null; - let minDistance = config.fixOptions.maxEditDistance + 1; - - // Use Array.from to work around TS iteration issues with Maps - Array.from(existingPaths.keys()).forEach(existingPath => { - const distance = levenshteinDistance(resolvedBrokenLink, existingPath); - if (distance <= config.fixOptions.maxEditDistance && distance < minDistance) { - minDistance = distance; - closestMatch = existingPath; - } - }); - - if (closestMatch) { - fixSuggestion = closestMatch; - } - } - - // If we have a suggestion, confirm and apply it - if (fixSuggestion) { - let shouldApply = true; - - if (config.interactiveMode && rl) { - const answer = await askQuestion( - rl, - `${colors.yellow}Line ${brokenLink.lineNumber}:${colors.reset} Fix "${colors.brightRed}${brokenLink.linkPath}${colors.reset}" to "${colors.brightGreen}${fixSuggestion}${colors.reset}"? (Y/n) ` - ); - shouldApply = answer.toLowerCase() !== 'n'; - } else { - console.log(`${colors.yellow}Line ${brokenLink.lineNumber}:${colors.reset} Fixing "${colors.brightRed}${brokenLink.linkPath}${colors.reset}" to "${colors.brightGreen}${fixSuggestion}${colors.reset}"`); - } - - if (shouldApply) { - // Convert the fix suggestion back to a relative path if needed - let newPath = fixSuggestion; - - // If the original link was relative (not starting with /), keep it relative - if (!brokenLink.linkPath.startsWith('/')) { - const sourceDirPath = path.dirname(sourcePath); - newPath = path.relative(sourceDirPath, newPath).replace(/\\/g, '/'); - if (!newPath.startsWith('.') && !newPath.startsWith('/')) { - newPath = `./${newPath}`; - } - } else { - // If it was absolute, keep it absolute - newPath = `/${newPath}`; - } - - // Replace the link in the file content - if (brokenLink.originalText) { - const newText = brokenLink.originalText.replace(brokenLink.linkPath, newPath); - fileContent = fileContent.replace(brokenLink.originalText, newText); - fileModified = true; - - fixedLinks.push({ - sourcePath, - oldLinkPath: brokenLink.linkPath, - newLinkPath: newPath, - lineNumber: brokenLink.lineNumber - }); - } - } else { - unfixableLinks.push(brokenLink); - } - } else { - console.log(`${colors.yellow}Line ${brokenLink.lineNumber}:${colors.reset} ${colors.brightRed}No suggestion found for "${brokenLink.linkPath}"${colors.reset}`); - unfixableLinks.push(brokenLink); - } - } - - // Save the modified file - if (fileModified) { - await writeFile(absoluteSourcePath, fileContent); - console.log(`${colors.green}✅ Updated: ${sourcePath}${colors.reset}`); - } - } - - if (rl) { - rl.close(); - } - - return { fixed: fixedLinks, unfixable: unfixableLinks }; -} - -function askQuestion(rl: readline.Interface, question: string): Promise { - return new Promise((resolve) => { - rl.question(question, (answer) => { - resolve(answer || 'y'); - }); - }); -} - -function levenshteinDistance(a: string, b: string): number { - const matrix: number[][] = []; - - // Initialize the matrix - for (let i = 0; i <= a.length; i++) { - matrix[i] = [i]; - } - - for (let j = 0; j <= b.length; j++) { - matrix[0][j] = j; - } - - // Fill the matrix - for (let i = 1; i <= a.length; i++) { - for (let j = 1; j <= b.length; j++) { - const cost = a[i - 1] === b[j - 1] ? 0 : 1; - matrix[i][j] = Math.min( - matrix[i - 1][j] + 1, // deletion - matrix[i][j - 1] + 1, // insertion - matrix[i - 1][j - 1] + cost // substitution - ); - } - } - - return matrix[a.length][b.length]; -} - -function generateReport( - totalFiles: number, - allLinks: string[], - brokenLinks: BrokenLink[], - fixedLinks: FixedLink[], - elapsedTime: string -): AuditReport { - const affectedFiles = new Set(brokenLinks.map(link => link.sourcePath)).size; - const fixedFiles = new Set(fixedLinks.map(link => link.sourcePath)).size; - - return { - timestamp: new Date().toISOString(), - totalFiles, - totalLinks: allLinks.length, - brokenLinks, - fixedLinks, - summary: { - totalBrokenLinks: brokenLinks.length, - totalFixedLinks: fixedLinks.length, - affectedFiles, - fixedFiles - }, - elapsedTime - }; -} - -function displayReport(report: AuditReport): void { - let result = ''; - - // Display fixed links summary if any - if (report.fixedLinks && report.fixedLinks.length > 0) { - result += `\n${colors.bold}${colors.green}🔧 Fixed ${report.summary.totalFixedLinks} links in ${report.summary.fixedFiles} files:${colors.reset}\n`; - - const linksBySource: Record = {}; - report.fixedLinks.forEach(link => { - if (!linksBySource[link.sourcePath]) { - linksBySource[link.sourcePath] = []; - } - linksBySource[link.sourcePath].push(link); - }); - - Object.entries(linksBySource).forEach(([sourcePath, links]) => { - result += `\n${colors.bold}${colors.cyan}File: ${sourcePath}${colors.reset}\n`; - links.forEach(link => { - result += ` ${colors.yellow}Line ${link.lineNumber}:${colors.reset} Changed "${colors.brightRed}${link.oldLinkPath}${colors.reset}" to "${colors.brightGreen}${link.newLinkPath}${colors.reset}"\n`; - }); - }); - } - - // Display remaining broken links if any - if (report.brokenLinks.length > 0) { - result += `\n${colors.bold}${colors.red}❌ ${report.brokenLinks.length} links could not be fixed:${colors.reset}\n`; - - const linksBySource: Record = {}; - report.brokenLinks.forEach(link => { - if (!linksBySource[link.sourcePath]) { - linksBySource[link.sourcePath] = []; - } - linksBySource[link.sourcePath].push(link); - }); - - Object.entries(linksBySource).forEach(([sourcePath, links]) => { - result += `\n${colors.bold}${colors.cyan}File: ${sourcePath}${colors.reset}\n`; - links.forEach(link => { - result += ` ${colors.yellow}Line ${link.lineNumber}:${colors.reset} Broken link to ${colors.brightRed}"${link.linkPath}"${colors.reset}\n`; - }); - }); - - result += `\n${colors.red}❌ LIFECYCLE\tCommand completed with warnings.${colors.reset}\n`; - } else { - result += `\n${colors.green}✅ LIFECYCLE\tCommand completed successfully.${colors.reset}\n`; - } - - // Display summary statistics - const totalFixed = report.summary.totalFixedLinks || 0; - const totalRemaining = report.brokenLinks.length; - const totalInitial = totalFixed + totalRemaining; - - const fixRate = totalInitial > 0 ? Math.round((totalFixed / totalInitial) * 100) : 0; - - const summaryStats = `\n${colors.bold}Summary: ${totalInitial} initial broken links, ${colors.green}${totalFixed} fixed (${fixRate}%)${colors.reset}, ${colors.red}${totalRemaining} remaining${colors.reset} (in ${report.elapsedTime}s)`; - - if (result.trim()) { - console.log(result); - } - console.log(summaryStats); - - if (report.brokenLinks.length > 0) { - process.exit(1); - } -} - -runLinkFixer().catch(console.error); \ No newline at end of file diff --git a/utils/fix-redirects.ts b/utils/fix-redirects.ts deleted file mode 100755 index 6e10064c3..000000000 --- a/utils/fix-redirects.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as fs from 'fs/promises'; -import * as path from 'path'; - -const rootDir = path.join(process.cwd(), 'pages'); -const redirectsPath = path.join(process.cwd(), 'public', '_redirects'); -const fixed: string[] = []; - -// ANSI color codes -const WHITE = '\x1b[37m'; -const GREEN = '\x1b[32m'; -const YELLOW = '\x1b[33m'; -const RESET = '\x1b[0m'; -const BOLD = '\x1b[1m'; - -interface Redirect { - from: string; - to: string; -} - -interface Summary { - total: number; - fixed: number; - unchanged: number; -} - -async function getRedirects(): Promise { - try { - const content = await fs.readFile(redirectsPath, 'utf-8'); - return content.split('\n') - .filter(line => line.trim() && !line.startsWith('#')) - .map(line => { - const [from, to] = line.split(/\s+/); - return { from, to }; - }); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error reading redirects file:${RESET}`, error); - return []; - } -} - -async function findMdxFiles(dir: string): Promise { - const files: string[] = []; - - try { - const entries = await fs.readdir(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory() && !entry.name.startsWith('_')) { - files.push(...await findMdxFiles(fullPath)); - } else if (entry.isFile() && /\.(md|mdx)$/.test(entry.name)) { - files.push(fullPath); - } - } - } catch (error) { - console.error(`${YELLOW}${BOLD}Error reading directory ${dir}:${RESET}`, error); - } - - return files; -} - -async function fixFile(filePath: string, redirects: Redirect[]): Promise { - try { - let content = await fs.readFile(filePath, 'utf-8'); - const relativeFilePath = path.relative(rootDir, filePath); - let fileChanged = false; - - // Fix markdown links - [text](link) - redirects.forEach(redirect => { - const markdownLinkRegex = new RegExp(`\\[([^\\]]+)\\]\\(${redirect.from.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\)`, 'g'); - if (markdownLinkRegex.test(content)) { - content = content.replace(markdownLinkRegex, `[$1](${redirect.to})`); - fixed.push(`${WHITE}Fixed in "${relativeFilePath}": ${YELLOW}"${redirect.from}"${WHITE} → ${GREEN}"${redirect.to}"${RESET}`); - fileChanged = true; - } - }); - - // Fix HTML links - href="link" - redirects.forEach(redirect => { - const hrefRegex = new RegExp(`href="${redirect.from.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"`, 'g'); - if (hrefRegex.test(content)) { - content = content.replace(hrefRegex, `href="${redirect.to}"`); - fixed.push(`${WHITE}Fixed in "${relativeFilePath}": ${YELLOW}"${redirect.from}"${WHITE} → ${GREEN}"${redirect.to}"${RESET}`); - fileChanged = true; - } - }); - - if (fileChanged) { - await fs.writeFile(filePath, content, 'utf-8'); - return true; - } - - return false; - } catch (error) { - console.error(`${YELLOW}${BOLD}Error fixing file ${filePath}:${RESET}`, error); - return false; - } -} - -function printSummary(summary: Summary) { - console.log('\nSummary:'); - console.log(`${WHITE}Total pages checked 🔍 - ${summary.total}`); - console.log(`${GREEN}Pages fixed ✅ - ${summary.fixed}`); - console.log(`${WHITE}Pages unchanged ⏩ - ${summary.unchanged}${RESET}`); -} - -async function main() { - const summary: Summary = { - total: 0, - fixed: 0, - unchanged: 0 - }; - - console.log('Starting automatic redirect fix...'); - console.log('Root directory:', rootDir); - - try { - // Check if directories exist - try { - await fs.access(rootDir); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error: Root directory not found at ${rootDir}${RESET}`); - console.log('Current working directory:', process.cwd()); - process.exit(1); - } - - try { - await fs.access(redirectsPath); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error: Redirects file not found at ${redirectsPath}${RESET}`); - process.exit(1); - } - - const redirects = await getRedirects(); - console.log(`Loaded ${redirects.length} redirects from ${redirectsPath}`); - - const files = await findMdxFiles(rootDir); - console.log(`Found ${files.length} MDX files to check`); - - summary.total = files.length; - - for (const file of files) { - const wasFixed = await fixFile(file, redirects); - if (wasFixed) { - summary.fixed++; - } else { - summary.unchanged++; - } - } - - if (fixed.length > 0) { - console.log(`${GREEN}${BOLD}Fixed ${fixed.length} outdated links:${RESET}`); - fixed.forEach(message => console.log(message)); - } else { - console.log(`${GREEN}All internal links are already up to date.${RESET}`); - } - - printSummary(summary); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error fixing redirects:${RESET}`, error); - process.exit(1); - } -} - -// Execute the script -main().catch(error => { - console.error(`${YELLOW}${BOLD}Error in main process:${RESET}`, error); - process.exit(1); -}); \ No newline at end of file diff --git a/utils/gtag.ts b/utils/gtag.ts deleted file mode 100644 index 50a0dd223..000000000 --- a/utils/gtag.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_ID - -// https://developers.google.com/analytics/devguides/collection/gtagjs/pages -export const pageview = (url) => { - (window as any).gtag('config', GA_TRACKING_ID, { - page_path: url, - }) -} - -// https://developers.google.com/analytics/devguides/collection/gtagjs/events -export const event = ({ action, category, label, value }) => { - (window as any).gtag('event', action, { - event_category: category, - event_label: label, - value: value, - }) -} diff --git a/utils/link-checker.ts b/utils/link-checker.ts deleted file mode 100644 index ace84ec9b..000000000 --- a/utils/link-checker.ts +++ /dev/null @@ -1,346 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import { promisify } from 'util'; - -const readFile = promisify(fs.readFile); -const readdir = promisify(fs.readdir); -const stat = promisify(fs.stat); - -const colors = { - reset: '\x1b[0m', - red: '\x1b[31m', - green: '\x1b[32m', - yellow: '\x1b[33m', - blue: '\x1b[34m', - cyan: '\x1b[36m', - brightRed: '\x1b[91m', - brightYellow: '\x1b[93m', - bold: '\x1b[1m', -}; - -interface BrokenLink { - sourcePath: string; - linkPath: string; - lineNumber: number; -} - -interface AuditReport { - timestamp: string; - totalFiles: number; - totalLinks: number; - brokenLinks: BrokenLink[]; - summary: { - totalBrokenLinks: number; - affectedFiles: number; - }; - elapsedTime: string; -} - -const config = { - rootDir: path.resolve(process.cwd(), 'pages'), - fileExtensions: ['.mdx', '.md', '.tsx', '.jsx', '.ts', '.js'], - excludePatterns: [ - /\.(jpg|jpeg|png|gif|svg|webp|bmp|ico)($|\?)/i, - /\.(pdf|doc|docx|xls|xlsx|ppt|pptx)($|\?)/i, - /\.(css|scss|less|sass)($|\?)/i, - /\.(js|jsx|ts|tsx|json)($|\?)/i, - /^(https?|ftp|mailto):/i, - /^#/, - ], -}; - -async function runLinkChecker(): Promise { - const startTime = Date.now(); - - try { - const allFiles = await findAllDocFiles(); - - const { allLinks, brokenLinks } = await checkLinks(allFiles); - - const duration = ((Date.now() - startTime) / 1000).toFixed(2); - const report = generateReport(allFiles.length, allLinks, brokenLinks, duration); - - displayReport(report); - - } catch (error) { - console.error(`${colors.red}❌ Error running link checker:${colors.reset}`, error); - process.exit(1); - } -} - -async function findAllDocFiles(dir = config.rootDir): Promise { - const entries = await readdir(dir, { withFileTypes: true }); - - const files = await Promise.all( - entries.map(async (entry) => { - const filePath = path.join(dir, entry.name); - - if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') { - return findAllDocFiles(filePath); - } - - if (entry.isFile() && config.fileExtensions.some(ext => entry.name.endsWith(ext))) { - return [filePath]; - } - - return []; - }) - ); - - return files.flat(); -} - -async function checkLinks(files: string[]): Promise<{ - allLinks: string[]; - brokenLinks: BrokenLink[]; -}> { - const allLinks: string[] = []; - const brokenLinks: BrokenLink[] = []; - const existingPaths = new Set(); - - for (const file of files) { - const relativePath = path.relative(config.rootDir, file); - - const pathWithoutExt = removeExtension(relativePath); - existingPaths.add(normalizeFilePath(pathWithoutExt)); - - if (pathWithoutExt.endsWith('/index') || pathWithoutExt === 'index') { - const dirPath = pathWithoutExt.replace(/index$/, '').replace(/\/$/, ''); - if (dirPath) existingPaths.add(normalizeFilePath(dirPath)); - } - } - - for (const file of files) { - const fileContent = await readFile(file, 'utf8'); - const relativePath = path.relative(config.rootDir, file); - - const extractedLinks = extractLinks(fileContent); - allLinks.push(...extractedLinks.links); - - for (const { link, lineNumber } of extractedLinks.linkDetails) { - if (shouldSkipLink(link)) continue; - - const normalizedLink = normalizeLink(link); - const resolvedLink = resolveLink(normalizedLink, relativePath); - - if (!existingPaths.has(resolvedLink)) { - brokenLinks.push({ - sourcePath: relativePath, - linkPath: link, - lineNumber, - }); - } - } - } - - return { allLinks, brokenLinks }; -} - -function extractLinks(content: string): { - links: string[], - linkDetails: Array<{link: string, lineNumber: number}> -} { - const links: string[] = []; - const linkDetails: Array<{link: string, lineNumber: number}> = []; - - let cleanContent = content; - try { - const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/); - if (frontmatterMatch) { - cleanContent = content.slice(frontmatterMatch[0].length); - } - } catch (error) { - } - - const lines = cleanContent.split('\n'); - - let inComment = false; - const isCommentLine = (line: string): boolean => { - const trimmedLine = line.trim(); - - if (trimmedLine.startsWith('//')) return true; - - if (trimmedLine.startsWith('/*')) { - inComment = true; - return true; - } - - if (inComment && trimmedLine.includes('*/')) { - inComment = false; - return true; - } - - if (inComment) return true; - - if (trimmedLine.startsWith('')) { - return true; - } - inComment = true; - return true; - } - - if (inComment && trimmedLine.includes('-->')) { - inComment = false; - return true; - } - - return false; - }; - - lines.forEach((line, index) => { - const lineNum = index + 1; - - if (isCommentLine(line)) return; - - let lineMatch; - - const markdownLinkRegex = /\[(?:[^\[\]]+)\]\(([^)]+)\)/g; - while ((lineMatch = markdownLinkRegex.exec(line)) !== null) { - const link = lineMatch[1].split(' ')[0].trim(); - links.push(link); - linkDetails.push({ link, lineNumber: lineNum }); - } - - const jsxLinkRegexSingleQuote = /href=['"]([^'"]+)['"]/g; - const jsxLinkRegexDoubleQuote = /href=["']([^"']+)["']/g; - const jsxLinkRegexCurly = /href=\{['"]?([^'"}\s]+)['"]?\}/g; - - [jsxLinkRegexSingleQuote, jsxLinkRegexDoubleQuote, jsxLinkRegexCurly].forEach(regex => { - while ((lineMatch = regex.exec(line)) !== null) { - const link = lineMatch[1].trim(); - links.push(link); - linkDetails.push({ link, lineNumber: lineNum }); - } - }); - }); - - return { links, linkDetails }; -} - -function shouldSkipLink(link: string): boolean { - if (!link.trim()) return true; - - return config.excludePatterns.some(pattern => pattern.test(link)); -} - -function normalizeLink(link: string): string { - let normalizedLink = link; - - normalizedLink = normalizedLink.split(/[?#]/)[0]; - - if (normalizedLink.startsWith('./')) { - normalizedLink = normalizedLink.substring(2); - } - - return normalizedLink; -} - -function resolveLink(link: string, sourcePath: string): string { - if (link.startsWith('/')) { - return normalizeFilePath(link.substring(1)); - } - - const sourceDir = path.dirname(sourcePath); - if (sourceDir === '.') { - return normalizeFilePath(link); - } - - let resolvedPath; - if (link.startsWith('../')) { - const relativeParent = path.resolve(sourceDir, '..'); - const relativePath = path.relative(config.rootDir, relativeParent); - resolvedPath = path.join(relativePath, link.substring(3)); - } else { - resolvedPath = path.join(sourceDir, link); - } - - return normalizeFilePath(resolvedPath); -} - -function normalizeFilePath(filePath: string): string { - let normalizedPath = filePath.replace(/^\.\//, ''); - - normalizedPath = normalizedPath.replace(/\\/g, '/'); - - normalizedPath = normalizedPath.replace(/\/$/, ''); - - return normalizedPath; -} - -function removeExtension(filePath: string): string { - const extname = path.extname(filePath); - if (config.fileExtensions.includes(extname)) { - return filePath.substring(0, filePath.length - extname.length); - } - return filePath; -} - -function generateReport( - totalFiles: number, - allLinks: string[], - brokenLinks: BrokenLink[], - elapsedTime: string -): AuditReport { - const affectedFiles = new Set(brokenLinks.map(link => link.sourcePath)).size; - - return { - timestamp: new Date().toISOString(), - totalFiles, - totalLinks: allLinks.length, - brokenLinks, - summary: { - totalBrokenLinks: brokenLinks.length, - affectedFiles, - }, - elapsedTime - }; -} - -function displayReport(report: AuditReport): void { - let result = ''; - - if (report.brokenLinks.length > 0) { - const sortedLinks = [...report.brokenLinks].sort((a, b) => - a.sourcePath.localeCompare(b.sourcePath) || a.lineNumber - b.lineNumber - ); - - const linksBySource: Record = {}; - sortedLinks.forEach(link => { - if (!linksBySource[link.sourcePath]) { - linksBySource[link.sourcePath] = []; - } - linksBySource[link.sourcePath].push(link); - }); - - Object.entries(linksBySource).forEach(([sourcePath, links]) => { - result += `\n${colors.bold}${colors.cyan}File: ${sourcePath}${colors.reset}\n`; - links.forEach(link => { - result += ` ${colors.yellow}Line ${link.lineNumber}:${colors.reset} Broken link to ${colors.brightRed}"${link.linkPath}"${colors.reset}\n`; - }); - }); - - result += `\n${colors.red}❌ LIFECYCLE\tCommand failed with exit code 1.${colors.reset}\n`; - } else { - result += `\n${colors.green}✅ LIFECYCLE\tCommand completed successfully.${colors.reset}\n`; - } - - const totalCount = report.totalFiles + report.summary.totalBrokenLinks; - const okCount = report.totalFiles - report.summary.affectedFiles; - const errorCount = report.summary.totalBrokenLinks; - const excludedCount = 0; - const timeoutCount = 0; - - const summary = `\n${colors.bold}${totalCount} Total (in ${report.elapsedTime}s) ${colors.green}✅ ${okCount} OK ${colors.red}❌ ${errorCount} Errors ${colors.brightYellow}🚫 ${excludedCount} Excluded ${colors.cyan}⏱️ ${timeoutCount} Timeouts${colors.reset}`; - - if (result.trim()) { - console.log(result); - } - console.log(summary); - - if (report.brokenLinks.length > 0) { - process.exit(1); - } -} - -runLinkChecker().catch(console.error); \ No newline at end of file diff --git a/utils/metadata-manager.ts b/utils/metadata-manager.ts deleted file mode 100644 index afd6c249e..000000000 --- a/utils/metadata-manager.ts +++ /dev/null @@ -1,346 +0,0 @@ -import { promises as fs } from 'node:fs' -import path from 'node:path' -import matter from 'gray-matter' -import yaml from 'js-yaml' -import { MetadataResult, MetadataOptions, ValidationResult, loadConfig as loadMetadataConfig, MetadataConfig } from './types/metadata-types' - -// Add the interfaces at the top of the file -interface ValidationOptions { - prMode?: boolean - dryRun?: boolean - validateOnly?: boolean -} - -interface UpdateOptions { - dryRun?: boolean - validateOnly?: boolean - prMode?: boolean - verbose?: boolean - analysis?: MetadataResult -} - -// Helper function to generate suggestions -function generateSuggestions(config: MetadataConfig) { - return { - validPersonas: config.metadata_rules.persona.validation_rules[0].enum, - validContentTypes: config.metadata_rules.content_type.validation_rules[0].enum, - validCategories: config.metadata_rules.categories.values - } -} - -// Validation functions -export async function validateMetadata(filepath: string, content: string): Promise { - const { data: frontmatter } = matter(content) - const errors: string[] = [] - - // Load config - const config = await loadMetadataConfig() - - // Check required fields - if (!frontmatter.title) errors.push('Missing required field: title') - if (!frontmatter.description) errors.push('Missing required field: description') - if (!frontmatter.topic) errors.push('Missing required field: topic') - - // Check personas - if (!frontmatter.personas || !Array.isArray(frontmatter.personas)) { - errors.push('Missing or invalid personas array') - } else { - if (frontmatter.personas.length < config.metadata_rules.persona.min) { - errors.push(`At least ${config.metadata_rules.persona.min} persona is required`) - } - const validPersonas = config.metadata_rules.persona.validation_rules[0].enum - frontmatter.personas.forEach(persona => { - if (!validPersonas.includes(persona)) { - errors.push(`Invalid persona: ${persona}`) - } - }) - } - - // Check content_type - if (!frontmatter.content_type) { - errors.push('Missing content_type') - } else { - const validTypes = config.metadata_rules.content_type.validation_rules[0].enum - if (!validTypes.includes(frontmatter.content_type)) { - errors.push(`Invalid content_type: ${frontmatter.content_type}`) - } - } - - // Check categories - if (!frontmatter.categories || !Array.isArray(frontmatter.categories)) { - errors.push('Missing or invalid categories array') - } else { - // Check minimum categories - if (frontmatter.categories.length < config.metadata_rules.categories.min) { - errors.push(`At least ${config.metadata_rules.categories.min} category is required`) - } - // Check maximum categories - if (frontmatter.categories.length > config.metadata_rules.categories.max) { - errors.push(`Maximum ${config.metadata_rules.categories.max} categories allowed`) - } - // Check for duplicates - const uniqueCategories = new Set(frontmatter.categories) - if (uniqueCategories.size !== frontmatter.categories.length) { - errors.push('Duplicate categories are not allowed') - } - const validCategories = config.metadata_rules.categories.values - frontmatter.categories.forEach(category => { - if (!validCategories.includes(category)) { - errors.push(`Invalid category: ${category}`) - } - }) - } - - // Add this new check for is_imported_content - if (frontmatter.is_imported_content === undefined) { - errors.push('Missing is_imported_content field (required for duplicate page handling)') - } else if (typeof frontmatter.is_imported_content !== 'string' || - !['true', 'false'].includes(frontmatter.is_imported_content)) { - errors.push('is_imported_content must be a string: "true" or "false"') - } - - return { - isValid: errors.length === 0, - errors, - suggestions: generateSuggestions(config) - } -} - -// Generation functions -export async function generateMetadata(filePath: string): Promise { - const content = await fs.readFile(filePath, 'utf8') - const { data: existingMetadata } = matter(content) - - // Handle categories that might be string or array - let categories = existingMetadata.categories || [] - if (typeof categories === 'string') { - categories = categories.split(',').map(c => c.trim()) - } - - let personas = existingMetadata.personas || [] - if (typeof personas === 'string') { - personas = [personas] - } - - const metadata: MetadataResult = { - ...existingMetadata, - title: existingMetadata.title || '', - lang: existingMetadata.lang || 'en', - description: existingMetadata.description || '', - topic: existingMetadata.topic || '', - personas: personas, - content_type: existingMetadata.content_type || '', - categories: categories, - is_imported_content: existingMetadata.is_imported_content || 'false', - content: content - } - - return metadata -} - -// Combined update function with validation and atomic writes -export async function updateMetadata( - filepath: string, - options: MetadataOptions -): Promise { - try { - const content = await fs.readFile(filepath, 'utf8') - const { data: frontmatter, content: docContent } = matter(content) - const config = await loadMetadataConfig() - - // Guard against undefined analysis with optional chaining - const safeAnalysis = options?.analysis || {} as MetadataResult - - // Create new metadata object with all fields - const newMetadata = { - title: safeAnalysis.title || frontmatter.title || '', - description: frontmatter.description || safeAnalysis.description || '', - lang: frontmatter.lang || safeAnalysis.lang || 'en-US', - content_type: safeAnalysis.content_type, - topic: safeAnalysis.topic || '', - personas: safeAnalysis.personas || [], - categories: safeAnalysis.categories || [], - is_imported_content: safeAnalysis.is_imported_content || 'false' - } - - // Validate metadata in all cases - const validationResult = await validateMetadata(filepath, content) - - // Check validation mode - if (options.validateOnly || options.prMode) { - return { - isValid: validationResult.isValid, - errors: validationResult.errors, - suggestions: generateSuggestions(config) - } - } - - // Only write if not in dry run mode and validation passed - if (!options.dryRun && validationResult.isValid) { - const updatedContent = matter.stringify(docContent, newMetadata) - await fs.writeFile(filepath, updatedContent, 'utf8') - } - - return { - isValid: validationResult.isValid, - errors: validationResult.errors, - suggestions: generateSuggestions(config) - } - } catch (error) { - const config = await loadMetadataConfig() - return { - isValid: false, - errors: [`Failed to update metadata for ${filepath}: ${error.message}`], - suggestions: generateSuggestions(config) - } - } -} - -// PR validation function -export async function validatePRChanges(): Promise { - try { - const gitOutput = process.env.CHANGED_FILES || '' - const modifiedFiles = gitOutput - .split('\n') - .filter(file => file.endsWith('.mdx')) - .map(file => path.resolve(process.cwd(), file)) - - if (modifiedFiles.length === 0) { - return true - } - - let hasErrors = false - for (const file of modifiedFiles) { - const content = await fs.readFile(file, 'utf8') - const result = await updateMetadata(file, { - validateOnly: true, - prMode: true, - dryRun: true, - verbose: false, - analysis: await generateMetadata(file) - }) - if (!result.isValid) { - hasErrors = true - console.error(`\n${file}:`) - result.errors.forEach(error => console.error(` - ${error}`)) - } - } - - return !hasErrors - } catch (error) { - console.error('Error:', error) - return false - } -} - -// CLI support -if (import.meta.url === `file://${process.argv[1]}`) { - const gitOutput = process.env.CHANGED_FILES || '' - const modifiedFiles = gitOutput - .split('\n') - .filter(file => file.endsWith('.mdx')) - .map(file => path.resolve(process.cwd(), file)) - - if (modifiedFiles.length === 0) { - console.log('\x1b[32m✓ Metadata validation: no files to check\x1b[0m') - process.exit(0) - } - - const validateFiles = async () => { - let hasErrors = false - for (const file of modifiedFiles) { - const content = await fs.readFile(file, 'utf8') - const result = await updateMetadata(file, { - validateOnly: true, - prMode: true, - dryRun: true, - verbose: false, - analysis: await generateMetadata(file) - }) - if (!result.isValid) { - console.log('\x1b[33m⚠️ Metadata validation warnings:\x1b[0m') - console.log(`\nFile: ${file}`) - result.errors.forEach(error => console.log(` → ${error}`)) - - // Show suggestions if available - if (result.suggestions?.validPersonas?.length || result.suggestions?.validContentTypes) { - console.log('\nSuggested metadata:') - if (result.suggestions.validContentTypes) { - console.log(` content_type: ${result.suggestions.validContentTypes}`) - } - if (result.suggestions.validPersonas?.length) { - console.log(` personas: ${result.suggestions.validPersonas.join(', ')}`) - } - } - - console.log('\nTo fix these warnings:') - console.log('Add required metadata to your MDX file\'s frontmatter:') - console.log('```yaml') - console.log('---') - console.log('title: Your Title') - console.log('lang: en-US') - console.log('description: A brief description') - console.log('topic: Your Topic') - console.log('personas: [Your Persona]') - console.log('content_type: Your Content Type') - console.log('categories: [Your Category]') - console.log('is_imported_content: "false"') - console.log('---') - console.log('```') - hasErrors = true - } - } - // Always exit with 0 to make it non-blocking - process.exit(0) - } - - validateFiles().catch(error => { - console.error('\x1b[33m⚠️ Metadata validation error occurred (non-blocking)\x1b[0m') - console.error(error) - // Exit with 0 even on error to make it non-blocking - process.exit(0) - }) -} - -async function loadConfig(configPath: string): Promise { - const content = await fs.readFile(configPath, 'utf8') - return yaml.load(content) -} - -async function validateConfig(configPath: string): Promise { - const config = await loadConfig(configPath) - if (!config.metadata_rules) { - throw new Error('Invalid config: missing metadata_rules') - } - // Silently validate - no console output at all -} - -export async function updateMetadataFile( - filepath: string, - options: { - dryRun?: boolean; - verbose?: boolean; - analysis: MetadataResult; - validateOnly: boolean; - prMode: boolean; - } -): Promise<{ isValid: boolean; errors: string[]; metadata: MetadataResult }> { - try { - const content = await fs.readFile(filepath, 'utf8') - const { data: frontmatter } = matter(content) - const result = await validateMetadata(filepath, content) - - // Return early if validation failed - if (!result.isValid) { - return { - isValid: false, - errors: result.errors, - metadata: options.analysis - } - } - - // ... rest of function - } catch (error) { - throw new Error(`Failed to update metadata for ${filepath}: ${error.message}`) - } -} \ No newline at end of file diff --git a/utils/metadata-validator.ts b/utils/metadata-validator.ts deleted file mode 100644 index 63d0f40ce..000000000 --- a/utils/metadata-validator.ts +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env node -import { promises as fs } from 'node:fs' -import { validateMetadata } from './metadata-manager' -import { loadConfig } from './types/metadata-types' - -async function main() { - try { - // Load config first to ensure it's available - await loadConfig() - - const changedFiles = process.env.CHANGED_FILES?.split('\n').filter(f => f.endsWith('.mdx')) || [] - - if (changedFiles.length === 0) { - console.log('✓ No MDX files to check') - process.exit(0) - } - - console.log('Changed files:', changedFiles) - let hasErrors = false - - for (const file of changedFiles) { - try { - console.log(`\nChecking file: ${file}`) - const content = await fs.readFile(file, 'utf8') - console.log('File content loaded') - const result = await validateMetadata(file, content) - console.log('Validation completed') - - if (!result.isValid) { - hasErrors = true - console.log(`\nFile: ${file}`) - console.log('Validation errors:') - result.errors.forEach(error => console.log(` ❌ ${error}`)) - console.log('\nValid options can be found in keywords.config.yaml:') - console.log(' - Personas:', result.suggestions?.validPersonas.join(', ')) - console.log(' - Content Types:', result.suggestions?.validContentTypes.join(', ')) - console.log(' - Categories:', result.suggestions?.validCategories.join(', ')) - console.log(' - Is Imported Content: true, false') - } else { - console.log(`✓ ${file} passed validation`) - } - } catch (fileError) { - console.error(`Error processing file ${file}:`, fileError) - hasErrors = true - } - } - - if (hasErrors) { - process.exit(1) - } - - console.log('✓ All files passed validation') - process.exit(0) - } catch (error) { - console.error('Error:', error) - process.exit(1) - } -} - -// Use top-level await pattern for better error handling -main().catch(error => { - console.error('Unhandled error:', error) - process.exit(1) -}) diff --git a/utils/networks.ts b/utils/networks.ts deleted file mode 100644 index 1db57da3a..000000000 --- a/utils/networks.ts +++ /dev/null @@ -1,58 +0,0 @@ -interface Chain { - name: string - id: number - explorer: string -} - -interface Network { - mainnet: { - l1: Chain - l2: Chain - } - testnet: { - l1: Chain - l2: Chain - } -} - -const chains: { - [name: string]: Chain -} = { - ethereum: { - name: 'Ethereum', - id: 1, - explorer: 'https://etherscan.io', - }, - opmainnet: { - name: 'OP Mainnet', - id: 10, - explorer: 'https://optimistic.etherscan.io', - }, - sepolia: { - name: 'Sepolia', - id: 11155111, - explorer: 'https://sepolia.etherscan.io', - }, - opsepolia: { - name: 'OP Sepolia', - id: 11155420, - explorer: 'https://sepolia-optimistic.etherscan.io/', - }, -} - -const networks: { - [name: string]: Network -} = { - op: { - mainnet: { - l1: chains.ethereum, - l2: chains.opmainnet, - }, - testnet: { - l1: chains.sepolia, - l2: chains.opsepolia, - }, - } -} - -export const network = networks[process.env.DOCS_NETWORK_NAME || 'op'] diff --git a/utils/plugins/remark/remark-lint-no-blocked-characters.mjs b/utils/plugins/remark/remark-lint-no-blocked-characters.mjs deleted file mode 100644 index 027635f28..000000000 --- a/utils/plugins/remark/remark-lint-no-blocked-characters.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import { visit } from 'unist-util-visit' -import { lintRule } from 'unified-lint-rule' - -/** - * Custom remark lint rule that blocks certain characters (smart quotes, - * invisible spaces, etc.) from being used in the docs. Helps make the docs - * more consistent and avoids characters that might cause issues on certain - * platforms. - */ -const remarkLintNoBlockedCharacters = lintRule( - { - url: 'https://github.com/ethereum-optimism/docs', - origin: 'remark-lint:no-blocked-characters' - }, - (tree, file) => { - visit(tree, 'text', (node) => { - const characterRegex = /[“”‘’ ]/g - const replacements = { - '“': '"', - '”': '"', - '‘': "'", - '’': "'", - ' ': " " - } - - let match - while ((match = characterRegex.exec(node.value)) !== null) { - file.message( - `Blocked character found: (${match[0]}) at index ${match.index}`, - node - ) - - node.value = node.value.substring(0, match.index) + replacements[match[0]] + node.value.substring(match.index + 1) - file.messages[file.messages.length - 1].fix = { - range: [node.position.start.offset, node.position.end.offset], - text: node.value - } - } - }) - } -) - -export default remarkLintNoBlockedCharacters diff --git a/utils/redirects.ts b/utils/redirects.ts deleted file mode 100755 index fc128f999..000000000 --- a/utils/redirects.ts +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env node -// Save this file as utils/redirects.ts - -import * as fs from 'fs/promises'; -import * as path from 'path'; - -const rootDir = path.join(process.cwd(), 'pages'); -const redirectsPath = path.join(process.cwd(), 'public', '_redirects'); -const warnings: string[] = []; - -// ANSI color codes -const WHITE = '\x1b[37m'; -const GREEN = '\x1b[32m'; -const YELLOW = '\x1b[33m'; -const RESET = '\x1b[0m'; -const BOLD = '\x1b[1m'; - -interface Redirect { - from: string; - to: string; -} - -interface Summary { - total: number; - ok: number; - errors: number; -} - -function formatWarning(filePath: string, fromLink: string, toLink: string): string { - return `${WHITE}File "${filePath}" contains outdated link ${YELLOW}"${fromLink}"${WHITE} - should be updated to ${GREEN}"${toLink}"${RESET}`; -} - -async function getRedirects(): Promise { - try { - const content = await fs.readFile(redirectsPath, 'utf-8'); - return content.split('\n') - .filter(line => line.trim() && !line.startsWith('#')) - .map(line => { - const [from, to] = line.split(/\s+/); - return { from, to }; - }); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error reading redirects file:${RESET}`, error); - return []; - } -} - -async function findMdxFiles(dir: string): Promise { - const files: string[] = []; - - try { - const entries = await fs.readdir(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory() && !entry.name.startsWith('_')) { - files.push(...await findMdxFiles(fullPath)); - } else if (entry.isFile() && /\.(md|mdx)$/.test(entry.name)) { - files.push(fullPath); - } - } - } catch (error) { - console.error(`${YELLOW}${BOLD}Error reading directory ${dir}:${RESET}`, error); - } - - return files; -} - -function extractLinks(content: string): string[] { - const markdownLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g; - const hrefRegex = /href="([^"]+)"/g; - const links: string[] = []; - - let match; - while ((match = markdownLinkRegex.exec(content)) !== null) { - if (!match[2].startsWith('http')) { - links.push(match[2]); - } - } - while ((match = hrefRegex.exec(content)) !== null) { - if (!match[1].startsWith('http')) { - links.push(match[1]); - } - } - return links; -} - -async function checkFile(filePath: string, redirects: Redirect[]): Promise { - try { - const content = await fs.readFile(filePath, 'utf-8'); - const links = extractLinks(content); - const relativeFilePath = path.relative(rootDir, filePath); - - for (const link of links) { - const redirect = redirects.find(r => r.from === link); - if (redirect) { - warnings.push(formatWarning(relativeFilePath, link, redirect.to)); - } - } - } catch (error) { - console.error(`${YELLOW}${BOLD}Error checking file ${filePath}:${RESET}`, error); - } -} - -function printSummary(summary: Summary) { - console.log('\nSummary:'); - console.log(`${WHITE}Total pages 🔍 - ${summary.total}`); - console.log(`${YELLOW}Pages with outdated links 🚫 - ${summary.errors}`); - console.log(`${GREEN}Pages OK ✅ - ${summary.ok}${RESET}`); -} - -async function main() { - const summary: Summary = { - total: 0, - ok: 0, - errors: 0 - }; - - console.log('Starting redirect link check...'); - console.log('Root directory:', rootDir); - - try { - // Check if directories exist - try { - await fs.access(rootDir); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error: Root directory not found at ${rootDir}${RESET}`); - console.log('Current working directory:', process.cwd()); - process.exit(1); - } - - try { - await fs.access(redirectsPath); - } catch (error) { - console.error(`${YELLOW}${BOLD}Error: Redirects file not found at ${redirectsPath}${RESET}`); - process.exit(1); - } - - const redirects = await getRedirects(); - console.log(`Loaded ${redirects.length} redirects from ${redirectsPath}`); - - const files = await findMdxFiles(rootDir); - console.log(`Found ${files.length} MDX files to check`); - - summary.total = files.length; - - for (const file of files) { - await checkFile(file, redirects); - } - - // Count files with errors, not total errors - const filesWithErrors = new Set(warnings.map(w => w.split('"')[1])).size; - summary.errors = filesWithErrors; - summary.ok = summary.total - filesWithErrors; - - if (warnings.length > 0) { - console.log(`${YELLOW}${BOLD}Found ${warnings.length} links that need updating:${RESET}`); - warnings.forEach(warning => console.log(warning)); - printSummary(summary); - process.exit(1); - } else { - console.log(`${GREEN}All internal links are up to date.${RESET}`); - printSummary(summary); - } - } catch (error) { - console.error(`${YELLOW}${BOLD}Error checking redirects:${RESET}`, error); - process.exit(1); - } -} - -// Execute the script -main().catch(error => { - console.error(`${YELLOW}${BOLD}Error in main process:${RESET}`, error); - process.exit(1); -}); \ No newline at end of file diff --git a/utils/schemas/page.schema.yaml b/utils/schemas/page.schema.yaml deleted file mode 100644 index 0b5f27615..000000000 --- a/utils/schemas/page.schema.yaml +++ /dev/null @@ -1,14 +0,0 @@ -title: Page - -properties: - title: - type: string - lang: - type: string - description: - type: string - -required: - - title - - lang - - description diff --git a/utils/transaction-types.ts b/utils/transaction-types.ts deleted file mode 100644 index 70f154ad6..000000000 --- a/utils/transaction-types.ts +++ /dev/null @@ -1,50 +0,0 @@ -export const transactionTypes = { - "General OP Mainnet": { - TransactionsPerDay: 489109, - AvgCalldataBytesPerTx: 1007.8, - AvgEstimatedSizePerTx: 474.6, - AvgBlobgasPerL2Tx: 361.6153521, - EstimatedSizeBlobgasRatio: 1.313, - EstimatedSizeCalldataGasRatio: 21.0, - }, - Base: { - TransactionsPerDay: 3227633, - AvgCalldataBytesPerTx: 632.3006064, - AvgEstimatedSizePerTx: 368.6, - AvgBlobgasPerL2Tx: 168.0497343, - EstimatedSizeBlobgasRatio: 2.193, - EstimatedSizeCalldataGasRatio: 35.09, - }, - Mode: { - TransactionsPerDay: 123889, - AvgCalldataBytesPerTx: 131.8318268, - AvgEstimatedSizePerTx: 144.3, - AvgBlobgasPerL2Tx: 102.9448416, - EstimatedSizeBlobgasRatio: 1.402, - EstimatedSizeCalldataGasRatio: 22.43, - }, - Zora: { - TransactionsPerDay: 126719, - AvgCalldataBytesPerTx: 318.8965479, - AvgEstimatedSizePerTx: 174.6, - AvgBlobgasPerL2Tx: 121.6317714, - EstimatedSizeBlobgasRatio: 1.435, - EstimatedSizeCalldataGasRatio: 22.96, - }, - Mint: { - TransactionsPerDay: 6341, - AvgCalldataBytesPerTx: 274.5535557, - AvgEstimatedSizePerTx: 206.9, - AvgBlobgasPerL2Tx: 317.11, - EstimatedSizeBlobgasRatio: 0.65, - EstimatedSizeCalldataGasRatio: 10.44, - }, - Metal: { - TransactionsPerDay: 430, - AvgCalldataBytesPerTx: 296.1833811, - AvgEstimatedSizePerTx: 237.2, - AvgBlobgasPerL2Tx: 947549.16, - EstimatedSizeBlobgasRatio: 0.0, - EstimatedSizeCalldataGasRatio: 0.0, - }, -}; diff --git a/utils/types/metadata-types.ts b/utils/types/metadata-types.ts deleted file mode 100644 index b1d85b8df..000000000 --- a/utils/types/metadata-types.ts +++ /dev/null @@ -1,140 +0,0 @@ -import yaml from 'js-yaml' -import { promises as fs } from 'node:fs' -import path from 'node:path' - -let config: MetadataConfig | null = null; - -export async function loadConfig(): Promise { - if (config) return config; - - const configPath = path.join(process.cwd(), 'keywords.config.yaml') - const configContent = await fs.readFile(configPath, 'utf8') - const loadedConfig = yaml.load(configContent) as MetadataConfig - - if (!isValidConfig(loadedConfig)) { - throw new Error('Invalid keywords.config.yaml structure') - } - - config = loadedConfig - return config -} - -// Type guard to ensure the config has the expected structure -function isValidConfig(config: any): config is MetadataConfig { - return ( - config && - config.metadata_rules && - config.metadata_rules.persona?.validation_rules?.[0]?.enum && - config.metadata_rules.content_type?.validation_rules?.[0]?.enum && - config.metadata_rules.categories?.values && - config.metadata_rules.is_imported_content?.validation_rules?.[0]?.enum - ) -} - -export interface ValidationRule { - pattern?: string - description?: string - enum?: string[] -} - -export interface MetadataField { - required?: boolean - multiple?: boolean - validation_rules?: ValidationRule[] -} - -export interface MetadataConfig { - metadata_rules: { - persona: { - required: boolean - multiple: boolean - min: number - validation_rules: Array<{ - enum: string[] - description: string - }> - } - content_type: { - required: boolean - multiple: boolean - validation_rules: Array<{ - enum: string[] - description: string - }> - } - categories: { - required: boolean - multiple: boolean - min: number - max: number - validation_rules: Array<{ - no_duplicates: boolean - description: string - }> - values: string[] - } - is_imported_content: { - required: boolean - multiple: boolean - validation_rules: Array<{ - enum: ['true', 'false'] - description: string - }> - } - } -} - -export interface MetadataResult { - title: string - lang: string - description: string - topic: string - personas: Array - content_type: string - categories: Array - is_imported_content: string - content?: string - detectionLog?: Array - suggestions?: { - content_type?: string - categories?: string[] - topic?: string - personas?: string[] - } -} - -export interface ProcessedFile { - file: string - topic: string - is_imported: boolean -} - -export interface Manifest { - timestamp: string - processed_files: Array -} - -export interface MetadataOptions { - dryRun: boolean; - verbose: boolean; - analysis: MetadataResult; - validateOnly: boolean; - prMode: boolean; -} - -export interface ValidationResult { - isValid: boolean - errors: string[] - suggestions?: { - validPersonas: string[] - validContentTypes: string[] - validCategories: string[] - } -} - -export const getConfig = () => { - if (!config) { - throw new Error('Config not loaded. Call loadConfig() first.') - } - return config -} \ No newline at end of file diff --git a/words.txt b/words.txt index 19a182f51..a7b77b0e3 100644 --- a/words.txt +++ b/words.txt @@ -1,7 +1,7 @@ -ACCOUNTQUEUE accountqueue -ACCOUNTSLOTS +ACCOUNTQUEUE accountslots +ACCOUNTSLOTS ACDC ADDI ADDIU @@ -9,63 +9,61 @@ ADDU airgap Allnodes allocs -Alphanet alphanet -Alphanets +Alphanet alphanets +Alphanets altda ANDI Ankr Apeworx Arweave authrpc -Autorelay autorelay autorelayer basefee bcde -Betanet betanet -Betanets +Betanet betanets +Betanets BGEZ BGTZ Biconomy BLEZ -BLOBPOOL blobpool +BLOBPOOL blobspace Blockdaemon blockhash blocklists -BLOCKLOGS blocklogs -BLOCKPROFILERATE +BLOCKLOGS blockprofilerate +BLOCKPROFILERATE Blockscout -Blockspace blockspace +Blockspace blocktime -Blocktimes blocktimes -BLOOMFILTER +Blocktimes bloomfilter +BLOOMFILTER BLTZ Bootcamp bootnode -BOOTNODES -Bootnodes bootnodes +Bootnodes +BOOTNODES bottlenecked -Brotli brotli -Callouts +Brotli callouts +Callouts CCIP cdef Celestia Celestia's -chainid Chainlink Chainlink's Chainstack @@ -73,119 +71,118 @@ chaosnet Chugsplash Clabby codebases -Collateralized collateralized +Collateralized compr Comprensive -COMPUTEPENDINGBLOCK computependingblock +COMPUTEPENDINGBLOCK confs corsdomain counterfactually -Crosschain crosschain +Crosschain Crossmint daserver -DATACAP datacap -DATADIR +DATACAP datadir +DATADIR Defi Defillama's delegatecall -Devnet devnet -Devnets +Devnet devnets +Devnets devs direnv -DISABLETXPOOLGOSSIP disabletxpoolgossip -Discv +DISABLETXPOOLGOSSIP discv +Discv DIVU Drand dripcheck Drippie Eigen EIPs -ENABLEDEPRECATEDPERSONAL enabledeprecatedpersonal +ENABLEDEPRECATEDPERSONAL enginekind -Erigon erigon -ETHERBASE +Erigon etherbase +ETHERBASE Ethernity Ethernow -ETHSTATS ethstats -EVMTIMEOUT +ETHSTATS evmtimeout +EVMTIMEOUT executability exfiltrate -EXITWHENSYNCED exitwhensynced +EXITWHENSYNCED extensibly -EXTRADATA extradata +EXTRADATA Farcaster Faultproof -FDLIMIT fdlimit +FDLIMIT Flashblocks Flashbots -forkable forkchoice FPVM FPVMs Fraxtal Funct -GASCAP gascap +GASCAP gaslessly -GCMODE gcmode +GCMODE Gelato gifs -GLOBALQUEUE globalqueue -GLOBALSLOTS +GLOBALQUEUE globalslots +GLOBALSLOTS gokzg growthepie hardfork hardforks -HEALTHCHECK healthcheck +HEALTHCHECK healthchecks -HISTORICALRPC historicalrpc -HISTORICALRPCTIMEOUT +HISTORICALRPC historicalrpctimeout -HOLESKY -Holesky +HISTORICALRPCTIMEOUT holesky +Holesky +HOLESKY IERC -IGNOREPRICE ignoreprice +IGNOREPRICE Immunefi -Inator inator -INFLUXDBV +Inator influxdbv +INFLUXDBV initcode -IPCDISABLE ipcdisable +IPCDISABLE ipcfile -IPCPATH ipcpath +IPCPATH IPFS JALR -JOURNALREMOTES journalremotes -JSPATH +JOURNALREMOTES jspath +JSPATH jwtsecret Keccak leveldb @@ -194,34 +191,34 @@ Lisk logfile logfmt Mainnets -MAXAGE maxage -MAXBACKUPS +MAXAGE maxbackups -MAXPEERS +MAXBACKUPS maxpeers -MAXPENDPEERS +MAXPEERS maxpendpeers -MAXPRICE +MAXPENDPEERS maxprice -MEMPROFILERATE +MAXPRICE memprofilerate -Merkle +MEMPROFILERATE merkle +Merkle MFHI MFLO Mgas Minato -MINFREEDISK minfreedisk -MINSUGGESTEDPRIORITYFEE +MINFREEDISK minsuggestedpriorityfee +MINSUGGESTEDPRIORITYFEE Mintable Mintplex MIPSEVM Mitigations -Monitorism monitorism +Monitorism Moralis Mordor mountpoint @@ -231,45 +228,42 @@ MTHI MTLO MULT multiaddr -Multichain multichain +Multichain multiclient multisigs MULTU nethermind -NETRESTRICT netrestrict -NETWORKID +NETRESTRICT networkid -NEWPAYLOAD +NETWORKID newpayload -nextra -NOCOMPACTION +NEWPAYLOAD nocompaction -NODEKEY +NOCOMPACTION nodekey -NODEKEYHEX +NODEKEY nodekeyhex +NODEKEYHEX nodename Nodies -NODISCOVER nodiscover -NOLOCALS +NODISCOVER nolocals -NOPREFETCH +NOLOCALS noprefetch -NOPRUNING +NOPREFETCH nopruning -NOSYNCSERVE +NOPRUNING nosyncserve +NOSYNCSERVE Numba NVME -Offchain offchain -opchaina -opchainb -OPCM +Offchain opcm +OPCM Openfort oplabs opnode's @@ -277,98 +271,96 @@ outfile outperformance pcscdpath Pectra -pectra Pectra's -Peerstore peerstore +Peerstore peerstores -Permissioned permissioned +Permissioned permissioning -Permissionless permissionless +Permissionless permissionlessly Perps Peta Pimlico POAP POAPs -PPROF pprof -Precommitments +PPROF precommitments +Precommitments preconfigured predeploy -Predeployed predeployed -Predeploys +Predeployed predeploys +Predeploys prefunded -Preimage preimage -PREIMAGES +Preimage preimages +PREIMAGES preinstall -Preinstalls preinstalls -Prestate +Preinstalls prestate +Prestate prestates PREVRANDAO -PRICEBUMP pricebump -PRICELIMIT +PRICEBUMP pricelimit +PRICELIMIT productionize productionized Protip Proxied -Proxyd proxyd Pyth Pyth's QRNG -Quicknode quicknode +Quicknode quickstarts rebalancing reemit Reemitting -Regenesis regenesis +Regenesis Reimagine -REJOURNAL rejournal -REMOTEDB +REJOURNAL remotedb +REMOTEDB Reown Reown's replayability replayor reposts reproven -REQUIREDBLOCKS requiredblocks +REQUIREDBLOCKS rollouts -Rollups rollups +Rollups Routescan rpckind -RPCPREFIX rpcprefix +RPCPREFIX rpcs RPGF -Runbooks runbooks +Runbooks RWAs safedb Schnorr -SEPOLIA -Sepolia sepolia +Sepolia +SEPOLIA seqnr -SEQUENCERHTTP sequencerhttp +SEQUENCERHTTP serv signup SLLV @@ -377,16 +369,16 @@ SLTIU SLTU smartcard snapshotlog -Snapsync snapsync +Snapsync Solana Soneium soyboy Spearbit SRAV SRLV -Stablecoins stablecoins +Stablecoins statefulset structs subcomponents @@ -395,21 +387,20 @@ subheaders subsecond SUBU Sunnyside -SUPERCHAIN -Superchain superchain +Superchain +SUPERCHAIN Superchain's -superchainerc Superlend Superloans Superscan Superseed -Supersim supersim -SYNCMODE +Supersim syncmode -SYNCTARGET +SYNCMODE synctarget +SYNCTARGET syscalls SYSCON thirdweb @@ -423,10 +414,9 @@ Twei txfeecap txmgr txns -TXPOOL txpool +TXPOOL txproxy -txproxyd uncensorable uncountered undercollateralize @@ -435,21 +425,21 @@ Unprotect unsubmitted UPNP upstreaming -VERKLE verkle -VHOSTS +VERKLE vhosts -Viem +VHOSTS viem -Viem's +Viem viem's -VMDEBUG +Viem's vmdebug -VMODULE +VMDEBUG vmodule +VMODULE xlarge XORI ZKPs ZKVM -Zora zora +Zora