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

# Program Derived Addresses (PDAs)

> Learn how to use Program Derived Addresses for deterministic account creation and program signing in Anchor

Program Derived Addresses (PDAs) are deterministic addresses derived from a program ID and a set of seeds. PDAs enable programs to sign for accounts without requiring a private key.

## What are PDAs?

PDAs are addresses that:

1. Are derived deterministically from seeds and a program ID
2. Do not have a corresponding private key
3. Can only be signed by the program that derived them
4. Are guaranteed to not lie on the ed25519 curve

## Finding PDAs

To find a PDA, use `Pubkey::find_program_address`:

```rust theme={null}
let (pda, bump) = Pubkey::find_program_address(
    &[b"vault", user.key().as_ref()],
    program_id
);
```

The `bump` is a value (0-255) that ensures the address doesn't lie on the curve.

## Using PDAs in Anchor

Anchor simplifies PDA usage with the `seeds` and `bump` constraints:

### Initializing PDAs

```rust theme={null}
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = user,
        space = 8 + 32 + 8,
        seeds = [b"vault", user.key().as_ref()],
        bump
    )]
    pub vault: Account<'info, Vault>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}
```

Anchor automatically:

* Derives the PDA address
* Finds the bump seed
* Validates the derived address matches the provided account

### Accessing PDAs

```rust theme={null}
#[derive(Accounts)]
pub struct Access<'info> {
    #[account(
        seeds = [b"vault", user.key().as_ref()],
        bump
    )]
    pub vault: Account<'info, Vault>,
    pub user: Signer<'info>,
}
```

For existing PDAs, Anchor validates the address without the `init` constraint.

## Storing the bump

Store the bump seed in your account to avoid recalculating it:

```rust theme={null}
#[account]
pub struct Vault {
    pub authority: Pubkey,
    pub bump: u8,
}

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
    let vault = &mut ctx.accounts.vault;
    vault.authority = ctx.accounts.user.key();
    vault.bump = ctx.bumps.vault;  // Access the bump
    Ok(())
}
```

Then use it in future instructions:

```rust theme={null}
#[account(
    seeds = [b"vault", user.key().as_ref()],
    bump = vault.bump  // Use stored bump
)]
pub vault: Account<'info, Vault>,
```

## Signing with PDAs

Programs can sign CPIs using PDA seeds:

```rust theme={null}
pub fn transfer_from_vault(ctx: Context<TransferFromVault>, amount: u64) -> Result<()> {
    let seeds = &[
        b"vault",
        ctx.accounts.authority.key().as_ref(),
        &[ctx.accounts.vault.bump],
    ];
    let signer_seeds = &[&seeds[..]];

    let cpi_context = CpiContext::new_with_signer(
        ctx.accounts.token_program.to_account_info(),
        Transfer {
            from: ctx.accounts.vault_token_account.to_account_info(),
            to: ctx.accounts.destination.to_account_info(),
            authority: ctx.accounts.vault.to_account_info(),
        },
        signer_seeds,
    );

    transfer(cpi_context, amount)?;
    Ok(())
}
```

## PDA use cases

### 1. Deterministic account addresses

Create predictable addresses for user-specific accounts:

```rust theme={null}
// User profile PDA
seeds = [b"profile", user.key().as_ref()]

// Token vault PDA
seeds = [b"vault", mint.key().as_ref(), user.key().as_ref()]
```

### 2. Program authority

Use PDAs as authorities for tokens or other accounts:

```rust theme={null}
#[derive(Accounts)]
pub struct InitializeVault<'info> {
    #[account(
        init,
        payer = authority,
        seeds = [b"vault"],
        bump,
        token::mint = mint,
        token::authority = vault
    )]
    pub vault: Account<'info, TokenAccount>,
    // ...
}
```

### 3. Account relationships

Enforce relationships between accounts:

```rust theme={null}
// Game account PDA derived from player
seeds = [b"game", player.key().as_ref()]

// Item PDA derived from game and item ID
seeds = [b"item", game.key().as_ref(), &item_id.to_le_bytes()]
```

## Multiple seeds

You can use multiple seeds for more specific PDAs:

```rust theme={null}
#[account(
    init,
    payer = user,
    space = 8 + 32,
    seeds = [
        b"escrow",
        user.key().as_ref(),
        mint.key().as_ref(),
        &escrow_id.to_le_bytes()
    ],
    bump
)]
pub escrow: Account<'info, Escrow>,
```

## Complete example

```rust theme={null}
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer};

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod pda_example {
    use super::*;

    pub fn initialize_vault(ctx: Context<InitializeVault>) -> Result<()> {
        let vault = &mut ctx.accounts.vault;
        vault.authority = ctx.accounts.authority.key();
        vault.bump = ctx.bumps.vault;
        msg!("Vault initialized at {}", vault.key());
        Ok(())
    }

    pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
        let authority_key = ctx.accounts.authority.key();
        let seeds = &[
            b"vault",
            authority_key.as_ref(),
            &[ctx.accounts.vault.bump],
        ];
        let signer_seeds = &[&seeds[..]];

        let cpi_context = CpiContext::new_with_signer(
            ctx.accounts.token_program.to_account_info(),
            Transfer {
                from: ctx.accounts.vault_token_account.to_account_info(),
                to: ctx.accounts.user_token_account.to_account_info(),
                authority: ctx.accounts.vault.to_account_info(),
            },
            signer_seeds,
        );

        token::transfer(cpi_context, amount)?;
        msg!("Withdrew {} tokens from vault", amount);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct InitializeVault<'info> {
    #[account(
        init,
        payer = authority,
        space = 8 + 32 + 1,
        seeds = [b"vault", authority.key().as_ref()],
        bump
    )]
    pub vault: Account<'info, Vault>,
    #[account(mut)]
    pub authority: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Withdraw<'info> {
    #[account(
        seeds = [b"vault", authority.key().as_ref()],
        bump = vault.bump,
        has_one = authority
    )]
    pub vault: Account<'info, Vault>,
    #[account(mut)]
    pub vault_token_account: Account<'info, TokenAccount>,
    #[account(mut)]
    pub user_token_account: Account<'info, TokenAccount>,
    pub authority: Signer<'info>,
    pub token_program: Program<'info, Token>,
}

#[account]
pub struct Vault {
    pub authority: Pubkey,
    pub bump: u8,
}
```

## Best practices

<Tip>
  **Store the bump seed** in your account to avoid recalculating it on every instruction.
</Tip>

<Warning>
  **Be careful with seed choice** - anyone can derive the same PDA with the same seeds, so ensure seeds uniquely identify the resource.
</Warning>

<Note>
  **PDAs cannot sign transactions** - they can only sign CPIs within a program.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="Cross-program invocations" icon="arrows-turn-right" href="/concepts/cpi">
    Learn how to use PDAs with CPIs
  </Card>

  <Card title="SPL integrations" icon="coins" href="/advanced/spl-integrations">
    Use PDAs with token accounts
  </Card>
</CardGroup>
