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.
Swig SDK V2 Protocol Features
This guide demonstrates the key features introduced in Swig SDK v2, including automatic version detection, enhanced account structure, and improved instruction handling.
Automatic Version Detection
The SDK automatically detects whether a Swig account is v1 or v2:
import { fetchSwigAccount } from '@swig-wallet/classic';
// Fetch any Swig account
const swig = await fetchSwigAccount(connection, swigAccountAddress);
// Automatic version detection
const version = swig.accountVersion(); // Returns 'v1' | 'v2'
console.log(`Account version: ${version}`);
// Automatic wallet address resolution
const walletAddress = await getSwigWalletAddress(swig);
// For v1: returns account address directly
// For v2: returns system program derived address
Enhanced Account Structure
V2 accounts use an optimized structure with PDA-based addressing:
// Version detection logic
if (swig.accountVersion() === 'v2') {
// V2 account uses bump seed and PDA-derived wallet address
const accountPda = getSwigAccountAddressRaw(swig); // The account PDA
const systemWallet = await getSwigSystemAddressRaw(swig); // System-derived wallet
console.log(`Account PDA: ${accountPda.toBase58()}`);
console.log(`System wallet: ${systemWallet.toBase58()}`);
} else {
// V1 account uses direct address
const directAddress = getSwigAccountAddressRaw(swig);
console.log(`Direct address: ${directAddress.toBase58()}`);
}
Automatic Instruction Selection
The SDK automatically chooses the correct instruction type based on account version:
import {
getSignInstructions,
SystemProgram,
LAMPORTS_PER_SOL
} from '@swig-wallet/classic';
// This works for both v1 and v2 accounts
const signInstructions = await getSignInstructions(
swig,
0, // role id
[
SystemProgram.transfer({
fromPubkey: await getSwigWalletAddress(swig), // Auto-resolves correct address
toPubkey: recipient,
lamports: BigInt(LAMPORTS_PER_SOL / 2),
}),
]
);
// SDK automatically uses:
// - signV2 instruction for v2 accounts
// - sign instruction for v1 accounts
Complete V2 Example
Here’s a complete example demonstrating v2 features:
import {
Connection,
Keypair,
SystemProgram,
LAMPORTS_PER_SOL,
Transaction,
} from '@solana/web3.js';
import {
Actions,
createEd25519AuthorityInfo,
fetchSwigAccount,
getCreateSwigInstruction,
getAddAuthorityInstructions,
getSignInstructions,
findSwigPda,
} from '@swig-wallet/classic';
async function demonstrateV2Features() {
const connection = new Connection('https://api.devnet.solana.com');
// Setup keypairs
const userKeypair = Keypair.generate();
const authorityKeypair = Keypair.generate();
const recipientKeypair = Keypair.generate();
// Fund the user account
const airdropSignature = await connection.requestAirdrop(
userKeypair.publicKey,
2 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction(airdropSignature);
// Create a new Swig account
const swigId = Keypair.generate().publicKey;
const swigAccountAddress = findSwigPda(swigId);
const createInstructions = getCreateSwigInstruction(
userKeypair.publicKey,
swigId,
Actions.set().all().get(),
createEd25519AuthorityInfo({
id: userKeypair.publicKey,
signer: userKeypair.publicKey,
})
);
// Create the account
const createTx = new Transaction().add(...createInstructions);
createTx.feePayer = userKeypair.publicKey;
createTx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
createTx.sign(userKeypair);
await connection.sendAndConfirmTransaction(createTx, [userKeypair]);
// Fetch the created account and check version
const swig = await fetchSwigAccount(connection, swigAccountAddress);
console.log(`Created account version: ${swig.accountVersion()}`);
console.log(`Wallet address: ${(await getSwigWalletAddress(swig)).toBase58()}`);
// Add an authority with automatic program action management
const addAuthorityInstructions = await getAddAuthorityInstructions(
swig,
0, // root role
createEd25519AuthorityInfo({
id: authorityKeypair.publicKey,
signer: authorityKeypair.publicKey,
}),
Actions.set().manageAuthority().get()
);
const addAuthorityTx = new Transaction().add(...addAuthorityInstructions);
addAuthorityTx.feePayer = userKeypair.publicKey;
addAuthorityTx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
addAuthorityTx.sign(userKeypair);
await connection.sendAndConfirmTransaction(addAuthorityTx, [userKeypair]);
// Perform a transfer using automatic instruction selection
const transferInstructions = await getSignInstructions(
swig,
0, // role id
[
SystemProgram.transfer({
fromPubkey: await getSwigWalletAddress(swig), // Auto-resolves correct address
toPubkey: recipientKeypair.publicKey,
lamports: BigInt(LAMPORTS_PER_SOL / 4),
}),
]
);
const transferTx = new Transaction().add(...transferInstructions);
transferTx.feePayer = userKeypair.publicKey;
transferTx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
transferTx.sign(userKeypair);
await connection.sendAndConfirmTransaction(transferTx, [userKeypair]);
console.log('Transfer completed successfully!');
// Check final balances
const walletBalance = await connection.getBalance(await getSwigWalletAddress(swig));
const recipientBalance = await connection.getBalance(recipientKeypair.publicKey);
console.log(`Wallet balance: ${walletBalance / LAMPORTS_PER_SOL} SOL`);
console.log(`Recipient balance: ${recipientBalance / LAMPORTS_PER_SOL} SOL`);
}
// Run the example
demonstrateV2Features().catch(console.error);
Enhanced Program Action Management
V2 includes automatic program action management:
import { Actions, ensureProgramAction } from '@swig-wallet/lib';
// The SDK automatically ensures proper program actions
const actions = Actions.set().manageAuthority().get();
// ensureProgramAction is called automatically in instruction builders
// It adds ProgramAll action if no program permissions exist
const enhancedActions = ensureProgramAction(actions);
// Use in authority management
const addAuthorityInstructions = await getAddAuthorityInstructions(
swig,
roleId,
authorityInfo,
enhancedActions // Automatically enhanced with program permissions
);
Version-Aware Development
Best practices for working with both v1 and v2 accounts:
// Always use walletAddress() instead of direct account access
const walletAddress = await getSwigWalletAddress(swig);
// Check version when debugging
if (swig.accountVersion() === 'v2') {
console.log('Using v2 account with PDA-based addressing');
console.log('Account PDA:', getSwigAccountAddressRaw(swig).toBase58());
console.log('System address:', (await getSwigSystemAddressRaw(swig)).toBase58());
} else {
console.log('Using v1 account with direct addressing');
console.log('Account address:', getSwigAccountAddressRaw(swig).toBase58());
}
// Let the SDK handle instruction selection automatically
const instructions = await getSignInstructions(swig, roleId, innerInstructions);
// No need to specify instruction version - it's automatic!
Key Benefits
Backward Compatibility
- All existing v1 code works without changes
- Automatic version detection eliminates manual configuration
- Same API surface for both account versions
- V2 accounts use optimized storage structure
- PDA-based addressing provides better isolation
- Reduced account size and transaction costs
Enhanced Developer Experience
- Automatic instruction selection
- Built-in program action management
- Version-aware debugging utilities
The v2 protocol improvements provide enhanced performance and developer experience while maintaining full backward compatibility with existing Swig applications.