This guide provides a comprehensive comparison of the two client modes available in nmcd: Embedded Mode (in-process) and Daemon Mode (RPC). Understanding the differences helps you choose the right mode for your application.
nmcd provides two distinct client implementations, both implementing the same NameClient interface:
┌─────────────────────────────────────────────────────────────────┐
│ NameClient Interface │
│ ResolveName | RegisterName | UpdateName | ListNames | GetInfo │
└─────────────────────────────────────────────────────────────────┘
▲ ▲
│ │
┌───────────┴───────────┐ ┌──────────┴──────────┐
│ EmbeddedClient │ │ DaemonClient │
│ (In-Process) │ │ (JSON-RPC) │
│ │ │ │
│ ┌─────────────────┐ │ │ ┌─────────────┐ │
│ │ Local Blockchain│ │ │ │ HTTP Client │ │
│ │ Local NameDB │ │ │ │ RPC Calls │ │
│ │ Local Wallet │ │ │ └─────────────┘ │
│ └─────────────────┘ │ │ │ │
└───────────────────────┘ └─────────┼──────────┘
│ │
▼ ▼
Local Database External Daemon
(~/.nmcd) (nmcd or Namecoin Core)
| Aspect | Embedded Mode | Daemon Mode |
|---|---|---|
| External Dependencies | None | Requires running daemon |
| Startup Time | ~1-5 seconds (depends on sync state) | Instant (~50ms) |
| Memory Usage | Higher (100-500 MB) | Lower (~10 MB) |
| CPU Usage | Higher (blockchain validation) | Minimal |
| Disk Usage | Higher (2-5 GB for mainnet) | Minimal (~1 MB for config) |
| Offline Operation | Yes (after initial sync) | No |
| Data Control | Full ownership | Shared with daemon |
| Deployment | Single binary | Daemon + client |
| Thread Safety | Fully thread-safe | Fully thread-safe |
| Network Access | Direct P2P | Via daemon only |
| Wallet Support | Built-in | Via daemon RPC |
| Best For | Standalone apps, testing | Microservices, web apps |
Embedded mode runs the full Namecoin node in-process, including blockchain validation, name database, and wallet functionality.
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ EmbeddedClient │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ Blockchain │ │ NameDB │ │ Wallet │ │ │
│ │ │ (btcd) │ │ (bbolt) │ │ (wallet.json) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ • Block │ │ • Names │ │ • Private Keys │ │ │
│ │ │ Validation│ │ • History │ │ • Signing │ │ │
│ │ │ • Chain │ │ • Expiration│ │ • Addresses │ │ │
│ │ │ Management│ │ • UTXOs │ │ │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ Data Directory │
│ ~/.nmcd/ │
│ ├── blocks/ │
│ ├── names.db │
│ └── wallet.json │
└─────────────────────────────────────────────────────────────┘
// Import the nmcd client package
import "github.com/opd-ai/nmcd/client"
// Create embedded client with custom configuration
nc, err := client.NewEmbeddedClient(&client.Config{
DataDir: "/path/to/data",
Network: "mainnet",
})
if err != nil {
log.Fatal(err)
}
defer nc.Close()
Daemon mode connects to an external nmcd or Namecoin Core daemon via JSON-RPC, delegating all blockchain operations to the daemon.
┌──────────────────────────────────────┐
│ Your Application │
│ │
│ ┌────────────────────────────────┐ │
│ │ DaemonClient │ │
│ │ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ HTTP Client │ │ │
│ │ │ │ │ │
│ │ │ • JSON-RPC requests │ │ │
│ │ │ • Retry logic │ │ │
│ │ │ • Authentication │ │ │
│ │ └──────────────────────────┘ │ │
│ └────────────────────────────────┘ │
│ │ │
└───────────────────┼───────────────────┘
│ HTTP/JSON-RPC
▼
┌──────────────────────────────────────┐
│ External Daemon │
│ (nmcd or Namecoin Core) │
│ │
│ ┌────────┐ ┌────────┐ ┌──────────┐ │
│ │Blockchain│ │NameDB │ │ Wallet │ │
│ └────────┘ └────────┘ └──────────┘ │
│ │
│ localhost:8336 (mainnet) │
│ localhost:18336 (testnet) │
└──────────────────────────────────────┘
// Before: Embedded mode
nc, err := client.NewClient(&client.Config{
Mode: client.ModeEmbedded,
DataDir: "/path/to/data",
})
// After: Daemon mode
nc, err := client.NewClient(&client.Config{
Mode: client.ModeDaemon,
RPCAddr: "http://localhost:8336",
RPCUser: "user",
RPCPassword: "pass",
})
// Application code remains unchanged
record, err := nc.ResolveName(ctx, "d/example")
Use environment variables for flexible deployment:
func getClientConfig() *client.Config {
cfg := &client.Config{
Network: getEnv("NMCD_NETWORK", "mainnet"),
}
if rpcAddr := os.Getenv("NMCD_RPC_ADDR"); rpcAddr != "" {
cfg.Mode = client.ModeDaemon
cfg.RPCAddr = rpcAddr
cfg.RPCUser = os.Getenv("NMCD_RPC_USER")
cfg.RPCPassword = os.Getenv("NMCD_RPC_PASSWORD")
} else if dataDir := os.Getenv("NMCD_DATA_DIR"); dataDir != "" {
cfg.Mode = client.ModeEmbedded
cfg.DataDir = dataDir
} else {
cfg.Mode = client.ModeAuto
}
return cfg
}
func getEnv(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return value
}
return fallback
}
| Field | Type | Default | Description |
|---|---|---|---|
Mode |
ClientMode |
ModeAuto |
Set to ModeEmbedded for explicit embedded mode |
DataDir |
string |
~/.nmcd |
Directory for blockchain and wallet data |
Network |
string |
mainnet |
Network: mainnet, testnet, or regtest |
MaxPeers |
int |
8 |
Maximum P2P peer connections |
BootstrapPeers |
[]string |
DNS seeds | Custom bootstrap peers |
DisableWallet |
bool |
false |
Disable wallet for read-only mode |
| Field | Type | Default | Description |
|---|---|---|---|
Mode |
ClientMode |
ModeAuto |
Set to ModeDaemon for explicit daemon mode |
RPCAddr |
string |
http://localhost:8336 |
Daemon RPC endpoint |
RPCUser |
string |
"" |
RPC authentication username |
RPCPassword |
string |
"" |
RPC authentication password |
Network |
string |
mainnet |
Network for port defaults |
| Network | P2P Port | RPC Port |
|---|---|---|
| mainnet | 8334 | 8336 |
| testnet | 18334 | 18336 |
| regtest | 18445 | 18443¹ |
¹ Regtest RPC port follows Namecoin Core convention. Check your daemon configuration.
Problem: Only one embedded client can open a database directory at a time.
Solutions:
```go