A Canton instance is the recommended entry point for @fairmint/canton-node-sdk. One constructor call wires up four cooperating handles — ledger, validator, scan, and the underlying runtime — all sharing the same OAuth2 token cache, party identity, and network/provider selection. You construct it once at process start and pass it (or its .ledger / .validator handles) into every other helper in the SDK.
Use Canton whenever you want HTTP, auth, and party identity to be coordinated. If you only ever need one client (typical for a serverless function that just polls Scan), you can still use Canton — the unused clients are cheap.
Install
npm install @fairmint/canton-node-sdk
Requires Node.js ≥ 22. TypeScript is strongly recommended; types ship with the package.
Minimal example
import { Canton } from '@fairmint/canton-node-sdk';
const canton = new Canton({
network: 'devnet',
provider: '5n',
});
// Authenticated ledger call
const version = await canton.ledger.getVersion();
// Authenticated validator call (same token cache)
const wallet = await canton.validator.getWalletBalance();
// Unauthenticated public network query
const dso = await canton.scan.getDsoInfo();
console.log({ version: version.version, wallet, dso });
The same shape works against a local Canton:
const local = new Canton({ network: 'localnet' });
When provider, partyId, OAuth credentials, or API URLs are omitted, Canton merges configuration from EnvLoader using CANTON_<NETWORK>_<PROVIDER>_* and related variables. See EnvLoader and the Quickstart for the exact .env layout.
What you get on the instance
After new Canton(config):
canton.ledger—LedgerJsonApiClient. All ledger reads/writes (commands, updates, ACS, packages, users, parties).canton.validator—ValidatorApiClient. Wallet, user, and validator-mediated party operations.canton.scan—ScanApiClient. Public Scan API. Often called without auth.canton.runtime—CantonRuntime. Shared HTTP/auth plumbing and the authentication-manager registry. Reach for it when you need a derived runtime (fork) or to understand how tokens are shared across clients.canton.getNetwork(),canton.getProvider()— read back what was resolved.canton.getPartyId()/canton.setPartyId(id)— identity helpers.setPartyIdupdates bothledgerandvalidatorin one call, useful when the party is discovered at runtime (for example fromvalidator.createUser).
All authenticated ledger and validator clients share the same cached OAuth sessions where their (authUrl, auth) pairs match. Authentication happens lazily on first authed call and is reused.
Parameters
new Canton(config: CantonConfig). Only network is required on the CantonConfig object; everything else falls back to env or runtime defaults when clients resolve their ApiConfig. See CantonConfig for every field.
Returns
The constructor returns a Canton instance with the clients above. There is no connect/init call; the instance is usable immediately. The first authenticated request triggers token acquisition through the runtime’s AuthenticationManager.
Errors and pitfalls
- Missing env:
Cantondoes not throw at construction for missing OAuth env. The first client operation that needs a resolved API config may surface aConfigurationErrornaming the missingCANTON_*key. To fail fast, eagerly callawait canton.ledger.getVersion()after construction. - Wrong party:
getPartyId()reads the constructorpartyIdfirst, then the ledger client’s resolved party. If neither is set, party-scoped operations throw. UsesetPartyIdaftervalidator.createUserto wire the freshly minted party in. - Scan vs ledger confusion:
scanis intentionally unauthenticated for most calls. Keep Scan base URLs onSCAN_API, not on ledger JSON API settings. - Reuse: Construct one
Cantonper process where possible. Token refresh and HTTP plumbing are tied to the runtime; per-request construction wastes work.
Auth and party
ledger and validator use OAuth2 (client_credentials or password), static bearer tokens, or a tokenGenerator, depending on how each service’s AuthConfig was resolved. scan is typically unauthenticated. The acting party for ledger commands comes from (in order): the per-call actAs field where applicable, then canton.getPartyId(), then env-derived API config. See AuthenticationManager and external signing when the acting party’s keys live outside the SDK.
See also
- Quickstart — full env layout and a minimal end-to-end run.
- CantonConfig — every constructor field in prose.
- CantonRuntime — shared auth registry and
fork. createParty— typical first call after construction.
Source
src/Canton.ts on GitHub.