Address Book
Manage named addresses with labels and notes for easy reference.
Overview
The Address Book helps you:
- Save addresses with human-readable labels
- Add notes and tags for organization
- Resolve labels to addresses in transactions
- Persist address book to file
- Track addresses across networks
Installation
import {
createAddressBook,
formatAddressBook,
resolveAddress,
addWellKnownAddresses,
} from 'cardano-devkit';
Creating an Address Book
// Default file-based persistence
const book = createAddressBook();
// Custom file path
const book = createAddressBook({
filePath: './my-addresses.json',
autoSave: true,
});
// In-memory only
const book = createAddressBook({ persist: false });
Adding Addresses
// Basic entry
book.add({
label: "alice",
address: "addr_test1qz...",
network: "Preprod",
});
// With tags and note
book.add({
label: "treasury",
address: "addr_test1qp...",
network: "Preprod",
tags: ["multisig", "organization"],
note: "DAO treasury - 3/5 multisig",
});
// With metadata
book.add({
label: "exchange-hot",
address: "addr1q...",
network: "Mainnet",
tags: ["exchange", "hot-wallet"],
note: "Exchange deposit address",
metadata: {
exchange: "SundaeSwap",
type: "deposit",
},
});
Retrieving Addresses
By Label
const entry = book.get("alice");
if (entry) {
console.log("Address:", entry.address);
console.log("Network:", entry.network);
console.log("Note:", entry.note);
}
List All
const entries = book.list();
entries.forEach(e => {
console.log(`${e.label}: ${e.address}`);
});
Search
// Search by label, address, note, or tags
const results = book.search("treasury");
const exchanges = book.search("exchange");
Filter by Tag
const multisigs = book.getByTag("multisig");
const hotWallets = book.getByTag("hot-wallet");
Filter by Network
const mainnetAddrs = book.getByNetwork("Mainnet");
const testnetAddrs = book.getByNetwork("Preprod");
Resolving Labels
Use resolveAddress to convert labels to addresses:
// Works with both labels and addresses
const addr1 = resolveAddress("alice", book); // Returns alice's address
const addr2 = resolveAddress("addr_test1...", book); // Returns as-is
// Use in transactions
const recipient = resolveAddress(userInput, book);
await sendAda(lucid, recipient, 5_000_000n);
Updating Entries
book.update("alice", {
note: "Updated note",
tags: ["friend", "developer"],
});
Removing Entries
book.remove("old-address");
Well-Known Addresses
Add common addresses (faucets, etc.):
const count = addWellKnownAddresses(book);
console.log(`Added ${count} well-known addresses`);
// Now you can use labels like:
// - "preprod-faucet"
// - "preview-faucet"
Formatting
console.log(formatAddressBook(book));
Output:
╔═════════════════════════ ══════════════════════════════════════╗
║ 📒 Address Book ║
╠═══════════════════════════════════════════════════════════════╣
║ ║
║ alice [Preprod] ║
║ addr_test1qz2fxv2umyhttkx... ║
║ Tags: friend, developer ║
║ Note: Alice's test wallet ║
║ ║
║ treasury [Preprod] ║
║ addr_test1qp5czta6hshg7z... ║
║ Tags: multisig, organization ║
║ Note: DAO treasury - 3/5 multisig ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
Persistence
Manual Save/Load
// Save to file
book.save();
// Reload from file
book.reload();
Export/Import
// Export as JSON
const json = book.exportJson();
fs.writeFileSync("addresses-backup.json", json);
// Import from JSON
const json = fs.readFileSync("addresses-backup.json", "utf-8");
const count = book.importJson(json);
console.log(`Imported ${count} addresses`);
Types
AddressEntry
interface AddressEntry {
label: string;
address: string;
network: NetworkType;
tags?: string[];
note?: string;
metadata?: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}
AddressBookOptions
interface AddressBookOptions {
filePath?: string; // Default: "./.cardano-address-book.json"
autoSave?: boolean; // Default: true
persist?: boolean; // Default: true
}
CLI Usage
# List all addresses
cardano-devkit address-book list
# Add a new address
cardano-devkit address-book add alice addr_test1qz... --network Preprod
# With tags and note
cardano-devkit address-book add treasury addr_test1qp... \
--network Preprod \
--tags "multisig,dao" \
--note "DAO treasury wallet"
# Remove an address
cardano-devkit address-book remove old-address
# Get address by label
cardano-devkit address-book get alice
# Resolve label to address
cardano-devkit address-book resolve alice
# Add well-known addresses
cardano-devkit address-book init-known
# Output as JSON
cardano-devkit address-book list --json
Integration Examples
In Transactions
import { createAddressBook, resolveAddress, sendAda } from 'cardano-devkit';
const book = createAddressBook();
// User input could be a label or address
const userInput = "alice"; // or "addr_test1..."
// Resolve to actual address
const recipient = resolveAddress(userInput, book);
// Send transaction
await sendAda(lucid, recipient, 10_000_000n);
Batch Payments
const payments = [
{ to: "alice", amount: 5_000_000n },
{ to: "bob", amount: 10_000_000n },
{ to: "treasury", amount: 50_000_000n },
].map(p => ({
address: resolveAddress(p.to, book),
lovelace: p.amount,
}));
await batchAdaPayments(lucid, payments);
React Component
function SendForm() {
const [recipient, setRecipient] = useState("");
const book = useMemo(() => createAddressBook(), []);
const handleSend = async () => {
try {
const address = resolveAddress(recipient, book);
await sendAda(lucid, address, amount);
} catch (e) {
console.error("Invalid recipient:", e);
}
};
return (
<div>
<input
placeholder="Address or label"
value={recipient}
onChange={e => setRecipient(e.target.value)}
/>
<button onClick={handleSend}>Send</button>
</div>
);
}
Best Practices
- Use descriptive labels - "treasury-multisig" not "addr1"
- Add notes for context and purpose
- Use tags for categorization and filtering
- Track network to prevent cross-network mistakes
- Backup regularly especially for mainnet addresses
- Use resolve to accept both labels and addresses from users