Skip to main content
A ParticipantSet lets several independent members authorize one Swig role with an M-of-N threshold. The set belongs to one Swig config, and the role controls what the set may do through the same typed actions used by any other role. Members can use Ed25519, secp256r1/passkeys, or secp256k1. Each member signs a challenge bound to the prepared operation, while every challenge in the plan commits to the same shared ParticipantSet nonce. ParticipantSet support is available in TypeScript 0.10.0 and Python 0.9.0.

Create the set and add its role

This 2-of-2 example prepares a SOL-transfer role using two Ed25519 members. First prepare and submit the ParticipantSet creation transaction. After that transaction lands, use the general Add Roles flow to attach the set to a role and choose its permissions. The address variables below are base58 strings. adminPublicKey / admin_public_key identifies the existing role allowed to add the new role. signAndSubmit / sign_and_submit represents your application-owned signing, RPC submission, and confirmation helper. wallets.use accepts the bare Swig config address used below. Pass a full wallet reference instead when your application already has both the config and wallet addresses.
TypeScript
Both SDK calls return prepared transactions. Wait for the ParticipantSet creation transaction to confirm before preparing the add-role transaction. Creating the set does not add a Swig role automatically.
Keep both actions on a scoped SOL-transfer role. The program action permits the wallet to invoke Solana’s System Program, while solLimit caps the lamports that may leave the wallet. SignV2 checks these permissions independently, so solLimit alone does not authorize the program invocation. The Developer SDK calls this action program; the Protocol SDK builder calls the same permission programLimit.
solLimit is the role’s remaining one-time SOL budget. Each successful transfer decrements it, so size the initial allowance for the operations the role should perform. The add-role requester must currently be an Ed25519 or secp256r1 authority. A ParticipantSet can be the new role authority, but cannot request the add-role operation itself.

Prepare an operation

After both setup transactions land, select the ParticipantSet as the requester. Supported preparation routes return a normal prepared transaction with a participantSetApprovalPlan / participant_set_approval_plan.
TypeScript
ParticipantSet preparation currently supports SOL transfers, token transfers, transfer batches, and custom instructions without address lookup tables. Swaps and custom transactions with address lookup tables require a direct non-ParticipantSet requester. Recovery preparation is not currently supported; see Guardian recovery for the scoped permission model and a possible extension requiring multiple approvals. Serialize ParticipantSet operations per set. Concurrent plans use the same next nonce; after one transaction lands, prepare and approve the others again.

Collect member approvals

Send each selected member only its own approval request. The detached signer helpers verify that the signer type and public key match that request before asking the application-owned signer to approve it.
TypeScript
Production applications normally distribute each request to its owning member and collect the resulting approvals out of band. The in-process 2-of-2 example keeps both Ed25519 callbacks together only to show the complete data flow. Your application remains responsible for passkey credential selection and its RP ID/origin policy. Do not ask a member to sign the raw serialized transaction or another member’s challenge.

Compile and submit

Return the detached approvals with the original prepared transaction. The API validates the plan and simulates the final transaction before returning it.
TypeScript
Compilation does not sponsor, broadcast, or confirm the transaction. Add every remaining Solana transaction signature, then submit directly or use Sponsor & Submit before the authorization expiration slot. If the slot has passed, prepare a fresh operation and collect fresh approvals. Compilation also rejects insufficient or duplicate approvals and a plan whose shared nonce no longer matches the on-chain ParticipantSet. Prepare a fresh operation after another transaction consumes the nonce.

Approval and submission boundaries

  • Prepare a fresh plan and collect fresh approvals for each distinct transaction.
  • Keep every approval with its original plan and shared nonce.
  • Keep the Swig API key in the server client; detached signer helpers accept no API key and make no hosted API calls.
  • Add transaction-level signatures such as the fee payer or another required Ed25519 signer after compilation.