pnpm install- Install dependenciespnpm build- Compile TypeScript to dist/pnpm test- Run tests in watch modepnpm test:run- Run tests oncepnpm test:anvil- Run Anvil integration tests (requires local Anvil)pnpm lint- Run ESLintpnpm lint:fix- Run ESLint with auto-fixpnpm format- Format with Prettierpnpm format:check- Check formatting without writingpnpm typecheck- Type check without emitting
- ALWAYS run
pnpm lintbefore committing - ALWAYS run
pnpm formatbefore committing - ALWAYS run
pnpm typecheckbefore committing
- Use explicit type imports:
import type { Foo } from "./foo.js" - Prefer functional style over imperative loops
- Use
viemtypes for Ethereum primitives (Address, Hex, etc.) - Keep functions small and focused
- Write tests that fail fast - use direct assertions, no Result returns
- Avoid unnecessary nesting and closures
src/abi/- Contract ABIssrc/constants/- Chain configs and addressessrc/signing/- Order/fill signing and EIP-712 logicsrc/types/- TypeScript type definitionstests/- Test files (vectors.test.ts for cross-impl verification)
- Unit tests use Vitest
vectors.jsoncontains test vectors from Rust implementation- Integration tests require Anvil or testnet RPC access
- Tests should throw on failure, not return error types
viemis the only production dependency (as peerDep)- Keep dependencies minimal - this is a library
- ALWAYS update
CHANGELOG.mdwhen adding features, fixing bugs, or making breaking changes - Follow Keep a Changelog format
- Add entries under
[Unreleased]section during development - Categories: Added, Changed, Deprecated, Removed, Fixed, Security
Releases are automated via GitHub Actions. To release:
- Update version in
package.json - Move
[Unreleased]entries to a new version section inCHANGELOG.md - Commit and push to
main - CI creates GitHub release and publishes to npm
The SDK focuses on:
- Types and type definitions
- Contract ABIs
- EIP-712 signing logic
- Chain constants and addresses
- Complex operations that add real value (validation, aggregation, edge case handling)
The SDK should NOT include:
- Thin wrappers around viem's
readContract/writeContract - Simple parameter rearrangement helpers
- Functions that just inject a constant into a viem call
Instead, export the ABIs and constants, then document direct viem usage patterns in README.