Skip to content

Commit ac4222e

Browse files
committed
change derivation path JSON serialization to be less verbose
And also aligned with other interfaces like cardano-addresses.
1 parent 4ad068a commit ac4222e

File tree

3 files changed

+247
-716
lines changed

3 files changed

+247
-716
lines changed

lib/core/src/Cardano/Wallet/Api/Types.hs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ import Data.ByteString
232232
( ByteString )
233233
import Data.Either.Extra
234234
( maybeToEither )
235+
import Data.Foldable
236+
( asum )
235237
import Data.Function
236238
( (&) )
237239
import Data.Generics.Internal.VL.Lens
@@ -246,6 +248,8 @@ import Data.Proxy
246248
( Proxy (..) )
247249
import Data.Quantity
248250
( Percentage, Quantity (..) )
251+
import Data.Scientific
252+
( Scientific, toBoundedInteger )
249253
import Data.String
250254
( IsString )
251255
import Data.Text
@@ -274,6 +278,8 @@ import GHC.TypeLits
274278
( Nat, Symbol )
275279
import Numeric.Natural
276280
( Natural )
281+
import Safe
282+
( readMay )
277283
import Servant.API
278284
( MimeRender (..), MimeUnrender (..), OctetStream )
279285
import Web.HttpApiData
@@ -954,9 +960,40 @@ instance FromJSON ApiAddressDerivationPath where
954960
parseJSON = fmap ApiAddressDerivationPath . parseJSON
955961

956962
instance ToJSON ApiAddressDerivationSegment where
957-
toJSON = genericToJSON defaultRecordTypeOptions
963+
toJSON (ApiAddressDerivationSegment (ApiRelativeAddressIndex ix) typ)
964+
| typ == Hardened = toJSON (show ix <> "H")
965+
| otherwise = toJSON (show ix)
958966
instance FromJSON ApiAddressDerivationSegment where
959-
parseJSON = genericParseJSON defaultRecordTypeOptions
967+
parseJSON value = asum
968+
[ parseJSON value >>= parseAsScientific
969+
, parseJSON value >>= parseAsText
970+
]
971+
where
972+
parseAsText :: Text -> Aeson.Parser ApiAddressDerivationSegment
973+
parseAsText txt =
974+
if "H" `T.isSuffixOf` txt then do
975+
path <- castNumber (T.init txt) >>= parseAsScientific
976+
pure $ path { derivationType = Hardened }
977+
else
978+
castNumber txt >>= parseAsScientific
979+
980+
parseAsScientific :: Scientific -> Aeson.Parser ApiAddressDerivationSegment
981+
parseAsScientific x =
982+
case toBoundedInteger x of
983+
Nothing -> fail "expected an unsigned int31"
984+
Just ix -> pure ApiAddressDerivationSegment
985+
{ derivationIndex = ApiRelativeAddressIndex ix
986+
, derivationType = Soft
987+
}
988+
989+
castNumber :: Text -> Aeson.Parser Scientific
990+
castNumber txt =
991+
case readMay (T.unpack txt) of
992+
Nothing ->
993+
fail "expected a number as string with an optional 'H' \
994+
\suffix (e.g. \"1815H\" or \"44\""
995+
Just s ->
996+
pure s
960997

961998
instance ToJSON (ApiAddressDerivationType) where
962999
toJSON = genericToJSON defaultSumTypeOptions

0 commit comments

Comments
 (0)