diff --git a/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala b/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala index 8b7f4734cd..9e6c1db578 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/Wallet.scala @@ -166,24 +166,26 @@ object Wallet extends CreateWalletApi with BitcoinSLogger { encrypted <- encryptedMnemonicE } yield { val wallet = WalletImpl(mnemonic) - val coin = - HDCoin(config.defaultAccountKind, HDUtil.getCoinType(config.network)) - val account = HDAccount(coin, 0) - val xpriv = wallet.xprivForPurpose(config.defaultAccountKind) - - // safe since we're deriving from a priv - val xpub = xpriv.deriveChildPubKey(account).get - val accountDb = AccountDb(xpub, account) - - val mnemonicPath = - WalletStorage.writeMnemonicToDisk(encrypted) - logger.debug(s"Saved encrypted wallet mnemonic to $mnemonicPath") for { _ <- config.initialize() - _ <- wallet.accountDAO - .create(accountDb) - .map(_ => logger.trace(s"Saved account to DB")) + _ = { + val mnemonicPath = + WalletStorage.writeMnemonicToDisk(encrypted) + logger.debug(s"Saved encrypted wallet mnemonic to $mnemonicPath") + } + _ <- { + // We want to make sure all level 0 accounts are created, + // so the user can change the default account kind later + // and still have their wallet work + val createAccountFutures = + HDPurposes.all.map(createRootAccount(wallet, _)) + + Future + .sequence(createAccountFutures) + .map(_ => logger.debug(s"Created root level accounts for wallet")) + } + } yield wallet } @@ -197,4 +199,26 @@ object Wallet extends CreateWalletApi with BitcoinSLogger { case Left(err) => err } } + + /** Creates the level 0 account for the given HD purpose */ + private def createRootAccount(wallet: Wallet, purpose: HDPurpose)( + implicit config: WalletAppConfig, + ec: ExecutionContext): Future[AccountDb] = { + val coin = + HDCoin(purpose, HDUtil.getCoinType(config.network)) + val account = HDAccount(coin, 0) + val xpriv = wallet.xprivForPurpose(purpose) + // safe since we're deriving from a priv + val xpub = xpriv.deriveChildPubKey(account).get + val accountDb = AccountDb(xpub, account) + + logger.debug(s"Creating account with constant prefix $purpose") + wallet.accountDAO + .create(accountDb) + .map { written => + logger.debug(s"Saved account with constant prefix $purpose to DB") + written + } + + } } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/models/AccountTable.scala b/wallet/src/main/scala/org/bitcoins/wallet/models/AccountTable.scala index 05c07bfcd6..ff97f64ddb 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/models/AccountTable.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/models/AccountTable.scala @@ -46,5 +46,5 @@ class AccountTable(tag: Tag) extends Table[AccountDb](tag, "wallet_accounts") { (purpose, xpub, coinType, index) <> (fromTuple, toTuple) def primaryKey: PrimaryKey = - primaryKey("pk_account", (coinType, index)) + primaryKey("pk_account", sourceColumns = (purpose, coinType, index)) } diff --git a/wallet/src/main/scala/org/bitcoins/wallet/models/AddressTable.scala b/wallet/src/main/scala/org/bitcoins/wallet/models/AddressTable.scala index 812bda1e0a..2dc0f43743 100644 --- a/wallet/src/main/scala/org/bitcoins/wallet/models/AddressTable.scala +++ b/wallet/src/main/scala/org/bitcoins/wallet/models/AddressTable.scala @@ -244,6 +244,9 @@ class AddressTable(tag: Tag) extends Table[AddressDb](tag, "addresses") { // for some reason adding a type annotation here causes compile error def fk = - foreignKey("fk_account", (accountCoin, accountIndex), accounts)( - accountTable => (accountTable.coinType, accountTable.index)) + foreignKey("fk_account", + sourceColumns = (purpose, accountCoin, accountIndex), + targetTableQuery = accounts) { accountTable => + (accountTable.purpose, accountTable.coinType, accountTable.index) + } }