Skip to content

Commit

Permalink
change derivation path JSON serialization to be less verbose
Browse files Browse the repository at this point in the history
  And also aligned with other interfaces like cardano-addresses.
  • Loading branch information
KtorZ committed Oct 6, 2020
1 parent 4ad068a commit ac4222e
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 716 deletions.
41 changes: 39 additions & 2 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ import Data.ByteString
( ByteString )
import Data.Either.Extra
( maybeToEither )
import Data.Foldable
( asum )
import Data.Function
( (&) )
import Data.Generics.Internal.VL.Lens
Expand All @@ -246,6 +248,8 @@ import Data.Proxy
( Proxy (..) )
import Data.Quantity
( Percentage, Quantity (..) )
import Data.Scientific
( Scientific, toBoundedInteger )
import Data.String
( IsString )
import Data.Text
Expand Down Expand Up @@ -274,6 +278,8 @@ import GHC.TypeLits
( Nat, Symbol )
import Numeric.Natural
( Natural )
import Safe
( readMay )
import Servant.API
( MimeRender (..), MimeUnrender (..), OctetStream )
import Web.HttpApiData
Expand Down Expand Up @@ -954,9 +960,40 @@ instance FromJSON ApiAddressDerivationPath where
parseJSON = fmap ApiAddressDerivationPath . parseJSON

instance ToJSON ApiAddressDerivationSegment where
toJSON = genericToJSON defaultRecordTypeOptions
toJSON (ApiAddressDerivationSegment (ApiRelativeAddressIndex ix) typ)
| typ == Hardened = toJSON (show ix <> "H")
| otherwise = toJSON (show ix)
instance FromJSON ApiAddressDerivationSegment where
parseJSON = genericParseJSON defaultRecordTypeOptions
parseJSON value = asum
[ parseJSON value >>= parseAsScientific
, parseJSON value >>= parseAsText
]
where
parseAsText :: Text -> Aeson.Parser ApiAddressDerivationSegment
parseAsText txt =
if "H" `T.isSuffixOf` txt then do
path <- castNumber (T.init txt) >>= parseAsScientific
pure $ path { derivationType = Hardened }
else
castNumber txt >>= parseAsScientific

parseAsScientific :: Scientific -> Aeson.Parser ApiAddressDerivationSegment
parseAsScientific x =
case toBoundedInteger x of
Nothing -> fail "expected an unsigned int31"
Just ix -> pure ApiAddressDerivationSegment
{ derivationIndex = ApiRelativeAddressIndex ix
, derivationType = Soft
}

castNumber :: Text -> Aeson.Parser Scientific
castNumber txt =
case readMay (T.unpack txt) of
Nothing ->
fail "expected a number as string with an optional 'H' \
\suffix (e.g. \"1815H\" or \"44\""
Just s ->
pure s

instance ToJSON (ApiAddressDerivationType) where
toJSON = genericToJSON defaultSumTypeOptions
Expand Down
Loading

0 comments on commit ac4222e

Please sign in to comment.