Skip to main content
The SwigInstructionBuilder is a fundamental component of the Swig SDK that handles the creation and management of Solana instructions for the Swig protocol.

Overview

The instruction builder provides low-level functionality for creating various types of instructions needed to interact with Swig wallets on the Solana blockchain.

Core Components

AuthorityManager

pub enum AuthorityManager {
    Ed25519(Pubkey),
    Secp256k1(Box<[u8]>, Box<dyn Fn(&[u8]) -> [u8; 65]>),
    Ed25519Session(CreateEd25519SessionAuthority),
    Secp256k1Session(CreateSecp256k1SessionAuthority, Box<dyn Fn(&[u8]) -> [u8; 65]>),
}
The AuthorityManager enum represents different types of signing authorities supported by the Swig protocol.

SwigInstructionBuilder

pub struct SwigInstructionBuilder {
    swig_id: [u8; 32],
    swig_account: Pubkey,
    authority_manager: AuthorityManager,
    payer: Pubkey,
    role_id: u32,
}

Core Functions

Creating a New Instance

pub fn new(
    swig_id: [u8; 32],
    authority_manager: AuthorityManager,
    payer: Pubkey,
    role_id: u32,
) -> Self
Creates a new instance of the instruction builder with the specified parameters.

Building a Swig Account

pub fn build_swig_account(&self) -> Result<Instruction, SwigError>
Creates an instruction to initialize a new Swig account on-chain.

Signing Instructions

pub fn sign_instruction(
    &mut self,
    instructions: Vec<Instruction>,
    current_slot: Option<u64>,
) -> Result<Vec<Instruction>, SwigError>
Creates signed instructions for the provided transaction instructions.

Authority Management

Adding Authorities

pub fn add_authority_instruction(
    &mut self,
    new_authority_type: AuthorityType,
    new_authority: &[u8],
    permissions: Vec<ClientPermission>,
    current_slot: Option<u64>,
) -> Result<Instruction, SwigError>
Creates an instruction to add a new authority with specified permissions.

Removing Authorities

pub fn remove_authority(
    &mut self,
    authority_to_remove_id: u32,
    current_slot: Option<u64>,
) -> Result<Instruction, SwigError>
Creates an instruction to remove an existing authority.

Replacing Authorities

pub fn replace_authority(
    &mut self,
    authority_to_replace_id: u32,
    new_authority_type: AuthorityType,
    new_authority: &[u8],
    permissions: Vec<ClientPermission>,
    current_slot: Option<u64>,
) -> Result<Vec<Instruction>, SwigError>
Creates instructions to replace an existing authority with a new one.

Session Management

Creating Sessions

pub fn create_session_instruction(
    &self,
    session_key: Pubkey,
    session_duration: u64,
    current_slot: Option<u64>,
) -> Result<Instruction, SwigError>
Creates an instruction to create a new session for temporary authority delegation.

Utility Functions

Getting the Swig Account

pub fn get_swig_account(&self) -> Result<Pubkey, SwigError>
Returns the public key of the Swig account.

Getting the Role ID

pub fn get_role_id(&self) -> u32
Returns the current role ID of the Swig account.

Switching Authority

pub fn switch_authority(&mut self, role_id: u32, authority: Pubkey) -> Result<(), SwigError>
Switches the current authority and role ID.

SubAccount Management

Creating SubAccounts

New in v1.4.0: Support for multiple subaccounts per role (indices 0-254).
pub fn create_sub_account_with_index(
    &mut self,
    sub_account_index: u8,
) -> Result<Instruction, SwigError>
Creates an instruction to create a subaccount at a specific index (0-254). Parameters:
  • sub_account_index: The index of the subaccount to create (0-254). Index 0 uses legacy PDA derivation for backwards compatibility.

Deriving SubAccount PDAs

use swig_interface::derive_sub_account_pda;

// Derive subaccount PDA with index support
let (sub_account_0, bump_0) = derive_sub_account_pda(&swig_id, role_id, 0);
let (sub_account_1, bump_1) = derive_sub_account_pda(&swig_id, role_id, 1);
let (sub_account_2, bump_2) = derive_sub_account_pda(&swig_id, role_id, 2);
The derive_sub_account_pda function automatically handles:
  • Index 0: Uses legacy 3-seed PDA derivation for backwards compatibility
  • Indices 1-254: Uses new 4-seed PDA derivation with index in seeds

Examples

Creating a New Swig Account

let instruction_builder = SwigInstructionBuilder::new(
    swig_id,
    AuthorityManager::Ed25519(authority_pubkey),
    payer_pubkey,
    0
);

let create_ix = instruction_builder.build_swig_account()?;

Adding a New Authority

let add_authority_ix = instruction_builder.add_authority_instruction(
    AuthorityType::Ed25519,
    new_authority_bytes,
    vec![Permission::All],
    Some(current_slot)
)?;

Adding Authority with Multiple SubAccount Permissions

// Add authority with permissions for 3 different subaccounts
let add_authority_ix = instruction_builder.add_authority_instruction(
    AuthorityType::Ed25519,
    new_authority_bytes,
    vec![
        Permission::SubAccount { sub_account: [0; 32] }, // Index 0
        Permission::SubAccount { sub_account: [0; 32] }, // Index 1
        Permission::SubAccount { sub_account: [0; 32] }, // Index 2
    ],
    Some(current_slot)
)?;

Creating Multiple SubAccounts

use swig_interface::derive_sub_account_pda;

// Create subaccount at index 0 (backwards compatible)
let create_sub_0_ix = instruction_builder.create_sub_account_with_index(0)?;

// Create subaccount at index 1
let create_sub_1_ix = instruction_builder.create_sub_account_with_index(1)?;

// Create subaccount at index 2
let create_sub_2_ix = instruction_builder.create_sub_account_with_index(2)?;

// Derive the addresses
let (sub_account_0, _) = derive_sub_account_pda(&swig_id, role_id, 0);
let (sub_account_1, _) = derive_sub_account_pda(&swig_id, role_id, 1);
let (sub_account_2, _) = derive_sub_account_pda(&swig_id, role_id, 2);

println!("SubAccount 0: {}", sub_account_0);
println!("SubAccount 1: {}", sub_account_1);
println!("SubAccount 2: {}", sub_account_2);