Skip to content

Add CLAUDE.md / AGENTS.md for AI coding assistant context #1145

@crtahlin

Description

@crtahlin

Why

AI coding assistants (Claude Code, Cursor, Copilot, Codex, etc.) load project context files on startup. Without them, every session starts from zero — the tool doesn't know the project structure, conventions, build commands, or domain concepts. Adding these files provides:

  • Faster onboarding — AI tools immediately understand the SDK architecture, the typed-bytes pattern, the modules layer, and the dual CJS/ESM build
  • Fewer mistakes — tools know about browser vs Node.js platform variants, the Stamper client-side stamping system, and Swarm-specific domain concepts
  • Consistent patterns — respects the existing code style, module organization, and the cafe-utility dependency convention

Proposed CLAUDE.md

Click to expand full file
# CLAUDE.md — bee-js

This file provides guidance to AI coding assistants when working with this repository.

## Project Overview

**bee-js** (`@ethersphere/bee-js`) is the official TypeScript/JavaScript client library for the Ethereum Swarm Bee node. It wraps the Bee HTTP API into a type-safe SDK that works in both Node.js and browsers.

- **Version**: 11.x (current)
- **License**: BSD-3-Clause
- **Runtime**: Node.js 18+ and modern browsers
- **Key dependencies**: `axios` (HTTP), `cafe-utility` (binary helpers, crypto, types), `isomorphic-ws` / `ws` (WebSocket for PSS/GSOC), `semver` (version checks), `debug` (logging)
- **Compatible Bee version**: specified in `package.json` under `engines.bee` and `engines.beeApiVersion`

## Build & Development Commands

```bash
npm install          # Install dependencies
npm run build        # Full build: CJS + ESM + types + browser bundle
npm run build:node   # CJS (dist/cjs/) + ESM (dist/mjs/) via tsc + babel
npm run build:types  # Type declarations (dist/types/)
npm run build:browser # Webpack UMD bundle (dist/index.browser.js)
npm test             # Jest tests (requires running Bee node — see Testing below)
npm run check        # TypeScript type-check only (no emit)
npm run lint         # ESLint + Prettier
npm run depcheck     # Check for unused dependencies
```

### Build Pipeline

1. **CJS**: `tsc -p tsconfig.json``dist/cjs/` (Node16 module resolution)
2. **ESM**: `tsc -p tsconfig-mjs.json``dist/mjs/`, then `babel` adds `.js` import extensions
3. **Types**: `tsc --emitDeclarationOnly``dist/types/`
4. **Browser**: `webpack``dist/index.browser.js` (UMD, exposed as `window.BeeJs`)
5. **Fixup**: `./build-fixup` script patches `package.json` files in dist directories

The `tsconfig-base.json` targets ES2020 with strict mode. CJS and ESM configs extend it.

## Architecture

### Entry Point & Exports

`src/index.ts` exports:
- **`Bee`** — main client class (all standard API operations)
- **`BeeDev`** — extends Bee with dev-mode methods (`getNodeAddresses`, `getTopology`)
- **`Stamper`** — client-side postage stamp issuing
- **Typed bytes**`PrivateKey`, `PublicKey`, `EthAddress`, `Reference`, `BatchId`, `Topic`, `FeedIndex`, `Identifier`, `Span`, `PeerAddress`, `TransactionId`, `Signature`
- **Utilities**`Utils` namespace, `Bytes`, `BZZ`, `DAI`, `Duration`, `Size`, `MantarayNode`, `MerkleTree`
- **Types** — all interfaces re-exported from `src/types/`
- **Errors**`BeeError`, `BeeArgumentError`, `BeeResponseError`

### Layer Structure

