Skip to content

Commit

Permalink
add new integration tests for shared wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
paweljakubas committed May 5, 2021
1 parent a12ea53 commit 3f5b531
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 9 deletions.
39 changes: 39 additions & 0 deletions lib/core-integration/src/Test/Integration/Framework/DSL.hs
Expand Up @@ -78,6 +78,8 @@ module Test.Integration.Framework.DSL
, deleteSharedWallet
, getSharedWallet
, patchSharedWallet
, getSharedWalletKey
, postAccountKeyShared

-- * Wallet helpers
, listFilteredWallets
Expand Down Expand Up @@ -213,6 +215,7 @@ import Cardano.Mnemonic
)
import Cardano.Wallet.Api.Types
( AddressAmount
, ApiAccountKeyShared
, ApiAddress
, ApiBlockReference (..)
, ApiByronWallet
Expand All @@ -228,6 +231,7 @@ import Cardano.Wallet.Api.Types
, ApiTransaction
, ApiTxId (ApiTxId)
, ApiUtxoStatistics (..)
, ApiVerificationKeyShared
, ApiWallet
, ApiWalletDelegation (..)
, ApiWalletDelegationNext (..)
Expand Down Expand Up @@ -1433,6 +1437,41 @@ getSharedWallet ctx (ApiSharedWallet (Right w)) = do
let link = Link.getSharedWallet w
request @ApiSharedWallet ctx link Default Empty

getSharedWalletKey
:: forall m.
( MonadIO m
, MonadUnliftIO m
)
=> Context
-> ApiSharedWallet
-> Role
-> DerivationIndex
-> m (HTTP.Status, Either RequestException ApiVerificationKeyShared)
getSharedWalletKey ctx (ApiSharedWallet (Left w)) role ix = do
let link = Link.getSharedWalletKey w role ix
request @ApiVerificationKeyShared ctx link Default Empty
getSharedWalletKey ctx (ApiSharedWallet (Right w)) role ix = do
let link = Link.getSharedWalletKey w role ix
request @ApiVerificationKeyShared ctx link Default Empty

postAccountKeyShared
:: forall m.
( MonadIO m
, MonadUnliftIO m
)
=> Context
-> ApiSharedWallet
-> DerivationIndex
-> Headers
-> Payload
-> m (HTTP.Status, Either RequestException ApiAccountKeyShared)
postAccountKeyShared ctx (ApiSharedWallet (Left w)) ix headers payload = do
let link = Link.postAccountKeyShared w ix
request @ApiAccountKeyShared ctx link headers payload
postAccountKeyShared ctx (ApiSharedWallet (Right w)) ix headers payload = do
let link = Link.postAccountKeyShared w ix
request @ApiAccountKeyShared ctx link headers payload

patchEndpointEnding :: CredentialType -> Text
patchEndpointEnding = \case
Payment -> "payment-script-template"
Expand Down
Expand Up @@ -23,13 +23,14 @@ import Cardano.Address.Script
import Cardano.Mnemonic
( MkSomeMnemonic (..) )
import Cardano.Wallet.Api.Types
( ApiSharedWallet (..)
( ApiAccountKeyShared (..)
, ApiSharedWallet (..)
, DecodeAddress
, DecodeStakeAddress
, EncodeAddress (..)
)
import Cardano.Wallet.Primitive.AddressDerivation
( DerivationIndex (..), Passphrase (..), PaymentAddress )
( DerivationIndex (..), Passphrase (..), PaymentAddress, Role (..), hex )
import Cardano.Wallet.Primitive.AddressDerivation.Shelley
( ShelleyKey )
import Cardano.Wallet.Primitive.AddressDiscovery.Script
Expand All @@ -40,6 +41,8 @@ import Control.Monad.IO.Class
( liftIO )
import Control.Monad.Trans.Resource
( runResourceT )
import Data.Aeson
( ToJSON (..), Value (String) )
import Data.Bifunctor
( second )
import Data.Generics.Internal.VL.Lens
Expand Down Expand Up @@ -68,9 +71,11 @@ import Test.Integration.Framework.DSL
, genXPubs
, getFromResponse
, getSharedWallet
, getSharedWalletKey
, json
, notDelegating
, patchSharedWallet
, postAccountKeyShared
, postSharedWallet
, verify
)
Expand All @@ -85,8 +90,10 @@ import Test.Integration.Framework.TestData

import qualified Data.ByteArray as BA
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Network.HTTP.Types as HTTP
import qualified Test.Hspec.Expectations.Lifted as Expectations

spec :: forall n.
( DecodeAddress n
Expand All @@ -101,8 +108,9 @@ spec = describe "SHARED_WALLETS" $ do
let (Right m15) = mkSomeMnemonic @'[ 15 ] m15txt
let (Right m12) = mkSomeMnemonic @'[ 12 ] m12txt
let passphrase = Passphrase $ BA.convert $ T.encodeUtf8 fixturePassphrase
let accXPubDerived = accPubKeyFromMnemonics m15 (Just m12) 30 passphrase
let payload = Json [json| {
let index = 30
let accXPubDerived = accPubKeyFromMnemonics m15 (Just m12) index passphrase
let payloadPost = Json [json| {
"name": "Shared Wallet",
"mnemonic_sentence": #{m15txt},
"mnemonic_second_factor": #{m12txt},
Expand All @@ -119,8 +127,8 @@ spec = describe "SHARED_WALLETS" $ do
}
}
} |]
r <- postSharedWallet ctx Default payload
verify (second (\(Right (ApiSharedWallet (Right res))) -> Right res) r)
rPost <- postSharedWallet ctx Default payloadPost
verify (second (\(Right (ApiSharedWallet (Right res))) -> Right res) rPost)
[ expectResponseCode HTTP.status201
, expectField
(#name . #getApiT . #getWalletName) (`shouldBe` "Shared Wallet")
Expand All @@ -137,13 +145,30 @@ spec = describe "SHARED_WALLETS" $ do
, expectField (#accountIndex . #getApiT) (`shouldBe` DerivationIndex 2147483678)
]

let wal = getFromResponse id rPost

let payloadKey = Json [json|{
"passphrase": #{fixturePassphrase},
"extended": true
}|]
rKey <-
postAccountKeyShared ctx wal (DerivationIndex $ 2147483648 + index) Default payloadKey

verify rKey
[ expectResponseCode HTTP.status202
, expectField #extended (`shouldBe` True)
]
let (ApiAccountKeyShared bytes _) = getFromResponse id rKey
(T.decodeUtf8 $ hex bytes) `Expectations.shouldBe` accXPubDerived

it "SHARED_WALLETS_CREATE_02 - Create a pending shared wallet from root xprv" $ \ctx -> runResourceT $ do
m15txt <- liftIO $ genMnemonics M15
m12txt <- liftIO $ genMnemonics M12
let (Right m15) = mkSomeMnemonic @'[ 15 ] m15txt
let (Right m12) = mkSomeMnemonic @'[ 12 ] m12txt
let passphrase = Passphrase $ BA.convert $ T.encodeUtf8 fixturePassphrase
let accXPubDerived = accPubKeyFromMnemonics m15 (Just m12) 30 passphrase
let index = 30
let accXPubDerived = accPubKeyFromMnemonics m15 (Just m12) index passphrase
let payload = Json [json| {
"name": "Shared Wallet",
"mnemonic_sentence": #{m15txt},
Expand All @@ -162,8 +187,8 @@ spec = describe "SHARED_WALLETS" $ do
}
}
} |]
r <- postSharedWallet ctx Default payload
verify (second (\(Right (ApiSharedWallet (Left res))) -> Right res) r)
rPost <- postSharedWallet ctx Default payload
verify (second (\(Right (ApiSharedWallet (Left res))) -> Right res) rPost)
[ expectResponseCode HTTP.status201
, expectField
(#name . #getApiT . #getWalletName) (`shouldBe` "Shared Wallet")
Expand All @@ -173,6 +198,23 @@ spec = describe "SHARED_WALLETS" $ do
, expectField (#accountIndex . #getApiT) (`shouldBe` DerivationIndex 2147483678)
]

let wal = getFromResponse id rPost

let payloadKey = Json [json|{
"passphrase": #{fixturePassphrase},
"extended": true
}|]
rKey <-
postAccountKeyShared ctx wal (DerivationIndex $ 2147483648 + index) Default payloadKey

verify rKey
[ expectResponseCode HTTP.status202
, expectField #extended (`shouldBe` True)
]
let (ApiAccountKeyShared bytes _) = getFromResponse id rKey
(T.decodeUtf8 $ hex bytes) `Expectations.shouldBe` accXPubDerived


it "SHARED_WALLETS_CREATE_03 - Create an active shared wallet from account xpub" $ \ctx -> runResourceT $ do
(_, accXPubTxt):_ <- liftIO $ genXPubs 1
let payload = Json [json| {
Expand Down Expand Up @@ -526,3 +568,68 @@ spec = describe "SHARED_WALLETS" $ do
rPatch <- patchSharedWallet ctx wal Payment payloadPatch
expectResponseCode HTTP.status403 rPatch
expectErrorMessage errMsg403CannotUpdateThisCosigner rPatch

it "SHARED_WALLET_KEYS_01 - Getting verification keys works for active shared wallet" $ \ctx -> runResourceT $ do
(_, accXPubTxt):_ <- liftIO $ genXPubs 1
let payload = Json [json| {
"name": "Shared Wallet",
"account_public_key": #{accXPubTxt},
"account_index": "10H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubTxt} },
"template":
{ "all":
[ "cosigner#0",
{ "active_from": 120 }
]
}
}
} |]
rPost <- postSharedWallet ctx Default payload
verify rPost
[ expectResponseCode HTTP.status201
]
let wal@(ApiSharedWallet (Right _activeWal)) = getFromResponse id rPost

(_, Right paymentKey) <- getSharedWalletKey ctx wal UtxoExternal (DerivationIndex 10)
(_, Right stakeKey) <- getSharedWalletKey ctx wal MutableAccount (DerivationIndex 0)

let (String paymentAddr) = toJSON paymentKey
T.isPrefixOf "addr_shared_vk" paymentAddr `Expectations.shouldBe` True

let (String stakeAddr) = toJSON stakeKey
T.isPrefixOf "stake_shared_vk" stakeAddr `Expectations.shouldBe` True

it "SHARED_WALLET_KEYS_02 - Getting verification keys works for pending shared wallet" $ \ctx -> runResourceT $ do
(_, accXPubTxt):_ <- liftIO $ genXPubs 1
let payload = Json [json| {
"name": "Shared Wallet",
"account_public_key": #{accXPubTxt},
"account_index": "10H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": #{accXPubTxt} },
"template":
{ "all":
[ "cosigner#0",
"cosigner#1",
{ "active_from": 120 }
]
}
}
} |]
rPost <- postSharedWallet ctx Default payload
verify rPost
[ expectResponseCode HTTP.status201
]
let wal@(ApiSharedWallet (Left _pendingWal)) = getFromResponse id rPost

(_, Right paymentKey) <- getSharedWalletKey ctx wal UtxoExternal (DerivationIndex 10)
(_, Right stakeKey) <- getSharedWalletKey ctx wal MutableAccount (DerivationIndex 0)

let (String paymentAddr) = toJSON paymentKey
T.isPrefixOf "addr_shared_vk" paymentAddr `Expectations.shouldBe` True

let (String stakeAddr) = toJSON stakeKey
T.isPrefixOf "stake_shared_vk" stakeAddr `Expectations.shouldBe` True
33 changes: 33 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Link.hs
Expand Up @@ -110,6 +110,10 @@ module Cardano.Wallet.Api.Link
, getSharedWallet
, patchSharedWallet

-- * SharedWalletKeys
, getSharedWalletKey
, postAccountKeyShared

, PostWallet
, Discriminate
) where
Expand Down Expand Up @@ -729,6 +733,35 @@ patchSharedWallet w cred =
where
wid = w ^. typed @(ApiT WalletId)

--
-- SharedWalletKeys
--
getSharedWalletKey
:: forall w.
( HasType (ApiT WalletId) w
)
=> w
-> Role
-> DerivationIndex
-> (Method, Text)
getSharedWalletKey w role_ index =
endpoint @Api.GetSharedWalletKey (\mk -> mk wid (ApiT role_) (ApiT index))
where
wid = w ^. typed @(ApiT WalletId)

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


--
-- Internals
--
Expand Down

0 comments on commit 3f5b531

Please sign in to comment.