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¶
- Send Your First Transaction - Use your wallet
- Deploy an ADL Contract - Deploy contracts
- TypeScript SDK Guide - Full SDK reference