Skip to main content

Create and Manage Wallets

This tutorial covers creating, securing, and managing ACDC wallets using both the CLI and SDK.

Overview

ACDC wallets support both chains:

ChainAddress PrefixModel
Alphaax1UTXO/Record (privacy)
Deltadx1Account-based

A single mnemonic generates addresses for both chains.

Using the CLI

Create a New Wallet

# Generate new wallet
acdc wallet create

# Output:
# Wallet created successfully!
#
# Mnemonic (SAVE THIS SECURELY):
# abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
#
# Alpha Address: ax1qz3k7m8n9p0r2s4t6v8w0x2y4z6a8c0e2g4i6k8m
# Delta Address: dx1abc123def456ghi789jkl012mno345pqr678stu
danger

Save your mnemonic phrase securely. Anyone with your mnemonic has full access to your funds. Never share it, never store it digitally in plain text.

Create with Password Protection

# Create with password-encrypted keystore
acdc wallet create --keystore ~/.acdc/wallet.json

# You'll be prompted:
# Enter password: ********
# Confirm password: ********
#
# Keystore saved to ~/.acdc/wallet.json

Import Existing Wallet

# Import from mnemonic
acdc wallet import

# You'll be prompted:
# Enter mnemonic: <your 12 or 24 word phrase>
#
# Wallet imported successfully!

# Import with keystore
acdc wallet import --keystore ~/.acdc/wallet.json

List Wallets

# List all wallets
acdc wallet list

# Output:
# Wallets:
# 1. dx1abc123... (default)
# 2. dx1def456...

Set Default Wallet

# Set default wallet by address
acdc wallet default dx1def456...

# Or by index
acdc wallet default 2

Using the TypeScript SDK

Generate New Wallet

import { Wallet } from '@acdc/sdk';

// Generate with random entropy
const wallet = Wallet.create();

console.log('Mnemonic:', wallet.mnemonic);
console.log('Delta Address:', wallet.address);
console.log('Alpha Address:', wallet.alphaAddress);
console.log('Private Key:', wallet.privateKey);

// Generate with specific word count
const wallet24 = Wallet.create({ wordCount: 24 });

Import from Mnemonic

import { Wallet } from '@acdc/sdk';

const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';

// Default derivation path
const wallet = Wallet.fromMnemonic(mnemonic);

// Custom derivation path
const customWallet = Wallet.fromMnemonic(mnemonic, {
path: "m/44'/60'/0'/0/5" // Account index 5
});

console.log('Address:', wallet.address);

Import from Private Key

import { Wallet } from '@acdc/sdk';

const privateKey = '0x...'; // 64 hex characters
const wallet = Wallet.fromPrivateKey(privateKey);

console.log('Address:', wallet.address);

HD Wallet (Multiple Accounts)

import { HDWallet } from '@acdc/sdk';

// Create HD wallet
const hdWallet = HDWallet.fromMnemonic(
'abandon abandon abandon ...'
);

// Derive multiple accounts
const accounts = [];
for (let i = 0; i < 5; i++) {
const account = hdWallet.derive(i);
accounts.push({
index: i,
address: account.address,
privateKey: account.privateKey
});
}

console.log('Accounts:');
accounts.forEach(acc => {
console.log(` ${acc.index}: ${acc.address}`);
});

Encrypt/Decrypt Keystore

import { Wallet, Keystore } from '@acdc/sdk';

const wallet = Wallet.create();

// Encrypt to keystore
const password = 'secure-password';
const keystore = await Keystore.encrypt(wallet.privateKey, password);

// Save to file
const fs = require('fs');
fs.writeFileSync('wallet.json', JSON.stringify(keystore, null, 2));

// Later: decrypt from keystore
const loaded = JSON.parse(fs.readFileSync('wallet.json', 'utf8'));
const decrypted = await Keystore.decrypt(loaded, password);
const restoredWallet = Wallet.fromPrivateKey(decrypted);

console.log('Restored:', restoredWallet.address);

Using the Rust SDK

Generate New Wallet

use acdc_sdk::{Wallet, Mnemonic};

// Generate new wallet
let wallet = Wallet::generate()?;

println!("Mnemonic: {}", wallet.mnemonic().unwrap());
println!("Address: {}", wallet.address());
println!("Private Key: 0x{}", hex::encode(wallet.private_key()));

// Generate with 24 words
let wallet24 = Wallet::generate_with_word_count(24)?;

Import from Mnemonic

use acdc_sdk::{Wallet, Mnemonic};

let phrase = "abandon abandon abandon ...";
let mnemonic = Mnemonic::parse(phrase)?;

// Default derivation
let wallet = Wallet::from_mnemonic(&mnemonic, None)?;

// Custom path
let custom = Wallet::from_mnemonic(&mnemonic, Some("m/44'/60'/0'/0/5"))?;

println!("Address: {}", wallet.address());

HD Wallet

use acdc_sdk::{HDWallet, Mnemonic};

let mnemonic = Mnemonic::parse("abandon abandon ...")?;
let hd = HDWallet::from_mnemonic(&mnemonic)?;

// Derive accounts
for i in 0..5 {
let account = hd.derive(i)?;
println!("Account {}: {}", i, account.address());
}

Wallet Security Best Practices

Mnemonic Storage

Do:

  • Write on paper, store in secure location
  • Use a hardware wallet for large amounts
  • Split mnemonic using Shamir's Secret Sharing

Do Not:

  • Store in cloud storage (Google Drive, iCloud, etc.)
  • Take screenshots
  • Store in plain text files
  • Share with anyone

