Skip to content

Commit

Permalink
Try #2229:
Browse files Browse the repository at this point in the history
  • Loading branch information
iohk-bors[bot] committed Oct 13, 2020
2 parents 77e04fc + e064518 commit 039fd87
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 53 deletions.
14 changes: 14 additions & 0 deletions lib/core-integration/src/Test/Integration/Framework/DSL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ module Test.Integration.Framework.DSL
, rootPrvKeyFromMnemonics
, unsafeGetTransactionTime
, getTxId
, getWalletKey

-- * Delegation helpers
, mkEpochInfo
Expand Down Expand Up @@ -174,6 +175,7 @@ import Cardano.Wallet.Api.Types
, ApiTransaction
, ApiTxId (ApiTxId)
, ApiUtxoStatistics (..)
, ApiVerificationKeyHash
, ApiWallet
, ApiWalletDelegation (..)
, ApiWalletDelegationNext (..)
Expand Down Expand Up @@ -212,6 +214,7 @@ import Cardano.Wallet.Primitive.Types
( ActiveSlotCoefficient (..)
, Address (..)
, Coin (..)
, DerivationIndex
, EpochLength (..)
, EpochNo
, Hash (..)
Expand Down Expand Up @@ -1348,6 +1351,17 @@ listAddresses ctx w = do
(_, addrs) <- unsafeRequest @[ApiAddress n] ctx link Empty
return addrs

getWalletKey
:: forall t w. ( HasType (ApiT WalletId) w )
=> Context t
-> w
-> ApiT DerivationIndex
-> IO ApiVerificationKeyHash
getWalletKey ctx w index = do
let link = Link.getWalletKey w index
(_, keyHash) <- unsafeRequest @ApiVerificationKeyHash ctx link Empty
return keyHash

listAllTransactions
:: forall n t w.
( DecodeAddress n
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Cardano.Wallet.Api.Types
, ApiT (..)
, ApiTransaction
, ApiUtxoStatistics
, ApiVerificationKeyHash
, ApiWallet
, DecodeAddress
, DecodeStakeAddress
Expand Down Expand Up @@ -1118,6 +1119,24 @@ spec = describe "SHELLEY_WALLETS" $ do
r <- request @ApiUtxoStatistics ctx (Link.getUTxOsStatistics @'Shelley w) headers Empty
verify r expectations

describe "WALLETS_GET_KEY_01 - can get verification key hash for valid indices" $ do
let indices = fmap (ApiT . DerivationIndex) [ 0, 100, 2147483647 ]
forM_ indices $ \index -> it (show index) $ \ctx -> do

m <- genMnemonics M15
let payload = Json [json| {
"name": "Wallet",
"mnemonic_sentence": #{m},
"passphrase": #{fixturePassphrase}
} |]
r <- request @ApiWallet ctx (Link.postWallet @'Shelley) Default payload
verify r [ expectResponseCode @IO HTTP.status201 ]
let apiWal = getFromResponse id r

let link = Link.getWalletKey (apiWal ^. id) index
rGet <- request @ApiVerificationKeyHash ctx link Default Empty
verify rGet [ expectResponseCode @IO HTTP.status200 ]

it "BYRON_WALLETS_UTXO -\
\ Cannot show Byron wal utxo with shelley ep (404)" $ \ctx -> do
w <- emptyRandomWallet ctx
Expand Down
22 changes: 22 additions & 0 deletions lib/core/src/Cardano/Wallet/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ module Cardano.Wallet.Api
, PutWalletPassphrase
, GetUTxOsStatistics

, WalletKeys
, GetWalletKey

, Addresses
, ListAddresses
, InspectAddress
Expand Down Expand Up @@ -128,6 +131,7 @@ import Cardano.Wallet.Api.Types
, ApiTransactionT
, ApiTxId
, ApiUtxoStatistics
, ApiVerificationKeyHash
, ApiWallet
, ApiWalletMigrationInfo
, ApiWalletMigrationPostDataT
Expand Down Expand Up @@ -156,6 +160,7 @@ import Cardano.Wallet.Primitive.Types
( AddressState
, Block
, Coin (..)
, DerivationIndex
, NetworkParameters
, SortOrder (..)
, WalletId (..)
Expand Down Expand Up @@ -205,6 +210,7 @@ type ApiV2 n apiPool = "v2" :> Api n apiPool
-- The API used in cardano-wallet-jormungandr may differ from this one.
type Api n apiPool =
Wallets
:<|> WalletKeys
:<|> Addresses n
:<|> CoinSelections n
:<|> Transactions n
Expand Down Expand Up @@ -273,6 +279,22 @@ type GetUTxOsStatistics = "wallets"
:> "utxos"
:> Get '[JSON] ApiUtxoStatistics

{-------------------------------------------------------------------------------
Wallet Keys
See also: https://input-output-hk.github.io/cardano-wallet/api/#tag/WalletKeys
-------------------------------------------------------------------------------}

type WalletKeys =
GetWalletKey

-- | https://input-output-hk.github.io/cardano-wallet/api/#operation/getWalletKey
type GetWalletKey = "wallets"
:> Capture "walletId" (ApiT WalletId)
:> "keys"
:> "script"
:> Capture "index" (ApiT DerivationIndex)
:> Get '[JSON] ApiVerificationKeyHash

{-------------------------------------------------------------------------------
Addresses
Expand Down
28 changes: 27 additions & 1 deletion lib/core/src/Cardano/Wallet/Api/Link.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ module Cardano.Wallet.Api.Link
, getMigrationInfo
, migrateWallet

-- * WalletKeys
, getWalletKey

-- * Addresses
, postRandomAddress
, putRandomAddresses
Expand Down Expand Up @@ -104,7 +107,14 @@ import Cardano.Wallet.Api.Types
import Cardano.Wallet.Primitive.AddressDerivation
( NetworkDiscriminant (..) )
import Cardano.Wallet.Primitive.Types
( AddressState, Coin (..), Hash, PoolId, SortOrder, WalletId (..) )
( AddressState
, Coin (..)
, DerivationIndex
, Hash
, PoolId
, SortOrder
, WalletId (..)
)
import Data.Function
( (&) )
import Data.Generics.Internal.VL.Lens
Expand Down Expand Up @@ -255,6 +265,22 @@ getMigrationInfo w = discriminate @style
where
wid = w ^. typed @(ApiT WalletId)

--
-- WalletKeys
--

getWalletKey
:: forall w.
( HasType (ApiT WalletId) w
)
=> w
-> ApiT DerivationIndex
-> (Method, Text)
getWalletKey w index =
endpoint @Api.GetWalletKey (\mk -> mk wid index)
where
wid = w ^. typed @(ApiT WalletId)

--
-- Addresses
--
Expand Down
27 changes: 27 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ module Cardano.Wallet.Api.Server
, putWalletPassphrase
, quitStakePool
, selectCoins
, getWalletKeyHash

-- * Internals
, LiftHandler(..)
Expand All @@ -95,8 +96,12 @@ import Prelude

import Cardano.Address.Derivation
( XPrv, XPub )
import Cardano.Address.Style.Shelley
( deriveMultisigPublicKey, hashKey, liftXPub )
import Cardano.Mnemonic
( SomeMnemonic )
import Cardano.Script
( KeyHash (..) )
import Cardano.Wallet
( ErrAdjustForFee (..)
, ErrCannotJoin (..)
Expand Down Expand Up @@ -185,6 +190,7 @@ import Cardano.Wallet.Api.Types
, ApiTxInput (..)
, ApiTxMetadata (..)
, ApiUtxoStatistics (..)
, ApiVerificationKeyHash (..)
, ApiWallet (..)
, ApiWalletDelegation (..)
, ApiWalletDelegationNext (..)
Expand Down Expand Up @@ -430,6 +436,7 @@ import qualified Cardano.Wallet.Api.Types as Api
import qualified Cardano.Wallet.Network as NW
import qualified Cardano.Wallet.Primitive.AddressDerivation.Byron as Byron
import qualified Cardano.Wallet.Primitive.AddressDerivation.Icarus as Icarus
import qualified Cardano.Wallet.Primitive.AddressDerivation.Shelley as Shelley
import qualified Cardano.Wallet.Primitive.Slotting as S
import qualified Cardano.Wallet.Primitive.Types as W
import qualified Cardano.Wallet.Registry as Registry
Expand Down Expand Up @@ -1101,6 +1108,26 @@ getUTxOsStatistics ctx (ApiT wid) = do
W.listUtxoStatistics wrk wid
return $ toApiUtxoStatistics stats

getWalletKeyHash
:: forall ctx s t k n.
( s ~ SeqState n k
, ctx ~ ApiLayer s t k
, k ~ ShelleyKey
)
=> ctx
-> ApiT WalletId
-> ApiT DerivationIndex
-> Handler ApiVerificationKeyHash
getWalletKeyHash ctx (ApiT wid) (ApiT (DerivationIndex index)) =
withWorkerCtx @_ @s @k ctx wid liftE liftE $ \wrk -> do
(cp, _, _) <- liftHandler $ W.readWallet @_ @s @k wrk wid
let accPub = getState cp ^. #externalPool . #accountPubKey
let (KeyHash bytes) =
hashKey $ deriveMultisigPublicKey
(liftXPub $ Shelley.getKey accPub)
(toEnum $ fromInteger $ toInteger index)
pure $ ApiVerificationKeyHash $ ApiT $ Hash bytes

{-------------------------------------------------------------------------------
Coin Selections
-------------------------------------------------------------------------------}
Expand Down
16 changes: 16 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ module Cardano.Wallet.Api.Types
, ApiWalletMigrationPostData (..)
, ApiWalletMigrationInfo (..)
, ApiWithdrawal (..)
, ApiVerificationKeyHash (..)

-- * API Types (Byron)
, ApiByronWallet (..)
Expand Down Expand Up @@ -711,6 +712,10 @@ data ApiWalletMigrationInfo = ApiWalletMigrationInfo
newtype ApiWithdrawRewards = ApiWithdrawRewards Bool
deriving (Eq, Generic, Show)

newtype ApiVerificationKeyHash = ApiVerificationKeyHash
{ verificationKeyHash :: ApiT (Hash "ScriptKey")
} deriving (Eq, Generic, Show)

-- | Error codes returned by the API, in the form of snake_cased strings
data ApiErrorCode
= NoSuchWallet
Expand Down Expand Up @@ -986,6 +991,17 @@ instance FromJSON (ApiT DerivationIndex) where
Just s ->
pure s

instance FromJSON (ApiT (Hash "ScriptKey")) where
parseJSON =
parseJSON >=> eitherToParser . bimap ShowFmt ApiT . fromText
instance ToJSON (ApiT (Hash "ScriptKey")) where
toJSON = toJSON . toText . getApiT

instance ToJSON ApiVerificationKeyHash where
toJSON = genericToJSON defaultRecordTypeOptions
instance FromJSON ApiVerificationKeyHash where
parseJSON = genericParseJSON defaultRecordTypeOptions

instance FromJSON ApiEpochInfo where
parseJSON = genericParseJSON defaultRecordTypeOptions
instance ToJSON ApiEpochInfo where
Expand Down
7 changes: 7 additions & 0 deletions lib/core/src/Cardano/Wallet/Primitive/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,12 @@ newtype DerivationIndex

instance NFData DerivationIndex

instance FromText DerivationIndex where
fromText = fmap DerivationIndex . fromText

instance ToText DerivationIndex where
toText (DerivationIndex index) = toText index

{-------------------------------------------------------------------------------
Coin
-------------------------------------------------------------------------------}
Expand Down Expand Up @@ -1848,6 +1854,7 @@ instance FromText (Hash "Genesis") where fromText = hashFromText 32
instance FromText (Hash "Block") where fromText = hashFromText 32
instance FromText (Hash "BlockHeader") where fromText = hashFromText 32
instance FromText (Hash "ChimericAccount") where fromText = hashFromText 28
instance FromText (Hash "ScriptKey") where fromText = hashFromText 28

hashFromText
:: forall t. (KnownSymbol t)
Expand Down
35 changes: 35 additions & 0 deletions lib/core/test/data/Cardano/Wallet/Api/ApiVerificationKeyHash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"seed": 3843240765986310815,
"samples": [
{
"verification_key_hash": "f83d391427406d430e30534349563a7f58c9383c3b0a9d21091e6354"
},
{
"verification_key_hash": "2b5a99483598726a1975e3465a1a1bdf08516715254a7b4b784b1a22"
},
{
"verification_key_hash": "082d0f1d626904470724a7d8374f4bf20a0218500b057fb85b3b8445"
},
{
"verification_key_hash": "666b2a40060e37485c5633397e354a430b18126b4634335f5d3701cd"
},
{
"verification_key_hash": "3a612ab449126476577c656a92333f7d401021e2283a375abf49a627"
},
{
"verification_key_hash": "0669fc3c392c5e37474eb4031c8125101230f01260472720646b1b44"
},
{
"verification_key_hash": "7f2869354b6a66d10dd9685c04586e252f2c457856123d66896c680a"
},
{
"verification_key_hash": "625301105b51b91772532b55a202104f03251949720c6c7b0327530b"
},
{
"verification_key_hash": "9a6a1860033e420319030e59015d544b0669298d1203097710d34f2a"
},
{
"verification_key_hash": "308e7f5902082e041774b45c515d9801702276230b792a6b76314277"
}
]
}
18 changes: 17 additions & 1 deletion lib/core/test/unit/Cardano/Wallet/Api/Malformed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import Cardano.Wallet.Api.Types
import Cardano.Wallet.Primitive.AddressDerivation
( NetworkDiscriminant (..) )
import Cardano.Wallet.Primitive.Types
( Address, WalletId, walletNameMaxLength )
( Address, DerivationIndex, WalletId, walletNameMaxLength )
import Control.Arrow
( first )
import Data.Aeson.QQ
Expand Down Expand Up @@ -151,6 +151,22 @@ instance Malformed (PathParam ApiTxId) where
where
msg = "Invalid tx hash: expecting a hex-encoded value that is 32 bytes in length."

instance Wellformed (PathParam (ApiT DerivationIndex)) where
wellformed = PathParam <$>
[ "0"
, "1000"
, "2147483647"
]

instance Malformed (PathParam (ApiT DerivationIndex)) where
malformed = first PathParam <$>
[ ("-1",msg)
, ("4.3",msg)
, ("something",msg)
]
where
msg = "Expecting natural number"

instance Wellformed (PathParam ApiPoolId) where
wellformed = PathParam <$>
[ T.replicate 64 "0"
Expand Down

0 comments on commit 039fd87

Please sign in to comment.