Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .changeset/generalize-fork-management.md

This file was deleted.

2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
// Clipboard support for wl-copy/wl-paste (used by CLAUDE.md)
"clipboard": "sudo apt-get update -qq && sudo apt-get install -y -qq --no-install-recommends wl-clipboard",
// Install vscode focus timer extension
"focus-timer": "d=~/focus-timer-ext && git clone https://github.com/phroi/vscode-focus-timer.git $d && ln -sfn $d ~/.vscode-server/extensions/phroi.focus"
"focus-timer": "d=~/focus-timer-ext && git clone --depth 1 https://github.com/phroi/vscode-focus-timer.git $d && ln -sfn $d ~/.vscode-server/extensions/phroi.focus"
},

// Run each time the container starts. Ensures updated dependencies are installed inside the container user environment.
Expand Down
2 changes: 1 addition & 1 deletion .planning/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Clean, CCC-aligned library packages published to npm that frontends can depend o

**Migration status:** Library packages are on CCC. Apps split: faucet/sampler already migrated; bot/interface/tester still on legacy Lumos (`@ckb-lumos/*`, `@ickb/lumos-utils@1.4.2`, `@ickb/v1-core@1.4.2`).

**Local CCC dev build:** `ccc-fork/` supports using local CCC builds for testing. `.pnpmfile.cjs` transparently rewires `@ckb-ccc/*` to local packages. `fork-scripts/patch.sh` rewrites exports to `.ts` source. This enables testing upstream changes before they're published.
**Local CCC dev build:** `forks/ccc/` supports using local CCC builds for testing. `.pnpmfile.cjs` transparently rewires `@ckb-ccc/*` to local packages. `forks/forker/patch.sh` rewrites exports to `.ts` source. This enables testing upstream changes before they're published.

## Constraints

Expand Down
2 changes: 1 addition & 1 deletion .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Which phases cover which requirements. Updated during roadmap creation.
| SMTX-03 | Phase 6 | Pending | |
| SMTX-04 | Phase 1 | Complete | getHeader()/HeaderKey removed, CCC client calls inlined |
| SMTX-05 | Phase 1, 4, 5 | Complete | addUdtHandlers() replaced with tx.addCellDeps(udtHandler.cellDeps) (01-03); UdtHandler/UdtManager replacement deferred to Phase 4-5 |
| SMTX-06 | Phase 1 | Complete | DAO check contributed to CCC core via ccc-fork/ (01-01) |
| SMTX-06 | Phase 1 | Complete | DAO check contributed to CCC core via forks/ccc/ (01-01) |
| SMTX-07 | Phase 5 | Pending | |
| SMTX-08 | Phase 6 | Pending | |
| SMTX-09 | Phase 7 | Pending | |
Expand Down
2 changes: 1 addition & 1 deletion .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Decimal phases appear between their surrounding integers in numeric order.
1. `SmartTransaction` class and `CapacityManager` class no longer exist in `@ickb/utils` source or exports
2. `UdtHandler` interface and `UdtManager` class remain in `@ickb/utils` with method signatures updated from `SmartTransaction` to `ccc.TransactionLike` (full replacement deferred to Phase 3+)
3. `getHeader()` function and `HeaderKey` type are removed from `@ickb/utils`; all call sites across dao/core/sdk inline CCC client calls (`client.getTransactionWithHeader()`, `client.getHeaderByNumber()`); `SmartTransaction.addHeaders()` call sites in DaoManager/LogicManager push to `tx.headerDeps` directly
4. A 64-output NervosDAO limit check exists in CCC core (via `ccc-fork/`): `completeFee()` safety net, standalone async utility, and `ErrorNervosDaoOutputLimit` error class; all 6+ scattered checks across dao/core packages are replaced with calls to this CCC utility
4. A 64-output NervosDAO limit check exists in CCC core (via `forks/ccc/`): `completeFee()` safety net, standalone async utility, and `ErrorNervosDaoOutputLimit` error class; all 6+ scattered checks across dao/core packages are replaced with calls to this CCC utility
5. ALL manager method signatures across ALL 5 library packages accept `ccc.TransactionLike` instead of `SmartTransaction`, following CCC's convention (TransactionLike input, Transaction output with `Transaction.from()` conversion at entry point)
6. `pnpm check:full` passes after each feature-slice removal step — no intermediate broken states
**Plans**: 3 plans
Expand Down
6 changes: 3 additions & 3 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ Recent decisions affecting current work:
- [Roadmap]: Phase 1 uses feature-slice approach -- each removal chased across all packages, build stays green after every step. SMTX-01 (all signatures to TransactionLike) completed in Phase 1, not Phase 5.
- [Roadmap]: UDT investigation (Phase 3) is a design phase that produces a decision document; its outcome determines UdtHandler/UdtManager replacement pattern used in Phases 4-5
- [Roadmap]: Phases 4-5 reduced in scope: Phase 4 focuses on deprecated API replacement + UDT pattern finalization in dao/order; Phase 5 focuses on IckbUdt implementation + conservation law in core
- [Phase 1 Context]: DAO 64-output limit check contributed to CCC core via ccc-fork/, CCC PR submitted during Phase 1
- [Phase 1 Context]: DAO 64-output limit check contributed to CCC core via forks/ccc/, CCC PR submitted during Phase 1
- [Phase 1 Context]: getHeader()/HeaderKey removed entirely -- inline CCC client calls at read-only call sites; addHeaders() call sites in DaoManager/LogicManager push to tx.headerDeps directly
- [Phase 1 Context]: Script comparison must always use full Script.eq(), never just codeHash comparison
- [01-01]: Added ccc-fork local patch mechanism for deterministic replay of CCC modifications (now multi-file format: manifest + res-N.resolution + local-*.patch)
- [01-01]: Added forks/ccc local patch mechanism for deterministic replay of CCC modifications (now multi-file format: manifest + res-N.resolution + local-*.patch)
- [01-01]: DaoManager.requestWithdrawal/withdraw client parameter placed before optional options for cleaner API
- [01-01]: assertDaoOutputLimit uses early return when outputs <= 64 for zero-cost common case
- [01-02]: Moved getHeader/HeaderKey to transaction.ts as non-exported internals (deleted alongside SmartTransaction in 01-03)
Expand Down Expand Up @@ -80,7 +80,7 @@ None yet.
- Resolved: CCC's `Transaction.getInputsCapacity()` handles DAO profit natively via `getInputsCapacityExtra()` -> `CellInput.getExtraCapacity()` -> `Cell.getDaoProfit()` (verified in STACK.md from CCC source). No standalone utility needed.
- Resolved: CCC Udt `getInputsInfo()` resolves inputs to `Cell` objects (which have `outPoint`) before passing to `infoFrom()`. `infoFrom()`'s `CellAnyLike` parameter has `outPoint?: OutPointLike | null` — optional, not absent. Input cells have outPoint (for header fetches), output cells don't. Both `infoFrom` and `getInputsInfo/getOutputsInfo` are viable override points for IckbUdt (verified during Phase 3 discuss-phase).
- Resolved: STACK.md research correction applied — `client.getHeaderByTxHash()` (non-existent) replaced with `client.getTransactionWithHeader()` in STACK.md, ROADMAP.md Phase 3 success criterion #2, and REQUIREMENTS.md UDT-02.
- Resolved: PR #328 stance updated during Phase 3 context — user decision is to design around PR #328 as target architecture (overrides research recommendation to "not wait for #328"). PR #328 is now integrated into `ccc-fork/ccc` via pins; FeePayer classes available at `ccc-fork/ccc/packages/core/src/signer/feePayer/`. The separate `reference/ccc-fee-payer` clone is no longer needed.
- Resolved: PR #328 stance updated during Phase 3 context — user decision is to design around PR #328 as target architecture (overrides research recommendation to "not wait for #328"). PR #328 is now integrated into `forks/ccc/` via pins; FeePayer classes available at `forks/ccc/packages/core/src/signer/feePayer/`. The separate ccc-fee-payer reference clone is no longer needed.
- Resolved: `CellAny` has `capacityFree` getter (CCC transaction.ts:404-405) — 03-RESEARCH.md corrected (previously claimed `CellAny` lacked it).

## Session Continuity
Expand Down
4 changes: 2 additions & 2 deletions .planning/codebase/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The iCKB protocol solves NervosDAO illiquidity by pooling DAO deposits and issui

## On-Chain Contracts (Rust)

Three production smart contracts (in `reference/contracts/` reference repo) implement the protocol on CKB L1. Each TS package in `packages/` corresponds to contract logic:
Three production smart contracts (in `forks/contracts/` reference repo) implement the protocol on CKB L1. Each TS package in `packages/` corresponds to contract logic:

| Contract | Script Type | TS Package | Purpose |
|---|---|---|---|
Expand All @@ -70,7 +70,7 @@ Receipts convert to UDT; deposits stay as deposits or convert to UDT. No iCKB ca

**Foundation: CCC Framework**
- Purpose: Provide blockchain primitives and client interface
- Location: `@ckb-ccc/core` (npm or local `ccc-fork/ccc/`)
- Location: `@ckb-ccc/core` (npm or local `forks/ccc/`)
- Contains: CKB RPC clients, transaction builders, signers, Molecule codec, UDT support, Epoch handling
- Used by: All packages and applications
- Note: CCC now includes UDT and Epoch features contributed by this project's maintainer
Expand Down
26 changes: 13 additions & 13 deletions .planning/codebase/CONCERNS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,28 @@

### Local UDT Handling May Overlap CCC Upstream (Medium)

- Issue: CCC now has a dedicated `@ckb-ccc/udt` package (at `ccc-fork/ccc/packages/udt/`). The local `packages/utils/src/udt.ts` and `packages/core/src/udt.ts` implement custom UDT handling (`UdtHandler` interface, `IckbUdtManager` class). While the local UDT handling is iCKB-specific (custom balance calculation accounting for DAO deposits), the generic UDT operations like `ccc.udtBalanceFrom()` are still being used from CCC upstream in `packages/utils/src/udt.ts` (4 locations).
- Issue: CCC now has a dedicated `@ckb-ccc/udt` package (at `forks/ccc/packages/udt/`). The local `packages/utils/src/udt.ts` and `packages/core/src/udt.ts` implement custom UDT handling (`UdtHandler` interface, `IckbUdtManager` class). While the local UDT handling is iCKB-specific (custom balance calculation accounting for DAO deposits), the generic UDT operations like `ccc.udtBalanceFrom()` are still being used from CCC upstream in `packages/utils/src/udt.ts` (4 locations).
- Files:
- `packages/utils/src/udt.ts` - `UdtHandler` interface, `UdtManager` class (~370 lines)
- `packages/core/src/udt.ts` - `IckbUdtManager` extending UDT handling for iCKB-specific logic
- `ccc-fork/ccc/packages/udt/src/` - CCC upstream UDT package
- `forks/ccc/packages/udt/src/` - CCC upstream UDT package
- Usage of `ccc.udtBalanceFrom()`: `packages/utils/src/udt.ts` lines 169, 197, 323, 368
- Impact: There may be duplicated utility code for standard UDT operations (finding cells, calculating balances). The iCKB-specific extensions (e.g., `IckbUdtManager` which modifies balance calculations based on DAO deposit/withdrawal state) are domain-specific and unlikely to be in CCC.
- Fix approach: Audit the CCC `@ckb-ccc/udt` package to identify which local utilities can be replaced. Keep iCKB-specific extensions but delegate standard UDT operations (cell finding, basic balance) to CCC where possible.

### Fragile CCC Local Override Mechanism (Medium)

- Issue: The `.pnpmfile.cjs` hook and `fork-scripts/record.sh` script create a fragile mechanism for overriding published CCC packages with local builds. The `.pnpmfile.cjs` `readPackage` hook intercepts pnpm's dependency resolution to redirect `@ckb-ccc/*` packages to local paths under `ccc-fork/ccc/packages/*/`.
- Issue: The `.pnpmfile.cjs` hook and `forks/forker/record.sh` script create a fragile mechanism for overriding published CCC packages with local builds. The `.pnpmfile.cjs` `readPackage` hook intercepts pnpm's dependency resolution to redirect `@ckb-ccc/*` packages to local paths under `forks/ccc/packages/*/`.
- Files:
- `.pnpmfile.cjs` - pnpm hook that overrides `@ckb-ccc/*` package resolutions
- `fork-scripts/record.sh` - generic fork record script (clones repo, merges refs, builds locally)
- `ccc-fork/config.json` - CCC fork configuration (upstream URL, refs, workspace config)
- `pnpm-workspace.yaml` - includes `ccc-fork/ccc/packages/*` in workspace (auto-generated section)
- `ccc-fork/ccc/` - local CCC checkout (when present)
- `forks/forker/record.sh` - generic fork record script (clones repo, merges refs, builds locally)
- `forks/config.json` - CCC fork configuration (upstream URL, refs, workspace config)
- `pnpm-workspace.yaml` - includes `forks/ccc/packages/*` in workspace (auto-generated section)
- `forks/ccc/` - local CCC checkout (when present)
- Impact: Multiple fragility points:
1. The local CCC repo at `ccc-fork/ccc/` must be manually cloned and kept in sync with a specific branch/commit.
1. The local CCC repo at `forks/ccc/` must be manually cloned and kept in sync with a specific branch/commit.
2. The `readPackage` hook modifies `dependencies` objects at install time, which can silently break if CCC reorganizes its packages.
3. CI/CD (`fork-scripts/replay.sh`) must run this setup before `pnpm install`, creating an ordering dependency.
3. CI/CD (`forks/forker/replay.sh`) must run this setup before `pnpm install`, creating an ordering dependency.
4. The override mechanism is invisible to developers who don't read `.pnpmfile.cjs`, leading to confusion when packages resolve differently than expected from `package.json`.
- Fix approach: Now that UDT and Epoch PRs have been merged into CCC upstream, evaluate whether the local overrides are still needed. If CCC publishes releases containing the merged features, switch to published versions and remove the override mechanism.

Expand Down Expand Up @@ -154,7 +154,7 @@
- Current capacity: Maximum 64 output cells per transaction containing NervosDAO operations.
- Limit: Enforced by the NervosDAO script itself. Consolidated into CCC core in Phase 1.
- Files:
- `ccc-fork/ccc/packages/core/src/ckb/transaction.ts` — `assertDaoOutputLimit` utility + `completeFee` safety net (contributed to CCC core in Phase 1)
- `forks/ccc/packages/core/src/ckb/transaction.ts` — `assertDaoOutputLimit` utility + `completeFee` safety net (contributed to CCC core in Phase 1)
- `packages/dao/src/dao.ts` — calls `assertDaoOutputLimit`
- `packages/core/src/owned_owner.ts` — calls `assertDaoOutputLimit`
- `apps/bot/src/index.ts`, line 414 (limits to 58 outputs to reserve 6 for change)
Expand Down Expand Up @@ -217,19 +217,19 @@

### TS Exchange Rate Must Match Rust Contract Logic

