Skip to main content

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 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

  1. Use descriptive labels - "treasury-multisig" not "addr1"
  2. Add notes for context and purpose
  3. Use tags for categorization and filtering
  4. Track network to prevent cross-network mistakes
  5. Backup regularly especially for mainnet addresses
  6. Use resolve to accept both labels and addresses from users