createParty is a high-level helper that wraps three lower-level operations into a single typed call:
- Calls
validator.createUserto allocate a new party (and underlying user) on the validator. - 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. - Once funded, creates a
TransferPreapprovalso 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 alwayscanton.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 alwayscanton.validator. Used for the underlyingcreateUsercall that allocates the party.partyName(required, string) — Human-readable prefix that becomes part of the party ID. The validator appends a unique namespace; the returnedpartyIdis 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 tocanton.setPartyId(partyId)if your process should now act as this party.preapprovalContractId(ContractId, optional) — TheTransferPreapprovalcontract created in step 3. Present only whenamount > 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:
amountis parsed withparseFloat. Non-numeric or negative input throws aValidationErrorsynchronously before any network calls. - Funder is broke: The transfer offer is created from
ledgerClient’s acting party. That party must hold at leastamountin spendable Amulets, otherwisecreateTransferOfferfails. Checkcanton.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
partyNameto attach to the existing party (the validator-sidecreateUseris 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
createPartyagainst an existing party with funding, the second preapproval creation will fail. Useamount: '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
partyIdas 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
- External signing — when the new party’s keys must live outside the SDK.
Canton— construct the clients passed in here.preApproveTransfers— lower-level preapproval only.createTransferOfferandacceptTransferOffer— split transfer-offer steps.validator.createUser— the lower-level primitive if you need party allocation without funding.
Source
src/utils/party/createParty.ts on GitHub.