Guidance for AI coding agents (Claude Code, Cursor, Copilot, etc.) working in this repository. Humans: see CONTRIBUTING.md — this file is a condensed, agent-oriented companion to it, not a replacement.
starknet.js is the JavaScript/TypeScript SDK for Starknet. It is a published npm
library (starknet), so the public API surface is a contract — treat breaking
changes deliberately (see Conventions).
- Node
>=22is required. Install withnpm install. npm run build— full build viatsup(CJS + ESM + IIFE +.d.ts). Required before publishing-related tasks; not needed just to run unit tests.npm run lint— ESLint (airbnb + prettier), autofix on.npm run ts:check— type-check only (tsc --noEmit).npm run format— Prettier write.
There are two kinds of tests, and the default command needs live infrastructure:
-
Unit tests — no infra needed. Use this loop.
npm run test:unit # all pure unit tests (~1400 tests, ~20s) npm run test:unit -- __tests__/utils/uint256.test.ts # a single file
This uses
jest.unit.config.ts, which runs the pure suites under__tests__/utils/and skips the devnet-connecting global setup. Use it to verify changes tosrc/utils/**and other logic with unit coverage. -
Integration tests — require a running Starknet devnet or RPC node.
npm test,npm run test:coverage, andnpm run test:watchrun the full suite viajest.config.ts, whoseglobalSetupthrows if it cannot reach a devnet (http://127.0.0.1:5050) and noTEST_ACCOUNT_*env vars are set. The root-level__tests__/*.test.tssuites (account, contract, provider, paymaster, wallet…) exercise real RPC calls. To run them, start a devnet (Docker:shardlabs/starknet-devnet-rs, 0.9.2 or later, which thenode-wsproject needs for JSON-RPC batches over/ws) or point at a node viaTEST_RPC_URL+TEST_ACCOUNT_ADDRESS+TEST_ACCOUNT_PRIVATE_KEY(see CONTRIBUTING.md). Two suites under__tests__/utils/(ethSigner,batch) also need a node and are excluded fromtest:unit.That one command declares four Jest projects, and the available URLs decide which ones exist:
Project Files Runs when unittests that never build a provider always node-httptests that do, over HTTP an HTTP url resolves node-wsthe same files, over a WebSocket a WS url resolves ws-specific*.ws.test.ts, needing a live socketa WS url resolves So a node-touching file runs twice, once per transport — expect two results per file, and
--selectProjects=node-httpto look at one.TEST_WS_URLenables the two WebSocket projects; against a devnet it is derived fromTEST_RPC_URLautomatically. A file needing a socket of its own says so by being named*.ws.test.ts.Only one account is authorized per run, so the config pins
maxWorkers: 1. Do not raise it: parallel suites drive the same account and fail on nonces and duplicate transaction hashes — errors that look like application bugs.
If you cannot start a devnet, run npm run test:unit + npm run lint +
npm run ts:check and say so explicitly — do not claim the full suite passed.
High-level classes are re-exported from src/index.ts; utils are exported as
namespaces (hash, num, cairo, shortString, …).
| Module | What lives there |
|---|---|
account/ |
Account (+ AccountInterface) — signs and sends transactions, declares/deploys, fees. |
contract/ |
Contract (+ ContractInterface) — typed wrapper to call/invoke a deployed contract via its ABI. |
provider/ |
RpcProvider (+ ProviderInterface) — read chain state; RPCResponseParser shapes responses. WebSocketProvider serves requests and subscriptions from one socket. |
channel/ |
JSON-RPC layer: RpcChannel (requests) and SubscriptionChannel / Subscription (WS subscriptions), both versioned; WebSocketChannel bundles a socket with the subscription surface. |
channel/transport/ |
What carries the envelopes, below the channels and independent of the spec version: HttpTransport, WsTransport, ReconnectingWsTransport. |
signer/ |
Signer, EthSigner, LedgerSigner* (+ SignerInterface) — message/transaction signing. The LedgerSigner* exported from here are deprecated: see ledger/. |
ledger/ |
Entry point of starknet/ledger (built to dist/ledger/): LedgerSigner* typed with the Ledger Transport. In v11 they extend the classes of signer/. |
falcon/ |
Entry point of starknet/falcon (built to dist/falcon/): Falcon512Signer, a post-quantum signer for the S2morrow account. engine/noble/ is a patched copy of noble: see PATCH.md. |
wallet/ |
WalletAccountV6 (recommended) / WalletAccountV5 / WalletAccount (deprecated) — browser wallet (get-starknet / wallet-standard) integration. |
paymaster/ |
PaymasterRpc (+ PaymasterInterface) — gasless / sponsored transaction flows. |
deployer/ |
Deployer (+ DeployerInterface) — UDC-based contract deployment helpers. |
plugins/ |
Plugin framework + implementations (starknet-id, fast-execute, brother-id). |
service/ |
Shared service-layer types. |
utils/ |
Pure helpers: calldata (encode/decode), hash, cairoDataTypes, num, shortString, merkle, typedData, transaction, address, ec, etc. Most have unit tests → test:unit. |
types/ |
Public TypeScript types, including RPC API types (types/api) and Starknet spec bindings. |
global/ |
Global config, constants, and logger. |
Multiple RPC spec versions are supported simultaneously (e.g. v0_8, v0_9); the
pinned starknet_specs dev-dependencies define them. Be version-aware when touching
channel/, provider/, or types/api.
Spec version and transport are two independent axes: the same channel code runs over
HTTP or over a WebSocket, and only channel/transport/ knows which. A change that ties
one axis to the other is a design regression, not a shortcut.
- Conventional Commits, enforced by commitlint (
feat(scope): subject). Onlyfeatandfixdrive the changelog — usechore/test/docs/refactorfor non-shipping changes. Subjects describe the change relative to the target branch, not your feature branch. - PR target branches (see CONTRIBUTING.md for the full table):
develop→ default target for fixes, features, docs (npm tagnext).beta→ API-breaking / behavior-changing work; mark the breaking change in the commit (npm tagbeta).main/maintenance/*→ maintainers only.
- Do not edit the version number or
CHANGELOG.md— semantic-release owns both. - Do not commit generated files (
dist/, coverage). Updatepackage-lock.jsonwhen you change dependencies. - Update docs in
www/and add tests for any behavior change (see CONTRIBUTING.md). skills/starknet-js/is the published agent skill that teaches AI coding agents how to use this library (installable vianpx skills add starknet-io/starknet.js). If you change the public API surface (signatures, constructor options, calldata handling…), check that the skill files are not made stale, and update them in the same PR if they are. The lineSkill verified against **starknet.js X.Y.Z**.inSKILL.mdis parsed bywww/docusaurus.config.tsto show the version on the docs landing page: change only the version number, or update the regex there in the same change — an unrecognized stamp fails the docs build.
npm testreformats files afterwards (posttestruns Prettier) — running it can leave unexpected diffs in your working tree.pretestrunslint+ts:checkbefore tests, sonpm testcan fail on a lint or type error before a single test executes.- A
pre-commithusky hook runs lint-staged andcommit-msgruns commitlint. A badly formatted commit message is rejected at commit time — get the format right up front. - The default test suite hard-fails without a reachable devnet (see above). A bare
jest <path>will also hit this — go throughnpm run test:unitfor infra-free runs. .claude/is git-ignored, so per-user agent config there is local-only. ThisAGENTS.mdis the shared, committed source of truth. Tools that only read aCLAUDE.md(e.g. Claude Code) can use a local, git-ignoredCLAUDE.mdthat points here.