Skip to content

Reference

createParty

Allocate a new party on the validator, optionally fund its wallet, and pre-approve incoming transfers in one call. The fastest way to mint a usable party for tests, fixtures, and onboarding flows.

createParty is a high-level helper that wraps three lower-level operations into a single typed call:

  1. Calls validator.createUser to allocate a new party (and underlying user) on the validator.
  2. If amount > 0, creates and accepts a transfer offer from the SDK’s acting party to fund the new wallet, then waits for the transfer to settle.
  3. Once funded, creates a TransferPreapproval so other parties can transfer to the new party without per-transfer acceptance.

This is the pattern most fixtures and onboarding flows want. If you only need a bare identity (no wallet, no preapproval), pass amount: '0' and the helper returns immediately after step 1.

Setup

import { Canton, createParty } from '@fairmint/canton-node-sdk';

const canton = new Canton({
  network: 'localnet',
  partyId: 'OWN_PARTY_ID', // funds come from this party
});

Minimal example — funded party with preapproval

const { partyId, preapprovalContractId } = await createParty({
  ledgerClient: canton.ledger,
  validatorClient: canton.validator,
  partyName: 'alice',
  amount: '100',
});

console.log({ partyId, preapprovalContractId });

Minimal example — bare identity

const { partyId } = await createParty({
  ledgerClient: canton.ledger,
  validatorClient: canton.validator,
  partyName: 'bob',
  amount: '0',
});

When amount is '0', no transfer is created and preapprovalContractId is undefined.

Parameters

A single CreatePartyOptions object:

  • ledgerClient (required, LedgerJsonApiClient) — Authenticated ledger client. Almost always canton.ledger. Used to create the transfer offer, accept it on behalf of the new party, and create the preapproval contract.
  • validatorClient (required, ValidatorApiClient) — Authenticated validator client. Almost always canton.validator. Used for the underlying createUser call that allocates the party.
  • partyName (required, string) — Human-readable prefix that becomes part of the party ID. The validator appends a unique namespace; the returned partyId is what you use for everything else.
  • amount (required, string) — Amulet amount to fund the new wallet with, as a decimal string. '0' skips funding and preapproval. Anything greater than zero triggers the full transfer plus preapproval flow. Must parse to a non-negative number.

Returns

Promise<PartyCreationResult>:

  • partyId (PartyId) — Branded party identifier returned by the validator. Use this for all subsequent ledger operations as the new party. Pass it to canton.setPartyId(partyId) if your process should now act as this party.
  • preapprovalContractId (ContractId, optional) — The TransferPreapproval contract created in step 3. Present only when amount > 0. Hand it to other parties (or store it on-chain) so they can pre-approve transfers without a round-trip per transfer.

Errors and pitfalls

  • Invalid amount: amount is parsed with parseFloat. Non-numeric or negative input throws a ValidationError synchronously before any network calls.
  • Funder is broke: The transfer offer is created from ledgerClient’s acting party. That party must hold at least amount in spendable Amulets, otherwise createTransferOffer fails. Check canton.validator.getWalletBalance() first if you’re not sure.
  • Settlement timeout: Step 2 polls for up to 60 seconds for the transfer to settle. On a congested network this can fail with a “Timeout waiting for transfer to settle” error even though the transfer eventually lands. Re-run with the same partyName to attach to the existing party (the validator-side createUser is idempotent on name in many configurations) or query the validator for the existing party first.
  • Preapproval is a one-time setup: It is created once per party. If you re-run createParty against an existing party with funding, the second preapproval creation will fail. Use amount: '0' or skip the helper entirely.
  • Party name collisions: Different validators have different rules. On localnet, names are usually free-form. On shared networks, choose a name unlikely to collide and treat the returned partyId as the source of truth.

Auth and party

Acts as the configured ledger party (the funder) and uses the validator’s user identity for createUser. The returned partyId is a new party — the helper does not switch the SDK’s acting party. If you want the rest of your script to operate as the new party, call canton.setPartyId(partyId) afterwards.

See also

Source

src/utils/party/createParty.ts on GitHub.