Skip to main content

How many parties and legs

A settlement is not limited to two parties. The ceilings are enforced by the settlement contract at registration, and the API imposes no lower one of its own: Exceeding any of them reverts the registration. The exact party count for a given settlement is set by its template, not by the platform. Each template names the roles its product requires; a settlement must have exactly one party per named role, and no party in a role the template does not name. A standard DvP template names two roles, and the tri-party repo template names three (lender, borrower_1, borrower_2).

Two ways a settlement is created

They differ in how many parties they can carry, so pick by party count: Both routes run the same template-role validation, the same compliance screening, and reach the identical on-chain registration. Everything after creation - funding, the compliance gate, execution, recovery - is identical and party-count agnostic: the contract holds an array of legs and an array of party hashes and requires all of them. The guides below describe the paired route, since it is the more involved of the two. For a settlement with three or more parties, use direct initiation.

Parties

A party represents an entity in a settlement with a specific role. Party details are provided inline when submitting instructions - there is no separate registration step.

Party fields

A party object carrying any other key is refused with 422. KeyStone writes a party from the fields above alone, so a key it does not declare would be one you believe KeyStone holds and it does not.

Roles

Roles are defined by the template’s required_roles field. Every settlement must include parties covering all required roles. Role names are flexible - the template defines what roles are needed. Common role patterns:
  • DvP: buyer, seller
  • Repo: cash_provider, securities_provider
  • Tri-party repo: lender, borrower_1, borrower_2
  • Lending: lender, borrower
A template naming more than two roles can only be satisfied through direct initiation, since the paired route creates exactly two parties.

Wallet addresses and escrow

The wallet_address field is used for off-chain identification and for recipient reveal at settlement execution time. With the commitment-based deposit scheme:
  1. Deposit authorization - Each leg has a deposit_secret (random 32 bytes) and a deposit_key = keccak256(abi.encode(wallet, deposit_secret)). The party deposits by providing the secret from the wallet the key was computed for; the key binds both the depositor wallet and the secret. This preserves pre-execution privacy on public chains while ensuring only the screened wallet can deposit.
  2. Recipients bound at registration - Each leg’s recipient wallet is fixed permanently in registerSettlement. No later call can change where funds go, which is what makes execution autonomous and safe for any depositor to trigger.
  3. Pre-built calldata - The deposit-calldata endpoint returns pre-built calldata for each leg, one leg per call, so platforms can submit deposit transactions directly via their custody provider or any signing infrastructure. That endpoint is the only place the API serves the deposit secret; settlement reads never include it.
Parties interact with escrow contracts directly using their own custody solution (MPC wallets, institutional signing infrastructure, etc.). KeyStone does not handle deposits or custody.

Example: providing party details in an instruction

Cross-platform parties

On the paired route, each platform provides its own party’s details independently in its own instruction. When the two instructions are confirmed against each other, the settlement is created with both parties confirmed from the start. On the direct route, the submitting platform supplies every party’s details in the one call. See Cross-Platform Settlements for the full flow.

Legs

A leg represents a single obligation within a settlement - something that needs to move from one party to another. A settlement carries 1 to 50 legs, and there is no requirement that they pair up: a tri-party repo opens with one collateral leg and two cash legs.

Leg fields

Deposit material (the leg’s deposit_secret and its on-chain deposit_key) is not part of the leg read model. The secret is served one leg at a time by POST /v1/settlements/{id}/legs/{leg_index}/deposit-calldata, embedded in pre-built transaction calldata.

Instrument ID formats

The instrument_id identifies what is being transferred. The format depends on the asset type: In production, always use the deployed contract address. In documentation examples, we sometimes use human-readable shorthand like USDC or ISINs like US09311A1007 for clarity.

Who deposits to escrow?

Only legs with direction: "deliver" require an escrow deposit. The party assigned to a deliver-direction leg is the one who must deposit the corresponding tokens to the escrow contract. Legs with direction: "receive" are fulfilled automatically when the escrow executes the settlement atomically.

How legs relate to parties

Legs reference parties by role, not by ID:
This reads as: “The party with role seller delivers 100 units of token 0xTokenAddress.”

How legs map to escrow deposits

Each leg with direction: "deliver" creates a deposit obligation on the escrow contract. The escrow uses a commitment scheme: each leg has a deposit_key registered on-chain, and the party deposits by providing the deposit_secret (preimage) from the bound wallet. The contract verifies keccak256(abi.encode(msg.sender, secret)) == depositKey, so only the wallet the key was computed for can deposit. When all deliver-direction legs have confirmed deposits, the atomicity gate passes. The API generates deposit secrets at settlement creation, stores them encrypted, and serves each one only through the deposit-calldata endpoint, embedded in pre-built calldata for that leg, so platforms can submit deposit transactions directly without handling the commitment scheme themselves.

Multiple legs

A settlement can have any number of legs; each instruction must carry at least one. The template’s required_roles governs which parties must be present, and the legs each party submits define the obligations. Typical leg sets by settlement type: