Repo layout
A map of dead-pool-aka-wilson/apyx-sdk. The repo is a small
pnpm workspace: one publishable package (the SDK), one in-tree
playground (the example app), one mdBook (this manual).
- Top level
src/— what gets publishedexample/— playgroundtest/— vitestbook/— this manual- CI workflows
- Naming conventions
- Related
Top level
apyx-sdk/
├── abis/ # JSON ABIs vendored from apyx-labs/subquery
├── book/ # mdBook user manual (this site)
├── example/ # browser playground (Vite + React 19 + Tailwind)
├── scripts/ # tsx generators (gen:abis, etc.)
├── src/ # SDK + CLI source
├── test/ # vitest unit + e2e specs
├── package.json # publishable package — @koed_jang/apyx-sdk
├── pnpm-workspace.yaml # workspace: root + example/
├── rollup.config.mjs # ESM (browser) + CJS (Node) + CLI bundles
├── tsconfig.json
├── vitest.config.ts # unit tests
└── vitest.e2e.config.ts # fork + packaging tests
src/ — what gets published
src/
├── addresses.ts # APYX_ADDRESSES + getAddresses + UnsupportedChainError
├── client.ts # createApyxClient — the single public factory
├── errors.ts # WalletClientRequiredError + InvalidAddressError
├── index.ts # re-export barrel
├── contracts/
│ ├── apxUSD.ts # ERC-20 + permit + supply views
│ ├── apyUSD.ts # ERC-4626 + share-token ERC-20 surface
│ └── apyUSDRateView.ts# apy / annualizedYield / vault / precision
├── generated/ # `as const` ABI tuples (see `pnpm gen:abis`)
└── cli/ # apyx CLI (Node-only)
├── cli.ts # entry — argv parsing, dispatch
├── config.ts # config schema, resolution rules, validation
├── repl.ts # Node REPL with injected globals
├── signer.ts # key + ledger dispatch (resolveSigner)
├── ledger.ts # @ledgerhq/hw-app-eth dynamic import
└── commands/ # contract-registry.ts (the 18-command source of truth)
The factory createApyxClient in src/client.ts is the
gateway. Every consumer either calls it directly (programmatic) or via
the CLI (which calls it under the hood).
example/ — playground
example/
├── src/ # React app
├── e2e/smoke.spec.ts # Playwright smoke (CI-runnable)
├── package.json # @apyx-labs/sdk-playground (private)
├── playwright.config.ts
├── tailwind.config.js
├── vite.config.ts
└── README.md # → see book/src/playground/*
The playground depends on the SDK via the workspace protocol
("@koed_jang/apyx-sdk": "workspace:*"). Edits to src/** reflect
without re-publishing.
test/ — vitest
test/
├── *.spec.ts # unit tests (run via `pnpm test`)
└── e2e/
├── fixtures/ # anvil + funded-account helpers
├── sdk/ # SDK module tests against an anvil mainnet fork
├── cli/ # CLI tests (config, repl, methods, session-flags, ledger)
└── packaging/ # tarball install + CJS/ESM consumer smoke
Two vitest configs — vitest.config.ts for the unit suite,
vitest.e2e.config.ts for fork + packaging. The split keeps the
unit run under a few seconds and the e2e run isolated to PRs that
touch src/** or test/e2e/** (path-filtered in CI).
book/ — this manual
Already familiar.
book/
├── book.toml # mdBook config (mermaid + toc preprocessors)
├── src/SUMMARY.md # chapter map
└── src/**/*.md
CI builds via mdbook build book and lychee-checks all intra-book
links — see
.github/workflows/docs.yml.
CI workflows
.github/workflows/
├── ci.yml # lint + typecheck + unit tests on every push
├── e2e.yml # fork tests (anvil via foundry-toolchain action) on src/** + test/e2e/** changes
├── packaging.yml # nightly tarball install smoke
├── release.yml # npm publish on `v*` tags
└── docs.yml # mdbook build on book/** + src/** changes
Naming conventions
- Files: kebab-case for everything user-facing (
apyx-sdk,apyx.config.json,apxusd-balance-of.md); camelCase for TypeScript identifiers (createApyxClient,apxUSD.balanceOf); PascalCase for types and classes (ApyxClient,UnsupportedChainError). - Contract names:
apxUSD(lowercase ‘a’),apyUSD(lowercase ‘a’),apyUSDRateView. The same casing is used in code, the CLI command tree, and the docs. - Imports: ESM-style
from './x.js'(with.jsextension) throughoutsrc/because the CJS bundle is built via Rollup with the same source.
Related
- Build and test — what each of these scripts actually runs.
- E2E testing — the test plan.
- Releasing — what happens when
release.ymlfires.