diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## 0.17.6
+### Added
+- Serialize instances for `XPubKey` and `XPrvKey`.
+
 ## 0.17.5
 ### Fixed
 - Handle special case in block header binary search function.
diff --git a/haskoin-core.cabal b/haskoin-core.cabal
--- a/haskoin-core.cabal
+++ b/haskoin-core.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 1ea170297fcc675501a164406d4103bae8feb08c641258580d099edabac6360c
+-- hash: 80ca7faee9e1700b5927a262126a774fb45156219675eb255ba45e31aabcfe92
 
 name:           haskoin-core
-version:        0.17.5
+version:        0.17.6
 synopsis:       Bitcoin & Bitcoin Cash library for Haskell
 description:    Please see the README on GitHub at <https://github.com/haskoin/haskoin-core#readme>
 category:       Bitcoin, Finance, Network
diff --git a/src/Haskoin/Keys/Extended.hs b/src/Haskoin/Keys/Extended.hs
--- a/src/Haskoin/Keys/Extended.hs
+++ b/src/Haskoin/Keys/Extended.hs
@@ -164,6 +164,20 @@
     , xPrvKey    :: !SecKey      -- ^ private key of this node
     } deriving (Generic, Eq, Show, Read, NFData)
 
+instance Serialize XPrvKey where
+    put k = do
+        putWord8 $ xPrvDepth k
+        putWord32be $ xPrvParent k
+        putWord32be $ xPrvIndex k
+        put $ xPrvChain k
+        putPadPrvKey $ xPrvKey k
+    get =
+        XPrvKey <$> getWord8
+                <*> getWord32be
+                <*> getWord32be
+                <*> S.get
+                <*> getPadPrvKey
+
 xPrvToJSON :: Network -> XPrvKey -> Value
 xPrvToJSON net = A.String . xPrvExport net
 
@@ -187,6 +201,20 @@
     , xPubKey    :: !PubKey    -- ^ public key of this node
     } deriving (Generic, Eq, Show, Read, NFData)
 
+instance Serialize XPubKey where
+    put k = do
+        putWord8 $ xPubDepth k
+        putWord32be $ xPubParent k
+        putWord32be $ xPubIndex k
+        put $ xPubChain k
+        put $ wrapPubKey True (xPubKey k)
+    get =
+        XPubKey <$> getWord8
+                <*> getWord32be
+                <*> getWord32be
+                <*> S.get
+                <*> (pubKeyPoint <$> S.get)
+
 -- | Decode an extended public key from a JSON string
 xPubFromJSON :: Network -> Value -> Parser XPubKey
 xPubFromJSON net =
@@ -360,21 +388,13 @@
     ver <- getWord32be
     unless (ver == getExtSecretPrefix net) $ fail
         "Get: Invalid version for extended private key"
-    XPrvKey <$> getWord8
-            <*> getWord32be
-            <*> getWord32be
-            <*> S.get
-            <*> getPadPrvKey
+    S.get
 
 -- | Serialize an extended private key.
 putXPrvKey :: Network -> Putter XPrvKey
 putXPrvKey net k = do
     putWord32be $ getExtSecretPrefix net
-    putWord8 $ xPrvDepth k
-    putWord32be $ xPrvParent k
-    putWord32be $ xPrvIndex k
-    put $ xPrvChain k
-    putPadPrvKey $ xPrvKey k
+    put k
 
 -- | Parse a binary extended public key.
 getXPubKey :: Network -> Get XPubKey
@@ -382,21 +402,13 @@
     ver <- getWord32be
     unless (ver == getExtPubKeyPrefix net) $ fail
         "Get: Invalid version for extended public key"
-    XPubKey <$> getWord8
-            <*> getWord32be
-            <*> getWord32be
-            <*> S.get
-            <*> (pubKeyPoint <$> S.get)
+    S.get
 
 -- | Serialize an extended public key.
 putXPubKey :: Network -> Putter XPubKey
 putXPubKey net k = do
     putWord32be $ getExtPubKeyPrefix net
-    putWord8 $ xPubDepth k
-    putWord32be $ xPubParent k
-    putWord32be $ xPubIndex k
-    put $ xPubChain k
-    put $ wrapPubKey True (xPubKey k)
+    put k
 
 {- Derivation helpers -}
 