```
src/bee.ts          ← Bee class: public API surface (~100 methods)
src/bee-dev.ts      ← BeeDev: dev/debug extensions
src/modules/        ← HTTP call layer (one file per API group)
src/modules/debug/  ← Debug API modules (stamps, stake, balance, etc.)
src/chunk/          ← Content Addressed Chunks (CAC) and Single Owner Chunks (SOC)
src/feed/           ← Feed reader/writer, feed identifiers
src/manifest/       ← Mantaray manifest handling
src/stamper/        ← Client-side postage stamp issuing
src/types/          ← TypeScript interfaces and constants
src/utils/          ← Shared utilities (HTTP, bytes, crypto, collections, etc.)
```

### Bee Class Method Groups

The `Bee` class in `src/bee.ts` is the main public API. Methods are organized by domain:

| Group | Methods |
|-------|---------|
| **Data** | `uploadData`, `downloadData`, `downloadReadableData`, `probeData` |
| **Files** | `uploadFile`, `downloadFile`, `downloadReadableFile` |
| **Collections** | `uploadFiles`, `uploadFilesFromDirectory`, `uploadCollection`, `hashDirectory`, `streamDirectory`, `streamFiles` |
| **Chunks** | `uploadChunk`, `downloadChunk`, `makeContentAddressedChunk`, `unmarshalContentAddressedChunk`, `makeSingleOwnerChunk`, `unmarshalSingleOwnerChunk`, `calculateSingleOwnerChunkAddress` |
| **SOC** | `makeSOCReader`, `makeSOCWriter` |
| **Feeds** | `makeFeedReader`, `makeFeedWriter`, `createFeedManifest`, `fetchLatestFeedUpdate`, `isFeedRetrievable` |
| **Tags** | `createTag`, `retrieveTag`, `deleteTag`, `updateTag`, `getAllTags` |
| **Pinning** | `pin`, `unpin`, `getAllPins`, `getPin` |
| **Stewardship** | `reuploadPinnedData`, `isReferenceRetrievable` |
| **PSS** | `pssSend`, `pssSubscribe`, `pssReceive` |
| **GSOC** | `gsocMine`, `gsocSend`, `gsocSubscribe` |
| **Stamps** | `createPostageBatch`, `buyStorage`, `getStorageCost`, `extendStorage`, `extendStorageSize`, `extendStorageDuration`, `topUpBatch`, `diluteBatch`, `getPostageBatch`, `getPostageBatches`, `getPostageBatchBuckets`, `getGlobalPostageBatches`, `getExtensionCost`, `getSizeExtensionCost`, `getDurationExtensionCost` |
| **Access Control** | `createGrantees`, `getGrantees`, `patchGrantees` |
| **Chequebook** | `getChequebookAddress`, `getChequebookBalance`, `depositBZZToChequebook`, `withdrawBZZFromChequebook`, `getLastCheques`, `getLastChequesForPeer`, `getLastCashoutAction`, `cashoutLastCheque` |
| **Wallet** | `getWalletBalance`, `withdrawBZZToExternalWallet`, `withdrawDAIToExternalWallet` |
| **Balance & Settlements** | `getAllBalances`, `getPeerBalance`, `getPastDueConsumptionBalances`, `getPastDueConsumptionPeerBalance`, `getSettlements`, `getAllSettlements` |
| **Staking** | `getStake`, `depositStake`, `getWithdrawableStake`, `withdrawSurplusStake`, `migrateStake`, `getRedistributionState` |
| **Connectivity** | `getNodeAddresses`, `getTopology`, `getPeers`, `getBlocklist`, `removePeer`, `pingPeer` |
| **Status** | `checkConnection`, `isConnected`, `isGateway`, `getStatus`, `getHealth`, `getReadiness`, `getNodeInfo`, `getVersions`, `isSupportedExactVersion`, `isSupportedApiVersion` |
| **Transactions** | `getAllPendingTransactions`, `getPendingTransaction`, `rebroadcastPendingTransaction`, `cancelPendingTransaction` |
| **Envelopes** | `createEnvelope` |
| **Reserve** | `rchash`, `getReserveState`, `getChainState` |

### Modules Layer

