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

# Add signers

> Add third-party signers to wallets allowing delegated transaction execution

To allow a third-party to transact on wallets, follow the guide below.

<Info>
  This guide assumes your application has already [configured signers](/wallets/using-wallets/signers/configure-signers) in the Dashboard.
</Info>

<View title="React" icon="react">
  To provision server-side access for user's wallets, use the `addSigners` method from the `useSigners` hook:

  ```tsx theme={"system"}
  addSigners: async ({address: string, signers: {signerId: string, policyIds: string[]}[]}) => Promise<{user: User}>
  ```

  ### Usage

  ```tsx theme={"system"}
  import {useSigners} from '@privy-io/react-auth';
  const {addSigners} = useSigners();
  ```

  <Tip>
    Check out the [starter repo](https://github.com/privy-io/examples/blob/main/privy-next-starter/src/components/sections/session-signers.tsx) for an end to end example of how to use signers.
  </Tip>

  ### Parameters

  The `addSigners` method accepts a `params` object with the following fields:

  <ParamField path="address" type="string" required>
    Address of the embedded wallet to add a signer to.
  </ParamField>

  <ParamField path="signers" type="object[]" required>
    <Expandable defaultOpen="true">
      <ParamField path="signerId" type="string" required>
        The key quorum ID that will be allowed to transact on the wallet. This is the same key quorum ID you generated in the [Generate an authorization key](/wallets/using-wallets/signers/configure-signers) step.
      </ParamField>

      <ParamField path="policyIds" type="string[]">
        An ID for a policy that any transaction from the signer must satisfy to be signed. This is an optional field, if not provided, no policies will apply to the signers requests. Note that at this time, each signer can only have one override policy.
      </ParamField>
    </Expandable>
  </ParamField>
</View>

<View title="React Native" icon="react">
  To provision server-side access for user's wallets, use the `addSigners` method from the `useSigners` hook:

  ```tsx theme={"system"}
  addSigners: async ({address: string, signers: {signerId: string, policyIds: string[]}[]}) => Promise<{user: PrivyUser}>
  ```

  ### Usage

  ```tsx theme={"system"}
  import {useSigners} from '@privy-io/expo';
  const {addSigners} = useSigners();
  ```

  ### Parameters

  The `addSigners` method accepts a `params` object with the following fields:

  <ParamField path="address" type="string" required>
    Address of the embedded wallet to add a signer to.
  </ParamField>

  <ParamField path="signers" type="object[]" required>
    <Expandable defaultOpen="true">
      <ParamField path="signerId" type="string" required>
        The key quorum ID that will be allowed to transact on the wallet. This is the same key quorum ID you generated in the [Generate an authorization key](/wallets/using-wallets/signers/configure-signers) step.
      </ParamField>

      <ParamField path="policyIds" type="string[]">
        An ID for a policy that any transaction from the signer must satisfy to be signed. This is an optional field, if not provided, no policies will apply to the signers requests. Note that at this time, each signer can only have one override policy.
      </ParamField>
    </Expandable>
  </ParamField>
</View>

<View title="Swift" icon="swift">
  To provision server-side access for user's wallets, use the `addSigners` or `addSigner` method on an `EmbeddedWallet`:

  ```swift theme={"system"}
  func addSigners(_ signers: [SignerInput]) async throws
  func addSigner(_ signer: SignerInput) async throws
  ```

  ### Usage

  ```swift theme={"system"}
  guard let user = await privy.getUser() else {
      return
  }

  // Retrieve the desired embedded wallet
  guard let wallet = user.embeddedEthereumWallets.first else {
      return
  }

  // Add multiple signers
  let signers = [
      SignerInput(signerId: "your-key-quorum-id", policyIds: ["your-policy-id"]),
      SignerInput(signerId: "another-key-quorum-id")
  ]
  try await wallet.addSigners(signers)

  // Or add a single signer
  let signer = SignerInput(signerId: "your-key-quorum-id", policyIds: ["your-policy-id"])
  try await wallet.addSigner(signer)
  ```

  ### Parameters

  The `addSigners` method accepts an array of `SignerInput` objects with the following fields:

  <ParamField path="signerId" type="String" required>
    The key quorum ID that will be allowed to transact on the wallet. This is the same key quorum ID generated in the [Generate an authorization key](/wallets/using-wallets/signers/configure-signers) step.
  </ParamField>

  <ParamField path="policyIds" type="[String]?">
    An optional list of policy IDs that any transaction from the signer must satisfy to be signed. If `nil`, the wallet's default policies apply. Note that at this time, each signer can only have one override policy.
  </ParamField>

  The `addSigner` method is a convenience method that accepts a single `SignerInput` object with the same fields.
</View>

<View title="Android" icon="android">
  To provision server-side access for user's wallets, use the `addSigners` or `addSigner` method on an `EmbeddedWallet`:

  ```kotlin theme={"system"}
  suspend fun addSigners(signers: List<SignerInput>): Result<Unit>
  suspend fun EmbeddedWallet.addSigner(signer: SignerInput): Result<Unit>
  ```

  ### Usage

  ```kotlin theme={"system"}
  val user = privy.getUser() ?: return

  // Retrieve the desired embedded wallet
  val wallet = user.embeddedEthereumWallets.firstOrNull() ?: return

  // Add multiple signers
  val signers = listOf(
      SignerInput(signerId = "your-key-quorum-id", policyIds = listOf("your-policy-id")),
      SignerInput(signerId = "another-key-quorum-id")
  )
  wallet.addSigners(signers).fold(
      onSuccess = { /* Signers added successfully */ },
      onFailure = { error -> println("Error adding signers: ${error.message}") }
  )

  // Or add a single signer
  val signer = SignerInput(signerId = "your-key-quorum-id", policyIds = listOf("your-policy-id"))
  wallet.addSigner(signer).fold(
      onSuccess = { /* Signer added successfully */ },
      onFailure = { error -> println("Error adding signer: ${error.message}") }
  )
  ```

  ### Parameters

  The `addSigners` method accepts a list of `SignerInput` objects with the following fields:

  <ParamField path="signerId" type="String" required>
    The key quorum ID that will be allowed to transact on the wallet. This is the same key quorum ID generated in the [Generate an authorization key](/wallets/using-wallets/signers/configure-signers) step.
  </ParamField>

  <ParamField path="policyIds" type="List<String>?">
    An optional list of policy IDs that any transaction from the signer must satisfy to be signed. If `null`, the wallet's default policies apply. Note that at this time, each signer can only have one override policy.
  </ParamField>

  The `addSigner` method is a convenience extension that accepts a single `SignerInput` object with the same fields.
</View>

<View title="Flutter" icon="flutter">
  To provision server-side access for user's wallets, use the `addSigners` or `addSigner` method on an `EmbeddedWallet`:

  ```dart theme={"system"}
  Future<Result<void>> addSigners(List<SignerInput> signers)
  Future<Result<void>> addSigner(SignerInput signer)
  ```

  ### Usage

  ```dart theme={"system"}
  final user = await privy.getUser();
  if (user == null) return;

  // Retrieve the desired embedded wallet
  final wallet = user.embeddedEthereumWallets.firstOrNull;
  if (wallet == null) return;

  // Add multiple signers
  final signers = [
    SignerInput(signerId: 'your-key-quorum-id', policyIds: ['your-policy-id']),
    SignerInput(signerId: 'another-key-quorum-id'),
  ];
  final result = await wallet.addSigners(signers);
  result.fold(
    onSuccess: (_) {
      // Signers added successfully
    },
    onFailure: (error) {
      print('Error adding signers: $error');
    },
  );

  // Or add a single signer
  final signer = SignerInput(signerId: 'your-key-quorum-id', policyIds: ['your-policy-id']);
  final singleResult = await wallet.addSigner(signer);
  singleResult.fold(
    onSuccess: (_) {
      // Signer added successfully
    },
    onFailure: (error) {
      print('Error adding signer: $error');
    },
  );
  ```

  ### Parameters

  The `addSigners` method accepts a list of `SignerInput` objects with the following fields:

  <ParamField path="signerId" type="String" required>
    The key quorum ID that will be allowed to transact on the wallet. This is the same key quorum ID generated in the [Generate an authorization key](/wallets/using-wallets/signers/configure-signers) step.
  </ParamField>

  <ParamField path="policyIds" type="List<String>?">
    An optional list of policy IDs that any transaction from the signer must satisfy to be signed. If `null`, the wallet's default policies apply. Note that at this time, each signer can only have one override policy.
  </ParamField>

  The `addSigner` method is a convenience wrapper that accepts a single `SignerInput` object with the same fields.
</View>

<View title="NodeJS & REST API" icon="node-js">
  Make a request to [update the wallet](/wallets/wallets/update-a-wallet) with the desired
  `additional_signers` you'd like to add. The wallet owner must
  [sign](/controls/authorization-keys/using-owners/sign) the request.
</View>
