diff --git a/README.md b/README.md
index 3639fa430..d6dba04af 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,16 @@ the block execution logic.
Built on top of these libraries, this repository also features a [fault proof program][fpp-specs] designed to deterministically execute the
rollup state transition in order to verify an [L2 output root][g-output-root] from the L1 inputs it was [derived from][g-derivation-pipeline].
+### Alternative Backends
+
+Kona's libraries were built with alternative backend support and extensibility in mind - it is not just a fault proof
+program! Kona is also used by:
+
+- [`op-succinct`][op-succinct]
+
+To build your own backend for kona, or build a new application on top of its libraries,
+see the [SDK section of the book](https://anton-rs.github.io/kona/sdk/intro.html).
+
### Development Status
`kona` is currently in active development, and is not yet ready for use in production.
@@ -70,6 +80,7 @@ The [book][book] contains a more in-depth overview of the project, contributor g
[asterisc]: https://github.com/etheruem-optimism/asterisc
[fpp-specs]: https://specs.optimism.io/experimental/fault-proof/index.html
[book]: https://anton-rs.github.io/kona/
+[op-succinct]: https://github.com/succinctlabs/op-succinct
[op-labs]: https://github.com/ethereum-optimism
[bad-boi-labs]: https://github.com/BadBoiLabs
[g-output-root]: https://specs.optimism.io/glossary.html#l2-output-root
diff --git a/book/book.toml b/book/book.toml
index c2002cc2a..c6541b763 100644
--- a/book/book.toml
+++ b/book/book.toml
@@ -11,4 +11,9 @@ command = "mdbook-mermaid"
[preprocessor.template]
[output.html]
+default-theme = "ferra"
+preferred-dark-theme = "ferra"
+git-repository-url = "https://github.com/anton-rs/kona"
+edit-url-template = "https://github.com/anton-rs/kona/edit/main/book/{path}"
+additional-css = ["custom.css"]
additional-js = ["mermaid.min.js", "mermaid-init.js"]
diff --git a/book/custom.css b/book/custom.css
new file mode 100644
index 000000000..a5fdb46d9
--- /dev/null
+++ b/book/custom.css
@@ -0,0 +1,141 @@
+table {
+ width: 100%;
+}
+
+table thead th {
+ padding: .75rem;
+ text-align: left;
+ font-weight: 500;
+ line-height: 1.5;
+ width: auto;
+}
+
+table td {
+ padding: .75rem;
+ border: none;
+}
+
+table thead tr {
+ border: none;
+ border-bottom: 2px var(--table-border-color) solid;
+}
+
+table tbody tr {
+ border-bottom: 1px var(--table-border-line) solid;
+}
+
+table tbody tr:nth-child(2n) {
+ background: unset;
+}
+
+.content h1,
+.content h2,
+.content h3,
+.content h4 {
+ font-weight: 600;
+ margin-top: 1.275em;
+ margin-bottom: .875em;
+}
+
+.ferra {
+ --bg: #2b292d;
+ --fg: #fecdb2;
+ --heading-fg: #fff;
+
+ --sidebar-bg: #383539;
+ --sidebar-fg: #fecdb2;
+ --sidebar-non-existant: #feceb454;
+ --sidebar-active: #ffa07a;
+ --scrollbar: var(--sidebar-fg);
+
+ --icons: #f6b6c9ba;
+ --icons-hover: #b7b9cc;
+
+ --links: #ffa07a;
+
+ --inline-code-color: #f6b6c9ba;
+
+ --theme-popup-bg: #383539;
+ --theme-popup-border: #5f5a60;
+ --theme-hover: rgba(0, 0, 0, .2);
+
+ --quote-bg: #222124;
+ --quote-border: #2b292d;
+
+ --table-border-color: #383539;
+ --table-header-bg: hsla(226, 23%, 31%, 0);
+ --table-alternate-bg: hsl(226, 23%, 14%);
+ --table-border-line: #383539;
+
+ --searchbar-border-color: #222124;
+ --searchbar-bg: #222124;
+ --searchbar-fg: #fecdb2;
+ --searchbar-shadow-color: #aaa;
+ --searchresults-header-fg: #fce2d4;
+ --searchresults-border-color: #feceb454;
+ --search-mark-bg: #f6b6c9ba;
+
+}
+
+.ferra .content .header {
+ color: #fce2d4;
+}
+
+/* highlight.js theme, :where() is used to avoid increasing specificity */
+
+:where(.ferra) .hljs {
+ background: #222124;
+ color: #feceb4e1;
+}
+
+:where(.ferra) .hljs-comment,
+:where(.ferra) .hljs-quote {
+ color: #6F5D63;
+}
+
+:where(.ferra) .hljs-link,
+:where(.ferra) .hljs-meta,
+:where(.ferra) .hljs-name,
+:where(.ferra) .hljs-regexp,
+:where(.ferra) .hljs-selector-class,
+:where(.ferra) .hljs-selector-id,
+:where(.ferra) .hljs-tag,
+:where(.ferra) .hljs-template-variable,
+:where(.ferra) .hljs-variable {
+ color: #fecdb2;
+}
+
+:where(.ferra) .hljs-built_in,
+:where(.ferra) .hljs-deletion,
+:where(.ferra) .hljs-literal,
+:where(.ferra) .hljs-number,
+:where(.ferra) .hljs-params,
+:where(.ferra) .hljs-type {
+ color: #f6b6c9;
+}
+
+:where(.ferra) .hljs-attribute,
+:where(.ferra) .hljs-section,
+:where(.ferra) .hljs-title {
+ color: #ffa07a;
+}
+
+:where(.ferra) .hljs-addition,
+:where(.ferra) .hljs-bullet,
+:where(.ferra) .hljs-string,
+:where(.ferra) .hljs-symbol {
+ color: #b1b695;
+}
+
+:where(.ferra) .hljs-keyword,
+:where(.ferra) .hljs-selector-tag {
+ color: #d1d1e0;
+}
+
+:where(.ferra) .hljs-emphasis {
+ font-style: italic;
+}
+
+:where(.ferra) .hljs-strong {
+ font-weight: 700;
+}
diff --git a/book/src/CONTRIBUTING.md b/book/src/CONTRIBUTING.md
index 1a6437fe4..563d511ab 100644
--- a/book/src/CONTRIBUTING.md
+++ b/book/src/CONTRIBUTING.md
@@ -1,7 +1,7 @@
# Contributing
Thank you for wanting to contribute! Before contributing to this repository, please read through this document and
-discuss the change you wish to make via issue or in the development telegram.
+discuss the change you wish to make via issue.
## Dependencies
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index 7d0960e65..a9e81e06f 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -7,5 +7,9 @@
- [Prologue](./fpp-dev/prologue.md)
- [Execution](./fpp-dev/execution.md)
- [Epilogue](./fpp-dev/epilogue.md)
+- [Kona SDK](./sdk/intro.md)
+ - [FPVM Backend](./sdk/fpvm-backend.md)
+ - [Custom Backend](./sdk/custom-backend.md)
+ - [`kona-executor` Extensions](./sdk/exec-ext.md)
- [Glossary](./glossary.md)
- [Contributing](./CONTRIBUTING.md)
diff --git a/book/src/fpp-dev/env.md b/book/src/fpp-dev/env.md
index 3de69023f..3d4c1db14 100644
--- a/book/src/fpp-dev/env.md
+++ b/book/src/fpp-dev/env.md
@@ -28,9 +28,9 @@ when the `host` is the native implementation of the FPVM.
```mermaid
sequenceDiagram
Client->>+Host: Hint preimage (no-op on-chain / read-only mode)
- Host-->>Host: Prepare Preimage
Host-->>-Client: Hint acknowledgement
Client-->>+Host: Preimage Request
+ Host-->>Host: Prepare Preimage
Host-->>-Client: Preimage Data
```
diff --git a/book/src/fpp-dev/targets.md b/book/src/fpp-dev/targets.md
index 51ef9609c..f1237a35d 100644
--- a/book/src/fpp-dev/targets.md
+++ b/book/src/fpp-dev/targets.md
@@ -3,95 +3,13 @@
Kona seeks to support all FPVM targets that LLVM and `rustc` can offer introductory support for. Below is a matrix of features that Kona offers
for each FPVM target:
-| Target | Build Pipeline | IO | malloc | Program Stages |
-| ---------------------- | -------------- | --- | ------ | -------------- |
-| `cannon` & `cannon-rs` | ✅ | ✅ | ✅ | ❌ |
-| `asterisc` | ✅ | ✅ | ✅ | ❌ |
+| Target | Build Pipeline | IO | malloc |
+| ---------------------- | -------------- | --- | ------ |
+| `cannon` & `cannon-rs` | ✅ | ✅ | ✅ |
+| `asterisc` | ✅ | ✅ | ✅ |
If there is a feature that you would like to see supported, please [open an issue][new-issue] or [consider contributing][contributing]!
-## Cannon (MIPS32r2)
-
-Cannon is based off of the `mips32r2` target architecture, supporting 55 instructions:
-
-| Category | Instruction | Description |
-| -------------------- | ----------- | ----------------------------------------- |
-| `Arithmetic` | `addi` | Add immediate (with sign-extension). |
-| `Arithmetic` | `addiu` | Add immediate unsigned (no overflow). |
-| `Arithmetic` | `addu` | Add unsigned (no overflow). |
-| `Logical` | `and` | Bitwise AND. |
-| `Logical` | `andi` | Bitwise AND immediate. |
-| `Branch` | `b` | Unconditional branch. |
-| `Conditional Branch` | `beq` | Branch on equal. |
-| `Conditional Branch` | `beqz` | Branch if equal to zero. |
-| `Conditional Branch` | `bgez` | Branch on greater than or equal to zero. |
-| `Conditional Branch` | `bgtz` | Branch on greater than zero. |
-| `Conditional Branch` | `blez` | Branch on less than or equal to zero. |
-| `Conditional Branch` | `bltz` | Branch on less than zero. |
-| `Conditional Branch` | `bne` | Branch on not equal. |
-| `Conditional Branch` | `bnez` | Branch if not equal to zero. |
-| `Logical` | `clz` | Count leading zeros. |
-| `Arithmetic` | `divu` | Divide unsigned. |
-| `Unconditional Jump` | `j` | Jump. |
-| `Unconditional Jump` | `jal` | Jump and link. |
-| `Unconditional Jump` | `jalr` | Jump and link register. |
-| `Unconditional Jump` | `jr` | Jump register. |
-| `Data Transfer` | `lb` | Load byte. |
-| `Data Transfer` | `lbu` | Load byte unsigned. |
-| `Data Transfer` | `lui` | Load upper immediate. |
-| `Data Transfer` | `lw` | Load word. |
-| `Data Transfer` | `lwr` | Load word right. |
-| `Data Transfer` | `mfhi` | Move from HI register. |
-| `Data Transfer` | `mflo` | Move from LO register. |
-| `Data Transfer` | `move` | Move between registers. |
-| `Data Transfer` | `movn` | Move conditional on not zero. |
-| `Data Transfer` | `movz` | Move conditional on zero. |
-| `Data Transfer` | `mtlo` | Move to LO register. |
-| `Arithmetic` | `mul` | Multiply (to produce a word result). |
-| `Arithmetic` | `multu` | Multiply unsigned. |
-| `Arithmetic` | `negu` | Negate unsigned. |
-| `No Op` | `nop` | No operation. |
-| `Logical` | `not` | Bitwise NOT (pseudo-instruction in MIPS). |
-| `Logical` | `or` | Bitwise OR. |
-| `Logical` | `ori` | Bitwise OR immediate. |
-| `Data Transfer` | `sb` | Store byte. |
-| `Logical` | `sll` | Shift left logical. |
-| `Logical` | `sllv` | Shift left logical variable. |
-| `Comparison` | `slt` | Set on less than (signed). |
-| `Comparison` | `slti` | Set on less than immediate. |
-| `Comparison` | `sltiu` | Set on less than immediate unsigned. |
-| `Comparison` | `sltu` | Set on less than unsigned. |
-| `Logical` | `sra` | Shift right arithmetic. |
-| `Logical` | `srl` | Shift right logical. |
-| `Logical` | `srlv` | Shift right logical variable. |
-| `Arithmetic` | `subu` | Subtract unsigned. |
-| `Data Transfer` | `sw` | Store word. |
-| `Data Transfer` | `swr` | Store word right. |
-| `Serialization` | `sync` | Synchronize shared memory. |
-| `System Calls` | `syscall` | System call. |
-| `Logical` | `xor` | Bitwise XOR. |
-| `Logical` | `xori` | Bitwise XOR immediate. |
-
-### Syscalls
-
-| \$v0 | system call | \$a0 | \$a1 | \$a2 | Effect |
-| ---- | ----------- | --------------- | ---------- | ------------ | -------------------------------------------------------------------------------------------------------------------- |
-| 4090 | mmap | uint32 addr | uint32 len | 🚫 | Allocates a page from the heap. See [heap](#heap) for details. |
-| 4045 | brk | 🚫 | 🚫 | 🚫 | Returns a fixed address for the program break at `0x40000000` |
-| 4120 | clone | 🚫 | 🚫 | 🚫 | Returns 1 |
-| 4246 | exit_group | uint8 exit_code | 🚫 | 🚫 | Sets the Exited and ExitCode states to `true` and `$a0` respectively. |
-| 4003 | read | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned reads. See [I/O](#io) for more details. |
-| 4004 | write | uint32 fd | char \*buf | uint32 count | Similar behavior as Linux/MIPS with support for unaligned writes. See [I/O](#io) for more details. |
-| 4055 | fcntl | uint32 fd | int32 cmd | 🚫 | Similar behavior as Linux/MIPS. Only the `F_GETFL` (3) cmd is supported. Sets errno to `0x16` for all other commands |
-
-For all of the above syscalls, an error is indicated by setting the return
-register (`$v0`) to `0xFFFFFFFF` (-1) and `errno` (`$a3`) is set accordingly.
-The VM must not modify any register other than `$v0` and `$a3` during syscall handling.
-For unsupported syscalls, the VM must do nothing except to zero out the syscall return (`$v0`)
-and errno (`$a3`) registers.
-
-Note that the above syscalls have identical syscall numbers and ABIs as Linux/MIPS.
-
## Asterisc (RISC-V)
Asterisc is based off of the `rv64gc` target architecture, which defines the following extensions:
@@ -100,7 +18,6 @@ Asterisc is based off of the `rv64gc` target architecture, which defines the fol
- `FENCE`, `ECALL`, `EBREAK` are hardwired to implement a minimal subset of systemcalls of the linux kernel
- Work in progress. All syscalls used by the Golang `risc64` runtime.
- `RV64I` support
-- `RV64C`: Compressed instructions
- `RV32M`+`RV64M`: Multiplication support
- `RV32A`+`RV64A`: Atomics support
- `RV{32,64}{D,F,Q}`: no-op: No floating points support (since no IEEE754 determinism with rounding modes etc., nor worth the complexity)
@@ -116,6 +33,16 @@ programs to directly invoke a select few syscalls:
1. `WRITE` - Write the passed buffer to the passed file descriptor.
1. `READ` - Read the specified number of bytes from the passed file descriptor.
-[asterisc-syscalls]: https://github.com/ethereum-optimism/asterisc
+[asterisc-syscalls]: https://github.com/ethereum-optimism/asterisc/blob/master/docs/golang.md#linux-syscalls-used-by-go
+
+## Cannon (MIPS32r2)
+
+Cannon is based off of the `mips32r2` target architecture, specified in [_MIPS32™ Architecture For Programmers Volume III: The MIPS32™ Privileged Resource Architecture_](https://www.cs.cornell.edu/courses/cs3410/2013sp/MIPS_Vol3.pdf)
+
+### Syscalls
+
+Syscalls supported by `cannon` can be found within the `cannon` specification [here][cannon-syscalls].
+
+[cannon-syscalls]: https://specs.optimism.io/fault-proof/cannon-fault-proof-vm.html#syscalls
{{#include ../links.md}}
diff --git a/book/src/intro.md b/book/src/intro.md
index 83844cbca..294637bce 100644
--- a/book/src/intro.md
+++ b/book/src/intro.md
@@ -2,7 +2,7 @@
_Documentation for the Kona project._
-
+
> 📖 `kona` is in active development, and is not yet ready for use in production. During development, this book will evolve quickly and may contain inaccuracies.
>
diff --git a/book/src/links.md b/book/src/links.md
index da5a5a7fb..9d68ad149 100644
--- a/book/src/links.md
+++ b/book/src/links.md
@@ -10,6 +10,8 @@
[preimage-specs]: https://specs.optimism.io/experimental/fault-proof/index.html#pre-image-oracle
[cannon-specs]: https://specs.optimism.io/experimental/fault-proof/cannon-fault-proof-vm.html#cannon-fault-proof-virtual-machine
[l2-output-root]: https://specs.optimism.io/protocol/proposals.html#l2-output-commitment-construction
+[op-succinct]: https://github.com/succinctlabs/op-succinct
+[revm]: https://github.com/bluealloy/revm
diff --git a/book/src/sdk/custom-backend.md b/book/src/sdk/custom-backend.md
new file mode 100644
index 000000000..f008f8c88
--- /dev/null
+++ b/book/src/sdk/custom-backend.md
@@ -0,0 +1,120 @@
+# Custom Backends
+
+## Understanding the OP Stack STF
+
+The OP Stack state transition is comprised of two primary components:
+
+- **The [derivation pipeline](https://specs.optimism.io/protocol/derivation.html)** (`kona-derive`)
+ - Responsible for deriving L2 chain state from the DA layer.
+- **The [execution engine](https://specs.optimism.io/protocol/exec-engine.html#l2-execution-engine)** (`kona-executor`)
+ - Responsible for the execution of transactions and state commitments.
+ - Ensures correct application of derived L2 state.
+
+To prove the correctness of the state transition, Kona composes these two components:
+
+- It combines the derivation of the L2 chain with its execution in the same process.
+- It pulls in necessary data from sources to complete the STF, verifiably unrolling the input commitments along the way.
+
+`kona-client` serves as an implementation of this process, capable of deriving and executing a single L2 block in a
+verifiable manner.
+
+> 📖 Why just a single block by default?
+>
+> On the OP Stack, we employ an interactive bisection game that narrows in on the disagreed upon block -> block state
+> transition before requiring a fault proof to be ran. Because of this, the default implementation only serves
+> to derive and execute the single block that the participants of the bisection game landed on.
+
+## Backend Traits
+
+Covered in the [FPVM Backend](./fpvm-backend.md) section of the book, `kona-client` ships with an implementation of
+`kona-derive` and `kona-executor`'s data source traits which pull in data over the [PreimageOracle ABI][preimage-specs].
+
+However, running `kona-client` on top of a different verifiable environment, i.e. a zkVM or TEE, is also possible
+through custom implementations of these data source traits.
+
+[`op-succinct`](https://github.com/succinctlabs/op-succinct) is an excellent example of both a custom backend and a custom
+program, implementing both `kona-derive` and `kona-executor`'s data source traits backed by [sp1_lib::io](https://docs.rs/sp1-lib/latest/sp1_lib/io/index.html)
+in order to:
+
+1. Execute `kona-client` verbatim, proving a single block's derivation and execution on SP-1.
+1. Derive and execute an entire [Span Batch](https://specs.optimism.io/protocol/delta/span-batches.html#span-batches)
+ worth of L2 blocks, using `kona-derive` and `kona-executor`.
+
+This section of the book outlines how you can do the same for a different platform.
+
+### Custom `kona-derive` sources
+
+Before getting started, we need to create custom implementations of the following traits:
+
+| Trait | Description |
+| ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
+| [`ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.ChainProvider.html) | The `ChainProvider` trait describes the minimal interface for fetching data from L1 during L2 chain derivation. |
+| [`L2ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.L2ChainProvider.html) | The `ChainProvider` trait describes the minimal interface for fetching data from the safe L2 chain during L2 chain derivation. |
+| [`BlobProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.BlobProvider.html) | The `BlobProvider` trait describes an interface for fetching EIP-4844 blobs from the L1 consensus layer during L2 chain derivation. |
+
+Once these are implemented, constructing the pipeline is as simple as passing in the data sources to the `PipelineBuilder`. Keep in mind the requirements for validation of incoming data, depending on your platform. For example, programs
+targeting zkVMs must constrain that the incoming data is indeed valid, whereas fault proof programs can offload this validation to the on-chain implementation of the host.
+
+```rs
+let chain_provider = ...;
+let l2_chain_provider = ...;
+let blob_provider = ...;
+let l1_origin = ...;
+
+let cfg = Arc::new(RollupConfig::default());
+let attributes = StatefulAttributesBuilder::new(
+ cfg.clone(),
+ l2_chain_provider.clone(),
+ chain_provider.clone(),
+);
+let dap = EthereumDataSource::new(
+ chain_provider.clone(),
+ blob_provider,
+ cfg.as_ref()
+);
+
+// Construct a new derivation pipeline.
+let pipeline = PipelineBuilder::new()
+ .rollup_config(cfg)
+ .dap_source(dap)
+ .l2_chain_provider(l2_chain_provider)
+ .chain_provider(chain_provider)
+ .builder(attributes)
+ .origin(l1_origin)
+ .build();
+```
+
+From here, a custom derivation driver is needed to produce the desired execution payload(s). An example of this for
+`kona-client` can be found in the [DerivationDriver](https://github.com/anton-rs/kona/blob/main/bin/client/src/l1/driver.rs#L77).
+
+### `kona-mpt` / `kona-executor` sources
+
+Before getting started, we need to create custom implementations of the following traits:
+
+| Trait | Description |
+| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [`TrieDBFetcher`](https://docs.rs/kona-mpt/latest/kona_mpt/trait.TrieDBFetcher.html) | The `TrieDBFetcher` trait describes the interface for fetching trie node preimages and chain information while executing a payload on the L2 chain. |
+| [`TrieDBHinter`](https://docs.rs/kona-mpt/latest/kona_mpt/trait.TrieDBHinter.html) | The `TrieDBHinter` trait describes the interface for requesting the host program to prepare trie proof preimages for the client's consumption. For targets with upfront witness generation, i.e. zkVMs, a no-op hinter is exported as [`NoopTrieDBHinter`](https://docs.rs/kona-mpt/latest/kona_mpt/struct.NoopTrieDBHinter.html). |
+
+Once we have those, the `StatelessL2BlockExecutor` can be constructed like so:
+
+```rust
+let cfg = RollupConfig::default();
+let provider = ...;
+let hinter = ...;
+
+let executor = StatelessL2BlcokExecutor::builder(&cfg, provider, hinter)
+ .with_parent_header(...)
+ .build();
+
+let header = executor.execute_payload(...).expect("Failed execution");
+```
+
+### Bringing it Together
+
+Once your custom backend traits for both `kona-derive` and `kona-executor` have been implemented,
+your final binary may look something like [that of `kona-client`'s](https://github.com/anton-rs/kona/blob/main/bin/client/src/kona.rs).
+Alternatively, if you're looking to prove a wider range of blocks, [`op-succinct`'s `range` program](https://github.com/succinctlabs/op-succinct/tree/main/programs/range)
+offers a good example of running the pipeline and executor across a string of contiguous blocks.
+
+{{ #include ../links.md }}
diff --git a/book/src/sdk/exec-ext.md b/book/src/sdk/exec-ext.md
new file mode 100644
index 000000000..fef15caa9
--- /dev/null
+++ b/book/src/sdk/exec-ext.md
@@ -0,0 +1,55 @@
+# `kona-executor` Extensions
+
+The `kona-executor` crate offers a to-spec, stateless implementation of the OP Stack STF. However, due to the
+power of [`revm`][revm]'s Handler abstractions, the logic of the STF can be easily modified.
+
+To register a custom handler, for example to add a custom precompile, modify the behavior of an EVM opcode,
+or change the fee handling, `StatelessL2BlockExecutorBuilder::with_handle_register` is your friend. It accepts a
+[`KonaHandleRegister`](https://docs.rs/kona-executor/latest/kona_executor/type.KonaHandleRegister.html), which
+can be used to take full advantage of [`revm`'s Handler API](https://github.com/bluealloy/revm/blob/f57e3e639ee157c7e659e740bd175a7357003570/documentation/src/crates/revm/handler.md#handler).
+
+## Example - Custom Precompile
+
+```rs
+const MY_PRECOMPILE_ADDRESS: Address = u64_to_address(0xFF);
+
+fn my_precompile(input: &Bytes, gas_limit: u64) -> PrecompileResult {
+ Ok(PrecompileOutput::new(50, "hello, world!".as_bytes().into()))
+}
+
+fn custom_handle_register(
+ handler: &mut EvmHandler<'_, (), &mut State<&mut TrieDB>>,
+) where
+ F: TrieProvider,
+ H: TrieHinter,
+{
+ let spec_id = handler.cfg.spec_id;
+
+ handler.pre_execution.load_precompiles = Arc::new(move || {
+ let mut ctx_precompiles = spec_to_generic!(spec_id, {
+ revm::optimism::load_precompiles::>>()
+ });
+
+ let precompile = PrecompileWithAddress(
+ MY_PRECOMPILE_ADDRESS,
+ Precompile::Standard(my_precompile)
+ );
+ ctx_precompiles.extend([precompile]);
+
+ ctx_precompiles
+ });
+}
+
+// - snip -
+
+let cfg = RollupConfig::default();
+let provider = ...;
+let hinter = ...;
+
+let executor = StatelessL2BlcokExecutor::builder(&cfg, provider, hinter)
+ .with_parent_header(...)
+ .with_handle_register(custom_handle_register)
+ .build();
+```
+
+{{ #include ../links.md }}
diff --git a/book/src/sdk/fpvm-backend.md b/book/src/sdk/fpvm-backend.md
new file mode 100644
index 000000000..80f7d7fc0
--- /dev/null
+++ b/book/src/sdk/fpvm-backend.md
@@ -0,0 +1,139 @@
+# FPVM Backend
+
+> 📖 Before reading this section of the book, it is advised to read the [Fault Proof Program Environment](../fpp-dev/env.md)
+> section to familiarize yourself with the PreimageOracle IO pattern.
+
+Kona is effectively split into two parts:
+
+- OP Stack state transition logic & types (`kona-derive`, `kona-executor`, `kona-mpt`, `kona-primitives`)
+- {{#template ../../templates/glossary-link.md root=./ ref=fault-proof-vm text=Fault Proof VM}} IO and utilities
+ (`kona-common`, `kona-common-proc`, `kona-preimage`)
+
+This section of the book focuses on the usage of `kona-common` and `kona-preimage` to facilitate host<->client
+communication for programs running on top of the [FPVM targets](../fpp-dev/env.md).
+
+## Host <-> Client Communication API
+
+The FPVM system API is built on several layers. In this document, we'll cover these layers, from lowest-level to
+highest-level API.
+
+### `kona-common`
+
+`kona-common` implements raw syscall dispatch, a default global memory allocator, and a blocking async runtime.
+`kona-common` relies on a minimal linux backend to function, supporting only the syscalls required to implement the
+[PreimageOracle ABI][preimage-specs] (`read`, `write`, `exit_group`).
+
+These syscalls are exposed to the user through the `io` module directly, with each supported platform implementing the
+[`BasicKernelInterface`](https://docs.rs/kona-common/latest/kona_common/trait.BasicKernelInterface.html) trait.
+
+To directly dispatch these syscalls, the [`io`](https://docs.rs/kona-common/latest/kona_common/io/index.html) module
+exposes a safe API:
+
+```rs
+use kona_common::{io, FileDescriptor};
+
+// Print to `stdout`. Infalliable, will panic if dispatch fails.
+io::print("Hello, world!");
+
+// Print to `stderr`. Infalliable, will panic if dispatch fails.
+io::print_err("Goodbye, world!");
+
+// Read from or write to a specified file descriptor. Returns a result with the
+// return value or syscall errno.
+let _ = io::write(FileDescriptor::StdOut, "Hello, world!".as_bytes());
+let mut buf = Vec::with_capacity(8);
+let _ = io::read(FileDescriptor::StdIn, buf.as_mut_slice());
+
+// Exit the program with a specified exit code.
+io::exit(0);
+```
+
+With this library, you can implement a custom host<->client communication protocol, or extend the existing
+[PreimageOracle ABI][preimage-specs]. However, for most developers, we recommend sticking with `kona-preimage`
+when developing programs that target the [FPVMs](../fpp-dev/env.md), barring needs like printing directly to
+`stdout`.
+
+### `kona-preimage`
+
+`kona-preimage` is an implementation of the [PreimageOracle ABI][preimage-specs], built on top of `kona-common`. This
+crate enables synchronous communication between the host and client program, described in
+[Host <-> Client Communication](../fpp-dev/env.md#host---client-communication) in the FPP Dev environment section of the
+book.
+
+The crate is built around the [`PipeHandle`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.PipeHandle.html),
+which serves as a single end of a bidirectional pipe (see: [`pipe` manpage](https://man7.org/linux/man-pages/man2/pipe.2.html)).
+
+Through this handle, the higher-level constructs can read and write data to the counterparty holding on to the other end
+of the pipe, following the protocol below:
+
+
+
+The interfaces of each part of the above protocol are described by the following traits:
+
+- [`PreimageOracleClient`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.PreimageOracleClient.html)
+ - To-spec implementation: [`OracleReader`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.OracleReader.html)
+- [`HintWriterClient`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.HintWriterClient.html)
+ - To-spec implementation: [`HintWriter`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.HintWriter.html)
+- [`PreimageOracleServer`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.PreimageOracleServer.html)
+ - To-spec implementation: [`OracleServer`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.OracleServer.html)
+- [`HintReaderServer`](https://docs.rs/kona-preimage/latest/kona_preimage/trait.HintReaderServer.html)
+ - To-spec implementation: [`HintReader`](https://docs.rs/kona-preimage/latest/kona_preimage/struct.HintReader.html)
+
+Each of these traits, however, can be re-implemented to redefine the host<->client communication protocol if the needs
+of the consumer are not covered by the to-[spec][preimage-specs] implementations.
+
+### `kona-client` - Oracle-backed sources (example)
+
+Finally, in `kona-client`, implementations of data source traits from `kona-derive` and `kona-executor` are implemented
+to pull in untyped data from the host by `PreimageKey`. These data source traits are covered in more detail within
+the [Custom Backend](./custom-backend.md) section, but we'll quickly gloss over them here to build intuition.
+
+Let's take, for example, [`OracleL1ChainProvider`](https://github.com/anton-rs/kona/blob/40a8d7ec3def4a1eeb26492a1e4338d8b032e428/bin/client/src/l1/chain_provider.rs#L16-L23).
+The [`ChainProvider`](https://docs.rs/kona-derive/latest/kona_derive/traits/trait.ChainProvider.html) trait in `kona-derive`
+defines a simple interface for fetching information about the L1 chain. In the `OracleL1ChainProvider`, this information
+is pulled in over the [PreimageOracle ABI][preimage-specs]. There are many other examples of these data source traits,
+namely the `L2ChainProvider`, `BlobProvider`, `TrieProvider`, and `TrieHinter`, which enable the creation of different
+data-source backends.
+
+As an example, let's look at `OracleL1ChainProvider::header_by_hash`, built on top of the `CommsClient` trait, which
+is a composition trait of the `PreimageOracleClient + HintReaderServer` traits outlined above.
+
+```rs
+#[async_trait]
+impl ChainProvider for OracleL1ChainProvider {
+ type Error = anyhow::Error;
+
+ async fn header_by_hash(&mut self, hash: B256) -> Result {
+ // Send a hint for the block header.
+ self.oracle.write(&HintType::L1BlockHeader.encode_with(&[hash.as_ref()])).await?;
+
+ // Fetch the header RLP from the oracle.
+ let header_rlp =
+ self.oracle.get(PreimageKey::new(*hash, PreimageKeyType::Keccak256)).await?;
+
+ // Decode the header RLP into a Header.
+ Header::decode(&mut header_rlp.as_slice())
+ .map_err(|e| anyhow!("Failed to decode header RLP: {e}"))
+ }
+
+ // - snip -
+}
+```
+
+In `header_by_hash`, we use the inner `HintWriter` to send a hint to the host to prepare the block hash preimage.
+Then, once we've received an acknowledgement from the host that the preimage has been prepared, we reach out for
+the RLP (which is the preimage of the hash). After the RLP is received, we decode the `Header` type, and return
+it to the user.
+
+{{ #include ../links.md }}
diff --git a/book/src/sdk/intro.md b/book/src/sdk/intro.md
new file mode 100644
index 000000000..24df6f58d
--- /dev/null
+++ b/book/src/sdk/intro.md
@@ -0,0 +1,36 @@
+# Kona SDK
+
+Welcome to the Kona SDK, a powerful set of libraries designed to revolutionize the way developers build proofs for the
+OP Stack STF on top of the OP Stack's FPVMs and other verifiable backends like [SP-1][sp-1], [Risc0][rzero],
+[Intel TDX][tdx], and [AMD SEV-SNP][sev-snp]. At its core, Kona is built on the principles of modularity, extensibility,
+and developer empowerment.
+
+## A Foundation of Flexibility
+
+The kona repository is more than a fault proof program for the OP Stack — it's an ecosystem of interoperable components,
+each crafted with reusability and extensibility as primary goals. While we provide
+{{#template ../../templates/glossary-link.md root=./ ref=fault-proof-vm text=Fault Proof VM}} and "online" backends
+for key components like `kona-derive` and `kona-executor`, the true power of `kona` lies in its adaptability.
+
+## Extend Without Forking
+
+One of Kona's standout features is its ability to support custom features and data sources without requiring you to fork
+the entire project. Through careful use of Rust's powerful trait system and abstract interfaces, we've created a
+framework that allows you to plug in your own features and ideas seamlessly.
+
+## What You'll Learn
+
+In this section of the developer book, we'll dive deep into the Kona SDK, covering:
+* **Building on the FPVM Backend**: Learn how to leverage the Fault Proof VM tooling to create your own fault proof programs.
+* **Creating Custom Backends**: Discover the process of designing and implementing your own backend to run `kona-client` or a variation of it on different targets.
+* **Extending Core Components**: Explore techniques for creating new constructs that integrate smoothly with crates like `kona-derive` and `kona-executor`.
+
+Whether you're looking to use Kona as-is, extend its functionality, or create entirely new programs based on its libraries,
+this guide is intended to provide you with the knowledge and tools you need to succeed.
+
+[sp-1]: https://github.com/succinct-labs/sp-1
+[rzero]: https://github.com/risc0/risc0
+[tdx]: https://www.intel.com/content/www/us/en/developer/tools/trust-domain-extensions/documentation.html
+[sev-snp]: https://www.amd.com/en/developer/sev.html
+
+{{#include ../links.md}}
diff --git a/book/theme/index.hbs b/book/theme/index.hbs
new file mode 100644
index 000000000..c4fd6f237
--- /dev/null
+++ b/book/theme/index.hbs
@@ -0,0 +1,364 @@
+
+
+
+
+
+
+ {{ title }}
+ {{#if is_print }}
+
+ {{/if}}
+ {{#if base_url}}
+
+ {{/if}}
+
+
+
+ {{> head}}
+
+
+
+
+
+ {{#if favicon_svg}}
+
+ {{/if}}
+ {{#if favicon_png}}
+
+ {{/if}}
+
+
+
+ {{#if print_enable}}
+
+ {{/if}}
+
+
+
+ {{#if copy_fonts}}
+
+ {{/if}}
+
+
+
+
+
+
+
+ {{#each additional_css}}
+
+ {{/each}}
+
+ {{#if mathjax_support}}
+
+
+ {{/if}}
+
+
+
+