Each file in `src/modules/` makes HTTP calls to specific Bee API endpoints using the `http()` function from `src/utils/http.ts`. The Bee class delegates to these modules.

Files: `bytes.ts`, `bzz.ts`, `chunk.ts`, `envelope.ts`, `feed.ts`, `grantee.ts`, `gsoc.ts`, `pinning.ts`, `pss.ts`, `rchash.ts`, `soc.ts`, `status.ts`, `stewardship.ts`, `tag.ts`

Debug modules (in `src/modules/debug/`): `balance.ts`, `chequebook.ts`, `connectivity.ts`, `settlements.ts`, `stake.ts`, `stamps.ts`, `states.ts`, `status.ts`, `transactions.ts`

### Typed Bytes Pattern

All Swarm identifiers are strongly typed via classes extending `Bytes` (from `src/utils/bytes.ts`). Each class enforces a fixed byte length:

| Class | Length | Purpose |
|-------|--------|---------|
| `PrivateKey` | 32 | Ethereum private key; can derive `PublicKey`, sign data |
| `PublicKey` | 64 | Uncompressed public key (supports compressed 33-byte input) |
| `EthAddress` | 20 | Ethereum address with checksum encoding |
| `Reference` | 32 or 64 | Content hash (32 unencrypted, 64 encrypted); supports CID input |
| `BatchId` | 32 | Postage batch identifier |
| `Topic` | 32 | Feed topic (often keccak256 of a string) |
| `Identifier` | 32 | SOC/chunk identifier (keccak256 of a string) |
| `FeedIndex` | 8 | Sequential feed index (big-endian uint64) |
| `Span` | 8 | Chunk data length (little-endian uint64) |
| `PeerAddress` | 32 | Swarm overlay address |
| `TransactionId` | 32 | Blockchain transaction hash |
| `Signature` | 65 | ECDSA signature (r + s + v); supports `recoverPublicKey` |

Constructors accept `Uint8Array | string | Bytes`, making the API flexible for callers.

### Token Classes

`src/utils/tokens.ts` provides immutable fixed-point arithmetic:

- **`BZZ`** — 16 decimal digits (1 BZZ = 10^16 PLUR). Create via `BZZ.fromDecimalString("1.5")` or `BZZ.fromPLUR("15000000000000000")`.
- **`DAI`** — 18 decimal digits (1 DAI = 10^18 wei). Create via `DAI.fromDecimalString("1.0")` or `DAI.fromWei("1000000000000000000")`.

Both have `plus`, `minus`, `divide`, comparison operators, and exchange methods.

### Browser vs Node.js

Platform-specific code uses `.browser.ts` variants resolved via `package.json` `"browser"` field:

| Node.js file | Browser variant | Purpose |
|---|---|---|
| `utils/data.ts` | `utils/data.browser.ts` | Data preparation for uploads |
| `utils/chunk-stream.ts` | `utils/chunk-stream.browser.ts` | Streaming chunk upload |
| `utils/collection.node.ts` | `utils/collection.browser.ts` | File collection building |
| `utils/tar.ts` | `utils/tar.browser.ts` | Tar archive creation |
| `utils/tar-writer.ts` | `utils/tar-writer.browser.ts` | Tar stream writing |
| `utils/tar-uploader.ts` | `utils/tar-uploader.browser.ts` | Tar upload orchestration |

The Webpack build defines `process.env.IS_WEBPACK_BUILD` for runtime detection.

### Stamper (Client-Side Stamping)

`src/stamper/stamper.ts` provides `Stamper` — a client-side postage stamp issuing system. It tracks 65,536 buckets and assigns stamps to chunks locally (without needing the Bee node to stamp).

Create via `Stamper.fromBlank(signer, batchId, depth)` or `Stamper.fromState(...)` to resume from saved state.

### HTTP Client

`src/utils/http.ts` wraps `axios` with:
- Deep-merging of default config, call config, and user options
- Retry logic for `ECONNABORTED` when `endlesslyRetry` is set
- Abort signal support
- Buffer-to-ArrayBuffer conversion for request bodies
- `onRequest` hook for request inspection
- Errors wrapped in `BeeResponseError`

