Skip to content

Commit

Permalink
Merge #3420
Browse files Browse the repository at this point in the history
3420: Construct address with hashes r=paweljakubas a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->


- [x] used CredentialFromKeyHash in ApiCredential
- [x] added extended public key in ApiCredential
- [x] cleaned parser (better reuse), also updated swagger
- [x] added more golden in ANY_ADDRESS   

### Comments
depends on IntersectMBO/cardano-addresses#193
<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-1985
<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <[email protected]>
Co-authored-by: Jonathan Knowles <[email protected]>
  • Loading branch information
3 people authored Aug 4, 2022
2 parents 7b1ad91 + 02fccba commit fc1355f
Show file tree
Hide file tree
Showing 11 changed files with 1,259 additions and 886 deletions.
4 changes: 2 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ source-repository-package
source-repository-package
type: git
location: https://github.com/input-output-hk/cardano-addresses
tag: 4a369086471d0849d40ba384ca39a4ab94f23d82
--sha256: 1rxbaycknxaadyrwn1knlz0mp1mwavm2kcw7dmp1pyb6ifrq62iq
tag: 8f57479422264f33bfbf58198623c035cc973f30
--sha256: 032knh0kli2shpqh9b4w2ci9rp01q6p8albj56brg6gn5l9sknzy
subdir: command-line
core

Expand Down

Large diffs are not rendered by default.

62 changes: 44 additions & 18 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,12 @@ import Prelude
import Cardano.Address.Derivation
( XPrv, XPub, xpubFromBytes, xpubToBytes )
import Cardano.Address.Script
( Cosigner (..), KeyHash, Script, ScriptTemplate, ValidationLevel (..) )
( Cosigner (..)
, KeyHash (..)
, Script
, ScriptTemplate
, ValidationLevel (..)
)
import Cardano.Api
( AnyCardanoEra (..)
, CardanoEra (..)
Expand Down Expand Up @@ -491,6 +496,7 @@ import qualified Data.Aeson.Types as Aeson
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as B8
import qualified Data.ByteString.Lazy as BL
import qualified Data.List as L
import qualified Data.Map as Map
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
Expand Down Expand Up @@ -645,7 +651,9 @@ data ApiAddress (n :: NetworkDiscriminant) = ApiAddress
deriving anyclass NFData

data ApiCredential =
CredentialPubKey ByteString
CredentialExtendedPubKey ByteString
| CredentialPubKey ByteString
| CredentialKeyHash ByteString
| CredentialScript (Script KeyHash)
deriving (Eq, Generic, Show)

Expand Down Expand Up @@ -2800,34 +2808,48 @@ instance ToJSON (ApiT (Passphrase purpose)) where

instance FromJSON ApiCredential where
parseJSON v =
(CredentialScript <$> parseJSON v) <|>
(CredentialPubKey <$> parsePubKey v)

parsePubKey :: Aeson.Value -> Aeson.Parser ByteString
parsePubKey = withText "CredentialPubKey" $ \txt ->
(CredentialKeyHash <$> parseCredential 28 ["stake_vkh","addr_vkh"] v) <|>
(CredentialPubKey <$> parseCredential 32 ["stake_vk","addr_vk"] v) <|>
(CredentialExtendedPubKey <$> parseCredential 64 ["stake_xvk","addr_xvk"] v) <|>
(CredentialScript <$> parseJSON v)

parseCredential
:: Int
-> [Text]
-> Aeson.Value
-> Aeson.Parser ByteString
parseCredential payloadLength prefixes = withText "Credential" $ \txt ->
case detectEncoding (T.unpack txt) of
Just EBech32{} -> do
(hrp, dp) <- case Bech32.decodeLenient txt of
Left _ -> fail "CredentialPubKey's Bech32 has invalid text."
Left _ -> fail "Credential's Bech32 has invalid text."
Right res -> pure res
let checkPayload bytes
| BS.length bytes /= 32 =
fail "CredentialPubKey must be 32 bytes."
| BS.length bytes /= payloadLength =
fail $ "Credential must be "
<> show payloadLength <> " bytes."
| otherwise = pure bytes
let proceedWhenHrpCorrect = case Bech32.dataPartToBytes dp of
Nothing ->
fail "CredentialPubKey has invalid Bech32 datapart."
fail "Credential has invalid Bech32 datapart."
Just bytes -> checkPayload bytes
case Bech32.humanReadablePartToText hrp of
"stake_vk" -> proceedWhenHrpCorrect
"addr_vk" -> proceedWhenHrpCorrect
_ -> fail "CredentialPubKey must have either 'addr_vk' or 'stake_vk' prefix."
_ -> fail "CredentialPubKey must be must be encoded as Bech32."
if Bech32.humanReadablePartToText hrp `L.elem` prefixes then
proceedWhenHrpCorrect
else
fail $ "Credential must have following prefixes: "
<> show prefixes
_ -> fail "Credential must be must be encoded as Bech32."

instance ToJSON ApiCredential where
toJSON (CredentialPubKey key') = do
let hrp = [Bech32.humanReadablePart|addr_vk|]
String $ T.decodeUtf8 $ encode (EBech32 hrp) key'
toJSON (CredentialExtendedPubKey key') = do
let hrp = [Bech32.humanReadablePart|addr_xvk|]
String $ T.decodeUtf8 $ encode (EBech32 hrp) key'
toJSON (CredentialKeyHash key') = do
let hrp = [Bech32.humanReadablePart|addr_vkh|]
String $ T.decodeUtf8 $ encode (EBech32 hrp) key'
toJSON (CredentialScript s) = toJSON s

instance FromJSON ApiAddressData where
Expand All @@ -2843,8 +2865,12 @@ instance FromJSON ApiAddressData where
\ with possible prefixes: 'stake_shared_vkh', 'stake_shared_vk', 'stake_shared_xvk', \
\'addr_shared_vkh', 'addr_shared_vk' or 'addr_shared_xvk' and proper \
\payload size. 'at_least' cannot exceed 255. When public key is used as a credential \
\then bech32 encoded public keys are expected to be used with possible prefixes:\
\ 'stake_vk' or 'addr_vk', always with proper payload size."
\then bech32 encoded public keys are expected to be used with possible prefixes: \
\'stake_xvk', 'addr_xvk', 'stake_vk' or 'addr_vk', always with proper payload size \
\(32-byte and 64-byte payload for non-extended and extended credential, respectively). \
\When key hash is used as a credential then bech32 encoded public keys are expected \
\to be used with possible prefixes: 'stake_vkh' or 'addr_vkh', always with 28-byte \
\payload size."
parseBaseAddr = withObject "AddrBase" $ \o -> do
addr <- AddrBase <$> o .: "payment" <*> o .: "stake"
ApiAddressData addr <$> o .:? "validation"
Expand Down
Loading

0 comments on commit fc1355f

Please sign in to comment.