// lib/address-manager.cjs - Address Generation & Management (Phase 6.2)
// CRITICAL: Load bare-node-runtime FIRST before any other requires
require('bare-node-runtime/global')
const {
initializeWallets,
storeAddress,
getAddresses,
getNextAddressIndex,
getCurrentAddress: getLatestAddress
} = require('./wallet-storage.cjs')
/**
* Generate new receiving address and store in Autobase
* @param {string} chain - 'bitcoin' or 'ethereum'
* @param {Object} config - { testnet: boolean }
* @returns {Object} - { address, path, index, chain }
*/
async function generateNewAddress(chain, config = { testnet: true }) {
// Normalize chain name
const chainNormalized = chain.toLowerCase()
if (chainNormalized !== 'bitcoin' && chainNormalized !== 'ethereum') {
throw new Error(`Unsupported chain: ${chain}. Use 'bitcoin' or 'ethereum'`)
}
// Initialize WDK
const { wdk } = await initializeWallets(config)
// Get next address index
const index = await getNextAddressIndex(chainNormalized)
// Determine derivation path fragment for WDK getAccountByPath
// Bitcoin (BIP-84): m/84'/coinType'/0'/0/{index}
// Ethereum (BIP-44): m/44'/60'/0'/0/{index}
// WDK expects path fragment like "0'/0/{index}"
const pathFragment = `0'/0/${index}`
// Get account using custom derivation path
const account = await wdk.getAccountByPath(chainNormalized, pathFragment)
const address = await account.getAddress()
// Build full path for display
const coinType = chainNormalized === 'bitcoin'
? (config.testnet ? "1'" : "0'")
: "60'"
const path = chainNormalized === 'bitcoin'
? `m/84'/${coinType}/${pathFragment}`
: `m/44'/${coinType}/${pathFragment}`
// Store address in Autobase (syncs to all devices)
await storeAddress({
chain: chainNormalized,
network: config.testnet ? 'testnet' : 'mainnet',
address,
path,
index
})
return { address, path, index, chain: chainNormalized }
}
/**
* List all addresses for a chain
* @param {string} chain - 'bitcoin', 'ethereum', or 'all'
* @returns {Array} - Array of address objects sorted by index
*/
async function listAddresses(chain = 'all') {
const chainNormalized = chain.toLowerCase()
return await getAddresses(chainNormalized)
}
/**
* Get current (latest) address for a chain
* @param {string} chain - 'bitcoin' or 'ethereum'
* @returns {Object|null} - Latest address or null if none exist
*/
async function getCurrentAddress(chain) {
const chainNormalized = chain.toLowerCase()
if (chainNormalized !== 'bitcoin' && chainNormalized !== 'ethereum') {
throw new Error(`Unsupported chain: ${chain}. Use 'bitcoin' or 'ethereum'`)
}
return await getLatestAddress(chainNormalized)
}
module.exports = {
generateNewAddress,
listAddresses,
getCurrentAddress
}