## Key Constants

```typescript
CHUNK_SIZE = 4096         // Swarm chunk payload size
SECTION_SIZE = 32         // BMT hash section size
BRANCHES = 128            // BMT branching factor
STAMPS_DEPTH_MIN = 17     // Minimum postage batch depth (512MB theoretical)
STAMPS_DEPTH_MAX = 255    // Maximum postage batch depth
PSS_TARGET_HEX_LENGTH_MAX = 4
```

## Testing

Tests require a running Bee node. Environment variables:

```bash
JEST_BEE_URL=http://localhost:1633     # Bee API URL
JEST_BEE_SIGNER=<private-key-hex>     # Private key for signing
JEST_MANAGED_BATCH_ID=<64-char-hex>   # Managed postage batch
JEST_EXTERNAL_BATCH_ID=<64-char-hex>  # External postage batch
JEST_WITHDRAW_ADDRESS=<eth-address>   # For withdrawal tests
```

Test setup in `jest.config.js` waits for the Bee node to finish warming up before running.

```bash
# Run all tests (requires Bee node)
npm test

# Type-check without running tests
npm run check
```

- Tests are in `test/` with `*.spec.ts` naming
- Test timeout: 4 minutes
- Uses `ts-jest` preset
- Coverage collected from `src/**/*.ts`

## Code Conventions

- **Strict TypeScript**`strict: true`, `alwaysStrict: true`, `skipLibCheck: false`
- **Formatting** — Prettier + ESLint (`eslint-config-prettier`)
- **Imports** — Use `cafe-utility` for binary operations (`Binary`), type assertions (`Types`), async helpers (`System`), string utilities (`Strings`), date utilities (`Dates`)
- **Conventional commits** — enforced by commitlint
- **Error handling** — use `BeeError`, `BeeArgumentError`, or `BeeResponseError` from `src/utils/error.ts`
- **Parameter validation** — typed-bytes constructors validate length; use assertion helpers in `src/utils/type.ts`
- **Method signatures** — most Bee class methods accept typed-bytes OR raw `Uint8Array | string`, converting internally
- **Request options** — every Bee method accepts optional `requestOptions?: BeeRequestOptions` as the last parameter

## Common Pitfalls

- **Gateway vs full node**: Many operations (PSS, GSOC, staking, stamps, chequebook) require a full node, not a gateway. The `isGateway()` method can check.
- **Stamp usability**: After `createPostageBatch`, the stamp needs block confirmations before it's usable. Set `waitForUsable: true` (default) or poll with `getPostageBatch` until `usable === true`.
- **Encrypted references**: Are 64 bytes (128 hex chars) instead of 32 bytes (64 hex chars). The `Reference` class accepts both.
- **CID support**: `Reference` constructor accepts `bah5...` CID strings and auto-decodes them.
- **Browser builds**: Don't use Node.js APIs (`fs`, `stream`, `path`) in code that must run in browsers. Use the `.browser.ts` pattern for platform-specific implementations.
- **BZZ amounts**: Methods accepting amounts take either a `BZZ` instance or a raw PLUR string/bigint. 1 BZZ = 10^16 PLUR.
- **Network parameter**: `Bee` constructor accepts `network: 'gnosis' | 'sepolia'` which affects block time calculations (5s vs 15s) for postage batch TTL.

## Directory Map

