diff --git a/waddrmgr/scoped_manager.go b/waddrmgr/scoped_manager.go
index f449a4e..08d8c1a 100644
--- a/waddrmgr/scoped_manager.go
+++ b/waddrmgr/scoped_manager.go
@@ -1513,14 +1513,56 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
 		return nil, managerError(ErrLocked, errLocked, nil)
 	}
 
+	// Encrypt the private key when not a watching-only address manager.
+	var encryptedPrivKey []byte
+	if !s.rootManager.WatchOnly() {
+		privKeyBytes := wif.PrivKey.Serialize()
+		var err error
+		encryptedPrivKey, err = s.rootManager.cryptoKeyPriv.Encrypt(privKeyBytes)
+		zero.Bytes(privKeyBytes)
+		if err != nil {
+			str := fmt.Sprintf("failed to encrypt private key for %x",
+				wif.PrivKey.PubKey().SerializeCompressed())
+			return nil, managerError(ErrCrypto, str, err)
+		}
+	}
+
+	err := s.importPublicKey(ns, wif.SerializePubKey(), encryptedPrivKey, bs)
+	if err != nil {
+		return nil, err
+	}
+
+	// The full derivation path for an imported key is incomplete as we
+	// don't know exactly how it was derived.
+	importedDerivationPath := DerivationPath{
+		Account: ImportedAddrAccount,
+	}
+
+	// Create a new managed address based on the imported address.
+	if !s.rootManager.WatchOnly() {
+		return s.toPrivateManagedAddress(
+			wif, true, importedDerivationPath,
+		)
+	}
+	pubKey := (*btcec.PublicKey)(&wif.PrivKey.PublicKey)
+	return s.toPublicManagedAddress(
+		pubKey, wif.CompressPubKey, true, importedDerivationPath,
+	)
+}
+
+// importPublicKey imports a public key into the address manager and updates the
+// wallet's start block if necessary. An error is returned if the public key
+// already exists.
+func (s *ScopedKeyManager) importPublicKey(ns walletdb.ReadWriteBucket,
+	serializedPubKey, encryptedPrivKey []byte, bs *BlockStamp) error {
+
 	// Prevent duplicates.
-	serializedPubKey := wif.SerializePubKey()
 	pubKeyHash := btcutil.Hash160(serializedPubKey)
 	alreadyExists := s.existsAddress(ns, pubKeyHash)
 	if alreadyExists {
 		str := fmt.Sprintf("address for public key %x already exists",
 			serializedPubKey)
-		return nil, managerError(ErrDuplicateAddress, str, nil)
+		return managerError(ErrDuplicateAddress, str, nil)
 	}
 
 	// Encrypt public key.
@@ -1530,20 +1572,7 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
 	if err != nil {
 		str := fmt.Sprintf("failed to encrypt public key for %x",
 			serializedPubKey)
-		return nil, managerError(ErrCrypto, str, err)
-	}
-
-	// Encrypt the private key when not a watching-only address manager.
-	var encryptedPrivKey []byte
-	if !s.rootManager.WatchOnly() {
-		privKeyBytes := wif.PrivKey.Serialize()
-		encryptedPrivKey, err = s.rootManager.cryptoKeyPriv.Encrypt(privKeyBytes)
-		zero.Bytes(privKeyBytes)
-		if err != nil {
-			str := fmt.Sprintf("failed to encrypt private key for %x",
-				serializedPubKey)
-			return nil, managerError(ErrCrypto, str, err)
-		}
+		return managerError(ErrCrypto, str, err)
 	}
 
 	// The start block needs to be updated when the newly imported address
@@ -1559,13 +1588,13 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
 		encryptedPubKey, encryptedPrivKey,
 	)
 	if err != nil {
-		return nil, err
+		return err
 	}
 
 	if updateStartBlock {
 		err := putStartBlock(ns, bs)
 		if err != nil {
-			return nil, err
+			return err
 		}
 	}
 
@@ -1577,30 +1606,42 @@ func (s *ScopedKeyManager) ImportPrivateKey(ns walletdb.ReadWriteBucket,
 		s.rootManager.mtx.Unlock()
 	}
 
-	// The full derivation path for an imported key is incomplete as we
-	// don't know exactly how it was derived.
-	importedDerivationPath := DerivationPath{
-		Account: ImportedAddrAccount,
-	}
+	return nil
+}
+
+// toPrivateManagedAddress converts a private key to a managed address.
+func (s *ScopedKeyManager) toPrivateManagedAddress(wif *btcutil.WIF,
+	imported bool, derivationPath DerivationPath) (*managedAddress, error) {
 
 	// Create a new managed address based on the imported address.
-	var managedAddr *managedAddress
-	if !s.rootManager.WatchOnly() {
-		managedAddr, err = newManagedAddress(
-			s, importedDerivationPath, wif.PrivKey,
-			wif.CompressPubKey, s.addrSchema.ExternalAddrType,
-		)
-	} else {
-		pubKey := (*btcec.PublicKey)(&wif.PrivKey.PublicKey)
-		managedAddr, err = newManagedAddressWithoutPrivKey(
-			s, importedDerivationPath, pubKey, wif.CompressPubKey,
-			s.addrSchema.ExternalAddrType,
-		)
-	}
+	managedAddr, err := newManagedAddress(
+		s, derivationPath, wif.PrivKey, wif.CompressPubKey,
+		s.addrSchema.ExternalAddrType,
+	)
 	if err != nil {
 		return nil, err
 	}
-	managedAddr.imported = true
+	managedAddr.imported = imported
+
+	// Add the new managed address to the cache of recent addresses and
+	// return it.
+	s.addrs[addrKey(managedAddr.Address().ScriptAddress())] = managedAddr
+	return managedAddr, nil
+}
+
+// toPublicManagedAddress converts a public key to a managed address.
+func (s *ScopedKeyManager) toPublicManagedAddress(pubKey *btcec.PublicKey,
+	compressed, imported bool, derivationPath DerivationPath) (*managedAddress, error) {
+
+	// Create a new managed address based on the imported address.
+	managedAddr, err := newManagedAddressWithoutPrivKey(
+		s, derivationPath, pubKey, compressed,
+		s.addrSchema.ExternalAddrType,
+	)
+	if err != nil {
+		return nil, err
+	}
+	managedAddr.imported = imported
 
 	// Add the new managed address to the cache of recent addresses and
 	// return it.