From 36044a62059fa2c664e34d48f9fa60ed2de99b1c Mon Sep 17 00:00:00 2001 From: RetricSu Date: Thu, 18 Dec 2025 14:40:39 +0800 Subject: [PATCH 01/20] chore(example): update simple-lock js-vm testnet info (#718) --- examples/dApp/simple-lock/deployment/system-scripts.json | 2 +- .../dApp/simple-lock/frontend/deployment/system-scripts.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/dApp/simple-lock/deployment/system-scripts.json b/examples/dApp/simple-lock/deployment/system-scripts.json index 9337b9847..fdbf3dcfa 100644 --- a/examples/dApp/simple-lock/deployment/system-scripts.json +++ b/examples/dApp/simple-lock/deployment/system-scripts.json @@ -605,7 +605,7 @@ { "cellDep": { "outPoint": { - "txHash": "0x9f6558e91efa7580bfe97830d11cd94ca5d614bbf4a10b36f3a5b9d092749353", + "txHash": "0x756fdaf0d1ba1d2e03dc13c71c967b24021bc054893a766ccee6879c468892d2", "index": 0 }, "depType": "code" diff --git a/examples/dApp/simple-lock/frontend/deployment/system-scripts.json b/examples/dApp/simple-lock/frontend/deployment/system-scripts.json index 9337b9847..fdbf3dcfa 100644 --- a/examples/dApp/simple-lock/frontend/deployment/system-scripts.json +++ b/examples/dApp/simple-lock/frontend/deployment/system-scripts.json @@ -605,7 +605,7 @@ { "cellDep": { "outPoint": { - "txHash": "0x9f6558e91efa7580bfe97830d11cd94ca5d614bbf4a10b36f3a5b9d092749353", + "txHash": "0x756fdaf0d1ba1d2e03dc13c71c967b24021bc054893a766ccee6879c468892d2", "index": 0 }, "depType": "code" From e5f32d813611488962f7b6ba00c5da2da4c8a842 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 5 Dec 2025 11:01:25 +0800 Subject: [PATCH 02/20] add CKB Features in tech explaination --- .../extreme-decentralization.md | 91 +++++++++++++ .../tech-explanation/quantum-resistance.md | 108 ++++++++++++++++ .../tech-explanation/vm-built-for-hackers.md | 121 ++++++++++++++++++ website/sidebars.js | 11 ++ 4 files changed, 331 insertions(+) create mode 100644 website/docs/tech-explanation/extreme-decentralization.md create mode 100644 website/docs/tech-explanation/quantum-resistance.md create mode 100644 website/docs/tech-explanation/vm-built-for-hackers.md diff --git a/website/docs/tech-explanation/extreme-decentralization.md b/website/docs/tech-explanation/extreme-decentralization.md new file mode 100644 index 000000000..f8608af19 --- /dev/null +++ b/website/docs/tech-explanation/extreme-decentralization.md @@ -0,0 +1,91 @@ +--- +id: extreme-decentralization +title: Extreme Decentralization +--- + +Decentralization is the core value proposition of public blockchains. It ensures censorship resistance, permissionless access, and security without relying on trusted intermediaries. CKB (The layer 1 protocol) is designed from the ground up to make sure this core value is not compromised. + +## Decoupling: Our Approach to True Decentralization + +To achieve true decentralization, we must abandon the view of a blockchain as a monolithic, "do-it-all" platform. If a single blockchain layer tries to be everything to everyone—fast for users, easy for developers, and secure for the network—it inevitably creates conflicting incentives. High throughput demands often override verification needs, and the push for seamless developer experiences frequently introduces centralized dependencies. + +Nervos CKB addresses this by decoupling concerns across a multi-layered architecture, viewing the blockchain landscape as a continuous spectrum: + +- **The Far Left:** Extreme decentralization, lowest-threshold verification, and uncompromised security. +- **The Far Right:** Developer experience, high throughput, the middleware and centralized services needed for mass adoption. + +### The Last Line of Defense + +The CKB team consciously positions the Layer 1 protocol at the **absolute left-most edge** of this spectrum. By holding this ground, Layer 1 acts as the immutable trust anchor and the **last line of defense** for the entire network. If the CKB team were to compromise here for the sake of usability or speed, the security of the entire structure would crumble. + +This philosophy dictates a clear division of labor, ensuring every point on the spectrum receives dedicated effort from the actors best suited for it: + +- **Layer 1 (CKB):** Focuses exclusively on being the ultimate guardian of value. Its design prioritizes maximum decentralization, security, and censorship resistance—the original spirit of crypto—above all else. +- **Layer 2 & Ecosystem:** Focuses on scalability, high performance, the developer and user experience necessary for mass adoption, free from the burden of base-layer consensus trade-offs. + +It is not only about code, but also for operational decisions. For example, the CKB team might deliberately reject providing centralized conveniences, such as a default, productional RPC service (similar to Infura in Ethereum). While such a service would offer a shortcut for developers, it introduces a central point of failure. Note that the [public RPC service](/docs/getting-started/rpcs) that CKB team provide is only for testing purpose, it is strongly recommended to run your own RPC service for your dApp. By refusing to encroach on the "service layer," CKB forces the ecosystem to build its own robust, distributed access layers, ensuring the foundation remains a neutral, decentralized settlement platform. + +## How to Achieve Extreme Decentralization + +Decentralization is not just about who _mines_ the next block; it is about who can _verify_ the history. If running a node becomes too expensive due to data bloat, the network centralizes into a few server farms regardless of its consensus algorithm. + +CKB ensures this never happens through three radical approaches: **Sustainable State Management**, **Proof-of-Work Consensus**, and a viable **Light Client** with a engineer effort on building nodes that lowers the entry barrier for participants. + +### 1. Sustainable State Management + +Most blockchains operate as "General Computation Networks" (like a world computer). Users pay a one-time fee to execute a transaction, but the resulting data (state) occupies the network's storage forever at no further cost. This leads to the **"Tragedy of the Commons"**: because storage is effectively free, the state grows indefinitely ([State Explosion](https://medium.com/nervosnetwork/state-explosion-and-the-tragedy-of-the-blockchain-commons-1fbd4837e859)). Eventually, only enterprise-grade hardware can store the chain, forcing regular users to trust third parties. + +CKB adopts a "General Verification Network" architecture based on [Cell Model](/docs/tech-explanation/cell-model). The **Common Knowledge Base** acts as a verified state layer rather than a computation layer. To maintain "Extreme Decentralization," CKB creates a direct economic link between state and scarcity: + +- **State as a Scarce Resource:** In CKB, state is not an afterthought; it is the physical "land" of the blockchain. +- **The CKB = Byte Equation:** The native token (CKB) represents **state capacity**. Holding 1 CKB entitles you to store 1 byte of data on the blockchain. +- **Targeted Inflation (State Rent):** To occupy space on the Global State, users must lock CKB tokens. This incurs an opportunity cost (via secondary issuance inflation), effectively acting as a "State Rent." This forces developers and users to be efficient—they only store what is truly valuable. + +**Why this guarantees decentralization:** + +By economically constraining the growth of the state, CKB ensures that the hardware requirements for running a full node remain low and predictable over decades. This allows users to run nodes on consumer hardware, preserving the network's permissionless nature. + +Moving computation off-chain also reduces the burden on full nodes. They only need to verify the result, which is typically much faster than executing the computation itself. + +### 2. Proof-of-Work (PoW) over Proof-of-Stake (PoS) + +CKB utilizes **NC-Max** (a variant of Nakamoto Consensus) with a custom hash function, **Eaglesong**. While many modern blockchains have shifted to Proof-of-Stake (PoS), CKB adheres to PoW for specific reasons regarding decentralization: + +1. **Permissionless Participation:** In PoW, anyone with hardware and electricity can participate. There is no need to buy tokens from existing holders to become a validator, avoiding the "rich get richer" centralization loop often criticized in PoS. +2. **Objective Security:** PoW provides an objective measure of the chain's security (accumulated work). A new node can independently verify the valid chain with the most work without trusting any peers or checkpoints. +3. **Cost of Attack:** Attacking a PoW network requires tangible external resources (energy and hardware), whereas attacking a PoS network involves internal resources (staked tokens). + +### 3. Viable Light Client + +True decentralization requires that users can verify the state of the blockchain themselves rather than relying on trusted third-party RPC nodes (like Infura or Alchemy). If a user relies on a server to tell them their balance, they are not using a blockchain; they are using a bank. + +However, running a full node (downloading terabytes of history) is impossible for mobile and web users. CKB solves this with a next-generation **Light Client** protocol that brings full-node-level security to consumer devices. + +#### The FlyClient Protocol & MMR + +Unlike traditional SPV (Simplified Payment Verification) clients that must download linearly increasing amounts of headers, CKB implements the **FlyClient** protocol. + +- **Logarithmic Scaling:** Instead of downloading every block header, the client uses a probabilistic sampling technique. It downloads only a logarithmic number of block headers to statistically verify the Proof-of-Work with overwhelming certainty. +- **Merkle Mountain Ranges (MMR):** CKB blocks include an MMR root in their headers. This cryptographic structure allows the light client to prove that any specific block is part of the valid chain history without storing the history itself. +- **Result:** A user can sync the chain in seconds with minimal bandwidth, regardless of how long the blockchain becomes. + +#### WASM & In-Browser Verification + +The most radical feature of the CKB Light Client is its portability. The CKB team has compiled the light client into **WebAssembly (WASM)**, enabling it to run in environments previously thought impossible for blockchain nodes. + +- **No Installation Required:** The light client can be embedded directly into a web wallet or dApp. When a user visits a website, the browser _becomes_ a node. +- **Trustless Interaction:** The dApp does not ask a server "What is my balance?" or "Did this trade settle?" Instead, the browser connects directly to the P2P network, samples headers, and mathematically verifies the data locally. +- **Mobile Ready:** Because it requires minimal storage (storing only a single block header between executions) and low CPU usage, it runs efficiently on mobile devices without draining battery. + +#### Privacy and Sovereignty + +The CKB Light Client protocol allows the client to request specific transaction data and state (Cells) related _only_ to the user. + +- **Data Minimization:** The client filters data at the network level. If you own 5 UTXOs (Cells), your device only fetches and verifies the proofs for those 5 items, ignoring the rest of the global state. +- **Censorship Resistance:** Because the client connects to a randomized mesh of peers rather than a single RPC endpoint, it is extremely difficult for any single entity to block the user's access to the network. + +By embedding the verification layer directly into the user's application, CKB closes the final gap in decentralization: **The user is not just a customer of the network; the user _is_ the network.** + +## Summary + +This completes the picture of "Extreme Decentralization" on CKB: a system where users own their state(Cell Model), participate permissionlessly (PoW), compute locally (Verification Network), and verify independently (Light Client). diff --git a/website/docs/tech-explanation/quantum-resistance.md b/website/docs/tech-explanation/quantum-resistance.md new file mode 100644 index 000000000..97522e964 --- /dev/null +++ b/website/docs/tech-explanation/quantum-resistance.md @@ -0,0 +1,108 @@ +--- +id: native-quantum-resistance +title: Native Quantum Resistance +--- + +# Native Quantum Resistance + +As the blockchain industry matures, it faces an existential threat on the horizon: **Large-scale Quantum Computing**. While often discussed as a distant future problem, the "Harvest Now, Decrypt Later" strategy employed by attackers—where encrypted data is intercepted today to be decrypted once quantum hardware matures—makes this an urgent architectural concern. + +Most major blockchains, including Bitcoin and Ethereum, rely on **Elliptic Curve Cryptography (ECC)** to derive addresses and sign transactions. A sufficiently powerful quantum computer running [Shor’s Algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm) could effectively calculate a private key from a public key, rendering the security of these networks obsolete. + +While the industry is standardizing defenses (e.g., NIST's PQC competition), the **implementation path** differs drastically between other blockchains and CKB. CKB does not merely hope to survive the quantum era, it was architected to embrace it. + +## Why CKB is native quantum-resistant + +Most blockchains struggle with the quantum-resistant problem with two main reasons. CKB is native quantum-resistant not because it outperforms the other blockchains in solving these two problems, but because it is designed from the first principle, which doesn't have those two problems in the first place. + +### The hardcoded Cryptographic Primitives problem + +The fundamental flaw in most Layer 1 blockchains is that their cryptographic primitives are **hardcoded** into the consensus protocol. This rigidity creates one massive hurdle: the "Hard Fork" crisis. If you want to upgrade to quantum-resistant cryptography, you must coordinate a hard fork with the entire network. + +In Ethereum or Bitcoin, the rule "Transaction X is valid" is effectively hardwired to check a specific ECDSA signature. Changing this rule is not a software update; it is a change to the fundamental laws of that blockchain's universe. + +CKB is by design a **Cryptographic Abstraction** blockchain. In CKB, the protocol does not know or care what "secp256k1" is. Cryptography is not a consensus rule; it is simply a **Lock Script** (smart contract) that runs in a virtual machine. As a contrast, Ethereum baked the hardcoded ECC into the EVM as a Precompile. + +- **Other blockchains:** Act like a pocket calculator. They calculate specific math (ECC) very fast, but you cannot add new buttons. +- **Nervos CKB:** Acts like a generic CPU. If you need a new mathematical operation (like the matrix multiplications used in Lattice-based cryptography), you simply upload the code for it. + +This abstraction turns Quantum Resistance from a "Governance Crisis" into a simple "User Choice." Users can choose to migrate to quantum-resistant cryptography without a hard fork. By ten years later, if there are quantum computers that can break the current cryptography, CKB users can follow the process for upgrades in the following: + +1. **Deploy:** Developers deploy a new Lock Script implementing PQC algorithms (e.g., SPHINCS+). +2. **Adopt:** Users create new addresses referencing this script's `Code Hash`. +3. **Migrate:** Users transfer assets from old addresses to new quantum-secure ones. + +The network does not fork. Old addresses continue to function. The upgrade is permissionless and gradual. + +### The Data Size Limitation + +Even if a other blockchains successfully coordinates a hard fork, it still faces a physical limit: **Data Size**. Quantum-resistant signatures are orders of magnitude larger than classical ones. + +- **Secp256k1 (Bitcoin/ETH):** ~64 bytes +- **ML-DSA (Dilithium):** ~2.5 KB (~40x larger) +- **SPHINCS+:** 8 KB – 49 KB (~125x - 760x larger) + +Take Bitcoin as an [example](https://x.com/bensig/status/1985426927893823667), a simple consolidation of 100 UTXOs using ML-DSA signatures could result in a **250KB+ transaction**, potentially costing hundreds of thousands of dollars in fees during peak congestion. + +CKB doesn't face such a problem, since the verification of signatures is done by separting the rule(Lock Script) from the proof(Witness). There are also mechanisms that grouping the same Lock Scripts so multiple inputs can share one signature in the transaction Witnesses. That makes moving 100 Cells with SPHINCS+ signatures as simple as moving 1 Cell with SPHINCS+ signature. You can learn more about this in [Script Group Execution](/docs/tech-explanation/script-group-exe) and [Witness](/docs/tech-explanation/witness). + +## What CKB has achieved + +### Implementation Details: SPHINCS+ on CKB + +In 2023, The CKB team and Cryptape researchers have successfully implemented a production-ready **Quantum Resistant Lock Script** using **SPHINCS+**. In August 2024, NIST has finally approved SPHINCS+ as a quantum-resistant digital signature algorithm in its FIPS 205 standard. In 2025, The CKB team started to deploy SPHINCS+ Lock Script on the CKB mainnet. + +- **Repository:** [cryptape/quantum-resistant-lock-script](https://github.com/cryptape/quantum-resistant-lock-script) + +The Lock Script supports [12 different SPHINCS+ parameter sets](https://github.com/sphincs/sphincsplus#parameters), which can be selected by the user. It is based on the new definition of [CKB_TX_MESSAGE_ALL](https://github.com/nervosnetwork/rfcs/pull/446) to generate the signing message. By default, the Lock script is implemented as a multi-signature contract, and the single-signature process is just a special case of multi-signature. + +#### Why SPHINCS+? + +We selected SPHINCS+ for the reference implementation because it is a **stateless hash-based signature scheme**. + +- **Safety:** It does not rely on complex number-theoretic assumptions (like Lattice problems) that could potentially be broken by future mathematical discoveries. Its security relies entirely on **Hash Functions** (like SHA-256), which are incredibly robust. +- **Statelessness:** Unlike XMSS, it does not require managing state, making it safe for the distributed nature of blockchains. + +The trade-off for SPHINCS+ is signature size. However, CKB handles this gracefully using the **Witness** data structure. CKB separates the "Lock" (which defines the rules) from the "Witness" (which provides the proof). A large 20KB signature lives in the Witness field, which is flexible, rather than clogging the state-defining Lock field. + +#### Performance Benchmarks + +There are 3 implementations for the Lock Script: + +- [A C lock script](./contracts/c-sphincs-all-in-one-lock/) using [SPHINCS+](https://github.com/sphincs/sphincsplus) +- [A Rust lock script](./contracts/sphincs-all-in-one-lock/) using [fips205](https://github.com/integritychain/fips205) +- [A hybrid lock script](./contracts/hybrid-sphincs-all-in-one-lock/) with the implementation of SPHINCS+ utilizing the sphincsplus C library and Rust glue code. + +The exact cycle consumptions will slightly vary from one signature to another, a ballpark estimation of cycle consumptions(here we measure cycle consumptions for the whole script, meaning CKB transaction signing is included as well) for each NIST approved parameter set, can be located below(`M` stands for million): + +| | 128s bit | 128f bit | 192s bit | 192f bit | 256s bit | 256f bit | +| --------------------- | -------- | -------- | -------- | -------- | -------- | -------- | +| pubkey size | 32 | 32 | 48 | 48 | 64 | 64 | +| signature size | 7856 | 17088 | 16224 | 35664 | 29792 | 49856 | +| sha2 simple (C) | 11.5M | 32.2M | 17.6M | 49.4M | 25.7M | 49.7M | +| sha2 simple (Hybrid) | 11.6M | 34.5M | 18.5M | 49.4M | 25.7M | 49.0M | +| sha2 simple (Rust) | 21.9M | 59.2M | 31.5M | 87.1M | 45.3M | 92.6M | +| shake simple (C) | 20.5M | 60.4M | 31.7M | 91.9M | 46.5M | 91.5M | +| shake simple (Hybrid) | 20.8M | 62.0M | 31.7M | 89.9M | 48.1M | 92.4M | +| shake simple (Rust) | 37.6M | 111.6M | 53.3M | 156.6M | 76.5M | 157.6M | + +In general, the `s` variants take longer to generate a signature, but takes less cycles to verify. The `f` variants are fast in signature generation but takes longer cycles to verify. + +### Community Applications and Tools + +Since the SPHINCS+ Lock Script is a production-ready implementation, there are already some experiments on building SPHINCS+ based real world applications from the CKB community. + +- [Quantum-Purse](https://github.com/tea2x/quantum-purse) - A CKB quantum-safe & lightweight wallet from community + +We are looking forward to more SPHINCS+ based applications and tools arised in the CKB community. + +## Summary + +While other blockchains rely on hope ("we will hard fork when the time comes"), CKB relies on architecture. By decoupling cryptography from consensus, CKB acts as a **future-proof vessel**—ready to absorb any cryptographic breakthrough the moment it is discovered. + +| Feature | Other Blockchains | Nervos CKB | +| :------------------ | :----------------------- | :--------------------------- | +| **Cryptography** | Hardcoded (Firmware) | Pluggable (Software) | +| **Upgrade Path** | Contentious Hard Fork | Permissionless Migration | +| **PQC Feasibility** | Low (Block space limits) | High (Flexible Witness data) | +| **Status** | Research / Theoretical | **Live on Mainnet** | diff --git a/website/docs/tech-explanation/vm-built-for-hackers.md b/website/docs/tech-explanation/vm-built-for-hackers.md new file mode 100644 index 000000000..0b5af7e58 --- /dev/null +++ b/website/docs/tech-explanation/vm-built-for-hackers.md @@ -0,0 +1,121 @@ +--- +id: vm-built-for-hackers +title: Virtual Machine for Hackers +--- + +Blockchains need a deterministic virtual machine to run code (smart contracts). A virtual machine decides what you can build on the blockchain. When we started designing CKB, we knew we wanted a VM that felt like working with real hardware. + +**CKB-VM** is our answer—a virtual machine that takes a totally different approach to blockchain computation. Instead of inventing a new, blockchain-specific instruction set (like the EVM) or adapting a web standard (like WebAssembly), CKB-VM emulates a real hardware CPU architecture: **RISC-V**. + +This choice isn’t just a technical detail; it’s a philosophy. By emulating hardware instead of software, CKB-VM gives you flexibility, stability, and future-proofing that’s hard to find in the blockchain world. + +## Why RISC-V? + +[RISC-V](https://riscv.org/) is an open standard Instruction Set Architecture (ISA) based on tried-and-true reduced instruction set computer (RISC) principles. It’s modular, extensible, and free from licensing fees—basically, the "Linux of CPUs." + +Nervos picked RISC-V for some pretty solid reasons: + +1. **A Real Hardware Standard**: RISC-V is built for physical hardware. Engineers from academia and industry have tested it to be efficient, simple, and reliable. +2. **Stability**: Hardware ISAs don’t change much. Code written for an Intel 8086 in the 1970s can still run on modern x86 processors. By using a standardized hardware ISA, CKB ensures that smart contracts written today will still work decades from now. +3. **Broad Toolchain Support**: RISC-V is a global standard, so it’s supported by major compilers like GCC, LLVM, and Rust. This means CKB developers get top-notch optimization and tools "out of the box." + +## What Makes CKB-VM Unique? + +CKB-VM is a pure software implementation of the RISC-V instruction set. Specifically, it uses the **RV64IMC** instruction set: + +- **RV64**: 64-bit address space and registers. +- **I**: Integer instructions (basic arithmetic). +- **M**: Integer Multiplication and Division. +- **C**: Compressed instructions (smaller code size). + +### The "No Precompiles" Philosophy + +One of the coolest things about CKB-VM is what it _doesn’t_ have: **Precompiles**. + +In the Ethereum Virtual Machine (EVM), expensive operations like SHA-256 hashing or ECDSA signature verification are "precompiled" into the client software. These are special opcodes that cost less gas because they’re run natively by the node. + +The problem with precompiles? **They’re rigid.** + +- Want to use a new cryptographic algorithm (e.g., Schnorr signatures or BLS)? You’re stuck until the chain developers add a new precompile via a hard fork. +- You’re limited to the specific version of the algorithm the chain supports. + +**CKB-VM has zero precompiles.** +Because CKB-VM runs a hardware ISA, it’s fast enough to run cryptographic primitives _as script code_. + +- **Secp256k1**: On CKB, this is just a C library compiled to RISC-V. +- **Blake2b**: Just a library. +- **Schnorr / BLS / ZK-SNARKs**: Just libraries. + +This makes CKB **crypto-agnostic**. Developers can use any cryptographic primitive they want, whenever they want, without waiting for a hard fork. That’s how CKB already supports quantum-resistant algorithms like SPHINCS+, while other chains are still figuring it out. + +To keep things fast without precompiles, CKB-VM uses some clever optimization tricks: + +1. **Macro-op Fusion** + +CKB-VM uses **Macro-op Fusion**, a technique found in modern high-end CPUs. It spots common instruction sequences and merges them into a single, internal "macro-operation." + +- **Example**: A comparison followed by a branch (`CMP` + `BNE`) becomes a single "Compare-and-Branch" operation. +- **Benefit**: This cuts down the overhead of the interpreter loop, speeding up complex logic. + +2. **B Extension (Bit Manipulation)** + +CKB-VM supports the RISC-V **B Extension**, which adds special instructions for bit manipulation (like rotation, bit counting, etc.). + +- **Benefit**: Cryptographic algorithms rely heavily on bitwise operations. The B extension makes these way faster, so crypto verification on CKB-VM is blazing fast. + +### Feels Like a Single-Core Linux Environment + +CKB-VM doesn’t have an MMU unit and uses a simple linear memory model. Each script instance gets its own memory space (defaulting to 4MB), which is cleared after execution. The VM’s runtime memory includes space for executable code pages, stack space, heap space, and mmapped pages of external cells. To keep things secure, **W^X (Write XOR Execute)** memory protection is enforced. A memory page can be either Writable or Executable, but never both at the same time. This stops common attacks like buffer overflows. + +CKB-VM is strictly single-threaded, so RISC-V atomic instructions aren’t needed. Contracts can include their own coroutines. For simplicity and deterministic behavior, CKB doesn’t support floating-point numbers. If you really need them, we suggest using a softfloat solution. + +These designs make the execution model super simple—kind of like early-era CPUs or embedded systems. To keep the virtual machine as close to a real CPU as possible, CKB also uses the Linux ELF format directly as the contract format. + +This gives you maximum tooling and debugging support and **makes running a contract almost the same as running an executable in a single-core Linux environment**: + +- Contracts start from the `main` function in the ELF-formatted contract file. +- Arguments are passed in via standard `argc` and `argv`. +- When `main` returns 0, the contract is considered successful. + +Due to space constraints, we might not store full input and output data in `argv`. Instead, we provide metadata in `argv` and use additional libraries and syscalls to handle input/output loading. This keeps runtime costs low. + +When interacting with the blockchain, CKB-VM uses **Syscalls** (System Calls), just like a program talks to a Linux OS. CKB-VM syscalls handle communication between the RISC-V-based CKB-VM and the main CKB process, letting scripts read transaction info and general blockchain data. Common syscalls include `Exit`, `Load Transaction Hash`, `Load Cell Data`, `Load Input`, `Debug`, etc. Using syscalls instead of custom instructions keeps the RISC-V implementation standard-compliant and widely supported. + +Resource usage in CKB-VM is measured in **Cycles**. Unlike "Gas," which can feel arbitrary, Cycles are a deterministic measure of the actual CPU instructions executed. To measure contract costs, CPU cycles are tracked for each instruction. The total cycles at the end of execution represent the runtime cost. We also track the cost of reading/writing additional cells during contract execution. This gives developers a predictable and fair cost model. + +## Virtual Machine for Hackers + +Since CKB-VM acts like a bare-metal computer, it’s a playground for creative hackers. You’re not limited to a specific blockchain virtual machine—it’s more like working with regular Linux executables. + +One of the coolest things is the flexibility of programming languages for CKB smart contracts. CKB only defines the low-level virtual machine. In theory, any language with a RISC-V backend can be used for CKB contract development: + +- CKB can use standard `riscv-gcc`, `riscv-llvm`, or even upstream GCC/LLVM for C/C++ contract development. Executables from these compilers can be directly used as CKB contracts. +- C-based Bitcoin or Ethereum VMs can be compiled into RISC-V binaries as common cells. Contracts can load these common cells to run Bitcoin or Ethereum-compatible contracts. +- Higher-level language VMs, like Duktape or mruby, can be compiled and loaded to run contracts written in JavaScript or Ruby. +- System languages like Rust can also be used to write contracts targeting RISC-V. + +CKB-VM is like a mini-computer based on RISC-V, making things like running a [Bitcoin VM](https://github.com/xxuejie/ckb-bitcoin-vm) in a smart contract totally doable by porting original C++ codes from Bitcoin. The possibilities are endless. We encourage low-level engineers and curious hackers to dive in and explore. + +## Comparison with Other VMs + +| Feature | EVM (Ethereum) | WASM (Polkadot, Near) | CKB-VM (Nervos) | +| :--------------- | :--------------------- | :------------------------ | :--------------------------------------- | +| **Abstraction** | Software Emulation | Web Standard | **Hardware Emulation** | +| **Word Size** | 256-bit | 32/64-bit | **64-bit** | +| **Cryptography** | Hardcoded Precompiles | Host Functions | **Libraries (Scripts)** | +| **Flexibility** | Low (Hard Fork needed) | Medium | **High (Permissionless)** | +| **Languages** | Solidity, Vyper | Rust, C++, AssemblyScript | **Any Language, Rust, C, Go, Lua, etc.** | + +### vs EVM + +The EVM uses 256-bit words to make crypto math easier, but this doesn’t match real CPUs (which are 64-bit). This forces the EVM to do expensive software emulation for basic math operations. CKB-VM uses 64-bit registers, mapping 1:1 with the host CPU for maximum performance. + +### vs WASM + +WebAssembly is great for the web, but it’s complex and always evolving (WASI, GC, Threads). It’s designed for JIT compilation in browsers. RISC-V is simpler and more stable, designed for bare-metal execution—perfect for blockchain needs. + +## Future-Proofing + +The biggest risk for any blockchain is becoming obsolete. By anchoring on the RISC-V standard, CKB ensures its VM will never become "legacy tech." As RISC-V hardware gets faster and more common, CKB-VM benefits automatically. + +CKB-VM isn’t just a virtual machine; it’s a **universal computer** embedded in the blockchain, ready to run the cryptography and logic of tomorrow, today. diff --git a/website/sidebars.js b/website/sidebars.js index 9f42a6b00..cd52d7627 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -261,6 +261,17 @@ export default { }, ], "Tech Explanation": [ + { + type: "category", + label: "What makes CKB unique", + className: "category-ckb-features", + collapsible: false, + items: [ + "tech-explanation/extreme-decentralization", + "tech-explanation/native-quantum-resistance", + "tech-explanation/vm-built-for-hackers", + ], + }, { type: "category", label: "CKB Fundamentals", From 17e9c7b466e1139f587bff3f60e527c7a9e4e028 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 5 Dec 2025 13:34:30 +0800 Subject: [PATCH 03/20] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- website/docs/tech-explanation/extreme-decentralization.md | 4 ++-- website/docs/tech-explanation/quantum-resistance.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/docs/tech-explanation/extreme-decentralization.md b/website/docs/tech-explanation/extreme-decentralization.md index f8608af19..b22630ef2 100644 --- a/website/docs/tech-explanation/extreme-decentralization.md +++ b/website/docs/tech-explanation/extreme-decentralization.md @@ -23,13 +23,13 @@ This philosophy dictates a clear division of labor, ensuring every point on the - **Layer 1 (CKB):** Focuses exclusively on being the ultimate guardian of value. Its design prioritizes maximum decentralization, security, and censorship resistance—the original spirit of crypto—above all else. - **Layer 2 & Ecosystem:** Focuses on scalability, high performance, the developer and user experience necessary for mass adoption, free from the burden of base-layer consensus trade-offs. -It is not only about code, but also for operational decisions. For example, the CKB team might deliberately reject providing centralized conveniences, such as a default, productional RPC service (similar to Infura in Ethereum). While such a service would offer a shortcut for developers, it introduces a central point of failure. Note that the [public RPC service](/docs/getting-started/rpcs) that CKB team provide is only for testing purpose, it is strongly recommended to run your own RPC service for your dApp. By refusing to encroach on the "service layer," CKB forces the ecosystem to build its own robust, distributed access layers, ensuring the foundation remains a neutral, decentralized settlement platform. +It is not only about code, but also for operational decisions. For example, the CKB team might deliberately reject providing centralized conveniences, such as a default, production RPC service (similar to Infura in Ethereum). While such a service would offer a shortcut for developers, it introduces a central point of failure. Note that the [public RPC service](/docs/getting-started/rpcs) that CKB team provide is only for testing purpose, it is strongly recommended to run your own RPC service for your dApp. By refusing to encroach on the "service layer," CKB forces the ecosystem to build its own robust, distributed access layers, ensuring the foundation remains a neutral, decentralized settlement platform. ## How to Achieve Extreme Decentralization Decentralization is not just about who _mines_ the next block; it is about who can _verify_ the history. If running a node becomes too expensive due to data bloat, the network centralizes into a few server farms regardless of its consensus algorithm. -CKB ensures this never happens through three radical approaches: **Sustainable State Management**, **Proof-of-Work Consensus**, and a viable **Light Client** with a engineer effort on building nodes that lowers the entry barrier for participants. +CKB ensures this never happens through three radical approaches: **Sustainable State Management**, **Proof-of-Work Consensus**, and a viable **Light Client** with an engineering effort on building nodes that lowers the entry barrier for participants. ### 1. Sustainable State Management diff --git a/website/docs/tech-explanation/quantum-resistance.md b/website/docs/tech-explanation/quantum-resistance.md index 97522e964..74bbebc89 100644 --- a/website/docs/tech-explanation/quantum-resistance.md +++ b/website/docs/tech-explanation/quantum-resistance.md @@ -36,7 +36,7 @@ The network does not fork. Old addresses continue to function. The upgrade is pe ### The Data Size Limitation -Even if a other blockchains successfully coordinates a hard fork, it still faces a physical limit: **Data Size**. Quantum-resistant signatures are orders of magnitude larger than classical ones. +Even if other blockchains successfully coordinate a hard fork, they still face a physical limit: **Data Size**. Quantum-resistant signatures are orders of magnitude larger than classical ones. - **Secp256k1 (Bitcoin/ETH):** ~64 bytes - **ML-DSA (Dilithium):** ~2.5 KB (~40x larger) @@ -44,7 +44,7 @@ Even if a other blockchains successfully coordinates a hard fork, it still faces Take Bitcoin as an [example](https://x.com/bensig/status/1985426927893823667), a simple consolidation of 100 UTXOs using ML-DSA signatures could result in a **250KB+ transaction**, potentially costing hundreds of thousands of dollars in fees during peak congestion. -CKB doesn't face such a problem, since the verification of signatures is done by separting the rule(Lock Script) from the proof(Witness). There are also mechanisms that grouping the same Lock Scripts so multiple inputs can share one signature in the transaction Witnesses. That makes moving 100 Cells with SPHINCS+ signatures as simple as moving 1 Cell with SPHINCS+ signature. You can learn more about this in [Script Group Execution](/docs/tech-explanation/script-group-exe) and [Witness](/docs/tech-explanation/witness). +CKB doesn't face such a problem, since the verification of signatures is done by separting the rule(Lock Script) from the proof(Witness). There are also mechanisms for grouping the same Lock Scripts so multiple inputs can share one signature in the transaction Witnesses. That makes moving 100 Cells with SPHINCS+ signatures as simple as moving 1 Cell with SPHINCS+ signature. You can learn more about this in [Script Group Execution](/docs/tech-explanation/script-group-exe) and [Witness](/docs/tech-explanation/witness). ## What CKB has achieved @@ -94,7 +94,7 @@ Since the SPHINCS+ Lock Script is a production-ready implementation, there are a - [Quantum-Purse](https://github.com/tea2x/quantum-purse) - A CKB quantum-safe & lightweight wallet from community -We are looking forward to more SPHINCS+ based applications and tools arised in the CKB community. +We are looking forward to more SPHINCS+ based applications and tools arisen in the CKB community. ## Summary From 98e7a1216636dc1cd5c3aa4b6169367a16d20ed0 Mon Sep 17 00:00:00 2001 From: yfeng2824 <140578792+yfeng2824@users.noreply.github.com> Date: Tue, 16 Dec 2025 16:57:02 +0800 Subject: [PATCH 04/20] feat: add ckb features to landing page (#711) --- .../extreme-decentralization.md | 0 .../quantum-resistance.md | 0 .../vm-built-for-hackers.md | 0 website/sidebars.js | 6 +- website/src/components/Home/index.tsx | 423 ++++++++++-------- website/src/components/Home/styles.module.css | 280 +++++++++--- website/src/pages/homeContents.tsx | 76 ++-- website/src/pages/index.tsx | 134 ++++-- website/src/pages/styles.module.css | 70 ++- website/static/svg/square-nodes.svg | 43 ++ website/static/svg/square-quantum.svg | 18 + website/static/svg/square-vm.svg | 18 + website/static/svg/unique-card-shape.svg | 6 + 13 files changed, 711 insertions(+), 363 deletions(-) rename website/docs/{tech-explanation => ckb-features}/extreme-decentralization.md (100%) rename website/docs/{tech-explanation => ckb-features}/quantum-resistance.md (100%) rename website/docs/{tech-explanation => ckb-features}/vm-built-for-hackers.md (100%) create mode 100644 website/static/svg/square-nodes.svg create mode 100644 website/static/svg/square-quantum.svg create mode 100644 website/static/svg/square-vm.svg create mode 100644 website/static/svg/unique-card-shape.svg diff --git a/website/docs/tech-explanation/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md similarity index 100% rename from website/docs/tech-explanation/extreme-decentralization.md rename to website/docs/ckb-features/extreme-decentralization.md diff --git a/website/docs/tech-explanation/quantum-resistance.md b/website/docs/ckb-features/quantum-resistance.md similarity index 100% rename from website/docs/tech-explanation/quantum-resistance.md rename to website/docs/ckb-features/quantum-resistance.md diff --git a/website/docs/tech-explanation/vm-built-for-hackers.md b/website/docs/ckb-features/vm-built-for-hackers.md similarity index 100% rename from website/docs/tech-explanation/vm-built-for-hackers.md rename to website/docs/ckb-features/vm-built-for-hackers.md diff --git a/website/sidebars.js b/website/sidebars.js index cd52d7627..57d214634 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -267,9 +267,9 @@ export default { className: "category-ckb-features", collapsible: false, items: [ - "tech-explanation/extreme-decentralization", - "tech-explanation/native-quantum-resistance", - "tech-explanation/vm-built-for-hackers", + "ckb-features/extreme-decentralization", + "ckb-features/native-quantum-resistance", + "ckb-features/vm-built-for-hackers", ], }, { diff --git a/website/src/components/Home/index.tsx b/website/src/components/Home/index.tsx index eb598ea23..d5c17082d 100644 --- a/website/src/components/Home/index.tsx +++ b/website/src/components/Home/index.tsx @@ -1,21 +1,25 @@ import clsx from "clsx"; +import { useEffect, useMemo, useState } from "react"; +import Link from "@docusaurus/Link"; + import styles from "./styles.module.css"; -import WalletCard, { WalletCardProps } from "../WalletCard"; -import { useEffect, useState } from "react"; import CardLayout from "../CardLayout"; -import Link from "@docusaurus/Link"; -import EcoCard, { EcoCardProps } from "../EcoCard"; import Button from "../Button"; +import TutorialFrame from "../TutorialFrame"; +import WalletCard, { WalletCardProps } from "../WalletCard"; +import EcoCard, { EcoCardProps } from "../EcoCard"; + import { TutorialProps, contactUsContents, devToolSectionContents, homeCardContents, tutorialSectionContents, + uniqueSectionContents, } from "../../pages/homeContents"; + import { walletCardContents } from "../../../docs/integrate-wallets/CardContents"; import ecoCardContents from "../../../docs/ecosystem/EcoCardContents"; -import TutorialFrame from "../TutorialFrame"; interface EcoSectionProps { title: string; @@ -25,47 +29,42 @@ interface EcoSectionProps { children: React.ReactNode; } -// Card component at the top of the home page +/* ---------------- Top cards ---------------- */ function HomeCardSection() { return ( - {homeCardContents.map((card, index) => ( + {homeCardContents.map((card) => ( - {card.links ? ( -
- {card.icon} -
- ) : ( -
- {card.icon} -
- )} +
+ {card.icon} +
+

