Skip to 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:

Chain Address Prefix Model
Alpha ax1 UTXO/Record (privacy)
Delta dx1 Account-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