Repository: inkonchain/docs Branch: main Commit: 7668c004c0bb Files: 121 Total size: 178.9 KB Directory structure: gitextract_zhocjkyg/ ├── .dockerignore ├── .eslintrc.js ├── .github/ │ ├── CODEOWNERS │ ├── actions/ │ │ └── base-setup/ │ │ └── action.yaml │ ├── dependabot.yaml │ └── workflows/ │ ├── cicd.yaml │ └── securesdlc.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierrc ├── .vscode/ │ └── settings.json ├── Dockerfile ├── README.md ├── amplify.yml ├── cspell/ │ └── project-words.txt ├── cspell.json ├── eslint.config.js ├── global-env.d.ts ├── next-env.d.ts ├── next-sitemap.config.js ├── next.config.mjs ├── package.json ├── postcss.config.js ├── src/ │ ├── components/ │ │ ├── AddNetworkButton.tsx │ │ ├── BlockExplorersContentWrapper.tsx │ │ ├── BridgesContentWrapper.tsx │ │ ├── Button.tsx │ │ ├── CommunityContentWrapper.tsx │ │ ├── CopyButton.tsx │ │ ├── CopyableCode.tsx │ │ ├── CrosschainContentWrapper.tsx │ │ ├── DownloadButton.tsx │ │ ├── FaucetsContentWrapper.tsx │ │ ├── Footer.tsx │ │ ├── Head.tsx │ │ ├── MultisigContentWrapper.tsx │ │ ├── SidebarTitleComponent.tsx │ │ ├── TestnetDisclaimer.tsx │ │ ├── ThemeToggle.tsx │ │ └── Toc.tsx │ ├── content/ │ │ └── shared/ │ │ ├── _badges.mdx │ │ ├── block-explorers-content.mdx │ │ ├── bridges-content.mdx │ │ ├── community-content.mdx │ │ ├── crosschain-content.mdx │ │ ├── faucets-content.mdx │ │ └── multisig-content.mdx │ ├── fonts.ts │ ├── globals.css │ ├── icons/ │ │ ├── Check.tsx │ │ ├── ConnectedPulse.tsx │ │ ├── Download.tsx │ │ ├── InkLogo.tsx │ │ ├── Moon.tsx │ │ ├── Pencil.tsx │ │ ├── Sun.tsx │ │ └── ThumbUp.tsx │ ├── pages/ │ │ ├── 404.mdx │ │ ├── 500.mdx │ │ ├── _app.mdx │ │ ├── _meta.json │ │ ├── build/ │ │ │ ├── _meta.json │ │ │ ├── getting-started.mdx │ │ │ ├── ink-kit.mdx │ │ │ ├── onchain-clients.mdx │ │ │ ├── transaction-fees.mdx │ │ │ ├── tutorials/ │ │ │ │ ├── _meta.json │ │ │ │ ├── deploying-a-smart-contract/ │ │ │ │ │ ├── _meta.json │ │ │ │ │ ├── foundry.mdx │ │ │ │ │ ├── hardhat.mdx │ │ │ │ │ └── remix.mdx │ │ │ │ ├── deploying-a-superchainerc20.mdx │ │ │ │ ├── shipping-on-the-superchain.mdx │ │ │ │ └── verify-smart-contract.mdx │ │ │ ├── tutorials.mdx │ │ │ └── verify.mdx │ │ ├── faq.mdx │ │ ├── general/ │ │ │ ├── _meta.json │ │ │ ├── about.mdx │ │ │ ├── connect-wallet.mdx │ │ │ ├── faucet.mdx │ │ │ ├── network-information.mdx │ │ │ ├── support/ │ │ │ │ ├── _meta.json │ │ │ │ └── troubleshooting.mdx │ │ │ └── support.mdx │ │ ├── index.mdx │ │ ├── ink-builder-program/ │ │ │ ├── _meta.json │ │ │ ├── echo-program.mdx │ │ │ ├── forge-program.mdx │ │ │ ├── office-hours.mdx │ │ │ ├── overview.mdx │ │ │ └── spark-program.mdx │ │ ├── status.mdx │ │ ├── tools/ │ │ │ ├── _meta.json │ │ │ ├── account-abstraction.mdx │ │ │ ├── block-explorers.mdx │ │ │ ├── bridges.mdx │ │ │ ├── crosschain.mdx │ │ │ ├── faucets.mdx │ │ │ ├── indexers.mdx │ │ │ ├── multisig.mdx │ │ │ ├── oracles.mdx │ │ │ ├── rpc.mdx │ │ │ ├── security.mdx │ │ │ └── vrf.mdx │ │ ├── useful-information/ │ │ │ ├── _meta.json │ │ │ ├── contracts.mdx │ │ │ ├── ink-contracts.mdx │ │ │ ├── ink-token-contracts.mdx │ │ │ └── the-superchain.mdx │ │ └── work-with-ink/ │ │ ├── _meta.json │ │ ├── brand-kit.mdx │ │ ├── community.mdx │ │ └── contributing.mdx │ ├── types/ │ │ └── mdx.d.ts │ └── utils/ │ ├── networks.ts │ └── urls.ts ├── tailwind.config.js ├── theme.config.tsx └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ node_modules .github .next dist .env* *.log .git .gitignore ================================================ FILE: .eslintrc.js ================================================ module.exports = { extends: ["next/core-web-vitals", "prettier"], plugins: ["simple-import-sort"], rules: { "react-hooks/exhaustive-deps": "error", "import/newline-after-import": [ "error", { count: 1, }, ], // increase the severity of rules so they are auto-fixable "simple-import-sort/imports": [ "error", { groups: [ // Packages `react` related packages come first. ["^react", "^@?\\w"], // Internal packages. ["^(@)(/.*|$)"], // Side effect imports. ["^\\u0000"], // Parent imports. Put `..` last. ["^\\.\\.(?!/?$)", "^\\.\\./?$"], // Other relative imports. Put same-folder imports and `.` last. ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], // Style imports. ["^.+\\.?(css)$"], ], }, ], "simple-import-sort/exports": "error", }, }; ================================================ FILE: .github/CODEOWNERS ================================================ * @inkonchain/developers-secret ================================================ FILE: .github/actions/base-setup/action.yaml ================================================ name: 'Basic Setup' description: 'Basic setup with pnpm and cache restore' runs: using: "composite" steps: - name: Setup pnpm uses: pnpm/action-setup@v2 with: run_install: false - name: Setup Node 22 uses: actions/setup-node@v4 with: node-version: "22.x" cache: "pnpm" - name: Add pnpm store path to env var id: pnpm-cache shell: bash run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - name: Restore Cache uses: actions/cache@v4 with: path: | ${{ steps.pnpm-cache.outputs.STORE_PATH }} **/node_modules key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- ================================================ FILE: .github/dependabot.yaml ================================================ version: 2 updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" ================================================ FILE: .github/workflows/cicd.yaml ================================================ name: CI/CD Workflow on: pull_request: push: branches: - main jobs: securesdlc: uses: inkonchain/.github/.github/workflows/securesdlc.yml@main secrets: inherit install_modules: needs: securesdlc runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: volta-cli/action@v4 - uses: pnpm/action-setup@v4 with: run_install: false - uses: actions/setup-node@v4 with: node-version: "22.x" cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Add pnpm store path to env var id: pnpm-cache shell: bash run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - name: Cache node modules uses: actions/cache@v4 with: path: | ${{ steps.pnpm-cache.outputs.STORE_PATH }} **/node_modules key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- js-lint: needs: install_modules runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/base-setup name: Base Setup - name: JS linting run: pnpm run lint:js md-lint: needs: install_modules runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/base-setup name: Base Setup - name: MDX linting run: pnpm run lint:mdx format: needs: install_modules runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/base-setup name: Base Setup - name: Run formatting run: pnpm run format:js # spell-check: # needs: install_modules # runs-on: ubuntu-latest # steps: # - uses: actions/checkout@v4 # - uses: ./.github/actions/base-setup # name: Base Setup # - name: Run Spellcheck # run: pnpm run spellcheck:lint build: needs: install_modules runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/base-setup name: Base Setup - name: Building app run: pnpm run build - name: Cache build uses: actions/cache/save@v4 with: path: .next key: ${{ runner.os }}-build-store-${{ hashFiles('.next') }} docker-publish: if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: build steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log in to GitHub Container Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . push: true tags: ghcr.io/inkonchain/docs:latest - name: Log out from GitHub Container Registry run: docker logout ghcr.io ================================================ FILE: .github/workflows/securesdlc.yml ================================================ name: Nautilus SecureSDLC Reusable run-name: "[Nautilus SecureSDLC Reusable] Ref:${{ github.ref_name }} Event:${{ github.event_name }}" on: workflow_dispatch: {} workflow_call: {} push: branches: [ main ] jobs: securesdlc-umbrella: permissions: contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/upload-sarif to upload SARIF results actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status uses: nautilus-wraith/securesdlc-umbrella/.github/workflows/securesdlc-umbrella.yml@release-stable secrets: SEMGREP_APP_URL: ${{ secrets.SEMGREP_APP_URL }} SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} SDLC_SLACK_NOTIFICATIONS: ${{ secrets.SDLC_SLACK_NOTIFICATIONS }} ================================================ FILE: .gitignore ================================================ # packages node_modules # os specific files .DS_Store # build artifacts .next public/robots.txt public/sitemap-0.xml public/sitemap.xml # log files *.log out ================================================ FILE: .npmrc ================================================ # https://www.npmjs.com/package/next-sitemap#building-sitemaps-with-pnpm enable-pre-post-scripts=true ================================================ FILE: .nvmrc ================================================ v22.14.0 ================================================ FILE: .prettierrc ================================================ { "trailingComma": "es5", "tabWidth": 2, "semi": true, "singleQuote": false } ================================================ FILE: .vscode/settings.json ================================================ { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "[typescriptreact, javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" } }, "[plaintext]": { "editor.formatOnSave": false }, "editor.formatOnPaste": false, "prettier.useEditorConfig": false, "prettier.useTabs": false, "prettier.configPath": ".prettierrc", "prettier.prettierPath": "node_modules/prettier" } ================================================ FILE: Dockerfile ================================================ FROM node:22-alpine RUN corepack enable && corepack prepare pnpm@9.12.3 --activate WORKDIR /app COPY package.json pnpm-lock.yaml ./ RUN pnpm install --frozen-lockfile COPY . . RUN pnpm run build RUN adduser --system --uid 1001 docs-user USER docs-user EXPOSE 3000 CMD ["pnpm", "start"] ================================================ FILE: README.md ================================================ [![Twitter](https://img.shields.io/twitter/follow/inkonchain)](https://x.com/inkonchain) # InkChain Documentation App An advanced, streamlined documentation platform built with Next.js and Nextra for InkChain. ## 🚀 Build & Run 1. **Build Docker image**: ```bash docker build -t docs . ``` 2. **Run Docker container**: ```bash docker run -p 3000:3000 docs ``` ## 📋 Requirements * **Node.js**: v20.11.0 or higher ## 📖 Overview This is a documentation application powered by [Nextra](https://nextra.site/) and built on [Next.js](https://nextjs.org/). Nextra simplifies the creation of documentation sites, allowing us to leverage the **Pages Router** for efficient navigation and routing. Currently, due to compatibility limitations, we have not yet upgraded to the App Router. ## 🏁 Getting Started To get started with local development: 1. **Clone the repository** 2. **Install dependencies**: ```bash pnpm install ``` 3. **Start development server**: ```bash pnpm run dev ``` ## 🛠 Tooling Our development setup includes multiple tools to maintain high-quality code and documentation: * **[CSpell](https://cspell.org/)**: Real-time spell checking to maintain documentation accuracy. * **[Remark](https://remark.js.org/)**: Processes and renders Markdown content with added plugins. * **[ESLint](https://eslint.org/)**: Ensures code quality by catching potential issues. * **[Prettier](https://prettier.io/)**: Enforces consistent code formatting. * **[Tailwind CSS](https://tailwindcss.com/)**: Utility-first CSS framework for fast, responsive UI development. ## 🚦 CI/CD Pipeline Our CI/CD setup utilizes GitHub Actions to run automated checks on every pull request (PR): * **js-lint**: Ensures proper JavaScript code formatting with ESLint. * **md-lint**: Checks Markdown code formatting with Remark. * **format**: Enforces consistent code style with Prettier. * **spell-check**: Uses CSpell to verify correct spelling in the documentation. For any unique terms (e.g., "InkChain"), add them to the [`./cspell/project-words.txt`](./cspell/project-words.txt) file to whitelist. ## 🌐 Feature Branch Deployment For every new PR, our CI/CD pipeline deploys a temporary environment via **AWS Amplify**. This real-time deployment enables live testing and review of changes before merging, ensuring a smoother workflow. The deployment URL is automatically provided within the PR checks, allowing team members to interact with new features. ## 🚀 Production Deployment The `main` branch is configured for automatic continuous deployment via **AWS Amplify**. Every merge triggers a new build and deployment, ensuring that the latest version of the documentation is available to users without manual intervention. ================================================ FILE: amplify.yml ================================================ version: 1 frontend: phases: preBuild: commands: - npm install -g pnpm - pnpm install --frozen-lockfile build: commands: - pnpm run build artifacts: baseDirectory: .next files: - '**/*' cache: paths: - node_modules/**/* ================================================ FILE: cspell/project-words.txt ================================================ Blockscout inkchain Superchain’s blockscout amet adipiscing elit eiusmod tempor incididunt labore dolore aliqua enim veniam quis nostrud ullamco laboris aliquip commodo consequat Duis aute irure reprehenderit voluptate velit cillum fugiat nulla pariatur Excepteur occaecat cupidatat proident sunt officia deserunt mollit laborum CSpell: Files checked: 11, Issues found: 42 in 4 files. adipiscing aliqua aliquip amet aute Blockscout blockscout cillum commodo consequat cupidatat deserunt dolore Duis eiusmod elit enim Excepteur fugiat incididunt irure labore laboris laborum mollit nostrud nulla occaecat officia pariatur proident quis reprehenderit sunt tempor ullamco velit veniam voluptate untar NVME nextra Gelato QuickNode Superchain Sepolia userbase synergizing vewy scawy Brid Rabby Protofire Zerodev Permissionless Crosschain Supersim verif Sourcify sourcify sourcecode Superbridge inkonchain Drand Viem viem hackathons Goldsky Multicall Mintable Permissioned preinstalls multisignatures baselayer Smol foundryup inksepolia INKSEPOLIA commoditizes multichain Routescan Lurus wordmark SEDA shadcn Chakra wagmi superchainerc krakenfx Remappings remappings blocktimes cypherpunk predeploy DYOR subsecond microgrants Microgrants Inkubator microgrant Chainlink cryptoeconomically drpc Hypernative Hypernative's predeterministic sfrx ================================================ FILE: cspell.json ================================================ { "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", "version": "0.2", "dictionaryDefinitions": [ { "name": "project-words", "path": "./cspell/project-words.txt", "addWords": true } ], "dictionaries": [ "project-words" ], "ignorePaths": [ "node_modules", "/project-words.txt" ] } ================================================ FILE: eslint.config.js ================================================ const simpleImportSort = require("eslint-plugin-simple-import-sort"); const path = require("node:path"); const js = require("@eslint/js"); const { FlatCompat } = require("@eslint/eslintrc"); const baseDirectory = __dirname; const compat = new FlatCompat({ baseDirectory: baseDirectory, recommendedConfig: js.configs.recommended, allConfig: js.configs.all, }); module.exports = [ // Default ignores - node_modules is ignored by default in recent ESLint, but good to be explicit. // Add other ignores if needed (e.g., build output directories like .next) { ignores: ["**/node_modules/**", "**/.next/**", "**/out/**"], }, // Spread the configurations from extended configs ...compat.extends("next/core-web-vitals", "prettier"), // Configuration for JS/JSX/TS/TSX files { files: ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"], plugins: { // Use the imported object directly as the key simpleImportSort: simpleImportSort, }, rules: { "react-hooks/exhaustive-deps": "error", "import/newline-after-import": ["error", { count: 1 }], "simpleImportSort/imports": [ "error", { groups: [ ["^react", "^@?\\w"], ["^(@)(/.*|$)"], ["^\\u0000"], ["^\\.\\.(?!/?$)", "^\\.\\./?$"], ["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"], ["^.+\\.?(css)$"], ], }, ], "simpleImportSort/exports": "error", }, }, ]; ================================================ FILE: global-env.d.ts ================================================ interface Window { ethereum: any; } ================================================ FILE: next-env.d.ts ================================================ /// /// /// // NOTE: This file should not be edited // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information. ================================================ FILE: next-sitemap.config.js ================================================ /** @type {import('next-sitemap').IConfig} */ module.exports = { exclude: ['*/_meta'], siteUrl: 'https://docs.inkonchain.com', generateRobotsTxt: true, robotsTxtOptions: { policies: [ { userAgent: '*', allow: '/', }, ] } } ================================================ FILE: next.config.mjs ================================================ import nextra from "nextra"; import path from "path"; import remarkCodeImport from "remark-code-import"; import { fileURLToPath } from "url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const withNextra = nextra({ theme: "nextra-theme-docs", themeConfig: "./theme.config.tsx", defaultShowCopyCode: true, mdxOptions: { remarkPlugins: [remarkCodeImport], }, }); const config = withNextra({ eslint: { ignoreDuringBuilds: true, }, images: { unoptimized: true, }, webpack: (config) => { config.resolve.alias = { ...config.resolve.alias, "@": path.join(__dirname, "src"), }; return config; }, experimental: { mdxRs: true, }, }); export default config; ================================================ FILE: package.json ================================================ { "name": "inkchain-docs", "volta": { "node": "22.14.0", "pnpm": "9.12.3" }, "packageManager": "pnpm@9.12.3", "scripts": { "dev": "next dev", "build": "next build", "postbuild": "next-sitemap", "start": "next start", "lint": "pnpm run lint:js && pnpm run lint:mdx && pnpm run format:js:check && pnpm run spellcheck:lint", "lint:fix": "pnpm run lint:js:fix && pnpm run lint:mdx:fix && pnpm run format:js && pnpm run spellcheck:fix", "lint:js": "eslint ./src theme.config.tsx --ext js,jsx,ts,tsx", "lint:js:fix": "eslint ./src theme.config.tsx --fix --ext js,jsx,ts,tsx", "format:js": "prettier --write \"**/*.{ts,tsx,css,scss}\"", "format:js:check": "prettier --check \"**/*.{ts,tsx,css,scss}\"", "lint:mdx": "remark . --quiet --frail", "lint:mdx:fix": "remark . -o --quiet", "spellcheck:lint": "cspell lint \"**/*.mdx\"", "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq" }, "remarkConfig": { "settings": { "emphasis": "*", "strong": "*" }, "plugins": [ "remark-frontmatter", "remark-preset-lint-consistent", "remark-preset-lint-recommended", "remark-gfm", [ "remark-mdx", { "commonmark": true, "extensions": [ ".mdx" ], "jsx": true } ], "remark-lint-frontmatter-schema", "remark-lint-heading-style", "remark-lint-list-item-indent", "remark-lint-table-cell-padding", "remark-lint-table-pipe-alignment", "remark-lint-table-pipes", "remark-lint-unordered-list-marker-style" ] }, "dependencies": { "clsx": "2.1.1", "next": "15.5.10", "next-sitemap": "4.2.3", "next-themes": "0.4.6", "nextra": "2.13.4", "nextra-theme-docs": "2.13.4", "react": "18.3.1", "react-dom": "18.3.1" }, "devDependencies": { "@eslint/eslintrc": "3.3.1", "@eslint/js": "9.32.0", "@types/node": "24.1.0", "@types/react": "18.3.12", "@types/react-dom": "18.3.1", "autoprefixer": "10.4.21", "cspell": "9.2.0", "eslint": "9.32.0", "eslint-config-next": "15.5.10", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "eslint-plugin-mdx": "3.6.2", "eslint-plugin-simple-import-sort": "12.1.1", "mdx": "0.3.1", "postcss": "8.5.6", "prettier": "3.6.2", "remark": "15.0.1", "remark-cli": "12.0.1", "remark-code-import": "1.2.0", "remark-frontmatter": "5.0.0", "remark-gfm": "4.0.1", "remark-lint-frontmatter-schema": "3.15.4", "remark-lint-heading-style": "4.0.1", "remark-lint-list-item-indent": "4.0.1", "remark-lint-table-cell-padding": "5.1.1", "remark-lint-table-pipe-alignment": "4.1.1", "remark-lint-table-pipes": "5.0.1", "remark-lint-unordered-list-marker-style": "4.0.1", "remark-mdx": "3.1.0", "remark-preset-lint-consistent": "6.0.1", "remark-preset-lint-recommended": "7.0.1", "tailwindcss": "3.4.17", "typescript": "5.8.3" } } ================================================ FILE: postcss.config.js ================================================ module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, } ================================================ FILE: src/components/AddNetworkButton.tsx ================================================ import { CheckIcon } from "@/icons/Check"; import { ConnectedPulse } from "@/icons/ConnectedPulse"; import { networkParams, NetworkType, useNetwork, UseNetworkResponse, } from "@/utils/networks"; import { Button } from "./Button"; interface AddNetworkButtonProps { network: NetworkType; heading: string; } export const AddNetworkButton = ({ network, heading, }: AddNetworkButtonProps) => { const { isWalletInstalled, isAdded, isSelected, addNetwork, selectNetwork } = useNetwork(network); return (

{heading} {isSelected && }

); }; const AddNetworkButtonContent = ({ isWalletInstalled, isAdded, isSelected, addNetwork, selectNetwork, network, }: UseNetworkResponse & { network: NetworkType }) => { if (!isWalletInstalled) { return

No wallet connected

; } if (isAdded && isSelected) { return ( Network added & selected. ); } if (isAdded) { return (

Network added.

Click here to select it.

); } return ( ); }; ================================================ FILE: src/components/BlockExplorersContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import BlockExplorersContent from "@/content/shared/block-explorers-content.mdx"; export function BlockExplorersContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/BridgesContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import BridgesContent from "@/content/shared/bridges-content.mdx"; export function BridgesContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/Button.tsx ================================================ import { PropsWithChildren } from "react"; import clsx from "clsx"; interface ButtonProps { variant: "primary" | "secondary"; onClick?: () => void; className?: string; } export const Button: React.FC> = ({ children, variant, onClick, className, }) => { return ( ); }; ================================================ FILE: src/components/CommunityContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import CommunityContent from "@/content/shared/community-content.mdx"; export function CommunityContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/CopyButton.tsx ================================================ "use client"; import { useState } from "react"; interface CopyButtonProps { text: string; className?: string; } export default function CopyButton({ text, className = "" }: CopyButtonProps) { const [copied, setCopied] = useState(false); const handleCopy = async () => { try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { console.error("Failed to copy:", err); } }; return ( ); } ================================================ FILE: src/components/CopyableCode.tsx ================================================ "use client"; import CopyButton from "./CopyButton"; interface CopyableCodeProps { code: string; display?: string; className?: string; href?: string; } export default function CopyableCode({ code, display, className = "", href, }: CopyableCodeProps) { const CodeContent = () => ( {display || code} ); return ( {href ? ( ) : ( )} ); } ================================================ FILE: src/components/CrosschainContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import CrosschainContent from "@/content/shared/crosschain-content.mdx"; export function CrosschainContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/DownloadButton.tsx ================================================ import { PropsWithChildren } from "react"; import { DownloadIcon } from "@/icons/Download"; import { Button } from "./Button"; interface DownloadButtonProps { sourceFilePath: string; destinationFileName: string; label: string; size: string; } export const DownloadButton: React.FC< PropsWithChildren > = ({ sourceFilePath, destinationFileName, label, size }) => { return ( ); }; ================================================ FILE: src/components/FaucetsContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import FaucetsContent from "@/content/shared/faucets-content.mdx"; export function FaucetsContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/Footer.tsx ================================================ import { ThemeToggle } from "./ThemeToggle"; export const Footer = () => { return (
Made with 💜 by the Ink team
); }; ================================================ FILE: src/components/Head.tsx ================================================ import { useRouter } from "next/router"; import { useConfig } from "nextra-theme-docs"; export const Head = () => { const { asPath, defaultLocale, locale } = useRouter(); const { frontMatter } = useConfig(); const baseUrl = "https://docs.inkonchain.com"; const url = baseUrl + (defaultLocale === locale ? asPath : `/${locale}${asPath}`); const title = frontMatter.title || "Ink Docs - The Official Developer Guide for Ink"; const description = frontMatter.description || "Comprehensive documentation for Ink, a cutting-edge Layer 2 (L2) blockchain built on Optimism's Superchain. Learn how to build, integrate, and leverage Ink's DeFi capabilities."; const ogImage = frontMatter.image || `${baseUrl}/logo/build-the-future.png`; return ( <> {/* Basic Meta Tags */} {/* Open Graph / Facebook */} {/* Twitter */} {/* Favicon */} ); }; ================================================ FILE: src/components/MultisigContentWrapper.tsx ================================================ import CopyableCode from "@/components/CopyableCode"; import MultisigContent from "@/content/shared/multisig-content.mdx"; export function MultisigContentWrapper() { const components = { CopyableCode, }; return ; } ================================================ FILE: src/components/SidebarTitleComponent.tsx ================================================ import clsx from "clsx"; import { useRouter } from "next/router"; interface SidebarTitleComponentProps { title: string; type: string; route: string; } export const SidebarTitleComponent: React.FC = ({ title, type, route, }) => { const { asPath } = useRouter(); const isActive = route === asPath; if (type === "separator") { return (
{title}
); } return (
{title}
); }; ================================================ FILE: src/components/TestnetDisclaimer.tsx ================================================ import { Callout } from "nextra/components"; export const TestnetDisclaimer = () => { return ( This guide currently references Ink Sepolia (testnet) however, it can be used for Ink mainnet as well. Please be sure to change the necessary parameters based on your network of choice. ); }; ================================================ FILE: src/components/ThemeToggle.tsx ================================================ import { useEffect, useState } from "react"; import { useTheme } from "nextra-theme-docs"; import { MoonIcon } from "../icons/Moon"; import { SunIcon } from "../icons/Sun"; export const ThemeToggle = () => { const { resolvedTheme, setTheme } = useTheme(); const [isMounted, setIsMounted] = useState(false); const onToggleTheme = () => { if (resolvedTheme == "dark") { setTheme("light"); } else { setTheme("dark"); } }; /** * This is not ideal, but it's the best solution we have to avoid rendering the button * with the wrong color */ useEffect(() => { setIsMounted(true); }, [setIsMounted]); if (!isMounted) { return null; } return ( ); }; ================================================ FILE: src/components/Toc.tsx ================================================ import Link from "next/link"; import { PencilIcon } from "@/icons/Pencil"; import { ThumbUpIcon } from "@/icons/ThumbUp"; import { URLS } from "@/utils/urls"; interface Heading { id: string; depth: number; value: string; } interface TocProps { headings: Heading[]; } export const Toc: React.FC = ({ headings }) => { return (
{headings.length > 0 && (
On this page
    {headings.map(({ id, value }) => (
  • {value}
  • ))}
)}
Edit this page on GitHub
); }; ================================================ FILE: src/content/shared/_badges.mdx ================================================ # Badges ## Welcome To Ink > Awarded for bridging Ethereum to Ink. To bridge Ethereum, you can use the `L1StandardBridge` on the sepolia network crafted for Ink. There are two ways to do it: ### Gelato Bridge app The app provides a very simple UI to deposit or withdraw SepoliaETH from and to Sepolia Ink. Here is the app: [https://testnet-bridge.gelato.network/bridge/ink-sepolia](https://testnet-bridge.gelato.network/bridge/ink-sepolia) Connect your wallet, select the amount to transfer, and that's it! ### Directly calling the contract You can call the `bridgeETH` method in the contract here: [https://sepolia.etherscan.io/address/0xC0d337f71aD19a8f17a1b297cDb3a86c5EEf9Eec#writeProxyContract](https://sepolia.etherscan.io/address/0xC0d337f71aD19a8f17a1b297cDb3a86c5EEf9Eec#writeProxyContract) For instance, if you want to bridge 1 Sepolia ETH into 1 Sepolia "Ink" ETH: 1. Connect your Wallet using the "Connect to Wallet" button 2. Expand the `bridgeETH` method and enter `bridgeETH: 1` 3. Enter `_minGasLimit: 1000` (or whatever suits you) 4. Enter `_extraData: 0x00` 5. Click "Write", then validate the transaction in MetaMask, then sign it to complete the transaction. ## Wrapped ETH > Awarded for wrapping Ethereum into WETH. To create Wrapped ETH tokens (WETH), you can interact with the `deposit` method in the contract here: [https://explorer-sepolia.inkonchain.com/token/0x47d1f931eaff721549cc0ad57da81729baa8b4b2?tab=write\_contract](https://explorer-sepolia.inkonchain.com/token/0x47d1f931eaff721549cc0ad57da81729baa8b4b2?tab=write_contract) 1. Connect your Wallet using the button 2. Expand the `deposit` method and enter `Send native ETH: 10 000 000 000 000 000`. * This is equivalent to 0.01 ETH, adjust as needed 3. Click "Write", then validate the transaction in MetaMask, then sign it to complete the transaction. If you want the token to appear in MetaMask, click on the MetaMask button at the top of the page ## ERC20 Interactions > Awarded for minting, sending, and receiving ERC20 tokens. *coming soon* ## NFT Interactions > Awarded for minting, sending, and receiving NFTs. *coming soon* ## Faucet User > Awarded for using the Ink faucet. Get here: [https://mystery-faucet.inkonchain.com/](https://mystery-faucet.inkonchain.com/) Enter your address, enter the captcha, that's it! ## Smart Contract Deployer > Awarded for deploying a smart contract. *coming soon* ================================================ FILE: src/content/shared/block-explorers-content.mdx ================================================ ## Blockscout Blockscout is a universal block explorer providing detailed chain information and tools for debugging smart contracts and transactions. Visit the [Blockscout Docs](https://docs.blockscout.com/) for details. ###### Supported Networks * Ink Sepolia: [https://explorer-sepolia.inkonchain.com/](https://explorer-sepolia.inkonchain.com/) * API: [https://explorer-sepolia.inkonchain.com/api](https://explorer-sepolia.inkonchain.com/api) ###### Verifying Smart Contract Code on Blockscout * Please see [this tutorial](/build/tutorials/verify-smart-contract) ## Routescan Routescan is a unified explorer for over 54 blockchains. ###### Supported Networks * Ink Sepolia: [https://sepolia.inkonscan.xyz/](https://sepolia.inkonscan.xyz/) * API: [https://sepolia.inkonscan.xyz/documentation/api-swagger](https://sepolia.inkonscan.xyz/documentation/api-swagger) ================================================ FILE: src/content/shared/bridges-content.mdx ================================================ import { Callout } from 'nextra/components' # Bridges These bridges provide different interfaces to the canonical smart contracts that facilitate migrating ETH from one chain to another. Transaction times vary based on network congestion and gas fees. Please ensure you have enough ETH in your wallet to cover transaction fees. ##### How to use 1. Visit the bridge and connect your wallet. 2. Choose Sepolia as your source and Ink as the destination. 3. Input the amount of assets you want to bridge. 4. Confirm and sign the transaction with your wallet. 5. Once the bridging is complete, the assets will appear in your wallet on Ink. ## Gelato bridge Bridge: [https://bridge-gel-sepolia.inkonchain.com/](https://bridge-gel-sepolia.inkonchain.com/) ## Ink Bridge Bridge: [https://inkonchain.com/bridge](https://inkonchain.com/bridge) ## Brid.gg Bridge: [https://testnet.brid.gg/](https://testnet.brid.gg/) ## Superbridge Bridge: [https://superbridge.app/](https://superbridge.app/) (enable testnet in settings) ================================================ FILE: src/content/shared/community-content.mdx ================================================ import { URLS } from "@/utils/urls"; # Get Support Join the Ink community, vibe with fellow developers and get support: - Join the Ink Telegram for announcements: Join Telegram ================================================ FILE: src/content/shared/crosschain-content.mdx ================================================ # Crosschain Infrastructure ## Wormhole Wormhole is an interoperability platform powering multichain apps and bridges. * Wormhole currently supports Ink Sepolia. ================================================ FILE: src/content/shared/faucets-content.mdx ================================================ # Faucets Get Sepolia ETH on Ink from these faucets below! Alternatively, you can [bridge](https://inkonchain.com/bridge) testnet funds to Ink. ## [Ink](https://inkonchain.com/faucet) Our in-house faucet provides a quick and easy way to acquire testnet ETH. ## [Optimism Superchain Faucet](https://console.optimism.io/faucet) The Superchain Faucet provides testnet ETH for Ink and all other OP chains. Sign in to claim 0.10 test ETH on 1 network every 24 hours or verify your onchain identity for more tokens. ## [QuickNode](https://faucet.quicknode.com/drip) Use QuickNode Faucet to claim Ink Sepolia for testnet ETH for free - one drip per network every 12 hours. ## [Gelato](https://faucet-gel-sepolia.inkonchain.com) Gelato's Faucet uses Cloudflare authentication and drops up to 0.3 Ink Sepolia ETH every 12 hours. ## [Tenderly](https://tenderly.co/?mtm_campaign=ext-docs&mtm_kwd=ink) Tenderly's [Unlimited Faucet](https://docs.tenderly.co/virtual-testnets/unlimited-faucet?mtm_campaign=ext-docs&mtm_kwd=ink) allows you to mint native and ERC20 tokens for development and testing on Virtual TestNets. The unlimited faucet is part of the [Admin RPC](https://docs.tenderly.co/virtual-testnets/admin-rpc?mtm_campaign=ext-docs&mtm_kwd=ink), a collection of cheat-codes allowing full customization of the network. ================================================ FILE: src/content/shared/multisig-content.mdx ================================================ # Multisig ## Safe Ink hosts [Safe](https://docs.safe.global/home/what-is-safe)'s technology to bring digital ownership of accounts to everyone by building universal and open contract standards for the custody of digital assets, data, and identity. Using Safe you can: * Manage customizable non-custodial wallets supporting multisignatures for individuals and teams * Perform financial management of onchain assets incl. ERC20s, ERC721s and ETH * Access your safe using Web, Mobile and Desktop apps. * Safe also features access to DeFi, open source code, batch transactions, modular extensions, gasless signatures and more. **Supported Networks** * [Ink Mainnet](https://app.safe.global/new-safe/load?chain=ink) * [Ink Sepolia](https://safe.optimism.io/welcome/accounts?chain=ink-sepolia) ================================================ FILE: src/fonts.ts ================================================ import { Inter, Plus_Jakarta_Sans } from "next/font/google"; export const inter = Inter({ subsets: ["latin"], variable: "--font-inter", display: "swap", }); export const plus_jakarta_sans = Plus_Jakarta_Sans({ subsets: ["latin"], variable: "--font-plus-jakarta-sans", display: "swap", }); ================================================ FILE: src/globals.css ================================================ @tailwind base; @tailwind components; @tailwind utilities; @layer utilities { body { font-family: var(--font-plus-jakarta-sans), var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } } @layer base { h1, h2, h3, h4 { @apply !text-magic-deep-purple dark:!text-magic-white; } a:not(.nextra-sidebar-container a):not(nav a):not(.toc-link) { @apply !text-magic-purple dark:!text-magic-soft-pink !underline hover:!text-magic-purple/80 dark:hover:!text-magic-soft-pink/80; } nav > a { @apply !text-ink-grey-400 dark:!text-magic-white dark:hover:!text-ink-grey-400 hover:!text-ink-grey-700 !no-underline; } nav > a > svg { @apply !fill-magic-black dark:!fill-magic-white; } nav { @apply bg-white dark:bg-magic-black; } pre { @apply !bg-magic-semi-deep-purple/15; } .toc-link { @apply cursor-pointer !text-ink-grey-400 dark:!text-magic-white group-hover:!text-ink-grey-700 dark:group-hover:!text-ink-grey-700; } /* We need to override the underline for nav links and sidebar items */ nav > a, a:has(div.ink-sidebar-item), .toc-link { @apply no-underline; } } /* Some custom hacks to override some issues with Nextra */ .nextra-nav-container-blur { display: none !important ; } /* Remove the padding from the sidebar link, so that we can pply our own style */ a:has(div.ink-sidebar-item) { padding: 0 !important; background-color: transparent !important; } /* Target both the banner container and its text */ .nextra-banner-container { @apply text-white !important; } .nextra-banner-container a { @apply text-white hover:text-white/80 no-underline !important; } /* Override the purple link styles specifically for the banner */ .nextra-banner-container a:not(.nextra-sidebar-container a):not(nav a):not(.toc-link) { @apply text-white hover:text-white/80 underline !important; } /* Ensure all text in banner is white, not just links */ .nextra-banner-container { @apply text-white !important; } ================================================ FILE: src/icons/Check.tsx ================================================ export const CheckIcon: React.FC<{ className?: string }> = ({ className = "size-6", }) => { return ( ); }; ================================================ FILE: src/icons/ConnectedPulse.tsx ================================================ import clsx from "clsx"; export const ConnectedPulse: React.FC<{ className?: string }> = ({ className, }) => { return ( ); }; ================================================ FILE: src/icons/Download.tsx ================================================ interface PencilProps { className?: string; } export const DownloadIcon: React.FC = ({ className = "size-6", }) => { return ( ); }; ================================================ FILE: src/icons/InkLogo.tsx ================================================ import Image from "next/image"; import { useTheme } from "nextra-theme-docs"; interface InkLogoProps { className?: string; } export const InkLogo: React.FC = ({ className = "text-magic-purple", }) => { const { resolvedTheme } = useTheme(); const logoSrc = resolvedTheme === "dark" ? "/logo/ink-logo-dark.svg" : "/logo/ink-logo-light.svg"; return ( Ink logo ); }; ================================================ FILE: src/icons/Moon.tsx ================================================ interface MoonIconProps { className?: string; } export const MoonIcon: React.FC = ({ className = "w-6 h-6", }) => { return ( ); }; ================================================ FILE: src/icons/Pencil.tsx ================================================ interface PencilProps { className?: string; } export const PencilIcon: React.FC = ({ className = "size-6" }) => { return ( ); }; ================================================ FILE: src/icons/Sun.tsx ================================================ interface SunIconProps { className?: string; } export const SunIcon: React.FC = ({ className = "w-6 h-6" }) => { return ( ); }; ================================================ FILE: src/icons/ThumbUp.tsx ================================================ interface ThumbUpProps { className?: string; } export const ThumbUpIcon: React.FC = ({ className = "size-6", }) => { return ( ); }; ================================================ FILE: src/pages/404.mdx ================================================ # Page Not Found #### Return [home](/). #### Please help by [submitting an issue](https://github.com/inkonchain/docs/issues/new) for the broken link. 💜 ================================================ FILE: src/pages/500.mdx ================================================ # 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/inkonchain/docs/issues/new) for the broken link. ❤️ # CHANGE \n ================================================ FILE: src/pages/_app.mdx ================================================ import { ThemeProvider } from "next-themes"; import Script from "next/script"; import { inter, plus_jakarta_sans } from "../fonts"; import "../globals.css"; export default function App({ Component, pageProps }) { return (