# 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)
```
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:
cafe-utilitydependency conventionProposed
CLAUDE.mdClick to expand full file
AGENTS.mdWe recommend also adding
AGENTS.mdwith identical content. Different AI tools look for different filenames:CLAUDE.md.cursorrulesorAGENTS.mdAGENTS.mdor.github/copilot-instructions.mdAGENTS.mdHaving both
CLAUDE.mdandAGENTS.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