```
src/
├── index.ts              # Public exports
├── bee.ts                # Bee class (~2700 lines, ~100 methods)
├── bee-dev.ts            # BeeDev class (dev-mode extensions)
├── chunk/                # CAC and SOC implementations
│   ├── bmt.ts            # Binary Merkle Tree hashing
│   ├── cac.ts            # Content Addressed Chunks
│   └── soc.ts            # Single Owner Chunks
├── feed/                 # Feed reader/writer
│   ├── index.ts          # makeFeedReader, makeFeedWriter
│   ├── identifier.ts     # Feed identifier construction
│   └── retrievable.ts    # Feed retrievability checks
├── manifest/             # Mantaray manifest
├── modules/              # HTTP API call layer
│   ├── bytes.ts          # /bytes endpoints
│   ├── bzz.ts            # /bzz endpoints
│   ├── chunk.ts          # /chunks endpoints
│   ├── envelope.ts       # /envelope endpoints
│   ├── feed.ts           # /feeds endpoints
│   ├── grantee.ts        # /grantees endpoints
│   ├── gsoc.ts           # GSOC WebSocket
│   ├── pinning.ts        # /pins endpoints
│   ├── pss.ts            # /pss endpoints
│   ├── rchash.ts         # /rchash endpoint
│   ├── soc.ts            # /soc endpoints
│   ├── status.ts         # /status, /gateway endpoints
│   ├── stewardship.ts    # /stewardship endpoints
│   ├── tag.ts            # /tags endpoints
│   └── debug/            # Debug/admin API modules
│       ├── balance.ts    # /balances endpoints
│       ├── chequebook.ts # /chequebook endpoints
│       ├── connectivity.ts # /addresses, /topology, /peers
│       ├── settlements.ts  # /settlements endpoints
│       ├── stake.ts      # /stake endpoints
│       ├── stamps.ts     # /stamps endpoints
│       ├── states.ts     # /chainstate, /reservestate, /wallet
│       ├── status.ts     # /status, /health, /readiness, /node
│       └── transactions.ts # /transactions endpoints
├── stamper/              # Client-side stamping
│   └── stamper.ts
├── types/                # TypeScript interfaces
│   ├── index.ts          # Main types + constants
│   └── debug.ts          # Debug API types
└── utils/                # Shared utilities
    ├── bytes.ts          # Base Bytes class
    ├── typed-bytes.ts    # PrivateKey, PublicKey, Reference, etc.
    ├── tokens.ts         # BZZ and DAI token classes
    ├── http.ts           # axios HTTP wrapper
    ├── error.ts          # Error classes
    ├── constants.ts      # Exported constants
    ├── duration.ts       # Duration helper class
    ├── size.ts           # Size helper class
    ├── cid.ts            # CID ↔ Reference conversion
    ├── collection*.ts    # Collection building (node + browser)
    ├── data*.ts          # Data preparation (node + browser)
    ├── tar*.ts           # Tar archive (node + browser)
    ├── chunk-stream*.ts  # Streaming uploads (node + browser)
    ├── expose.ts         # Utils namespace exports
    ├── file.ts           # File type helpers
    ├── headers.ts        # Swarm header handling
    ├── mime.ts           # MIME type detection
    ├── pss.ts            # PSS utilities
    ├── redundancy.ts     # Erasure coding helpers
    ├── resource-locator.ts # Reference/ENS/CID resolution
    ├── stamps.ts         # Stamp cost calculations
    ├── type.ts           # Assertion/validation helpers
    ├── upload-progress.ts # Upload progress tracking
    ├── url.ts            # URL validation
    └── workaround.ts     # Platform workarounds
test/
├── unit/                 # Unit tests
└── integration/          # Integration tests (require Bee node)
```

AGENTS.md

We recommend also adding AGENTS.md with identical content. Different AI tools look for different filenames:

Tool File
Claude Code CLAUDE.md
Cursor .cursorrules or AGENTS.md
GitHub Copilot AGENTS.md or .github/copilot-instructions.md
OpenAI Codex AGENTS.md

Having both CLAUDE.md and AGENTS.md (same content) covers the broadest range of AI coding tools.

Reference

This is part of the effort tracked in https://github.com/ethersphere/DevRel/issues/825.


Generated with AI

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High: Likely tackled by core team if no one steps updif:easySomeone with a little familiarity can pick upkind:enhancementA net-new feature or an improvement to an existing feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions