> ## Documentation Index
> Fetch the complete documentation index at: https://build.onswig.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Roles

> Prepare, sign, and submit the transaction that adds an authority to an existing wallet.

Use `wallet.roles.add()` to prepare a transaction that attaches a new authority
and its permitted actions to an existing Swig wallet. Your application signs
and submits the transaction.

Choose the actions from the [Permissions](/developer-sdk/permissions)
reference, then follow this guide to add the role.

General role creation is available in TypeScript `0.10.0` and Python `0.9.0`.

## Before you begin

You need:

* an existing Swig config address
* the fee payer public key
* an existing Ed25519 or secp256r1 requester authority whose role includes
  `manageAuthority` or `all`
* the public authority value for the new role
* one or more actions for the new role

The address variables below are base58 strings. `signAndSubmit` /
`sign_and_submit` represents your application-owned signing, RPC submission,
and confirmation helper.

## Add a scoped SOL-transfer role

This example gives a new Ed25519 authority permission to transfer up to
1,000,000 lamports through Solana's System Program.

<CodeGroup dropdown>
  ```typescript TypeScript theme={null}
  import { SystemProgram } from '@solana/web3.js';

  const wallet = swig.wallets.use(swigConfigAddress, {
    requesterAuthority: {
      ed25519: { publicKey: adminPublicKey },
    },
  });

  const prepared = await wallet.roles.add({
    feePayer,
    authority: {
      ed25519: { publicKey: newRolePublicKey },
    },
    actions: [
      {
        type: 'program',
        programId: SystemProgram.programId.toBase58(),
      },
      { type: 'solLimit', amount: 1_000_000n },
    ],
  });

  await signAndSubmit(prepared);
  ```

  ```python Python theme={null}
  from solders.system_program import ID as SYSTEM_PROGRAM_ID
  from swig_developer_sdk import ProgramAction, SolLimitAction

  wallet = swig.wallets.use(
      swig_config_address,
      requester_authority={
          "ed25519": {"publicKey": admin_public_key}
      },
  )

  prepared = await wallet.roles.add(
      fee_payer=fee_payer,
      authority={
          "ed25519": {"publicKey": new_role_public_key}
      },
      actions=(
          ProgramAction(program_id=str(SYSTEM_PROGRAM_ID)),
          SolLimitAction(amount=1_000_000),
      ),
  )

  await sign_and_submit(prepared)
  ```
</CodeGroup>

Both actions belong to the same new role. `program` permits the System Program
invocation, while `solLimit` provides the role's remaining one-time SOL budget.
Each successful transfer decrements that budget. SignV2 checks program access
and SOL spending independently, so the transfer needs both permissions.

For other operations, choose the required actions and fields from
[Permissions](/developer-sdk/permissions).

## Choose the new authority

The new role may use any of these authority shapes:

| Authority | New-role shape | Typical use |
| :- | :- | :- |
| Ed25519 | `{ ed25519: { publicKey } }` | Solana keypair or custody signer |
| secp256r1 | `{ secp256r1: { publicKey } }` | Passkey-backed signer |
| secp256k1 | `{ secp256k1: { publicKey } }` | EVM-compatible signer |
| ParticipantSet | `{ participantSet: { address } }` | M-of-N threshold authorization |

For a ParticipantSet role, create the set first and pass its address without a
role ID. Adding the authority creates a new role whose ID is assigned by Swig.
Continue to [Participant Sets](/developer-sdk/participant-sets) for member
approval collection and compilation.

<Note>
  The authority being added may use any supported shape above. The existing
  authority requesting the add-role operation must use Ed25519 or secp256r1.
</Note>

## Confirm the role

The add-role call returns a prepared transaction; it does not broadcast or
confirm it. After your signing helper submits the transaction and it lands,
read the wallet roles to confirm the new authority and actions.

<CodeGroup dropdown>
  ```typescript TypeScript theme={null}
  const { roles } = await wallet.roles.list();
  console.log(roles);
  ```

  ```python Python theme={null}
  roles_result = await wallet.roles.list()
  print(roles_result.roles)
  ```
</CodeGroup>

Wait for the add-role transaction to confirm before using the new authority.
Keep every private key, passkey assertion, and authorization decision in your
application-owned signing layer.

## Request boundaries

* Supply at least one action.
* Use an existing Ed25519 or secp256r1 authority as the requester.
* Pass a ParticipantSet address without a role ID when adding it as the new
  authority.
* Add the transaction-level signatures required by the serialized transaction
  before submission.

## What to read next

<CardGroup cols={2}>
  <Card title="Participant Sets" icon="users" href="/developer-sdk/participant-sets">
    Add M-of-N threshold authorization to a role
  </Card>

  <Card title="Transfer SOL and Tokens" icon="arrow-right-arrow-left" href="/developer-sdk/transfers-and-swaps">
    Use a configured role for wallet transfers
  </Card>

  <Card title="Permissions" icon="sliders" href="/developer-sdk/permissions">
    Look up available actions, fields, and units
  </Card>

  <Card title="Sponsor & Submit" icon="paper-plane" href="/developer-sdk/sponsor-and-submit">
    Submit application-signed transactions
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.