Keystore Files

Do:

  • Use strong, unique passwords (20+ characters)
  • Store keystore on encrypted drives
  • Keep backups in multiple secure locations

Do Not:

  • Use simple passwords
  • Store password with keystore
  • Share keystore files

Development vs Production

// Development: OK to use environment variables
const wallet = Wallet.fromPrivateKey(process.env.DEV_PRIVATE_KEY);

// Production: Use secure key management
import { KMS } from '@acdc/sdk';

const kms = new KMS({
provider: 'aws', // or 'gcp', 'azure', 'vault'
keyId: 'arn:aws:kms:...'
});

const signer = await kms.getSigner();

Multi-Signature Wallets

For enhanced security, use multi-signature wallets:

import { MultiSigWallet } from '@acdc/sdk';

// Create 2-of-3 multisig
const multisig = await MultiSigWallet.create({
owners: [
'dx1owner1...',
'dx1owner2...',
'dx1owner3...'
],
threshold: 2
});

console.log('Multisig address:', multisig.address);

// Create transaction proposal
const proposal = await multisig.proposeTransaction({
to: 'dx1recipient...',
value: parseUnits('10', 18)
});

// Each owner signs
const sig1 = await owner1Wallet.signMultisigProposal(proposal);
const sig2 = await owner2Wallet.signMultisigProposal(proposal);

// Execute with enough signatures
const tx = await multisig.executeTransaction(proposal, [sig1, sig2]);
await tx.wait();

View Keys (Alpha Chain)

For privacy-preserving balance viewing without spending ability:

import { AlphaWallet, ViewKey } from '@acdc/sdk';

const wallet = AlphaWallet.create();

// Derive view key (can see balances, cannot spend)
const viewKey = wallet.deriveViewKey();

console.log('View Key:', viewKey.toString());

// Share view key with auditors/accountants
// They can scan for your records but cannot spend

Address Validation

import { isValidAddress, getAddressChain } from '@acdc/sdk';

// Validate address format
console.log(isValidAddress('dx1abc...')); // true
console.log(isValidAddress('invalid')); // false

// Get chain from address
console.log(getAddressChain('dx1abc...')); // 'delta'
console.log(getAddressChain('ax1xyz...')); // 'alpha'

// Validate and get info
import { Address } from '@acdc/sdk';

try {
const addr = new Address('dx1abc...');
console.log('Chain:', addr.chain);
console.log('Checksum:', addr.toChecksum());
} catch (e) {
console.log('Invalid address');
}

Wallet Recovery

From Mnemonic

acdc wallet recover

# Enter your 12 or 24 word mnemonic phrase:
# > abandon abandon abandon ...

# Wallet recovered successfully!
# Alpha Address: ax1...
# Delta Address: dx1...

From Keystore

acdc wallet recover --keystore wallet.json

# Enter keystore password:
# > ********

# Wallet recovered successfully!

Complete Example

Here is a complete wallet management script:

// wallet-manager.ts
import { Wallet, HDWallet, Keystore } from '@acdc/sdk';
import * as fs from 'fs';
import * as readline from 'readline';

const KEYSTORE_PATH = './wallets';

async function prompt(question: string): Promise<string> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise(resolve => {
rl.question(question, answer => {
rl.close();
resolve(answer);
});
});
}

async function createWallet() {
const wallet = Wallet.create();

console.log('\nNew Wallet Created!');
console.log('==================');
console.log('Mnemonic:', wallet.mnemonic);
console.log('Delta Address:', wallet.address);
console.log('Alpha Address:', wallet.alphaAddress);

const save = await prompt('\nSave to keystore? (y/n): ');
if (save.toLowerCase() === 'y') {
const password = await prompt('Enter password: ');
const keystore = await Keystore.encrypt(wallet.privateKey, password);

if (!fs.existsSync(KEYSTORE_PATH)) {
fs.mkdirSync(KEYSTORE_PATH);
}

const filename = `${KEYSTORE_PATH}/${wallet.address}.json`;
fs.writeFileSync(filename, JSON.stringify(keystore, null, 2));
console.log(`Saved to ${filename}`);
}
}

async function listWallets() {
if (!fs.existsSync(KEYSTORE_PATH)) {
console.log('No wallets found');
return;
}

const files = fs.readdirSync(KEYSTORE_PATH);
console.log('\nWallets:');
files.forEach((file, i) => {
console.log(` ${i + 1}. ${file.replace('.json', '')}`);
});
}

async function loadWallet() {
const address = await prompt('Enter wallet address: ');
const password = await prompt('Enter password: ');

const filename = `${KEYSTORE_PATH}/${address}.json`;
const keystore = JSON.parse(fs.readFileSync(filename, 'utf8'));
const privateKey = await Keystore.decrypt(keystore, password);
const wallet = Wallet.fromPrivateKey(privateKey);

console.log('\nWallet loaded successfully!');
console.log('Address:', wallet.address);

return wallet;
}

// Main menu
async function main() {
while (true) {
console.log('\nWallet Manager');
console.log('1. Create new wallet');
console.log('2. List wallets');
console.log('3. Load wallet');
console.log('4. Exit');

const choice = await prompt('Choose option: ');

switch (choice) {
case '1': await createWallet(); break;
case '2': await listWallets(); break;
case '3': await loadWallet(); break;
case '4': process.exit(0);
default: console.log('Invalid option');
}
}
}

main().catch(console.error);

Next Steps