- What's not tested: The TypeScript exchange rate calculation (`packages/core/src/udt.ts`) must produce identical results to the Rust contract's `deposit_to_ickb()` function (`reference/contracts/scripts/contracts/ickb_logic/src/entry.rs`). Any discrepancy would cause transactions to be rejected on-chain.
- What's not tested: The TypeScript exchange rate calculation (`packages/core/src/udt.ts`) must produce identical results to the Rust contract's `deposit_to_ickb()` function (`forks/contracts/scripts/contracts/ickb_logic/src/entry.rs`). Any discrepancy would cause transactions to be rejected on-chain.
- Key formula: `iCKB = capacity * AR_0 / AR_m` with soft cap penalty `amount - (amount - 100000) / 10` when `amount > ICKB_SOFT_CAP_PER_DEPOSIT`
- Contract constants that TS must match:
- `CKB_MINIMUM_UNOCCUPIED_CAPACITY_PER_DEPOSIT = 1,000 * 100_000_000` (1,000 CKB)
- `CKB_MAXIMUM_UNOCCUPIED_CAPACITY_PER_DEPOSIT = 1,000,000 * 100_000_000` (1,000,000 CKB)
- `ICKB_SOFT_CAP_PER_DEPOSIT = 100,000 * 100_000_000` (100,000 iCKB)
- `GENESIS_ACCUMULATED_RATE = 10_000_000_000_000_000` (10^16)
- Reference: `reference/contracts/scripts/contracts/ickb_logic/src/entry.rs` function `deposit_to_ickb()`
- Reference: `forks/contracts/scripts/contracts/ickb_logic/src/entry.rs` function `deposit_to_ickb()`
- Fix approach: Add cross-validation tests with known inputs/outputs derived from the Rust contract logic

### TS Molecule Codecs Must Match Contract Schemas

- What's not tested: The TypeScript Molecule codec definitions (`@ccc.codec` decorators in `packages/order/src/entities.ts`, `packages/core/src/entities.ts`) must produce byte-identical encodings to the Molecule schema at `reference/contracts/schemas/encoding.mol`. Field order, sizes, and endianness must match exactly.
- What's not tested: The TypeScript Molecule codec definitions (`@ccc.codec` decorators in `packages/order/src/entities.ts`, `packages/core/src/entities.ts`) must produce byte-identical encodings to the Molecule schema at `forks/contracts/schemas/encoding.mol`. Field order, sizes, and endianness must match exactly.
- Key schemas:
- `ReceiptData { deposit_quantity: Uint32, deposit_amount: Uint64 }` = 12 bytes
- `OwnedOwnerData { owned_distance: Int32 }` = 4 bytes
Expand Down
4 changes: 2 additions & 2 deletions .planning/codebase/CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- All `@ckb-lumos/*` packages are **DEPRECATED** -- Lumos is being replaced by CCC.
- CCC PRs for UDT and Epochs have been **MERGED** upstream -- those features now exist in CCC itself.
- `SmartTransaction` was **DELETED** in Phase 1 in favor of CCC's client cache for header caching. Headers are now fetched inline via CCC client calls (`client.getTransactionWithHeader()`, `client.getHeaderByNumber()`). All manager method signatures now accept `ccc.TransactionLike` and return `ccc.Transaction` directly.
- CCC is sometimes overridden locally via `fork-scripts/record.sh` and `.pnpmfile.cjs` for testing unpublished changes.
- CCC is sometimes overridden locally via `bash forks/forker/record.sh` and `.pnpmfile.cjs` for testing unpublished changes.

**When writing new code:** Use CCC (`@ckb-ccc/core`) types and patterns exclusively in `packages/`. Never introduce new Lumos dependencies.

Expand Down Expand Up @@ -270,7 +270,7 @@ export * from "./utils.js";

## Molecule / Codec Patterns

**TS codecs must match the Molecule schema** at `reference/contracts/schemas/encoding.mol`. The on-chain contracts use Molecule for serialization; the TS packages must produce byte-identical encodings.
**TS codecs must match the Molecule schema** at `forks/contracts/schemas/encoding.mol`. The on-chain contracts use Molecule for serialization; the TS packages must produce byte-identical encodings.

**Entity classes** use CCC's `ccc.Entity.Base` with decorator-based codec definition:
```typescript
Expand Down
Loading