solana_address_book/lib.rs
1//! # Address Book
2//!
3//! A comprehensive Solana address management library for tracking and labeling addresses in your applications.
4//!
5//! This crate provides an organized way to manage Solana public keys with human-readable labels and role-based
6//! categorization. It's particularly useful for debugging, transaction analysis, and building developer tools
7//! that need to display meaningful information about addresses.
8//!
9//! ## Features
10//!
11//! - **Role-based categorization**: Organize addresses by their purpose (wallet, mint, ATA, PDA, program, custom)
12//! - **Colored terminal output**: Enhanced readability with color-coded address types
13//! - **PDA management**: Built-in support for Program Derived Addresses with seed tracking
14//! - **Text replacement**: Automatically replace raw pubkeys with labels in logs and output
15//! - **Duplicate prevention**: Ensures label uniqueness across your address book
16//!
17//! ## Quick Start
18//!
19//! ```rust
20//! use solana_address_book::{AddressBook, RegisteredAddress};
21//! use anchor_lang::prelude::*;
22//!
23//! // Create a new address book
24//! let mut book = AddressBook::new();
25//!
26//! // Add default Solana programs
27//! book.add_default_accounts().unwrap();
28//!
29//! // Add a user wallet
30//! let user = Pubkey::new_unique();
31//! book.add_wallet(user, "alice_wallet".to_string()).unwrap();
32//!
33//! // Add a token mint
34//! let token_mint = Pubkey::new_unique();
35//! book.add(token_mint, "usdc_mint".to_string(), RegisteredAddress::mint(token_mint)).unwrap();
36//!
37//! // Get a formatted label for display
38//! println!("User address: {}", book.format_address(&user));
39//! ```
40//!
41//! ## Usage Examples
42//!
43//! ### Managing Different Address Types
44//!
45//! ```rust
46//! use solana_address_book::{AddressBook, RegisteredAddress};
47//! use anchor_lang::prelude::*;
48//!
49//! let mut book = AddressBook::new();
50//!
51//! // Add a wallet address
52//! let wallet = Pubkey::new_unique();
53//! book.add_wallet(wallet, "treasury".to_string()).unwrap();
54//!
55//! // Add an Associated Token Account (ATA)
56//! let ata = Pubkey::new_unique();
57//! let mint = Pubkey::new_unique();
58//! let owner = Pubkey::new_unique();
59//! book.add(ata, "alice_usdc_ata".to_string(), RegisteredAddress::ata(ata, mint, owner)).unwrap();
60//!
61//! // Add a Program Derived Address (PDA)
62//! let pda = Pubkey::new_unique();
63//! let program_id = Pubkey::new_unique();
64//! book.add_pda(
65//! pda,
66//! "vault_pda".to_string(),
67//! vec!["vault".to_string(), "seed".to_string()],
68//! program_id,
69//! 255
70//! ).unwrap();
71//!
72//! // Add a custom role
73//! book.add_custom(
74//! Pubkey::new_unique(),
75//! "governance".to_string(),
76//! "dao_treasury".to_string()
77//! ).unwrap();
78//! ```
79//!
80//! ### Finding and Querying Addresses
81//!
82//! ```rust
83//! use solana_address_book::{AddressBook, AddressRole};
84//! use anchor_lang::prelude::*;
85//!
86//! let mut book = AddressBook::new();
87//! let wallet = Pubkey::new_unique();
88//! book.add_wallet(wallet, "alice".to_string()).unwrap();
89//!
90//! // Check if an address exists
91//! if book.contains(&wallet) {
92//! println!("Address is registered");
93//! }
94//!
95//! // Get label for an address
96//! let label = book.get_label(&wallet);
97//! println!("Address label: {}", label);
98//!
99//! // Find address by role
100//! if let Some(addr) = book.get_by_role(&AddressRole::Wallet) {
101//! println!("Found wallet: {}", addr);
102//! }
103//!
104//! // Get all addresses of a specific type
105//! let all_wallets = book.get_all_by_role_type("wallet");
106//! println!("Total wallets: {}", all_wallets.len());
107//! ```
108//!
109//! ### PDA Creation and Registration
110//!
111//! ```rust
112//! use solana_address_book::{AddressBook, RegisteredAddress};
113//! use anchor_lang::prelude::*;
114//!
115//! let mut book = AddressBook::new();
116//! let program_id = Pubkey::new_unique();
117//!
118//! // Create and register a PDA in one step
119//! let user = Pubkey::new_unique();
120//! let (pda_key, bump) = book.find_pda_with_bump(
121//! "user_vault",
122//! &[b"vault", user.as_ref()],
123//! program_id
124//! ).unwrap();
125//!
126//! // Or create a PDA manually
127//! let (pubkey, bump, registered) = RegisteredAddress::pda(
128//! &[b"config", b"v1"],
129//! &program_id
130//! );
131//! book.add(pubkey, "config_account".to_string(), registered).unwrap();
132//! ```
133//!
134//! ### Text Processing and Display
135//!
136//! ```rust
137//! use solana_address_book::{AddressBook, RegisteredAddress};
138//! use anchor_lang::prelude::*;
139//!
140//! let mut book = AddressBook::new();
141//! let token = Pubkey::new_unique();
142//! book.add(token, "my_token".to_string(), RegisteredAddress::mint(token)).unwrap();
143//!
144//! // Replace addresses in text with their labels
145//! let log = format!("Transfer from {} to {}", Pubkey::new_unique(), token);
146//! let formatted = book.replace_addresses_in_text(&log);
147//! println!("{}", formatted); // Will show colored "my_token" instead of raw pubkey
148//!
149//! // Print entire address book with formatting
150//! book.print_all();
151//! ```
152//!
153//! ## Integration with Testing Frameworks
154//!
155//! This crate is designed to work seamlessly with Solana testing frameworks:
156//!
157//! ```rust
158//! use solana_address_book::{AddressBook, RegisteredAddress};
159//! use anchor_lang::prelude::*;
160//!
161//! fn setup_test_environment() -> AddressBook {
162//! let mut book = AddressBook::new();
163//!
164//! // Add standard programs
165//! book.add_default_accounts().unwrap();
166//!
167//! // Add test accounts
168//! let admin = Pubkey::new_unique();
169//! book.add_wallet(admin, "test_admin".to_string()).unwrap();
170//!
171//! // Track all test tokens
172//! let test_token = Pubkey::new_unique();
173//! book.add(test_token, "test_token".to_string(), RegisteredAddress::mint(test_token))
174//! .unwrap();
175//!
176//! book
177//! }
178//! ```
179
180pub mod address_book;
181pub mod pda_seeds;
182pub mod registered_address;
183
184pub use address_book::AddressBook;
185pub use pda_seeds::{DerivedPda, find_pda_with_bump_and_strings, seed_to_string};
186pub use registered_address::{AddressRole, RegisteredAddress};