{card.title}

- {card.links && ( + + {card.links ? (
- {card.links.map((link, index) => ( + {card.links.map((l) => ( - {link.label} + {l.label} {"Navigate ))}
- )} + ) : null} ))}
); } +/* ---------------- DApp Tutorials ---------------- */ function DAppSection(): JSX.Element { - const [selectedTutorial, setSelectedTutorial] = useState( + const [selected, setSelected] = useState( tutorialSectionContents[0] ); - const handleTutorialClick = (tutorial: TutorialProps) => { - setSelectedTutorial(tutorial); - }; - return (
{"Glowing
{"Glowing
+

DApp Tutorials

+
- {tutorialSectionContents.map((tutorial, index) => ( -
handleTutorialClick(tutorial)} + {tutorialSectionContents.map((t) => ( +
+ ))}
-
+
); } -// General Component for Ecosytem section +/* ---------------- Unique cards ---------------- */ +function UniqueCardSection(): JSX.Element { + return ( +
+ + {uniqueSectionContents.map((card) => ( + +
+ +

{card.title}

+
+ +

{card.description}

+ + + + ))} +
+
+ ); +} + +/* ---------------- Ecosystem wrapper ---------------- */ function EcoSection({ title, icon, @@ -169,11 +198,12 @@ function EcoSection({ className={clsx(styles.section, styles.flexCol)} style={{ marginTop: topMargin }} > - {glow && ( + {glow ? (
- +
- )} + ) : null} +

{title}

+ {children}
); } -// Wallet - A subsection under Ecosystem section +/* ---------------- Wallets ---------------- */ function WalletDisplay(): JSX.Element { - const [currentTag, setCurrentTag] = useState("All"); - const [tags, setTags] = useState([]); - const [filteredCards, setFilteredCards] = useState([]); - - // Generate a list of unique tags - useEffect(() => { - const tagsArray: string[] = []; + const tags = useMemo(() => { + const uniq: string[] = []; walletCardContents.forEach((card) => { card.tags.forEach((tag) => { - if (!tagsArray.includes(tag)) { - tagsArray.push(tag); // Add tag if not already included - } + if (!uniq.includes(tag)) uniq.push(tag); }); }); - setTags(tagsArray); - }, [walletCardContents]); + return uniq; + }, []); + + const [currentTag, setCurrentTag] = useState("All"); + + const filteredCards: WalletCardProps[] = useMemo(() => { + return currentTag === "All" + ? walletCardContents + : walletCardContents.filter((c) => c.tags.includes(currentTag)); + }, [currentTag]); - // Filter cards based on the currentTag - useEffect(() => { - setFilteredCards( - currentTag === "All" - ? walletCardContents - : walletCardContents.filter((card) => card.tags.includes(currentTag)) - ); - }, [currentTag, walletCardContents]); - - // Render filters and cards return ( - +
setCurrentTag("All")} + type="button" > All Wallets - {tags.map((tag, index) => ( + + {tags.map((tag) => ( ))}
+ - {filteredCards.map((card, index) => ( + {filteredCards.map((card, idx) => ( ))} + @@ -269,129 +296,122 @@ function WalletDisplay(): JSX.Element { ); } -// Dev Tool - A subsection under Ecosystem section +/* ---------------- Dev tools ---------------- */ function ToolDisplay(): JSX.Element { - // Render filters and cards + const sdks = devToolSectionContents.filter((t) => t.category === "SDK"); + const others = devToolSectionContents.filter( + (t) => t.category === "Other DevTools" + ); + return ( - +
SDKs
- {devToolSectionContents - .filter((tool) => tool.category === "SDK") - .map((tool, index) => ( - - {tool.title} - - ))} + {sdks.map((tool) => ( + + {tool.title} + + ))}
+
Other Dev Tools
- {devToolSectionContents - .filter((tool) => tool.category === "Other DevTools") - .map((tool, index) => ( - - {tool.title} - - ))} + {others.map((tool) => ( + + {tool.title} + + ))}
-
); } +/* ---------------- Projects carousel ---------------- */ function ProjectDisplay(): JSX.Element { - const [filteredContent, setFilteredContent] = useState([]); const [currentIndex, setCurrentIndex] = useState(0); const [windowWidth, setWindowWidth] = useState(0); + const filteredContent = useMemo( + () => ecoCardContents.filter((c) => !c.tags.includes("Wallet")), + [] + ); + useEffect(() => { - function updateDimensions() { - setWindowWidth(window.innerWidth); - } - updateDimensions(); // Set initial size at client-side - window.addEventListener("resize", updateDimensions); - return () => window.removeEventListener("resize", updateDimensions); + const update = () => setWindowWidth(window.innerWidth); + update(); + window.addEventListener("resize", update); + return () => window.removeEventListener("resize", update); }, []); - const getCardsToShow = (): number => { - if (windowWidth >= 996) { - return 3; // for >=996px - } else if (windowWidth >= 769) { - return 2; // for 768px to 996px - } - return 1; - }; - - const cardsToShow = getCardsToShow(); + const cardsToShow = windowWidth >= 996 ? 3 : windowWidth >= 769 ? 2 : 1; - const goToPrevious = () => { - setCurrentIndex((prevIndex) => - prevIndex > 0 ? prevIndex - 1 : filteredContent.length - 1 - ); - }; + const goToPrevious = () => + setCurrentIndex((i) => (i > 0 ? i - 1 : filteredContent.length - 1)); - const goToNext = () => { - setCurrentIndex((prevIndex) => - prevIndex + 1 < filteredContent.length ? prevIndex + 1 : 0 - ); - }; - - useEffect(() => { - const filtered = ecoCardContents.filter( - (content) => !content.tags.includes("Wallet") - ); - setFilteredContent(filtered); - }, []); + const goToNext = () => + setCurrentIndex((i) => (i + 1 < filteredContent.length ? i + 1 : 0)); - // Creating a looped set of cards - const items = []; - if (filteredContent && filteredContent.length > 0) { - for (let i = 0; i < cardsToShow; i++) { - items.push(filteredContent[(currentIndex + i) % filteredContent.length]); - } + const items: EcoCardProps[] = []; + for (let i = 0; i < Math.min(cardsToShow, filteredContent.length); i++) { + items.push(filteredContent[(currentIndex + i) % filteredContent.length]); } return ( - +
- {items?.map((card, index) => ( - + {items.map((card, idx) => ( + ))}
+
- - - + +
@@ -399,14 +419,16 @@ function ProjectDisplay(): JSX.Element { ); } +/* ---------------- Dev log ---------------- */ function DevLogSection(): JSX.Element { return (
- +
+

Discover Dev Log

@@ -416,98 +438,106 @@ function DevLogSection(): JSX.Element { forward.
+
- {"dev + dev log
); } +/* ---------------- History ---------------- */ function HistorySection(): JSX.Element { return (
- +
+

Explore CKB History & Hard Forks

- Delve into the milestones and pivotal updates that have shaped CKB's - development. Gain detailed insights into each hard fork and understand - their impact on the evolution of the network. + Delve into the milestones and pivotal updates that have shaped + CKB's development. Gain detailed insights into each hard fork and + understand their impact on the evolution of the network.
-
+
{"history
); } +/* ---------------- CTA ---------------- */ function CTASection(): JSX.Element { const [copied, setCopied] = useState(false); - const handleCopyToClipboard = async () => { - const textToCopy = "npm install -g @offckb/cli"; - + const copy = async () => { try { - await navigator.clipboard.writeText(textToCopy); + await navigator.clipboard.writeText("npm install -g @offckb/cli"); setCopied(true); - setTimeout(() => setCopied(false), 3000); // Change text back after 3 seconds + setTimeout(() => setCopied(false), 3000); } catch (err) { console.error("Failed to copy: ", err); } }; + return (
- +
+

Learn Basics

- Begin your journey with our comprehensive guide on "How CKB Works” to - ensure you have a solid understanding before diving deeper. + Begin your journey with our comprehensive guide on "How CKB + Works" to ensure you have a solid understanding before diving + deeper.

+

OR

+

Jumpstart Your Development

Run the command below in your terminal to start developing dApps on the CKB Devnet immediately.

-
{copied ? ( "Copied to clipboard!" @@ -522,22 +552,24 @@ function CTASection(): JSX.Element { /> )} -
+
); } +/* ---------------- Footer ---------------- */ function FooterSection(): JSX.Element { return (
{`Copyright © ${new Date().getFullYear()} Nervos Foundation. All Rights Reserved.`}
+
- {contactUsContents.map((media, index) => ( + {contactUsContents.map((media) => ( .borderBtm:not(:last-child) { border-bottom: 1px solid var(--dark-border-invisible); } + .link { line-height: 3rem; color: var(--dark-text-secondary) !important; text-decoration: none !important; } + .line { cursor: pointer; padding: 0 0.5rem; } + .line:hover { background-color: var(--dark-hover); border-radius: 2px; } -/* wallet section specific */ +/* ---------------- Wallet section ---------------- */ .filters { width: 100%; display: flex; align-items: center; flex-wrap: wrap; } + .tag { display: flex; align-items: center; justify-content: center; height: 2rem; + + padding: 0 0.75rem; + margin: 0 1rem 1rem 0; + font-size: 0.875rem; + line-height: 2rem; + background-color: var(--dark-surface-03); color: var(--dark-text-tertiary); - line-height: 2rem; + border-radius: 32px; border: 1px solid var(--dark-border-subtle); box-shadow: none; cursor: pointer; - margin: 0 1rem 1rem 0; - padding: 0 0.75rem; } + .tag:hover { background-color: var(--dark-surface-03-hover); } + .activeTag { background-color: var(--dark-alert-success-bg) !important; border: 1px solid var(--dark-alert-success); color: var(--dark-text-primary); } -/* DApp section specific */ +/* ---------------- DApp tutorials ---------------- */ .tutorialSection { padding: 7.5rem 2.5rem; gap: 2.5rem; } + .tutorialLeft { width: 636px; } + .tutorialSidebar { margin: 2.5rem 0; color: var(--dark-text-secondary); } + .tutorialItem { + width: 100%; + text-align: left; + + border: none; + background: transparent; + border-radius: 8px; display: flex; flex-direction: column; + padding: 1rem 1.25rem; opacity: 0.5; cursor: pointer; + position: relative; overflow: hidden; } + .tutorialItem:hover { background-color: var(--dark-hover); } + +.itemTitle { + margin-bottom: 0.5rem; + color: var(--dark-text-primary); + z-index: 1; +} + .itemDecor { position: absolute; right: -1.5rem; @@ -179,52 +221,103 @@ z-index: 0; display: none; } -.itemTitle { - margin-bottom: 0.5rem; - color: var(--dark-text-primary); - z-index: 1; -} + .itemActive { background: var(--dark-surface-accent); box-shadow: 0px 10px 40px -5px rgba(7, 28, 39, 0.4); opacity: 1; } + .itemActive .itemDecor { display: block; } + .tutorialFrame { width: 567px; } -/* Dev tools section specific */ -.tableContainer { +/* ---------------- Unique cards ---------------- */ +.uniqueWrap { + width: 100%; +} + +.uniqueCard { + position: relative; + display: block; + text-decoration: none; + + height: 340px; + padding: 1.5rem; + + background-image: url("/svg/unique-card-shape.svg"); + background-repeat: no-repeat; + background-size: contain; + background-position: center; +} + +.uniqueCard:hover { + text-decoration: none; +} + +.uniqueCardHeader { display: flex; - justify-content: space-between; + align-items: center; + gap: 0.85rem; +} + +.uniqueIcon { + width: 56px; + height: 56px; +} + +.uniqueCardTitle { + margin: 0; } +.uniqueCardDesc { + margin: 0; + padding: 1rem 0; + + color: var(--dark-text-secondary); + font-size: 1rem; + line-height: 1.7; + min-height: 8rem; +} + +/* ---------------- Dev tools ---------------- */ +.devlogSection { + margin-bottom: 2.5rem; +} .column { display: flex; flex-direction: column; color: var(--dark-text-primary); flex: 1; } + .cell { - border: 1px solid var(--dark-border-subtle); - height: 3.5rem; - line-height: 3.5rem; display: flex; align-items: center; justify-content: center; + + height: 3.5rem; + line-height: 3.5rem; + + border: 1px solid var(--dark-border-subtle); cursor: pointer; + text-decoration: none !important; color: var(--dark-text-primary); font-weight: bold; + flex: 1 1 50%; } + .cell:hover { background-color: var(--dark-hover); border-color: var(--dark-border-accent); } + .columnHeader { background-color: var(--dark-surface-03) !important; border: 1px solid var(--dark-border-subtle) !important; @@ -232,68 +325,79 @@ cursor: default; } -/* Project Display specific */ +/* ---------------- Projects carousel ---------------- */ .carouselContainer { width: 100%; } + .carouselController { gap: 0.5rem; } + .arrowLeft, .arrowRight { width: 2rem; min-width: 2rem; height: 2rem; + display: flex; align-items: center; justify-content: center; - border: none; + + border: 1px solid var(--dark-border-accent); + border-radius: 50%; + cursor: pointer; - color: var(--dark-alert-success); background: var(--dark-alert-success-bg); - border-radius: 50%; - border: 1px solid var(--dark-border-accent); + color: var(--dark-alert-success); } + .arrowLeft:hover, .arrowRight:hover { background: var(--dark-surface-03-hover); } + .arrowLeft { transform: scaleX(-1); } -/* Dev Log specific */ +/* ---------------- Dev log / history ---------------- */ + .illusContainer { width: 417px; height: 350px; } + .leftContainer { max-width: 55%; } + .description { color: var(--dark-text-secondary); font-size: 1.25rem; } -/* CTA section specific */ +/* ---------------- CTA ---------------- */ .ctaSection { background-color: var(--dark-surface-02); } + .ctaSection::before { content: ""; position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; + inset: 0; + background-image: url("/img/noise.png"); background-position: center; background-repeat: repeat; + z-index: -1; } + .ctaSubsection { max-width: 40%; } + .or { background-color: var(--dark-surface-01); width: 5rem; @@ -301,15 +405,21 @@ height: 5rem; border-radius: 50%; } + .command { + border: none; + background-color: var(--dark-alert-success-bg); padding: 0 2rem; + line-height: 3rem; width: 286px; border-radius: 40px; + color: var(--dark-text-link); cursor: pointer; } + .command:hover { background: radial-gradient( 50% 50% at 50% 50%, @@ -319,77 +429,107 @@ transition: opacity 0.2s; } -/* Footer section specific */ +/* ---------------- Footer ---------------- */ .footerSection { border-top: 1px solid var(--dark-border-invisible); min-height: 4rem; padding: 1rem 4rem; } + .copyright { color: var(--dark-text-secondary); font-size: 0.875rem; text-align: center; } + .icons { flex-wrap: wrap; justify-content: center; } + .iconBG { display: flex; align-items: center; justify-content: center; + width: 2.25rem; height: 2.25rem; + background-color: var(--dark-surface-02); border-radius: 50%; cursor: pointer; } + .iconBG:hover { background-color: var(--dark-surface-03); } -/* Responsiveness */ +/* ---------------- Responsive ---------------- */ + +@media (max-width: 1440px) { + .uniqueCard { + background-image: none; + background-color: var(--dark-surface-02); + border: 1px solid var(--dark-border-invisible); + border-radius: 2rem; + height: fit-content; + } + .uniqueCardDesc { + min-height: 4rem; + } +} + @media (max-width: 996px) { .illusContainer { width: 100%; } + .tutorialSection { flex-direction: column; padding: 3.5rem; } + .tutorialLeft, .tutorialFrame { width: 100%; } + .devlogSection { flex-direction: column-reverse; - align-items: start; + align-items: flex-start; } + .leftContainer { max-width: 100%; } + .ctaSection { flex-direction: column; gap: 2.5rem; - align-items: start; + align-items: flex-start; } + .ctaSubsection { max-width: 100%; } + .footerSection { flex-direction: column; gap: 1rem; } } + @media (max-width: 768px) { .section { padding: 2.5rem 1.25rem; border-radius: 20px; } + .sectionGlow, .sectionGlowOpposite { display: none; } + .flexCol { gap: 1.25rem; } diff --git a/website/src/pages/homeContents.tsx b/website/src/pages/homeContents.tsx index bc096a538..e733558b5 100644 --- a/website/src/pages/homeContents.tsx +++ b/website/src/pages/homeContents.tsx @@ -2,6 +2,14 @@ export interface CardLinks { label: string; link: string; } + +export interface HomeCardProps { + title: string; + icon: string; + links?: CardLinks[]; + to?: string; +} + export interface TutorialProps { title: string; description: string; @@ -9,17 +17,18 @@ export interface TutorialProps { iframeSrc: string; illusSrc: string; } + export interface DevToolProps { title: string; href: string; - category: string; + category: "SDK" | "Other DevTools"; } -export interface HomeCardProps { - title: string; - links?: CardLinks[]; - to?: string; +export interface UniqueProps { icon: string; + title: string; + description: string; + link: string; } const homeCardContents: HomeCardProps[] = [ @@ -56,16 +65,8 @@ const homeCardContents: HomeCardProps[] = [ ], icon: "script", }, - { - title: "Run a Node", - to: "/docs/node/node-overview", - icon: "node", - }, - { - title: "Mining", - to: "/docs/mining/guide", - icon: "mining", - }, + { title: "Run a Node", to: "/docs/node/node-overview", icon: "node" }, + { title: "Mining", to: "/docs/mining/guide", icon: "mining" }, { title: "Tech Explanation", to: "/docs/tech-explanation/nervos-blockchain", @@ -108,27 +109,35 @@ const tutorialSectionContents: TutorialProps[] = [ }, ]; -const devToolSectionContents: DevToolProps[] = [ +const uniqueSectionContents: UniqueProps[] = [ { - title: "Rust", - href: "/docs/sdk-and-devtool/rust", - category: "SDK", + icon: "nodes", + title: "Extreme Decentralization", + description: + "Secured by Proof-of-Work so anyone can verify the network without trusting a central party.", + link: "/docs/ckb-features/extreme-decentralization", }, { - title: "Go", - href: "/docs/sdk-and-devtool/go", - category: "SDK", + icon: "quantum", + title: "Native Quantum Resistance", + description: + "Supports quantum-resistant cryptography to help protect assets and identities over time.", + link: "/docs/ckb-features/native-quantum-resistance", }, { - title: "Java", - href: "/docs/sdk-and-devtool/java", - category: "SDK", - }, - { - title: "TypeScript", - href: "/docs/sdk-and-devtool/ccc", - category: "SDK", + icon: "vm", + title: "Virtual Machine Built for Hackers", + description: + "Uses a public, open standard (RISC-V) to run and verify on-chain rules in a transparent way.", + link: "/docs/ckb-features/vm-built-for-hackers", }, +]; + +const devToolSectionContents: DevToolProps[] = [ + { title: "Rust", href: "/docs/sdk-and-devtool/rust", category: "SDK" }, + { title: "Go", href: "/docs/sdk-and-devtool/go", category: "SDK" }, + { title: "Java", href: "/docs/sdk-and-devtool/java", category: "SDK" }, + { title: "TypeScript", href: "/docs/sdk-and-devtool/ccc", category: "SDK" }, { title: "CKB-CLI", href: "https://github.com/nervosnetwork/ckb-cli", @@ -165,15 +174,14 @@ const contactUsContents: CardLinks[] = [ }, ]; -// Just to include a default export -const HomeContentsPage: React.FC = () => { - return null; -}; +// default export placeholder +const HomeContentsPage: React.FC = () => null; export default HomeContentsPage; export { homeCardContents, tutorialSectionContents, + uniqueSectionContents, devToolSectionContents, contactUsContents, }; diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 9708c4e24..b6d100e23 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -1,28 +1,31 @@ import { useEffect } from "react"; import LogRocket from "logrocket"; import Layout from "@theme/Layout"; +import clsx from "clsx"; +import { useColorMode } from "@docusaurus/theme-common"; + import styles from "./styles.module.css"; import CardLayout from "../components/CardLayout"; -import clsx from "clsx"; +import CookieConsent from "../components/CookieConsent"; + import { HomeCardSection, + DAppSection, + UniqueCardSection, WalletDisplay, ToolDisplay, + ProjectDisplay, DevLogSection, HistorySection, - ProjectDisplay, - FooterSection, CTASection, - DAppSection, + FooterSection, } from "../components/Home"; -import { useColorMode } from "@docusaurus/theme-common"; -import CookieConsent from "../components/CookieConsent"; export default function Home() { useEffect(() => { - // Initialize LogRocket LogRocket.init("ghkibu/nervos-doc"); }, []); + return ( {"glowing - + + -
-
Nervos CKB Documentation
-
+ +
+

Nervos CKB Documentation

+

Discover the power of Nervos CKB through tutorials, guides, and concepts -

+

-
-
+ + +
-
+ -
-
+
+ + +
+ +
+

Explore Ecosystem -

-
+ +

Explore our curated selection of featured tools and resources designed to empower your development on Nervos CKB -

+

+ + -
+ -
-
+
+

Unveil{" "} Updates and Evolution -

+ -
-
-
-
Ready to Dive In?
-
+ + +
+

Ready to Dive In?

+

Whether you're curious about how CKB works or eager to jump straight into building, we've got you covered. -

+

-
+ +
); } -function SwitchToDark() { +function Section({ + children, + className, +}: { + children: React.ReactNode; + className?: string; +}) { + return ( +
{children}
+ ); +} + +function UniqueHeader() { + return ( +
+

+ What Makes CKB + Unique +

+ +

+ CKB combines PoW security, quantum-resistant cryptography, and a RISC-V + VM—built for long-term, verifiable applications +

+
+ ); +} + +function ForceDarkMode() { const { setColorMode } = useColorMode(); useEffect(() => { setColorMode("dark"); - }, []); + }, [setColorMode]); + return null; } diff --git a/website/src/pages/styles.module.css b/website/src/pages/styles.module.css index 291c18a9c..356b2917b 100644 --- a/website/src/pages/styles.module.css +++ b/website/src/pages/styles.module.css @@ -1,28 +1,42 @@ @import "@css/customVariables.css"; -/* General styling */ .homeLayout { width: 100%; background: url("/svg/header-bg.svg") no-repeat top center; background-color: var(--dark-surface-01) !important; } + +.relative { + position: relative; +} + .headerGlow { position: absolute; top: 0; left: 0; z-index: 0; } -.relative { - position: relative; + +.sectionContainer { + width: 100%; + max-width: 1440px; + margin: 0 auto 10rem; + padding: 0 4rem; + display: flex; + flex-direction: column; + align-items: center; } + .header1 { font-size: 3.5em; margin: 7.5rem 0 1.25rem; } + .header2 { font-size: 3em; margin: 8.75rem 0 1.25rem; } + .header1, .header2 { font-family: "Poppins-Bold", sans-serif; @@ -30,49 +44,69 @@ text-align: center; color: var(--dark-text-primary); } + +.noTop { + margin-top: 0; +} + .description { text-align: center; color: var(--dark-text-secondary); - font-size: 1.25rem; + font-size: 1.125rem; } + .titleBtm { margin-bottom: 2rem; } -.flexCol { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; + +.textHighlight { + color: var(--dark-text-link); } -.sectionContainer { + +.textLeftAlign { + text-align: left; +} + +/* Unique header layout */ +.uniqueHeader { width: 100%; - max-width: 1440px; - margin: 0 auto; display: flex; - flex-direction: column; - align-items: center; - padding: 0 4rem; - margin-bottom: 10rem; + justify-content: space-between; + gap: 5rem; + align-items: flex-start; } -.textHighlight { - color: var(--dark-text-link); +.uniqueMaxWidth { + max-width: 560px; } + .ecoBG { background: url("/svg/bg-eco-header.svg") no-repeat top center; } + .updateBG { background: url("/svg/bg-update-header.svg") no-repeat top center; } +@media (max-width: 996px) { + .uniqueHeader { + flex-direction: column; + gap: 0; + } + .uniqueMaxWidth { + max-width: 100%; + } +} @media (max-width: 768px) { .header1 { font-size: 2.5rem; margin: 3rem 0 1.25rem; } + .header2 { font-size: 2em; margin: 8rem 0 1.25rem; } + .sectionContainer { padding: 0 1rem; margin-bottom: 5rem; diff --git a/website/static/svg/square-nodes.svg b/website/static/svg/square-nodes.svg new file mode 100644 index 000000000..c2440df67 --- /dev/null +++ b/website/static/svg/square-nodes.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-quantum.svg b/website/static/svg/square-quantum.svg new file mode 100644 index 000000000..a5e6af5ec --- /dev/null +++ b/website/static/svg/square-quantum.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-vm.svg b/website/static/svg/square-vm.svg new file mode 100644 index 000000000..957826ec9 --- /dev/null +++ b/website/static/svg/square-vm.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/unique-card-shape.svg b/website/static/svg/unique-card-shape.svg new file mode 100644 index 000000000..95cc4a5d2 --- /dev/null +++ b/website/static/svg/unique-card-shape.svg @@ -0,0 +1,6 @@ + +
+ + + +
From 01f60a5219cfc386d6acf07031f9eba1d34bb601 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 08:38:53 +0800 Subject: [PATCH 05/20] Apply suggestions from code review Co-authored-by: Yukang --- website/docs/ckb-features/quantum-resistance.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/ckb-features/quantum-resistance.md b/website/docs/ckb-features/quantum-resistance.md index 74bbebc89..dc7759a04 100644 --- a/website/docs/ckb-features/quantum-resistance.md +++ b/website/docs/ckb-features/quantum-resistance.md @@ -13,11 +13,11 @@ While the industry is standardizing defenses (e.g., NIST's PQC competition), the ## Why CKB is native quantum-resistant -Most blockchains struggle with the quantum-resistant problem with two main reasons. CKB is native quantum-resistant not because it outperforms the other blockchains in solving these two problems, but because it is designed from the first principle, which doesn't have those two problems in the first place. +Most blockchains struggle with quantum resistance for two primary reasons. CKB achieves native quantum resistance not by simply outperforming others in patching these flaws, but by being designed from first principles to avoid them entirely. ### The hardcoded Cryptographic Primitives problem -The fundamental flaw in most Layer 1 blockchains is that their cryptographic primitives are **hardcoded** into the consensus protocol. This rigidity creates one massive hurdle: the "Hard Fork" crisis. If you want to upgrade to quantum-resistant cryptography, you must coordinate a hard fork with the entire network. +The fundamental flaw in most Layer 1 blockchains is that their cryptographic primitives are **hardcoded** into the consensus protocol. This rigidity creates one massive hurdle: the "Hard Fork" crisis. If you want to upgrade to quantum-resistant cryptography, you must coordinate a network-wide hard fork. In Ethereum or Bitcoin, the rule "Transaction X is valid" is effectively hardwired to check a specific ECDSA signature. Changing this rule is not a software update; it is a change to the fundamental laws of that blockchain's universe. @@ -26,7 +26,7 @@ CKB is by design a **Cryptographic Abstraction** blockchain. In CKB, the protoco - **Other blockchains:** Act like a pocket calculator. They calculate specific math (ECC) very fast, but you cannot add new buttons. - **Nervos CKB:** Acts like a generic CPU. If you need a new mathematical operation (like the matrix multiplications used in Lattice-based cryptography), you simply upload the code for it. -This abstraction turns Quantum Resistance from a "Governance Crisis" into a simple "User Choice." Users can choose to migrate to quantum-resistant cryptography without a hard fork. By ten years later, if there are quantum computers that can break the current cryptography, CKB users can follow the process for upgrades in the following: +This abstraction turns Quantum Resistance from a "Governance Crisis" into a simple "User Choice." Users can choose to migrate to quantum-resistant cryptography without a hard fork. In the future, if quantum computers disrupt current encryption technology, CKB users can simply follow this upgrade process: 1. **Deploy:** Developers deploy a new Lock Script implementing PQC algorithms (e.g., SPHINCS+). 2. **Adopt:** Users create new addresses referencing this script's `Code Hash`. From ab80e0ac19c5807f12e510c3f8fe60bc635ba375 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 08:50:32 +0800 Subject: [PATCH 06/20] Apply suggestions from code review Co-authored-by: Sss_is_me <107824088+linnnsss@users.noreply.github.com> Co-authored-by: yfeng2824 <140578792+yfeng2824@users.noreply.github.com> --- .../ckb-features/extreme-decentralization.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index b22630ef2..dec01bb57 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -3,7 +3,7 @@ id: extreme-decentralization title: Extreme Decentralization --- -Decentralization is the core value proposition of public blockchains. It ensures censorship resistance, permissionless access, and security without relying on trusted intermediaries. CKB (The layer 1 protocol) is designed from the ground up to make sure this core value is not compromised. +Decentralization is the core value proposition of public blockchains. It ensures censorship resistance, permissionless access, and security without relying on trusted intermediaries. As the layer 1 protocol of Nervos Network, CKB is designed from the ground up to make sure this core value is not compromised. ## Decoupling: Our Approach to True Decentralization @@ -16,30 +16,30 @@ Nervos CKB addresses this by decoupling concerns across a multi-layered architec ### The Last Line of Defense -The CKB team consciously positions the Layer 1 protocol at the **absolute left-most edge** of this spectrum. By holding this ground, Layer 1 acts as the immutable trust anchor and the **last line of defense** for the entire network. If the CKB team were to compromise here for the sake of usability or speed, the security of the entire structure would crumble. +CKB is positioned at the **far-left edge** of this spectrum, serving as the immutable trust anchor and the **last line of defense** for the entire network. Compromising the base layer for usability or speed would weaken the security of the entire structure. -This philosophy dictates a clear division of labor, ensuring every point on the spectrum receives dedicated effort from the actors best suited for it: +This separation establishes a clear division of labor: - **Layer 1 (CKB):** Focuses exclusively on being the ultimate guardian of value. Its design prioritizes maximum decentralization, security, and censorship resistance—the original spirit of crypto—above all else. - **Layer 2 & Ecosystem:** Focuses on scalability, high performance, the developer and user experience necessary for mass adoption, free from the burden of base-layer consensus trade-offs. -It is not only about code, but also for operational decisions. For example, the CKB team might deliberately reject providing centralized conveniences, such as a default, production RPC service (similar to Infura in Ethereum). While such a service would offer a shortcut for developers, it introduces a central point of failure. Note that the [public RPC service](/docs/getting-started/rpcs) that CKB team provide is only for testing purpose, it is strongly recommended to run your own RPC service for your dApp. By refusing to encroach on the "service layer," CKB forces the ecosystem to build its own robust, distributed access layers, ensuring the foundation remains a neutral, decentralized settlement platform. +This principle applies not only to code, but also for operational decisions. For example, the CKB team deliberately avoid providing centralized conveniences, such as a default, production-grade RPC service (similar to Infura in Ethereum). While such a service would make developers’ lives easier, it introduces a central point of failure. Note that the [public RPC service](/docs/getting-started/rpcs) provided by CKB exists solely for testing, and developers are strongly encouraged to run their own RPC services for their dApps. By refusing to encroach on the "service layer," CKB forces the ecosystem to build its own robust, distributed access layers, ensuring the foundation remains a neutral, decentralized settlement layer. ## How to Achieve Extreme Decentralization -Decentralization is not just about who _mines_ the next block; it is about who can _verify_ the history. If running a node becomes too expensive due to data bloat, the network centralizes into a few server farms regardless of its consensus algorithm. +Decentralization is not just about who mines the next block–it is about who can independently **verify** the chain's history. If running a node becomes too expensive due to data bloat, participation collapses into a few data centers, and the system recentralizes in practice regardless of its consensus algorithm. -CKB ensures this never happens through three radical approaches: **Sustainable State Management**, **Proof-of-Work Consensus**, and a viable **Light Client** with an engineering effort on building nodes that lowers the entry barrier for participants. +CKB addresses this challenge through three radical design choices: **Sustainable State Management**, **Proof-of-Work Consensus**, and a viable **Light Client**, supported by ongoing engineering efforts to lower the barrier to running nodes. ### 1. Sustainable State Management Most blockchains operate as "General Computation Networks" (like a world computer). Users pay a one-time fee to execute a transaction, but the resulting data (state) occupies the network's storage forever at no further cost. This leads to the **"Tragedy of the Commons"**: because storage is effectively free, the state grows indefinitely ([State Explosion](https://medium.com/nervosnetwork/state-explosion-and-the-tragedy-of-the-blockchain-commons-1fbd4837e859)). Eventually, only enterprise-grade hardware can store the chain, forcing regular users to trust third parties. -CKB adopts a "General Verification Network" architecture based on [Cell Model](/docs/tech-explanation/cell-model). The **Common Knowledge Base** acts as a verified state layer rather than a computation layer. To maintain "Extreme Decentralization," CKB creates a direct economic link between state and scarcity: +CKB takes a different approach. It adopts a "General Verification Network" architecture built on the [Cell Model](/docs/tech-explanation/cell-model), where on-chain storage is treated as a scarce resource rather than free space. -- **State as a Scarce Resource:** In CKB, state is not an afterthought; it is the physical "land" of the blockchain. -- **The CKB = Byte Equation:** The native token (CKB) represents **state capacity**. Holding 1 CKB entitles you to store 1 byte of data on the blockchain. -- **Targeted Inflation (State Rent):** To occupy space on the Global State, users must lock CKB tokens. This incurs an opportunity cost (via secondary issuance inflation), effectively acting as a "State Rent." This forces developers and users to be efficient—they only store what is truly valuable. +- **State as a Scarce Resource:** On-chain state is modeled as a finite resource that must be explicitly accounted for. +- **1 CKB = 1 Byte of Storage:** The native token, CKB, represents state capacity; holding 1 CKB entitles the holder to store 1 byte of data on the blockchain. +- **Targeted Inflation (State Rent):** Occupying on-chain storage requires locking CKB, which carries an opportunity cost through secondary issuance. This mechanism functions as a form of "state rent" and encourages efficient use of capacity, ensuring that developers and users store only the truly valuable data. **Why this guarantees decentralization:** @@ -49,7 +49,7 @@ Moving computation off-chain also reduces the burden on full nodes. They only ne ### 2. Proof-of-Work (PoW) over Proof-of-Stake (PoS) -CKB utilizes **NC-Max** (a variant of Nakamoto Consensus) with a custom hash function, **Eaglesong**. While many modern blockchains have shifted to Proof-of-Stake (PoS), CKB adheres to PoW for specific reasons regarding decentralization: +CKB utilizes [**NC-Max**](https://eprint.iacr.org/2020/1101.pdf) (a variant of Nakamoto Consensus) with a custom hash function, **Eaglesong**. While many modern blockchains rely on Proof-of-Stake (PoS), CKB adheres to PoW for decentralization-related reasons: 1. **Permissionless Participation:** In PoW, anyone with hardware and electricity can participate. There is no need to buy tokens from existing holders to become a validator, avoiding the "rich get richer" centralization loop often criticized in PoS. 2. **Objective Security:** PoW provides an objective measure of the chain's security (accumulated work). A new node can independently verify the valid chain with the most work without trusting any peers or checkpoints. From ed5500705b903ed6b7eba3a9cd5bc84cae774641 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 08:56:24 +0800 Subject: [PATCH 07/20] Apply suggestions from code review Co-authored-by: Sss_is_me <107824088+linnnsss@users.noreply.github.com> Co-authored-by: yfeng2824 <140578792+yfeng2824@users.noreply.github.com> --- website/docs/ckb-features/extreme-decentralization.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index dec01bb57..6d851f986 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -63,9 +63,9 @@ However, running a full node (downloading terabytes of history) is impossible fo #### The FlyClient Protocol & MMR -Unlike traditional SPV (Simplified Payment Verification) clients that must download linearly increasing amounts of headers, CKB implements the **FlyClient** protocol. +Unlike traditional SPV (Simplified Payment Verification), where clients must download linearly increasing amounts of headers, CKB implements the **FlyClient** protocol. -- **Logarithmic Scaling:** Instead of downloading every block header, the client uses a probabilistic sampling technique. It downloads only a logarithmic number of block headers to statistically verify the Proof-of-Work with overwhelming certainty. +- **Logarithmic Scaling:** Instead of downloading every block header, the client uses a probabilistic sampling technique. It downloads only a logarithmic number of block headers to statistically verify the Proof-of-Work with near certainty. - **Merkle Mountain Ranges (MMR):** CKB blocks include an MMR root in their headers. This cryptographic structure allows the light client to prove that any specific block is part of the valid chain history without storing the history itself. - **Result:** A user can sync the chain in seconds with minimal bandwidth, regardless of how long the blockchain becomes. @@ -88,4 +88,7 @@ By embedding the verification layer directly into the user's application, CKB cl ## Summary -This completes the picture of "Extreme Decentralization" on CKB: a system where users own their state(Cell Model), participate permissionlessly (PoW), compute locally (Verification Network), and verify independently (Light Client). +In summary, CKB achieves extreme decentralization through three core components: +- **Sustainable State Management**: By enforcing the rule that **1 CKB = 1 byte of storage**, CKB treats state as a scarce resource, preventing unbounded growth and keeping full nodes practical to run. +- **Proof-of-Work Consensus**: Security is anchored in permissionless participation, allowing anyone to help secure the network by contributing computing power. +- **Light Client**: Independent verification is possible on browsers and mobile devices without requiring full-node resources. From a8b705c7fcc1967729cc02688076bb610d0a6f62 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 09:06:04 +0800 Subject: [PATCH 08/20] apply review suggestion --- website/docs/ckb-features/quantum-resistance.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/ckb-features/quantum-resistance.md b/website/docs/ckb-features/quantum-resistance.md index dc7759a04..68b19a376 100644 --- a/website/docs/ckb-features/quantum-resistance.md +++ b/website/docs/ckb-features/quantum-resistance.md @@ -21,7 +21,7 @@ The fundamental flaw in most Layer 1 blockchains is that their cryptographic pri In Ethereum or Bitcoin, the rule "Transaction X is valid" is effectively hardwired to check a specific ECDSA signature. Changing this rule is not a software update; it is a change to the fundamental laws of that blockchain's universe. -CKB is by design a **Cryptographic Abstraction** blockchain. In CKB, the protocol does not know or care what "secp256k1" is. Cryptography is not a consensus rule; it is simply a **Lock Script** (smart contract) that runs in a virtual machine. As a contrast, Ethereum baked the hardcoded ECC into the EVM as a Precompile. +CKB is by design a **Cryptographic Abstraction** blockchain. In CKB, the protocol does not know or care what "secp256k1" is. Cryptography is not a consensus rule; it is simply a [Lock Script](/docs/tech-explanation/lock-script) (smart contract) that runs in a virtual machine. As a contrast, Ethereum baked the hardcoded ECC into the EVM as a Precompile. - **Other blockchains:** Act like a pocket calculator. They calculate specific math (ECC) very fast, but you cannot add new buttons. - **Nervos CKB:** Acts like a generic CPU. If you need a new mathematical operation (like the matrix multiplications used in Lattice-based cryptography), you simply upload the code for it. @@ -69,9 +69,9 @@ The trade-off for SPHINCS+ is signature size. However, CKB handles this graceful There are 3 implementations for the Lock Script: -- [A C lock script](./contracts/c-sphincs-all-in-one-lock/) using [SPHINCS+](https://github.com/sphincs/sphincsplus) -- [A Rust lock script](./contracts/sphincs-all-in-one-lock/) using [fips205](https://github.com/integritychain/fips205) -- [A hybrid lock script](./contracts/hybrid-sphincs-all-in-one-lock/) with the implementation of SPHINCS+ utilizing the sphincsplus C library and Rust glue code. +- [A C lock script](https://github.com/cryptape/quantum-resistant-lock-script/blob/main/contracts/c-sphincs-all-in-one-lock) using [SPHINCS+](https://github.com/sphincs/sphincsplus) +- [A Rust lock script](https://github.com/cryptape/quantum-resistant-lock-script/blob/main/contracts/sphincs-all-in-one-lock) using [fips205](https://github.com/integritychain/fips205) +- [A hybrid lock script](https://github.com/cryptape/quantum-resistant-lock-script/blob/main/contracts/hybrid-sphincs-all-in-one-lock) with the implementation of SPHINCS+ utilizing the sphincsplus C library and Rust glue code. The exact cycle consumptions will slightly vary from one signature to another, a ballpark estimation of cycle consumptions(here we measure cycle consumptions for the whole script, meaning CKB transaction signing is included as well) for each NIST approved parameter set, can be located below(`M` stands for million): From f289c56c05769e81137d402c0e27da99c9b3a069 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 09:06:20 +0800 Subject: [PATCH 09/20] apply review suggestion --- website/docs/ckb-features/extreme-decentralization.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index 6d851f986..ce48e69fc 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -89,6 +89,7 @@ By embedding the verification layer directly into the user's application, CKB cl ## Summary In summary, CKB achieves extreme decentralization through three core components: + - **Sustainable State Management**: By enforcing the rule that **1 CKB = 1 byte of storage**, CKB treats state as a scarce resource, preventing unbounded growth and keeping full nodes practical to run. - **Proof-of-Work Consensus**: Security is anchored in permissionless participation, allowing anyone to help secure the network by contributing computing power. -- **Light Client**: Independent verification is possible on browsers and mobile devices without requiring full-node resources. +- **Light Client**: Independent verification is possible on browsers and mobile devices without requiring full-node resources. From 2efb44b9ca8911b5f1e24e28ccaf0fb3ae1624fe Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 09:11:32 +0800 Subject: [PATCH 10/20] Apply suggestions from code review Co-authored-by: yfeng2824 <140578792+yfeng2824@users.noreply.github.com> --- website/docs/ckb-features/extreme-decentralization.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index ce48e69fc..81ab103e1 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -7,7 +7,7 @@ Decentralization is the core value proposition of public blockchains. It ensures ## Decoupling: Our Approach to True Decentralization -To achieve true decentralization, we must abandon the view of a blockchain as a monolithic, "do-it-all" platform. If a single blockchain layer tries to be everything to everyone—fast for users, easy for developers, and secure for the network—it inevitably creates conflicting incentives. High throughput demands often override verification needs, and the push for seamless developer experiences frequently introduces centralized dependencies. +To achieve true decentralization, a blockchain cannot function as a "do everything" platform. If a single layer attempts to maximize performance, offer developer convenience, and maintain strong security at the same time, these goals create conflicting incentives. High throughput begins to override verification needs, and shortcuts taken for developer experience frequently introduce points of centralization. Nervos CKB addresses this by decoupling concerns across a multi-layered architecture, viewing the blockchain landscape as a continuous spectrum: @@ -71,11 +71,11 @@ Unlike traditional SPV (Simplified Payment Verification), where clients must dow #### WASM & In-Browser Verification -The most radical feature of the CKB Light Client is its portability. The CKB team has compiled the light client into **WebAssembly (WASM)**, enabling it to run in environments previously thought impossible for blockchain nodes. +The CKB Light Client is compiled to **WebAssembly (WASM)**, enabling it to run in browser environments and other platforms that do not support traditional full node operations. -- **No Installation Required:** The light client can be embedded directly into a web wallet or dApp. When a user visits a website, the browser _becomes_ a node. -- **Trustless Interaction:** The dApp does not ask a server "What is my balance?" or "Did this trade settle?" Instead, the browser connects directly to the P2P network, samples headers, and mathematically verifies the data locally. -- **Mobile Ready:** Because it requires minimal storage (storing only a single block header between executions) and low CPU usage, it runs efficiently on mobile devices without draining battery. +- **No Installation Required:** The light client can be embedded directly into a web wallet or dApp. When a user visits a website, the browser operates as a lightweight verification node. +- **Trustless Interaction:** Instead of relying on a server to check balances or transactions, the browser connects to the P2P network, samples block headers, and verifies data locally. +- **Mobile Ready:** With minimal storage requirements(storing only a single block header between executions) and low CPU usage, the light client can operate efficiently on mobile devices. #### Privacy and Sovereignty From 14a6cfef809ac03d5fb426ef03df79b77a0c367b Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 09:17:43 +0800 Subject: [PATCH 11/20] apply review suggestion --- website/docs/ckb-features/extreme-decentralization.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index 81ab103e1..3b69c8ebc 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -57,9 +57,9 @@ CKB utilizes [**NC-Max**](https://eprint.iacr.org/2020/1101.pdf) (a variant of N ### 3. Viable Light Client -True decentralization requires that users can verify the state of the blockchain themselves rather than relying on trusted third-party RPC nodes (like Infura or Alchemy). If a user relies on a server to tell them their balance, they are not using a blockchain; they are using a bank. +True decentralization requires that users can verify the state of the blockchain themselves rather than relying on trusted third-party RPC nodes (like Infura or Alchemy). If a user relies on a server to tell them their balance, they are not using a blockchain; they are using a bank. Running a full node (downloading terabytes of history), however, is too heavy for mobile and browser environments. -However, running a full node (downloading terabytes of history) is impossible for mobile and web users. CKB solves this with a next-generation **Light Client** protocol that brings full-node-level security to consumer devices. +CKB addresses this with a next-generation **Light Client** based on FlyClient and MMRs, bringing near-full-node security to everyday devices. #### The FlyClient Protocol & MMR @@ -74,7 +74,7 @@ Unlike traditional SPV (Simplified Payment Verification), where clients must dow The CKB Light Client is compiled to **WebAssembly (WASM)**, enabling it to run in browser environments and other platforms that do not support traditional full node operations. - **No Installation Required:** The light client can be embedded directly into a web wallet or dApp. When a user visits a website, the browser operates as a lightweight verification node. -- **Trustless Interaction:** Instead of relying on a server to check balances or transactions, the browser connects to the P2P network, samples block headers, and verifies data locally. +- **Trustless Interaction:** Instead of relying on a server to check balances or transactions, the browser connects to the P2P network, samples block headers, and verifies data locally. - **Mobile Ready:** With minimal storage requirements(storing only a single block header between executions) and low CPU usage, the light client can operate efficiently on mobile devices. #### Privacy and Sovereignty From 4aa17a5fb358573ef5ca580f4cb0f35048197144 Mon Sep 17 00:00:00 2001 From: RetricSu Date: Fri, 19 Dec 2025 09:22:57 +0800 Subject: [PATCH 12/20] add security audit note --- website/docs/ckb-features/quantum-resistance.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/docs/ckb-features/quantum-resistance.md b/website/docs/ckb-features/quantum-resistance.md index 68b19a376..893ee8dc4 100644 --- a/website/docs/ckb-features/quantum-resistance.md +++ b/website/docs/ckb-features/quantum-resistance.md @@ -54,6 +54,8 @@ In 2023, The CKB team and Cryptape researchers have successfully implemented a p - **Repository:** [cryptape/quantum-resistant-lock-script](https://github.com/cryptape/quantum-resistant-lock-script) +- **Security Audit:** The code has completed a security audit conducted by ScaleBit. + The Lock Script supports [12 different SPHINCS+ parameter sets](https://github.com/sphincs/sphincsplus#parameters), which can be selected by the user. It is based on the new definition of [CKB_TX_MESSAGE_ALL](https://github.com/nervosnetwork/rfcs/pull/446) to generate the signing message. By default, the Lock script is implemented as a multi-signature contract, and the single-signature process is just a special case of multi-signature. #### Why SPHINCS+? From d699979f8436d45e5b1f5db108bd9bf2310a9523 Mon Sep 17 00:00:00 2001 From: Yuqi Date: Mon, 15 Dec 2025 14:31:17 +0800 Subject: [PATCH 13/20] feat: restructure navbar --- .../serialization-molecule-in-ckb.mdx | 2 +- website/docusaurus.config.js | 180 ++++++++++++-- website/sidebars.js | 88 +++++-- .../Navbar/MegaMenuNavbarItem/index.tsx | 221 ++++++++++++++++++ .../MegaMenuNavbarItem/styles.module.css | 158 +++++++++++++ website/src/css/customTheme.css | 112 +-------- website/src/icons/index.ts | 71 ++++++ .../theme/DocSidebarItem/Category/index.tsx | 26 +++ .../theme/NavbarItem/ComponentTypes/index.ts | 10 + website/static/svg/icon-chevron-down.svg | 3 + .../static/svg/icon-sidebar-common-script.svg | 2 +- website/static/svg/icon-sidebar-concept.svg | 2 +- .../static/svg/icon-sidebar-contribution.svg | 4 + website/static/svg/icon-sidebar-ecosystem.svg | 2 +- website/static/svg/icon-sidebar-feature.svg | 3 + website/static/svg/icon-sidebar-history.svg | 2 +- website/static/svg/icon-sidebar-howto.svg | 6 +- website/static/svg/icon-sidebar-js.svg | 5 + website/static/svg/icon-sidebar-mining.svg | 2 +- website/static/svg/icon-sidebar-molecule.svg | 2 +- website/static/svg/icon-sidebar-node.svg | 10 +- .../static/svg/icon-sidebar-organization.svg | 3 + website/static/svg/icon-sidebar-project.svg | 3 + website/static/svg/icon-sidebar-resource.svg | 2 +- website/static/svg/icon-sidebar-rocket.svg | 2 +- website/static/svg/icon-sidebar-rpc.svg | 2 +- website/static/svg/icon-sidebar-rust.svg | 3 + website/static/svg/icon-sidebar-script.svg | 2 +- website/static/svg/icon-sidebar-structure.svg | 2 +- website/static/svg/icon-sidebar-token.svg | 6 +- website/static/svg/icon-sidebar-tool.svg | 2 +- website/static/svg/icon-sidebar-tutorial.svg | 2 +- website/static/svg/icon-sidebar-wallet.svg | 2 +- website/static/svg/square-concept.svg | 18 ++ website/static/svg/square-feature.svg | 18 ++ website/static/svg/square-history.svg | 18 ++ website/static/svg/square-mine.svg | 18 ++ website/static/svg/square-resource.svg | 18 ++ website/static/svg/square-structure.svg | 18 ++ 39 files changed, 884 insertions(+), 166 deletions(-) create mode 100644 website/src/components/Navbar/MegaMenuNavbarItem/index.tsx create mode 100644 website/src/components/Navbar/MegaMenuNavbarItem/styles.module.css create mode 100644 website/src/icons/index.ts create mode 100644 website/src/theme/DocSidebarItem/Category/index.tsx create mode 100644 website/src/theme/NavbarItem/ComponentTypes/index.ts create mode 100644 website/static/svg/icon-chevron-down.svg create mode 100644 website/static/svg/icon-sidebar-contribution.svg create mode 100644 website/static/svg/icon-sidebar-feature.svg create mode 100644 website/static/svg/icon-sidebar-js.svg create mode 100644 website/static/svg/icon-sidebar-organization.svg create mode 100644 website/static/svg/icon-sidebar-project.svg create mode 100644 website/static/svg/icon-sidebar-rust.svg create mode 100644 website/static/svg/square-concept.svg create mode 100644 website/static/svg/square-feature.svg create mode 100644 website/static/svg/square-history.svg create mode 100644 website/static/svg/square-mine.svg create mode 100644 website/static/svg/square-resource.svg create mode 100644 website/static/svg/square-structure.svg diff --git a/website/docs/serialization/serialization-molecule-in-ckb.mdx b/website/docs/serialization/serialization-molecule-in-ckb.mdx index fef114561..a9e2c3ec7 100644 --- a/website/docs/serialization/serialization-molecule-in-ckb.mdx +++ b/website/docs/serialization/serialization-molecule-in-ckb.mdx @@ -1,6 +1,6 @@ --- id: serialization-molecule-in-ckb -title: Serilization and Molecule in CKB +title: Serialization and Molecule in CKB --- import Tooltip from "@components/Tooltip"; diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 109a50190..957082e78 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -255,46 +255,182 @@ const config = { }, items: [ { - to: "/docs/getting-started/how-ckb-works", - label: "Getting Started", + type: "custom-megaMenu", + label: "Build", position: "left", + menuId: "build", activeBaseRegex: - "/(getting-started|how-tos|serialization|integrate-wallets|dapp|sdk-and-devtool)/", - }, - { - to: "/docs/script/intro-to-script", - label: "Scripts (Smart Contracts)", - position: "left", - activeBaseRegex: "/(script|ecosystem-scripts|script-course)/", + "/(getting-started|dapp|script|how-tos|integrate-wallets|sdk-and-devtool|serialization)/", + primaryItems: [ + { + title: "Getting Started", + description: "Basics for onboarding to CKB", + href: "/docs/getting-started/how-ckb-works", + icon: "squareRocket", + activeBaseRegex: "/getting-started/", + }, + { + title: "DApp Tutorials", + description: "Step-by-step examples for building on CKB", + href: "/docs/dapp/transfer-ckb", + icon: "squareDapp", + activeBaseRegex: "/dapp/", + }, + { + title: "Script Development", + description: "Implement smart-contract logic on CKB", + href: "/docs/script/intro-to-script", + icon: "squareScript", + activeBaseRegex: "/(script|ecosystem-scripts|script-course)/", + }, + ], + + otherLabel: "OTHER", + otherItems: [ + { + title: "How-Tos", + href: "/docs/how-tos/how-to-sign-a-tx", + icon: "howto", + activeBaseRegex: "/how-tos/", + }, + { + title: "Integrate Wallets", + href: "/docs/integrate-wallets/intro-to-wallets", + icon: "wallet", + activeBaseRegex: "/integrate-wallets/", + }, + { + title: "SDK & Dev Tools", + href: "/docs/sdk-and-devtool/devtool", + icon: "tool", + activeBaseRegex: "/sdk-and-devtool/", + }, + { + title: "Serialization (Molecule)", + href: "/docs/serialization/serialization-molecule-in-ckb", + icon: "molecule", + activeBaseRegex: "/serialization/", + }, + ], }, { - to: "/docs/tech-explanation/nervos-blockchain", - label: "Tech Explanation", + type: "custom-megaMenu", + label: "Learn", position: "left", + menuId: "learn", activeBaseRegex: "/(tech-explanation)/", + primaryItems: [ + { + title: "What Makes CKB Unique", + description: "Design choices behind CKB", + href: "/docs/tech-explanation/nervos-blockchain", + icon: "squareFeature", + }, + { + title: "CKB Fundamentals", + description: "Step-by-step examples for building on CKB", + href: "/docs/tech-explanation/nervos-blockchain", + icon: "squareConcept", + }, + { + title: "Core Structures", + description: "Implement smart-contract logic on CKB", + href: "/docs/tech-explanation/cell", + icon: "squareStructure", + }, + ], + + otherLabel: "OTHER", + otherItems: [ + { + title: "Assets & Token Standards", + href: "/docs/tech-explanation/assets-overview", + icon: "token", + activeBaseRegex: "/tech-explanation/(assets)", + }, + { + title: "Glossary", + href: "/docs/tech-explanation/glossary", + icon: "resource", + activeBaseRegex: "/tech-explanation/glossary", + }, + ], }, { - to: "/docs/node/node-overview", - label: "Nodes & Mining", + type: "custom-megaMenu", + label: "Network", position: "left", - activeBaseRegex: "/(node|mining)/", + menuId: "network", + activeBaseRegex: "/(node)/(mining)", + primaryItems: [ + { + title: "Run a Node", + description: "Design choices behind CKB", + href: "/docs/node/node-overview", + icon: "squareNodes", + activeBaseRegex: "/node/", + }, + { + title: "Mining", + description: "Step-by-step examples for building on CKB", + href: "/docs/mining/guide", + icon: "squareMine", + activeBaseRegex: "/mining/", + }, + ], }, { - to: "/docs/ecosystem/projects", - label: "Ecosystem", + type: "custom-megaMenu", + label: "Community", position: "left", - activeBaseRegex: "/(ecosystem|history-and-hard-forks)/", + menuId: "community", + activeBaseRegex: "/(ecosystem)/(history-and-hard-forks)", + primaryItems: [ + { + title: "Projects", + description: + "Applications, tools, and initiatives in the ecosystem", + href: "/docs/ecosystem/projects", + icon: "squareProject", + activeBaseRegex: "/ecosystem/projects", + }, + { + title: "History & Hard Forks", + description: "Timeline and evolution of the CKB network", + href: "/docs/history-and-hard-forks/intro-to-hard-fork", + icon: "squareHistory", + activeBaseRegex: "/history-and-hard-forks/", + }, + { + title: "Resources", + description: "Docs, guides, and external knowledge sources", + href: "/docs/history-and-hard-fork/intro-to-hardfork", + icon: "squareResource", + activeBaseRegex: "/history-and-hard-fork/", + }, + ], + otherLabel: "OTHER", + otherItems: [ + { + title: "Organizations", + href: "/docs/ecosystem/organizations", + icon: "organization", + activeBaseRegex: "/ecosystem/organizations", + }, + { + title: "Contribute", + href: "/docs/ecosystem/contribute", + icon: "contribution", + activeBaseRegex: "/ecosystem/contribute", + }, + ], }, + { type: "search", position: "right", className: "navbar-search", }, - { - to: "docs/ecosystem/contribute", - label: "Contribute", - position: "right", - }, { type: "html", position: "right", diff --git a/website/sidebars.js b/website/sidebars.js index 57d214634..4a2e6ced4 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -5,6 +5,9 @@ export default { label: "Getting Started", className: "category-getting-started", collapsible: false, + customProps: { + icon: "rocket", + }, items: [ "getting-started/how-ckb-works", "getting-started/quick-start", @@ -17,6 +20,9 @@ export default { label: "SDK & Devtools", className: "category-tool", collapsible: false, + customProps: { + icon: "tool", + }, items: [ "sdk-and-devtool/rust", "sdk-and-devtool/go", @@ -34,6 +40,9 @@ export default { label: "Build DApp", className: "category-dapp", collapsible: false, + customProps: { + icon: "tutorial", + }, items: [ "dapp/transfer-ckb", "dapp/store-data-on-cell", @@ -47,6 +56,9 @@ export default { label: "Integrate Wallets", className: "category-integrate-wallets", collapsible: false, + customProps: { + icon: "wallet", + }, items: [ "integrate-wallets/intro-to-wallets", "integrate-wallets/ccc-wallet", @@ -57,6 +69,9 @@ export default { label: "Serialization (Molecule)", className: "category-molecule", collapsible: false, + customProps: { + icon: "molecule", + }, items: [ "serialization/serialization-molecule-in-ckb", "serialization/features-molecule", @@ -73,6 +88,9 @@ export default { label: "How-Tos", className: "category-howto", collapsible: false, + customProps: { + icon: "howto", + }, items: [ "how-tos/how-to-sign-a-tx", "how-tos/how-to-query-tx-state", @@ -88,6 +106,9 @@ export default { label: "Smart Contract Basics", className: "category-script", collapsible: false, + customProps: { + icon: "script", + }, items: [ "script/intro-to-script", "script/program-language-for-script", @@ -110,6 +131,9 @@ export default { label: "Rust", className: "category-rust", collapsible: false, + customProps: { + icon: "rust", + }, items: [ "script/rust/rust-quick-start", "script/rust/rust-build", @@ -151,6 +175,9 @@ export default { label: " JavaScript", className: "category-js", collapsible: false, + customProps: { + icon: "js", + }, items: [ "script/js/js-quick-start", { @@ -197,6 +224,9 @@ export default { label: "Ecosystem Scripts", className: "category-ecosystem-scripts", collapsible: false, + customProps: { + icon: "commonScript", + }, items: [ "ecosystem-scripts/introduction", { @@ -245,6 +275,9 @@ export default { type: "category", label: "Script Development Course", className: "category-full-script-development-series", + customProps: { + icon: "tutorial", + }, collapsible: false, items: [ "script-course/intro-to-script-1", @@ -277,6 +310,9 @@ export default { label: "CKB Fundamentals", className: "category-ckb-fundamentals", collapsible: false, + customProps: { + icon: "concept", + }, items: [ "tech-explanation/nervos-blockchain", "tech-explanation/ckb-vs-btc", @@ -292,6 +328,9 @@ export default { label: "Core Structures", className: "category-core-structures", collapsible: false, + customProps: { + icon: "structure", + }, items: [ { type: "category", @@ -354,6 +393,9 @@ export default { label: "Assets & Token Standards", className: "category-token-standards", collapsible: false, + customProps: { + icon: "token", + }, items: [ "tech-explanation/assets-overview", "tech-explanation/economics", @@ -367,6 +409,9 @@ export default { label: "Resources", className: "category-resources", collapsible: false, + customProps: { + icon: "resource", + }, items: ["tech-explanation/glossary"], }, ], @@ -375,28 +420,43 @@ export default { type: "category", label: "Ecosystem", className: "category-ecosystem", + customProps: { + icon: "ecosystem", + }, collapsible: false, - items: [ - "ecosystem/projects", - "ecosystem/organizations", - "ecosystem/contribute", - ], + items: ["ecosystem/projects", "ecosystem/organizations"], }, { type: "category", label: "History & Hard Forks", className: "category-history", collapsible: false, + customProps: { + icon: "history", + }, items: [ "history-and-hard-forks/intro-to-hard-fork", "history-and-hard-forks/ckb-hard-fork-history", "history-and-hard-forks/rethinking-forks", ], }, + { + type: "category", + label: "Contribution", + className: "category-contribution", + collapsible: false, + customProps: { + icon: "contribution", + }, + items: ["ecosystem/contribute"], + }, { type: "category", label: "Resources", className: "category-resources", + customProps: { + icon: "resource", + }, collapsible: false, items: [ { @@ -424,14 +484,6 @@ export default { label: "CKB Cookbook", href: "https://cookbook.ckbdapps.com/", }, - ], - }, - { - type: "category", - label: "Other Protocols", - className: "category-other-protocols", - collapsible: false, - items: [ { type: "link", label: "Fiber network", @@ -445,11 +497,14 @@ export default { ], }, ], - "Nodes & Mining": [ + Nodes: [ { type: "category", label: "Run a Node", className: "category-node", + customProps: { + icon: "node", + }, collapsible: false, items: [ "node/node-overview", @@ -474,10 +529,15 @@ export default { "node/node-config", ], }, + ], + Mining: [ { type: "category", label: "Mining", className: "category-mining", + customProps: { + icon: "mining", + }, collapsible: false, items: [ "mining/guide", diff --git a/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx b/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx new file mode 100644 index 000000000..b5ba16dec --- /dev/null +++ b/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx @@ -0,0 +1,221 @@ +// src/components/Navbar/MegaMenuNavbarItem.tsx + +import React, { useEffect, useMemo, useRef, useState } from "react"; +import clsx from "clsx"; +import Link from "@docusaurus/Link"; +import { useLocation } from "@docusaurus/router"; +import useBaseUrl from "@docusaurus/useBaseUrl"; + +import ChevronDown from "/svg/icon-chevron-down.svg"; +import { sidebarIconMap, SidebarIconName } from "../../../icons"; +import styles from "./styles.module.css"; + +export type MegaMenuItem = { + title: string; + description?: string; + href: string; + icon?: SidebarIconName; + activeBaseRegex?: string; +}; + +export type MegaMenuNavbarItemProps = { + label: string; + menuId: string; + position?: "left" | "right"; + className?: string; + activeBaseRegex?: string; + primaryItems: MegaMenuItem[]; + otherItems?: MegaMenuItem[]; + otherLabel?: string; +}; + +const EVENT_NAME = "nervos:megamenu-open"; +const MegaMenuNavbarItem: React.FC = ({ + label, + menuId, + position = "left", + className, + activeBaseRegex, + primaryItems, + otherItems = [], + otherLabel = "OTHER", +}) => { + const location = useLocation(); + const [open, setOpen] = useState(false); + + // smooth close on tab-switch / pointer move + const closeTimerRef = useRef(null); + const clearCloseTimer = () => { + if (closeTimerRef.current) { + window.clearTimeout(closeTimerRef.current); + closeTimerRef.current = null; + } + }; + + const announceOpen = () => { + window.dispatchEvent(new CustomEvent(EVENT_NAME, { detail: { menuId } })); + }; + + const openNow = () => { + clearCloseTimer(); + setOpen(true); + announceOpen(); + }; + + const closeSoon = () => { + clearCloseTimer(); + closeTimerRef.current = window.setTimeout(() => setOpen(false), 120); + }; + + const closeNow = () => { + clearCloseTimer(); + setOpen(false); + }; + + // Close this menu when another opens + useEffect(() => { + const handler = (e: Event) => { + const ev = e as CustomEvent<{ menuId: string }>; + if (ev?.detail?.menuId && ev.detail.menuId !== menuId) setOpen(false); + }; + window.addEventListener(EVENT_NAME, handler); + return () => window.removeEventListener(EVENT_NAME, handler); + }, [menuId]); + + // ESC closes + useEffect(() => { + if (!open) return; + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape") setOpen(false); + }; + window.addEventListener("keydown", onKeyDown); + return () => window.removeEventListener("keydown", onKeyDown); + }, [open]); + + const isTabRouteActive = + activeBaseRegex !== undefined && + new RegExp(activeBaseRegex).test(location.pathname); + + const underlineActive = isTabRouteActive || open; + + const isItemActive = (item: MegaMenuItem) => { + if (item.activeBaseRegex) + return new RegExp(item.activeBaseRegex).test(location.pathname); + const base = useBaseUrl(item.href); + return location.pathname.startsWith(base); + }; + + return ( + <> +
+ +
+ +
+
+
+ {/* LEFT: Primary cards */} +
+ {primaryItems.map((item) => { + const Icon = item.icon ? sidebarIconMap[item.icon] : null; + const active = isItemActive(item); + + return ( + +
+ {Icon && ( +
+ + ); + })} +
+ + {/* RIGHT: Other list */} + {otherItems.length > 0 && ( +
+
{otherLabel}
+
+ {otherItems.map((item) => { + const Icon = item.icon ? sidebarIconMap[item.icon] : null; + const active = isItemActive(item); + + return ( + + {Icon && ( +
+
+ )} +
+
+
+ + ); +}; + +export default MegaMenuNavbarItem; diff --git a/website/src/components/Navbar/MegaMenuNavbarItem/styles.module.css b/website/src/components/Navbar/MegaMenuNavbarItem/styles.module.css new file mode 100644 index 000000000..6aa0aaf70 --- /dev/null +++ b/website/src/components/Navbar/MegaMenuNavbarItem/styles.module.css @@ -0,0 +1,158 @@ +.megaItem { + position: relative; +} + +.trigger { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.25rem 0; + background: none; + border: none; + cursor: pointer; + font: inherit; + border-bottom: 2px solid transparent; +} + +.megaItemActive .trigger { + color: var(--text-link); + border-bottom-color: var(--text-link); +} + +.chevron { + width: 14px; + height: 14px; + color: var(--text-secondary); + transition: transform 150ms ease, color 150ms ease; +} +.megaItemActive .chevron { + color: var(--text-link); +} + +.panelWrapper { + position: fixed; + left: 0; + right: 0; + top: var(--ifm-navbar-height); + z-index: 200; + + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 160ms ease, visibility 160ms ease; +} + +.panelWrapperOpen { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +.panel { + width: 100%; + background: var(--surface-02); + border-top: 1px solid var(--border-subtle); + padding: 1rem; +} + +.layout { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + align-items: start; +} + +.primaryCol { + display: grid; +} + +.primaryCard { + display: block; + text-decoration: none; + border-radius: 0.5rem; + transition: background 150ms ease, border-color 150ms ease; +} + +.primaryCard:hover, +.primaryCard:focus { + text-decoration: none; + background: var(--hover); +} + +.primaryInner { + display: flex; + gap: 0.85rem; + align-items: center; + padding: 1rem; +} + +.primaryIcon { + width: 56px; + height: 56px; + flex: 0 0 auto; +} + +.primaryTitle { + font-weight: 700; + font-size: 1.125rem; + color: var(--text-primary); + line-height: 1.4; +} + +.primaryDesc { + margin-top: 0.25rem; + font-size: 0.85rem; + color: var(--text-secondary); + line-height: 1.7; +} + +.otherLabel { + font-size: 1.125rem; + font-weight: 700; + color: var(--text-tertiary); +} + +.otherList { + display: grid; +} + +.otherItem { + display: inline-flex; + align-items: center; + gap: 0.5rem; + text-decoration: none; + color: var(--text-primary); + padding: 0.5rem 0; +} + +.otherItem:hover, +.otherItem:focus { + text-decoration: none; +} + +.otherIcon { + width: 24px; + height: 24px; + color: var(--text-primary); +} + +.otherTitle { + font-weight: 700; + font-size: 1.125rem; +} + +.primaryCard:hover .primaryIcon, +.primaryCard:hover .primaryTitle, +.primaryCard:hover .primaryDesc, +.otherItem:hover .otherIcon, +.otherItem:hover .otherTitle { + color: var(--text-link); +} + +.cardActive .primaryIcon, +.cardActive .primaryTitle, +.cardActive .primaryDesc, +.cardActive .otherIcon, +.cardActive .otherTitle { + color: var(--text-link); +} diff --git a/website/src/css/customTheme.css b/website/src/css/customTheme.css index 1820bfcb6..446713350 100644 --- a/website/src/css/customTheme.css +++ b/website/src/css/customTheme.css @@ -268,114 +268,18 @@ ul.dropdown__menu { padding-right: 1rem; } -/* Add icon next to the menus */ -.category-getting-started > div > a:before { - content: url("/svg/icon-sidebar-rocket.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-dapp > div > a:before { - content: url("/svg/icon-sidebar-tutorial.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-script > div > a:before { - content: url("/svg/icon-sidebar-script.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-tool > div > a:before { - content: url("/svg/icon-sidebar-tool.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-integrate-wallets > div > a:before { - content: url("/svg/icon-sidebar-wallet.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-node > div > a:before { - content: url("/svg/icon-sidebar-node.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-ecosystem-scripts > div > a:before { - content: url("/svg/icon-sidebar-common-script.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-molecule > div > a:before { - content: url("/svg/icon-sidebar-molecule.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-howto > div > a:before { - content: url("/svg/icon-sidebar-howto.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-mining > div > a:before { - content: url("/svg/icon-sidebar-mining.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-history-hardfork > div > a:before { - content: url("/svg/icon-sidebar-history.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-ckb-fundamentals > div > a:before { - content: url("/svg/icon-sidebar-concept.svg"); - margin-right: 0.5rem; +/* Customize sidebar icons next to category names */ +.sidebarIcon { width: 1.125rem; height: 1.125rem; -} -.category-core-structures > div > a:before { - content: url("/svg/icon-sidebar-structure.svg"); margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-token-standards > div > a:before { - content: url("/svg/icon-sidebar-token.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-ecosystem > div > a:before { - content: url("/svg/icon-sidebar-ecosystem.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-resources > div > a:before { - content: url("/svg/icon-sidebar-resource.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; -} -.category-rust > div > a:before { - content: url("/svg/icon-sidebar-script.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; + flex-shrink: 0; + color: var(--text-tertiary); } -.category-js > div > a:before { - content: url("/svg/icon-sidebar-script.svg"); - margin-right: 0.5rem; - width: 1.125rem; - height: 1.125rem; + +.sidebarCategoryLabelWithIcon { + display: inline-flex; + align-items: center; } /* Footer */ diff --git a/website/src/icons/index.ts b/website/src/icons/index.ts new file mode 100644 index 000000000..f2a5cee90 --- /dev/null +++ b/website/src/icons/index.ts @@ -0,0 +1,71 @@ +import CommonScript from "/svg/icon-sidebar-common-script.svg"; +import Concept from "/svg/icon-sidebar-concept.svg"; +import Ecosystem from "/svg/icon-sidebar-ecosystem.svg"; +import History from "/svg/icon-sidebar-history.svg"; +import HowTo from "/svg/icon-sidebar-howto.svg"; +import Mining from "/svg/icon-sidebar-mining.svg"; +import Molecule from "/svg/icon-sidebar-molecule.svg"; +import Node from "/svg/icon-sidebar-node.svg"; +import Resource from "/svg/icon-sidebar-resource.svg"; +import Rocket from "/svg/icon-sidebar-rocket.svg"; +import Rpc from "/svg/icon-sidebar-rpc.svg"; +import Script from "/svg/icon-sidebar-script.svg"; +import Structure from "/svg/icon-sidebar-structure.svg"; +import Token from "/svg/icon-sidebar-token.svg"; +import Tool from "/svg/icon-sidebar-tool.svg"; +import Tutorial from "/svg/icon-sidebar-tutorial.svg"; +import Wallet from "/svg/icon-sidebar-wallet.svg"; +import Project from "/svg/icon-sidebar-project.svg"; +import Contribution from "/svg/icon-sidebar-contribution.svg"; +import Rust from "/svg/icon-sidebar-rust.svg"; +import JS from "/svg/icon-sidebar-js.svg"; +import Organization from "/svg/icon-sidebar-organization.svg"; +import SquareRocket from "/svg/square-rocket.svg"; +import SquareDapp from "/svg/square-dapp.svg"; +import SquareScript from "/svg/square-script.svg"; +import SquareFeature from "/svg/square-feature.svg"; +import SquareConcept from "/svg/square-concept.svg"; +import SquareNodes from "/svg/square-nodes.svg"; +import SquareMine from "/svg/square-mine.svg"; +import SquareProject from "/svg/square-project.svg"; +import SquareHistory from "/svg/square-history.svg"; +import SquareResource from "/svg/square-resource.svg"; +import SquareStructure from "/svg/square-structure.svg"; + +export const sidebarIconMap = { + commonScript: CommonScript, + concept: Concept, + ecosystem: Ecosystem, + history: History, + howto: HowTo, + mining: Mining, + molecule: Molecule, + node: Node, + resource: Resource, + rocket: Rocket, + rpc: Rpc, + script: Script, + structure: Structure, + token: Token, + tool: Tool, + tutorial: Tutorial, + wallet: Wallet, + project: Project, + contribution: Contribution, + rust: Rust, + js: JS, + organization: Organization, + squareRocket: SquareRocket, + squareDapp: SquareDapp, + squareScript: SquareScript, + squareFeature: SquareFeature, + squareConcept: SquareConcept, + squareNodes: SquareNodes, + squareMine: SquareMine, + squareProject: SquareProject, + squareHistory: SquareHistory, + squareResource: SquareResource, + squareStructure: SquareStructure, +}; + +export type SidebarIconName = keyof typeof sidebarIconMap; diff --git a/website/src/theme/DocSidebarItem/Category/index.tsx b/website/src/theme/DocSidebarItem/Category/index.tsx new file mode 100644 index 000000000..6e47dce29 --- /dev/null +++ b/website/src/theme/DocSidebarItem/Category/index.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import OriginalCategory from "@theme-original/DocSidebarItem/Category"; +import type { Props } from "@theme/DocSidebarItem/Category"; +import { sidebarIconMap, SidebarIconName } from "../../../icons"; + +export default function DocSidebarItemCategoryWrapper(props: Props) { + const iconKey = props.item.customProps?.icon as SidebarIconName | undefined; + const Icon = iconKey ? sidebarIconMap[iconKey] : null; + + // If no icon, fall back to the original behavior + if (!Icon) { + return ; + } + + const newItem = { + ...props.item, + label: ( + + + {props.item.label} + + ), + }; + + return ; +} diff --git a/website/src/theme/NavbarItem/ComponentTypes/index.ts b/website/src/theme/NavbarItem/ComponentTypes/index.ts new file mode 100644 index 000000000..b218b0509 --- /dev/null +++ b/website/src/theme/NavbarItem/ComponentTypes/index.ts @@ -0,0 +1,10 @@ +import type { ComponentTypesObject } from "@theme/NavbarItem/ComponentTypes"; +import ComponentTypes from "@theme-original/NavbarItem/ComponentTypes"; +import MegaMenuNavbarItem from "@site/src/components/Navbar/MegaMenuNavbarItem"; + +const customTypes: ComponentTypesObject = { + ...ComponentTypes, + "custom-megaMenu": MegaMenuNavbarItem, +}; + +export default customTypes; diff --git a/website/static/svg/icon-chevron-down.svg b/website/static/svg/icon-chevron-down.svg new file mode 100644 index 000000000..66a28335e --- /dev/null +++ b/website/static/svg/icon-chevron-down.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/static/svg/icon-sidebar-common-script.svg b/website/static/svg/icon-sidebar-common-script.svg index 3a0c9551c..e36fc71e9 100644 --- a/website/static/svg/icon-sidebar-common-script.svg +++ b/website/static/svg/icon-sidebar-common-script.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-concept.svg b/website/static/svg/icon-sidebar-concept.svg index 6fb2fbf75..2b7dc19fc 100644 --- a/website/static/svg/icon-sidebar-concept.svg +++ b/website/static/svg/icon-sidebar-concept.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-contribution.svg b/website/static/svg/icon-sidebar-contribution.svg new file mode 100644 index 000000000..b2df9d86f --- /dev/null +++ b/website/static/svg/icon-sidebar-contribution.svg @@ -0,0 +1,4 @@ + + + + diff --git a/website/static/svg/icon-sidebar-ecosystem.svg b/website/static/svg/icon-sidebar-ecosystem.svg index cd259a738..3a2cd26a8 100644 --- a/website/static/svg/icon-sidebar-ecosystem.svg +++ b/website/static/svg/icon-sidebar-ecosystem.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-feature.svg b/website/static/svg/icon-sidebar-feature.svg new file mode 100644 index 000000000..3a9d44b94 --- /dev/null +++ b/website/static/svg/icon-sidebar-feature.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/static/svg/icon-sidebar-history.svg b/website/static/svg/icon-sidebar-history.svg index d890bceae..ab349d19f 100644 --- a/website/static/svg/icon-sidebar-history.svg +++ b/website/static/svg/icon-sidebar-history.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-howto.svg b/website/static/svg/icon-sidebar-howto.svg index 5cf5ff8dd..6219fcd30 100644 --- a/website/static/svg/icon-sidebar-howto.svg +++ b/website/static/svg/icon-sidebar-howto.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/website/static/svg/icon-sidebar-js.svg b/website/static/svg/icon-sidebar-js.svg new file mode 100644 index 000000000..ca7f983f0 --- /dev/null +++ b/website/static/svg/icon-sidebar-js.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/website/static/svg/icon-sidebar-mining.svg b/website/static/svg/icon-sidebar-mining.svg index 9d23ca8bd..a048421e8 100644 --- a/website/static/svg/icon-sidebar-mining.svg +++ b/website/static/svg/icon-sidebar-mining.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-molecule.svg b/website/static/svg/icon-sidebar-molecule.svg index 8d35d0c2f..d8297bc7a 100644 --- a/website/static/svg/icon-sidebar-molecule.svg +++ b/website/static/svg/icon-sidebar-molecule.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-node.svg b/website/static/svg/icon-sidebar-node.svg index 672f51458..c3b2b5849 100644 --- a/website/static/svg/icon-sidebar-node.svg +++ b/website/static/svg/icon-sidebar-node.svg @@ -1,7 +1,7 @@ - - - - - + + + + + diff --git a/website/static/svg/icon-sidebar-organization.svg b/website/static/svg/icon-sidebar-organization.svg new file mode 100644 index 000000000..5a7435432 --- /dev/null +++ b/website/static/svg/icon-sidebar-organization.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/static/svg/icon-sidebar-project.svg b/website/static/svg/icon-sidebar-project.svg new file mode 100644 index 000000000..36163366e --- /dev/null +++ b/website/static/svg/icon-sidebar-project.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/static/svg/icon-sidebar-resource.svg b/website/static/svg/icon-sidebar-resource.svg index 90fe75e09..fd3e49bbd 100644 --- a/website/static/svg/icon-sidebar-resource.svg +++ b/website/static/svg/icon-sidebar-resource.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-rocket.svg b/website/static/svg/icon-sidebar-rocket.svg index 8a178848b..e32862629 100644 --- a/website/static/svg/icon-sidebar-rocket.svg +++ b/website/static/svg/icon-sidebar-rocket.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-rpc.svg b/website/static/svg/icon-sidebar-rpc.svg index 2def9ae05..56a261e07 100644 --- a/website/static/svg/icon-sidebar-rpc.svg +++ b/website/static/svg/icon-sidebar-rpc.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-rust.svg b/website/static/svg/icon-sidebar-rust.svg new file mode 100644 index 000000000..1b294a022 --- /dev/null +++ b/website/static/svg/icon-sidebar-rust.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/static/svg/icon-sidebar-script.svg b/website/static/svg/icon-sidebar-script.svg index 6b080a340..5bffee89f 100644 --- a/website/static/svg/icon-sidebar-script.svg +++ b/website/static/svg/icon-sidebar-script.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-structure.svg b/website/static/svg/icon-sidebar-structure.svg index d0b09f571..2b59b03d9 100644 --- a/website/static/svg/icon-sidebar-structure.svg +++ b/website/static/svg/icon-sidebar-structure.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-token.svg b/website/static/svg/icon-sidebar-token.svg index 979999d3e..41dc3d079 100644 --- a/website/static/svg/icon-sidebar-token.svg +++ b/website/static/svg/icon-sidebar-token.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/website/static/svg/icon-sidebar-tool.svg b/website/static/svg/icon-sidebar-tool.svg index 653a50852..f6d9f4f17 100644 --- a/website/static/svg/icon-sidebar-tool.svg +++ b/website/static/svg/icon-sidebar-tool.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-tutorial.svg b/website/static/svg/icon-sidebar-tutorial.svg index 8d38522cc..cbc45d2e7 100644 --- a/website/static/svg/icon-sidebar-tutorial.svg +++ b/website/static/svg/icon-sidebar-tutorial.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/icon-sidebar-wallet.svg b/website/static/svg/icon-sidebar-wallet.svg index cdf40d361..f94e028fa 100644 --- a/website/static/svg/icon-sidebar-wallet.svg +++ b/website/static/svg/icon-sidebar-wallet.svg @@ -1,3 +1,3 @@ - + diff --git a/website/static/svg/square-concept.svg b/website/static/svg/square-concept.svg new file mode 100644 index 000000000..d5fa1fa41 --- /dev/null +++ b/website/static/svg/square-concept.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-feature.svg b/website/static/svg/square-feature.svg new file mode 100644 index 000000000..a5fcec867 --- /dev/null +++ b/website/static/svg/square-feature.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-history.svg b/website/static/svg/square-history.svg new file mode 100644 index 000000000..37cff32a0 --- /dev/null +++ b/website/static/svg/square-history.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-mine.svg b/website/static/svg/square-mine.svg new file mode 100644 index 000000000..b214bc99d --- /dev/null +++ b/website/static/svg/square-mine.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-resource.svg b/website/static/svg/square-resource.svg new file mode 100644 index 000000000..51803e656 --- /dev/null +++ b/website/static/svg/square-resource.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/website/static/svg/square-structure.svg b/website/static/svg/square-structure.svg new file mode 100644 index 000000000..afbca0410 --- /dev/null +++ b/website/static/svg/square-structure.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + From ddf7e0bf8e8e175e1d456533910926829cb1327f Mon Sep 17 00:00:00 2001 From: Yuqi Date: Tue, 16 Dec 2025 16:27:58 +0800 Subject: [PATCH 14/20] feat: update ckb feature related --- .../assets-token-standards/assets-overview.md | 24 ++++++++++++++ .../economics.md | 0 .../rgbpp.md | 0 .../spore-protocol.md | 0 .../xudt.md | 0 website/docs/dapp/create-dob.mdx | 4 +-- website/docs/dapp/create-token.mdx | 4 +-- .../docs/tech-explanation/assets-overview.md | 24 -------------- website/docs/tech-explanation/cell-model.md | 2 +- website/docs/tech-explanation/glossary.md | 2 +- website/docusaurus.config.js | 23 +++++++------ website/sidebars.js | 33 +++++++++++-------- website/src/components/Tooltip/key-terms.json | 2 +- website/src/icons/index.ts | 2 ++ 14 files changed, 65 insertions(+), 55 deletions(-) create mode 100644 website/docs/assets-token-standards/assets-overview.md rename website/docs/{tech-explanation => assets-token-standards}/economics.md (100%) rename website/docs/{tech-explanation => assets-token-standards}/rgbpp.md (100%) rename website/docs/{tech-explanation => assets-token-standards}/spore-protocol.md (100%) rename website/docs/{tech-explanation => assets-token-standards}/xudt.md (100%) delete mode 100644 website/docs/tech-explanation/assets-overview.md diff --git a/website/docs/assets-token-standards/assets-overview.md b/website/docs/assets-token-standards/assets-overview.md new file mode 100644 index 000000000..2acedcc60 --- /dev/null +++ b/website/docs/assets-token-standards/assets-overview.md @@ -0,0 +1,24 @@ +--- +id: assets-overview +title: Assets & Token Standards on Nervos +--- + +Nervos CKB uses [Cell Model](/docs/tech-explanation/cell-model), an evolution of Bitcoin’s UTXO model, where all digital assets (fungible, non-fungible tokens, collectibles) are represented as immutable Cells exclusively owned by users. Each Cell contains ownership rules enforced by [Scripts](/docs/tech-explanation/script), ensuring that assets comply with protocol rules during transactions while remaining under the sole control of their owners. + +## What Counts as an On-Chain Asset? + +Within this framework, any token or digital object represented with Cell—and capable of being owned, transferred, or redeemed by users—is considered a true on-chain digital asset. These assets include: + +- Native tokens (CKBytes) +- User-defined tokens (sUDTs, xUDTs) +- On-chain digital objects (DOBs via Spore Protocol) +- Assets validated via RGB++ protocol linking Bitcoin and Nervos CKB + +## Overview of Token Standards + +| Asset | Type | Equivalent | Description | Protocol | +| ------------------------------------------------------ | ---------------------------------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [CKByte (CKB)](/docs/assets-token-standards/economics) | Native | / | Native utility and governance token | Native | +| [xUDT Tokens](/docs/assets-token-standards/xudt) | User-defined | ERC-20 | Extensive user-defined fungible tokens | xUDT | +| [Spore](/docs/assets-token-standards/spore-protocol) | Digital Object (DOB) | ERC-721, Ordinals | Unique digital objects with redeemable intrinsic value, true on-chain ownership, privacy, and multi-content support | Spore Protocol | +| [RGB++](/docs/assets-token-standards/rgbpp) | [Isomorphically bound to Bitcoin](/docs/assets-token-standards/rgbpp#isomorphic-binding) | / | Enables bridgeless cross-chain asset issuance and interoperability between Bitcoin and Nervos CKB through isomorphic UTXO binding | RGB++ Protocol | diff --git a/website/docs/tech-explanation/economics.md b/website/docs/assets-token-standards/economics.md similarity index 100% rename from website/docs/tech-explanation/economics.md rename to website/docs/assets-token-standards/economics.md diff --git a/website/docs/tech-explanation/rgbpp.md b/website/docs/assets-token-standards/rgbpp.md similarity index 100% rename from website/docs/tech-explanation/rgbpp.md rename to website/docs/assets-token-standards/rgbpp.md diff --git a/website/docs/tech-explanation/spore-protocol.md b/website/docs/assets-token-standards/spore-protocol.md similarity index 100% rename from website/docs/tech-explanation/spore-protocol.md rename to website/docs/assets-token-standards/spore-protocol.md diff --git a/website/docs/tech-explanation/xudt.md b/website/docs/assets-token-standards/xudt.md similarity index 100% rename from website/docs/tech-explanation/xudt.md rename to website/docs/assets-token-standards/xudt.md diff --git a/website/docs/dapp/create-dob.mdx b/website/docs/dapp/create-dob.mdx index f1eaefda7..29877ff64 100644 --- a/website/docs/dapp/create-dob.mdx +++ b/website/docs/dapp/create-dob.mdx @@ -17,7 +17,7 @@ import ExampleLink from "@components/ExampleLink"; ## Tutorial Overview -[Spore](/docs/tech-explanation/spore-protocol) is an on-chain digital object (DOB) protocol backed by CKB. An “on-chain” asset refers to a digital asset with its data directly encoded on the blockchain. A Spore Cell can hold any type of asset users want to store on-chain. The data structure for a Spore Cell is as follows: +[Spore](/docs/assets-token-standards/spore-protocol) is an on-chain digital object (DOB) protocol backed by CKB. An “on-chain” asset refers to a digital asset with its data directly encoded on the blockchain. A Spore Cell can hold any type of asset users want to store on-chain. The data structure for a Spore Cell is as follows: ```js data: @@ -175,7 +175,7 @@ By following this tutorial this far, you have mastered how digital-object works ## Additional Resources -- [Spore Protocol High-Level Explanation](/docs/tech-explanation/spore-protocol) +- [Spore Protocol High-Level Explanation](/docs/assets-token-standards/spore-protocol) - [Spore Docs](https://docs.spore.pro/) - CKB transaction structure: [RFC-0022-transaction-structure](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md) - CKB data structure basics: [RFC-0019-data-structure](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md) diff --git a/website/docs/dapp/create-token.mdx b/website/docs/dapp/create-token.mdx index 3f68f7a2d..c8194ceef 100644 --- a/website/docs/dapp/create-token.mdx +++ b/website/docs/dapp/create-token.mdx @@ -19,7 +19,7 @@ import ExampleLink from "@components/ExampleLink"; Unlike [ERC20(Ethereum)](https://eips.ethereum.org/EIPS/eip-20) and [BRC20(Bitcoin)](https://www.brc-20.io/), CKB uses a unique way to build custom tokens based on its UTXO-like Cell Model. -In CKB, custom tokens are called User-Defined Tokens (UDTs). CKB defines a minimal standard for UDT called [xUDT(extensible UDT)](/docs/tech-explanation/xudt). In this tutorial, you will learn how to issue custom tokens using the pre-deployed `xUDT Script`. +In CKB, custom tokens are called User-Defined Tokens (UDTs). CKB defines a minimal standard for UDT called [xUDT(extensible UDT)](/docs/assets-token-standards/xudt). In this tutorial, you will learn how to issue custom tokens using the pre-deployed `xUDT Script`. Steps to Issue a Custom Token with xUDT: @@ -215,7 +215,7 @@ By following this tutorial this far, you have mastered how custom tokens work on ## Additional Resources -- [xUDT High-Level Explanation](/docs/tech-explanation/xudt) +- [xUDT High-Level Explanation](/docs/assets-token-standards/xudt) - xUDT specs: [RFC-0052-extensible-udt](https://github.com/XuJiandong/rfcs/blob/xudt/rfcs/0052-extensible-udt/0052-extensible-udt.md) - sUDT specs: [RFC-0025-simple-udt](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md) - CKB transaction structure: [RFC-0022-transaction-structure](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md) diff --git a/website/docs/tech-explanation/assets-overview.md b/website/docs/tech-explanation/assets-overview.md deleted file mode 100644 index 8414e38bc..000000000 --- a/website/docs/tech-explanation/assets-overview.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -id: assets-overview -title: Assets & Token Standards on Nervos ---- - -Nervos CKB uses [Cell Model](/docs/tech-explanation/cell-model), an evolution of Bitcoin’s UTXO model, where all digital assets (fungible, non-fungible tokens, collectibles) are represented as immutable Cells exclusively owned by users. Each Cell contains ownership rules enforced by [Scripts](/docs/tech-explanation/script), ensuring that assets comply with protocol rules during transactions while remaining under the sole control of their owners. - -## What Counts as an On-Chain Asset? - -Within this framework, any token or digital object represented with Cell—and capable of being owned, transferred, or redeemed by users—is considered a true on-chain digital asset. These assets include: - -- Native tokens (CKBytes) -- User-defined tokens (sUDTs, xUDTs) -- On-chain digital objects (DOBs via Spore Protocol) -- Assets validated via RGB++ protocol linking Bitcoin and Nervos CKB - -## Overview of Token Standards - -| Asset | Type | Equivalent | Description | Protocol | -| ------------------------------------------------ | ---------------------------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------- | -| [CKByte (CKB)](/docs/tech-explanation/economics) | Native | / | Native utility and governance token | Native | -| [xUDT Tokens](/docs/tech-explanation/xudt) | User-defined | ERC-20 | Extensive user-defined fungible tokens | xUDT | -| [Spore](/docs/tech-explanation/spore-protocol) | Digital Object (DOB) | ERC-721, Ordinals | Unique digital objects with redeemable intrinsic value, true on-chain ownership, privacy, and multi-content support | Spore Protocol | -| [RGB++](/docs/tech-explanation/rgbpp) | [Isomorphically bound to Bitcoin](/docs/tech-explanation/rgbpp#isomorphic-binding) | / | Enables bridgeless cross-chain asset issuance and interoperability between Bitcoin and Nervos CKB through isomorphic UTXO binding | RGB++ Protocol | diff --git a/website/docs/tech-explanation/cell-model.md b/website/docs/tech-explanation/cell-model.md index aa4a49cf0..a46b2714c 100644 --- a/website/docs/tech-explanation/cell-model.md +++ b/website/docs/tech-explanation/cell-model.md @@ -23,7 +23,7 @@ Transactions reflect the state change of Cells, where a group of Live Cells are In Cell Model, all digital assets (e.g., CKBytes, tokens, collectibles) are considered first-class, exclusively owned by their respective owners. While assets must comply with smart contracts rules during transactions, they are inherently owned by the user, not the smart contracts. This ownership structure ensures that only the owner has permission to use the assets, regardless of how the smart contract defines the token. If a contract exploit, attackers would be unable to access the asset, as it remains under the user's control, effectively mitigating the negative impact. -This ownership structure also defines the responsibility for asset upkeep. As assets occupy space on Nervos, the owner are subject to a small recurring upkeep fee, known as **state rent,** which is elaborated in the [Tokenomics](/docs/tech-explanation/economics) section. +This ownership structure also defines the responsibility for asset upkeep. As assets occupy space on Nervos, the owner are subject to a small recurring upkeep fee, known as **state rent,** which is elaborated in the [Tokenomics](/docs/assets-token-standards/economics) section. ## Flexible Transaction Fee Coverage diff --git a/website/docs/tech-explanation/glossary.md b/website/docs/tech-explanation/glossary.md index 7ec8d5b71..f839ca3e6 100644 --- a/website/docs/tech-explanation/glossary.md +++ b/website/docs/tech-explanation/glossary.md @@ -2817,7 +2817,7 @@ A token protocol that maps native Bitcoin UTXOs to Nervos CKB Cells using isomor #### See Also - [RGB](https://rgb.tech/) -- [RGB++ Protocol](/docs/tech-explanation/rgbpp) +- [RGB++ Protocol](/docs/assets-token-standards/rgbpp) ### RISC-V diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 957082e78..84b841211 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -161,7 +161,7 @@ const config = { }, { from: "/docs/basics/concepts/economics", - to: "/docs/tech-explanation/economics", + to: "/docs/assets-token-standards/economics", }, { from: "/docs/basics/glossary/", @@ -318,25 +318,28 @@ const config = { label: "Learn", position: "left", menuId: "learn", - activeBaseRegex: "/(tech-explanation)/", + activeBaseRegex: + "/(tech-explanation|ckb-features|assets-token-standards)/", primaryItems: [ { title: "What Makes CKB Unique", description: "Design choices behind CKB", - href: "/docs/tech-explanation/nervos-blockchain", + href: "/docs/ckb-features/extreme-decentralization", icon: "squareFeature", }, { title: "CKB Fundamentals", - description: "Step-by-step examples for building on CKB", + description: "Core concepts of how CKB works", href: "/docs/tech-explanation/nervos-blockchain", icon: "squareConcept", }, { title: "Core Structures", - description: "Implement smart-contract logic on CKB", + description: "Detailed breakdown of core components", href: "/docs/tech-explanation/cell", icon: "squareStructure", + activeBaseRegex: + "/tech-explanation/(cell|script|transaction|block)", }, ], @@ -344,9 +347,9 @@ const config = { otherItems: [ { title: "Assets & Token Standards", - href: "/docs/tech-explanation/assets-overview", + href: "/docs/assets-token-standards/assets-overview", icon: "token", - activeBaseRegex: "/tech-explanation/(assets)", + activeBaseRegex: "/assets-token-standards/", }, { title: "Glossary", @@ -361,18 +364,18 @@ const config = { label: "Network", position: "left", menuId: "network", - activeBaseRegex: "/(node)/(mining)", + activeBaseRegex: "/(node|mining)/", primaryItems: [ { title: "Run a Node", - description: "Design choices behind CKB", + description: "Install, configure, and operate CKB nodes", href: "/docs/node/node-overview", icon: "squareNodes", activeBaseRegex: "/node/", }, { title: "Mining", - description: "Step-by-step examples for building on CKB", + description: "Mining mechanics, tools, and rewards", href: "/docs/mining/guide", icon: "squareMine", activeBaseRegex: "/mining/", diff --git a/website/sidebars.js b/website/sidebars.js index 4a2e6ced4..b0ff82f81 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -299,6 +299,9 @@ export default { label: "What makes CKB unique", className: "category-ckb-features", collapsible: false, + customProps: { + icon: "feature", + }, items: [ "ckb-features/extreme-decentralization", "ckb-features/native-quantum-resistance", @@ -390,29 +393,31 @@ export default { }, { type: "category", - label: "Assets & Token Standards", - className: "category-token-standards", + label: "Resources", + className: "category-resources", collapsible: false, customProps: { - icon: "token", + icon: "resource", }, - items: [ - "tech-explanation/assets-overview", - "tech-explanation/economics", - "tech-explanation/xudt", - "tech-explanation/spore-protocol", - "tech-explanation/rgbpp", - ], + items: ["tech-explanation/glossary"], }, + ], + "Assets & Token": [ { type: "category", - label: "Resources", - className: "category-resources", + label: "Assets & Token Standards", + className: "category-token-standards", collapsible: false, customProps: { - icon: "resource", + icon: "token", }, - items: ["tech-explanation/glossary"], + items: [ + "assets-token-standards/assets-overview", + "assets-token-standards/economics", + "assets-token-standards/xudt", + "assets-token-standards/spore-protocol", + "assets-token-standards/rgbpp", + ], }, ], Ecosystem: [ diff --git a/website/src/components/Tooltip/key-terms.json b/website/src/components/Tooltip/key-terms.json index 76020a856..a1a9dbc51 100644 --- a/website/src/components/Tooltip/key-terms.json +++ b/website/src/components/Tooltip/key-terms.json @@ -1001,7 +1001,7 @@ }, "xudt": { "content": "An extended UDT standard upon sUDT (Simple UDT) to accommodate additional functionalities, including regulatory compliance.", - "link": "/docs/tech-explanation/xudt" + "link": "/docs/assets-token-standards/xudt" }, "zk-snark": { "content": "A form of cryptographic proof, that when used in cryptocurrencies, allows for privacy features which do not reveal the amounts or participants in transactions.", diff --git a/website/src/icons/index.ts b/website/src/icons/index.ts index f2a5cee90..f464ecdb1 100644 --- a/website/src/icons/index.ts +++ b/website/src/icons/index.ts @@ -20,6 +20,7 @@ import Contribution from "/svg/icon-sidebar-contribution.svg"; import Rust from "/svg/icon-sidebar-rust.svg"; import JS from "/svg/icon-sidebar-js.svg"; import Organization from "/svg/icon-sidebar-organization.svg"; +import Feature from "/svg/icon-sidebar-feature.svg"; import SquareRocket from "/svg/square-rocket.svg"; import SquareDapp from "/svg/square-dapp.svg"; import SquareScript from "/svg/square-script.svg"; @@ -55,6 +56,7 @@ export const sidebarIconMap = { rust: Rust, js: JS, organization: Organization, + feature: Feature, squareRocket: SquareRocket, squareDapp: SquareDapp, squareScript: SquareScript, From 6922b028680f4c15398750748980dc032a46209d Mon Sep 17 00:00:00 2001 From: Yuqi Date: Tue, 16 Dec 2025 22:10:31 +0800 Subject: [PATCH 15/20] feat: update mobile navbar & ckb-fundamentals --- .../assets-token-standards/assets-overview.md | 2 +- .../assets-token-standards/spore-protocol.md | 4 +- .../ckb-features/extreme-decentralization.md | 2 +- .../cell-model.md | 0 .../ckb-address.mdx | 0 .../ckb-vm.md | 0 .../ckb-vs-btc.mdx | 4 +- .../ckbhash.md | 0 .../consensus.md | 0 .../nervos-blockchain.md | 0 .../docs/getting-started/how-ckb-works.mdx | 4 +- .../how-tos/how-to-calculate-code-hash.mdx | 2 +- .../how-tos/how-to-calculate-script-hash.mdx | 2 +- .../docs/how-tos/how-to-calculate-tx-hash.mdx | 2 +- .../integrate-wallets/intro-to-wallets.mdx | 2 +- website/docs/node/run-light-client-node.mdx | 2 +- website/docs/sdk-and-devtool/go.mdx | 2 +- website/docs/sdk-and-devtool/java.mdx | 2 +- website/docs/sdk-and-devtool/rust.mdx | 2 +- .../docs/tech-explanation/data-type-diff.md | 2 +- website/docs/tech-explanation/glossary.md | 4 +- website/docs/tech-explanation/outputs-data.md | 2 +- website/docusaurus.config.js | 17 +- website/sidebars.js | 14 +- website/src/components/Tooltip/key-terms.json | 10 +- website/src/css/customTheme.css | 4 + website/src/pages/homeContents.tsx | 2 +- .../MobileSidebar/PrimaryMenu/index.tsx | 259 ++++++++++++++++++ .../PrimaryMenu/styles.module.css | 174 ++++++++++++ .../theme/NotFound/Content/linkContents.ts | 2 +- 30 files changed, 477 insertions(+), 45 deletions(-) rename website/docs/{tech-explanation => ckb-fundamentals}/cell-model.md (100%) rename website/docs/{tech-explanation => ckb-fundamentals}/ckb-address.mdx (100%) rename website/docs/{tech-explanation => ckb-fundamentals}/ckb-vm.md (100%) rename website/docs/{tech-explanation => ckb-fundamentals}/ckb-vs-btc.mdx (99%) rename website/docs/{tech-explanation => ckb-fundamentals}/ckbhash.md (100%) rename website/docs/{tech-explanation => ckb-fundamentals}/consensus.md (100%) rename website/docs/{tech-explanation => ckb-fundamentals}/nervos-blockchain.md (100%) create mode 100644 website/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx create mode 100644 website/src/theme/Navbar/MobileSidebar/PrimaryMenu/styles.module.css diff --git a/website/docs/assets-token-standards/assets-overview.md b/website/docs/assets-token-standards/assets-overview.md index 2acedcc60..ffa128ead 100644 --- a/website/docs/assets-token-standards/assets-overview.md +++ b/website/docs/assets-token-standards/assets-overview.md @@ -3,7 +3,7 @@ id: assets-overview title: Assets & Token Standards on Nervos --- -Nervos CKB uses [Cell Model](/docs/tech-explanation/cell-model), an evolution of Bitcoin’s UTXO model, where all digital assets (fungible, non-fungible tokens, collectibles) are represented as immutable Cells exclusively owned by users. Each Cell contains ownership rules enforced by [Scripts](/docs/tech-explanation/script), ensuring that assets comply with protocol rules during transactions while remaining under the sole control of their owners. +Nervos CKB uses [Cell Model](/docs/ckb-fundamentals/cell-model), an evolution of Bitcoin’s UTXO model, where all digital assets (fungible, non-fungible tokens, collectibles) are represented as immutable Cells exclusively owned by users. Each Cell contains ownership rules enforced by [Scripts](/docs/tech-explanation/script), ensuring that assets comply with protocol rules during transactions while remaining under the sole control of their owners. ## What Counts as an On-Chain Asset? diff --git a/website/docs/assets-token-standards/spore-protocol.md b/website/docs/assets-token-standards/spore-protocol.md index 4f45807ac..f02da46e5 100644 --- a/website/docs/assets-token-standards/spore-protocol.md +++ b/website/docs/assets-token-standards/spore-protocol.md @@ -21,7 +21,7 @@ Spore is comparable to Ethereum’s [ERC-721](https://eips.ethereum.org/EIPS/eip | Features | ERC-721 (Ethereum) | Ordinals (Bitcoin) | Spore Protocol (Nervos CKB) | | ------------------ | --------------------------- | ------------------ | ---------------------------------------------------------- | | Content | Mostly off-chain | On-chain | On-chain | -| Model | Account-based | UTXO | UTXO-based [Cell Model](/docs/tech-explanation/cell-model) | +| Model | Account-based | UTXO | UTXO-based [Cell Model](/docs/ckb-fundamentals/cell-model) | | Privacy | No | Maybe | Yes | | Immutability | Variable | Yes, immutable | Yes, immutable | | Redeemable | No | No | Yes | @@ -44,7 +44,7 @@ Spore is a unique class of digital assets linked to the native currency of the N Spore Protocol offers enhanced privacy and security features that are not inherent in account-based NFT protocols, particularly addressing the challenges faced by NFT holders. -- **Privacy through Cell Model**: Unlike account-based blockchains, where all transactions are tied to a single address, Nervos CKB uses a UTXO-based [Cell Model](/docs/tech-explanation/cell-model), which leverages independent Cells. In this model, each transaction uses a new address — even though it is controlled by the same key — effectively splitting ownership across multiple addresses and making it difficult to link them to a single identity. +- **Privacy through Cell Model**: Unlike account-based blockchains, where all transactions are tied to a single address, Nervos CKB uses a UTXO-based [Cell Model](/docs/ckb-fundamentals/cell-model), which leverages independent Cells. In this model, each transaction uses a new address — even though it is controlled by the same key — effectively splitting ownership across multiple addresses and making it difficult to link them to a single identity. ### Zero-Fee Transfers diff --git a/website/docs/ckb-features/extreme-decentralization.md b/website/docs/ckb-features/extreme-decentralization.md index 3b69c8ebc..5edbaf2a1 100644 --- a/website/docs/ckb-features/extreme-decentralization.md +++ b/website/docs/ckb-features/extreme-decentralization.md @@ -35,7 +35,7 @@ CKB addresses this challenge through three radical design choices: **Sustainable Most blockchains operate as "General Computation Networks" (like a world computer). Users pay a one-time fee to execute a transaction, but the resulting data (state) occupies the network's storage forever at no further cost. This leads to the **"Tragedy of the Commons"**: because storage is effectively free, the state grows indefinitely ([State Explosion](https://medium.com/nervosnetwork/state-explosion-and-the-tragedy-of-the-blockchain-commons-1fbd4837e859)). Eventually, only enterprise-grade hardware can store the chain, forcing regular users to trust third parties. -CKB takes a different approach. It adopts a "General Verification Network" architecture built on the [Cell Model](/docs/tech-explanation/cell-model), where on-chain storage is treated as a scarce resource rather than free space. +CKB takes a different approach. It adopts a "General Verification Network" architecture built on the [Cell Model](/docs/ckb-fundamentals/cell-model), where on-chain storage is treated as a scarce resource rather than free space. - **State as a Scarce Resource:** On-chain state is modeled as a finite resource that must be explicitly accounted for. - **1 CKB = 1 Byte of Storage:** The native token, CKB, represents state capacity; holding 1 CKB entitles the holder to store 1 byte of data on the blockchain. diff --git a/website/docs/tech-explanation/cell-model.md b/website/docs/ckb-fundamentals/cell-model.md similarity index 100% rename from website/docs/tech-explanation/cell-model.md rename to website/docs/ckb-fundamentals/cell-model.md diff --git a/website/docs/tech-explanation/ckb-address.mdx b/website/docs/ckb-fundamentals/ckb-address.mdx similarity index 100% rename from website/docs/tech-explanation/ckb-address.mdx rename to website/docs/ckb-fundamentals/ckb-address.mdx diff --git a/website/docs/tech-explanation/ckb-vm.md b/website/docs/ckb-fundamentals/ckb-vm.md similarity index 100% rename from website/docs/tech-explanation/ckb-vm.md rename to website/docs/ckb-fundamentals/ckb-vm.md diff --git a/website/docs/tech-explanation/ckb-vs-btc.mdx b/website/docs/ckb-fundamentals/ckb-vs-btc.mdx similarity index 99% rename from website/docs/tech-explanation/ckb-vs-btc.mdx rename to website/docs/ckb-fundamentals/ckb-vs-btc.mdx index 744b4afcc..af17e655a 100644 --- a/website/docs/tech-explanation/ckb-vs-btc.mdx +++ b/website/docs/ckb-fundamentals/ckb-vs-btc.mdx @@ -392,7 +392,7 @@ The following are the step-by-step breakdown of the verification process: ## Additional Resources -- [Cell Model](/docs/tech-explanation/cell-model) -- [CKB-VM](/docs/tech-explanation/ckb-vm) +- [Cell Model](/docs/ckb-fundamentals/cell-model) +- [CKB-VM](/docs/ckb-fundamentals/ckb-vm) - [CKB Script](/docs/tech-explanation/script) - [CKB Transaction](/docs/tech-explanation/transaction) diff --git a/website/docs/tech-explanation/ckbhash.md b/website/docs/ckb-fundamentals/ckbhash.md similarity index 100% rename from website/docs/tech-explanation/ckbhash.md rename to website/docs/ckb-fundamentals/ckbhash.md diff --git a/website/docs/tech-explanation/consensus.md b/website/docs/ckb-fundamentals/consensus.md similarity index 100% rename from website/docs/tech-explanation/consensus.md rename to website/docs/ckb-fundamentals/consensus.md diff --git a/website/docs/tech-explanation/nervos-blockchain.md b/website/docs/ckb-fundamentals/nervos-blockchain.md similarity index 100% rename from website/docs/tech-explanation/nervos-blockchain.md rename to website/docs/ckb-fundamentals/nervos-blockchain.md diff --git a/website/docs/getting-started/how-ckb-works.mdx b/website/docs/getting-started/how-ckb-works.mdx index fbd049072..a6c9c5a75 100644 --- a/website/docs/getting-started/how-ckb-works.mdx +++ b/website/docs/getting-started/how-ckb-works.mdx @@ -9,7 +9,7 @@ Whether you’re new to blockchain or have a technical background, this guide wi ## Intro to CKB -Blockchain is a decentralized, immutable ledger that records transactions across a network, enabling interactions without intermediaries. CKB, or Common Knowledge Base, is the foundational layer of the Nervos Network. It operates on [Proof of Work (POW) consensus](/docs/tech-explanation/consensus), where miners solve cryptographic puzzles to secure the network and validate transactions, ensuring strong security and decentralization. +Blockchain is a decentralized, immutable ledger that records transactions across a network, enabling interactions without intermediaries. CKB, or Common Knowledge Base, is the foundational layer of the Nervos Network. It operates on [Proof of Work (POW) consensus](/docs/ckb-fundamentals/consensus), where miners solve cryptographic puzzles to secure the network and validate transactions, ensuring strong security and decentralization. ## How Transaction Works @@ -55,7 +55,7 @@ Cells that have not been consumed are known as Live Cells, and these are availab alt="Transaction broadcasted to the nearest node" /> -4. **Validate**: The receiving node performs several checks to validate your transaction. For more details, you can check out the [verification process](/docs/tech-explanation/ckb-vs-btc#unlocking--verification-process) +4. **Validate**: The receiving node performs several checks to validate your transaction. For more details, you can check out the [verification process](/docs/ckb-fundamentals/ckb-vs-btc#unlocking--verification-process) void; + children: React.ReactNode; +}) { + return ( +
onToggle((e.currentTarget as HTMLDetailsElement).open)} + > + + + {label} + + + + {children} +
+ ); +} + +function PrimaryItem({ + item, + pathname, + onClick, +}: { + item: MegaMenuItem; + pathname: string; + onClick: () => void; +}) { + const Icon = resolveIcon(item.icon); + const active = isActive(pathname, item); + + return ( + + {Icon && } +
+
+ {item.title} +
+ {item.description && ( +
+ {item.description} +
+ )} +
+ + ); +} + +function OtherItem({ + item, + pathname, + onClick, +}: { + item: MegaMenuItem; + pathname: string; + onClick: () => void; +}) { + const Icon = resolveIcon(item.icon); + const active = isActive(pathname, item); + + return ( + + {Icon && } + + {item.title} + + + ); +} + +/* ---------- Main ---------- */ + +export default function NavbarMobilePrimaryMenu(): JSX.Element { + const { navbar } = useThemeConfig() as any; + const menus: MegaMenuNavbarItem[] = (navbar.items ?? []).filter(isMegaMenu); + + const mobileSidebar = useNavbarMobileSidebar(); + const close = () => mobileSidebar.toggle(); + + const { pathname } = useLocation(); + + const [openMap, setOpenMap] = useState>({}); + + useEffect(() => { + const next: Record = {}; + menus.forEach((menu) => { + if (isActive(pathname, menu)) { + next[menu.menuId] = true; + } + }); + setOpenMap((prev) => ({ ...prev, ...next })); + }, [pathname, menus]); + + return ( +
+
+ +
+ + {/* Groups */} +
+ {menus.map((menu) => { + const active = isActive(pathname, menu); + const open = openMap[menu.menuId] ?? false; + + return ( + + setOpenMap((prev) => ({ + ...prev, + [menu.menuId]: next, + })) + } + > +
+ {menu.primaryItems.map((item) => ( + + ))} +
+ + {menu.otherItems?.length ? ( + <> +
+ {menu.otherLabel || "OTHER"} +
+
+ {menu.otherItems.map((item) => ( + + ))} +
+ + ) : null} +
+ ); + })} +
+ + {/* Footer CTA */} +
+ + Get Help from Discord + {"Get Help"} + +
+
+ ); +} diff --git a/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/styles.module.css b/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/styles.module.css new file mode 100644 index 000000000..5e40cb695 --- /dev/null +++ b/website/src/theme/Navbar/MobileSidebar/PrimaryMenu/styles.module.css @@ -0,0 +1,174 @@ +.mobileNav { + display: flex; + flex-direction: column; + height: 100%; +} + +.mobileSearchRow { + width: 100%; +} + +.mobileSearchRow :global(.aa-DetachedSearchButton) { + width: 100% !important; + height: 2.5rem; + border-radius: 999px; + background: transparent; + border: 1px solid var(--dark-border-subtle); + padding: 0 1rem 0 0.5rem; +} +.mobileSearchRow :global(.aa-DetachedSearchButton):hover { + background: var(--dark-hover); +} +.mobileSearchRow :global(.aa-DetachedSearchButtonPlaceholder) { + display: block; +} + +.groups { + padding: 0.5rem 0 0; +} + +.summary { + list-style: none; + cursor: pointer; + padding: 0.5rem 0; + display: flex; + align-items: center; + justify-content: space-between; +} + +.summary::-webkit-details-marker { + display: none; +} + +.summaryLabel { + font-size: 1rem; + font-weight: 700; + color: var(--dark-text-primary); +} + +.chevron { + width: 0.5rem; + height: 0.5rem; + border-right: 1px solid var(--dark-text-secondary); + border-bottom: 1px solid var(--dark-text-secondary); + transform: rotate(45deg); +} + +details[open] .chevron { + transform: rotate(-135deg); +} + +details[open] { + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--dark-border-subtle); +} + +/* Primary items */ +.primaryList { + display: flex; + flex-direction: column; + gap: 0.25rem; +} +.primaryIcon { + width: 2.5rem; + min-width: 2.5rem; + height: 2.5rem; +} + +.primaryItem { + display: flex; + gap: 0.75rem; + align-items: flex-start; + text-decoration: none !important; + padding: 0.5rem 0; + border-radius: 0.5rem; +} + +.primaryItem:hover { + background: var(--dark-hover); +} + +.primaryTitle { + font-size: 1rem; + font-weight: 700; + line-height: 1.4; + color: var(--dark-text-primary); +} + +.primaryDesc { + font-size: 0.75rem; + line-height: 1.7; + color: var(--dark-text-secondary); +} + +/* Other items (within each menu) */ + +.otherLabel { + padding-bottom: 0.5rem; + font-size: 0.75rem; + color: var(--dark-text-tertiary); +} + +.otherList { + display: flex; + flex-direction: column; +} + +.otherItem { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0; + text-decoration: none !important; + border-radius: 0.5rem; + color: var(--dark-text-primary); +} + +.otherItem:hover { + background: var(--dark-hover); +} + +.otherTitle { + font-size: 1rem; + font-weight: 700; + line-height: 1.4; + color: var(--dark-text-primary); +} + +.primaryTitle.activeText { + color: var(--dark-text-link); +} + +.primaryDesc.activeText { + color: var(--dark-text-link); +} + +.otherTitle.activeText { + color: var(--dark-text-link); +} + +.otherItem.activeText { + color: var(--dark-text-link); +} + +/* Bottom CTA */ +.footer { + margin-top: 1rem; +} + +.helpButton { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + height: 2.5rem; + border-radius: 999px; + text-decoration: none !important; + border: 1px solid var(--dark-border-subtle); + color: var(--dark-text-primary) !important; +} + +.helpButton:hover { + background: var(--dark-hover); +} diff --git a/website/src/theme/NotFound/Content/linkContents.ts b/website/src/theme/NotFound/Content/linkContents.ts index e1c68dc24..a953a70db 100644 --- a/website/src/theme/NotFound/Content/linkContents.ts +++ b/website/src/theme/NotFound/Content/linkContents.ts @@ -8,7 +8,7 @@ const suggestedLinks: CardLinks[] = [ { label: "Mining", link: "/docs/mining/guide" }, { label: "Tech Explanation", - link: "/docs/tech-explanation/nervos-blockchain", + link: "/docs/ckb-fundamentals/nervos-blockchain", }, ]; export { suggestedLinks }; From a1f51c31e91eeb3e97632b1f6c07ec4a2b9eafa2 Mon Sep 17 00:00:00 2001 From: Yuqi Date: Fri, 19 Dec 2025 12:08:52 +0800 Subject: [PATCH 16/20] feat: update community tab & gen-term logic --- website/docusaurus.config.js | 52 +++++++++++++++---- website/scripts/generate-key-terms.mjs | 41 ++++++++++----- website/sidebars.js | 20 +++---- .../Navbar/MegaMenuNavbarItem/index.tsx | 26 ++++++++-- .../MegaMenuNavbarItem/styles.module.css | 19 ++++--- website/src/icons/index.ts | 4 ++ website/src/pages/homeContents.tsx | 2 +- .../MobileSidebar/PrimaryMenu/index.tsx | 21 ++++---- .../PrimaryMenu/styles.module.css | 6 +++ .../theme/NotFound/Content/linkContents.ts | 2 +- website/static/svg/icon-sidebar-external.svg | 4 ++ website/static/svg/square-contribution.svg | 23 ++++++++ 12 files changed, 165 insertions(+), 55 deletions(-) create mode 100644 website/static/svg/icon-sidebar-external.svg create mode 100644 website/static/svg/square-contribution.svg diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 244b26dde..4937c127f 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -388,7 +388,7 @@ const config = { label: "Community", position: "left", menuId: "community", - activeBaseRegex: "/(ecosystem)/(history-and-hard-forks)", + activeBaseRegex: "/(ecosystem|history-and-hard-forks)", primaryItems: [ { title: "Projects", @@ -405,21 +405,51 @@ const config = { icon: "squareHistory", activeBaseRegex: "/history-and-hard-forks/", }, - // TODO: Add Resources + { + title: "Contribute", + description: "Ways to participate and support the network", + href: "/docs/ecosystem/contribute", + icon: "squareContribution", + activeBaseRegex: "/ecosystem/contribute", + }, ], - otherLabel: "OTHER", + otherLabel: "RESOURCES", + otherCol: 2, otherItems: [ { - title: "Organizations", - href: "/docs/ecosystem/organizations", - icon: "organization", - activeBaseRegex: "/ecosystem/organizations", + title: "Positioning Paper", + href: "https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0001-positioning/0001-positioning.md", + external: true, }, { - title: "Contribute", - href: "/docs/ecosystem/contribute", - icon: "contribution", - activeBaseRegex: "/ecosystem/contribute", + title: "CKB RFCs", + href: "https://github.com/nervosnetwork/rfcs", + external: true, + }, + { + title: "Fiber Network", + href: "https://www.fiber.world/docs", + external: true, + }, + { + title: "Spore Protocol", + href: "https://docs.spore.pro/", + external: true, + }, + { + title: "CKB Academy", + href: "https://academy.ckb.dev/", + external: true, + }, + { + title: "CKB Cookbook", + href: "https://cookbook.ckbdapps.com/", + external: true, + }, + { + title: "CKB Dev Log", + href: "https://github.com/nervosnetwork/ckb/discussions/categories/dev-log", + external: true, }, ], }, diff --git a/website/scripts/generate-key-terms.mjs b/website/scripts/generate-key-terms.mjs index 34642a54d..a48781fa4 100644 --- a/website/scripts/generate-key-terms.mjs +++ b/website/scripts/generate-key-terms.mjs @@ -15,11 +15,37 @@ const outputPath = path.join( __dirname, "../src/components/Tooltip/key-terms.json" ); -const docsPath = path.join(__dirname, "../docs/tech-explanation"); + +const docSections = [ + { + slug: "tech-explanation", + dir: path.join(__dirname, "../docs/tech-explanation"), + }, + { + slug: "ckb-fundamentals", + dir: path.join(__dirname, "../docs/ckb-fundamentals"), + }, + { + slug: "assets-token-standards", + dir: path.join(__dirname, "../docs/assets-token-standards"), + }, +]; const glossaryContent = fs.readFileSync(glossaryPath, "utf8"); const terms = {}; +function resolveTermLink(normalizedTerm) { + for (const section of docSections) { + const md = path.join(section.dir, `${normalizedTerm}.md`); + const mdx = path.join(section.dir, `${normalizedTerm}.mdx`); + if (fs.existsSync(md) || fs.existsSync(mdx)) { + return `/docs/${section.slug}/${normalizedTerm}`; + } + } + // fallback to glossary anchor (same as before) + return `/docs/tech-explanation/glossary#${normalizedTerm}`; +} + remark() .use(() => (tree) => { let currentTerm = ""; @@ -59,17 +85,8 @@ remark() .toLowerCase() .replace(/[\s_]+/g, "-") .replace(/[()]/g, ""); - const termFilePathMd = path.join(docsPath, `${normalizedTerm}.md`); - const termFilePathMdx = path.join(docsPath, `${normalizedTerm}.mdx`); - if (fs.existsSync(termFilePathMd) || fs.existsSync(termFilePathMdx)) { - terms[ - currentTerm.toLowerCase() - ].link = `/docs/tech-explanation/${normalizedTerm}`; - } else { - terms[ - currentTerm.toLowerCase() - ].link = `/docs/tech-explanation/glossary#${normalizedTerm}`; - } + + terms[currentTerm.toLowerCase()].link = resolveTermLink(normalizedTerm); } }); }) diff --git a/website/sidebars.js b/website/sidebars.js index 8d304a699..523e32767 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -296,7 +296,7 @@ export default { "Tech Explanation": [ { type: "category", - label: "What makes CKB unique", + label: "What Makes CKB Unique", className: "category-ckb-features", collapsible: false, customProps: { @@ -476,8 +476,13 @@ export default { }, { type: "link", - label: "CKB Dev Log", - href: "https://github.com/nervosnetwork/ckb/discussions/categories/dev-log", + label: "Fiber Network", + href: "https://www.fiber.world/docs", + }, + { + type: "link", + label: "Spore Protocol", + href: "https://docs.spore.pro", }, { type: "link", @@ -491,13 +496,8 @@ export default { }, { type: "link", - label: "Fiber network", - href: "https://www.fiber.world/docs", - }, - { - type: "link", - label: "Spore Protocol", - href: "https://docs.spore.pro", + label: "CKB Dev Log", + href: "https://github.com/nervosnetwork/ckb/discussions/categories/dev-log", }, ], }, diff --git a/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx b/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx index b5ba16dec..c4591aaad 100644 --- a/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx +++ b/website/src/components/Navbar/MegaMenuNavbarItem/index.tsx @@ -1,11 +1,8 @@ -// src/components/Navbar/MegaMenuNavbarItem.tsx - import React, { useEffect, useMemo, useRef, useState } from "react"; import clsx from "clsx"; import Link from "@docusaurus/Link"; import { useLocation } from "@docusaurus/router"; import useBaseUrl from "@docusaurus/useBaseUrl"; - import ChevronDown from "/svg/icon-chevron-down.svg"; import { sidebarIconMap, SidebarIconName } from "../../../icons"; import styles from "./styles.module.css"; @@ -14,6 +11,7 @@ export type MegaMenuItem = { title: string; description?: string; href: string; + external?: boolean; icon?: SidebarIconName; activeBaseRegex?: string; }; @@ -27,6 +25,7 @@ export type MegaMenuNavbarItemProps = { primaryItems: MegaMenuItem[]; otherItems?: MegaMenuItem[]; otherLabel?: string; + otherCol?: 1 | 2; }; const EVENT_NAME = "nervos:megamenu-open"; @@ -39,6 +38,7 @@ const MegaMenuNavbarItem: React.FC = ({ primaryItems, otherItems = [], otherLabel = "OTHER", + otherCol = 1, }) => { const location = useLocation(); const [open, setOpen] = useState(false); @@ -183,15 +183,25 @@ const MegaMenuNavbarItem: React.FC = ({ {otherItems.length > 0 && (
{otherLabel}
-
+
{otherItems.map((item) => { const Icon = item.icon ? sidebarIconMap[item.icon] : null; + const External = sidebarIconMap["external"]; const active = isItemActive(item); return ( = ({ /> )} {item.title} + {item.external && ( +