Skip to content

Commit

Permalink
Merge #3617
Browse files Browse the repository at this point in the history
3617: Shared wallets with metadata 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] I have added metada integration tests demonstrating shared wallets support metadata

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number
adp-2248

<!-- 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 <pawel.jakubas@iohk.io>
  • Loading branch information
iohk-bors[bot] and paweljakubas committed Nov 30, 2022
2 parents 081fc68 + 762b9e6 commit bc6dbb6
Showing 1 changed file with 144 additions and 1 deletion.
Expand Up @@ -45,6 +45,7 @@ import Cardano.Wallet.Api.Types
, EncodeAddress (..)
, Iso8601Time (..)
, WalletStyle (..)
, fromApiEra
, insertedAt
)
import Cardano.Wallet.Api.Types.Transaction
Expand All @@ -67,6 +68,7 @@ import Cardano.Wallet.Primitive.Types.Tx
, TxMetadataValue (..)
, TxScriptValidity (..)
, TxStatus (..)
, cardanoTxIdeallyNoLaterThan
)
import Cardano.Wallet.Transaction
( AnyScript (..), WitnessCount (..) )
Expand All @@ -80,6 +82,8 @@ import Data.Aeson
( toJSON )
import Data.Either.Combinators
( swapEither )
import Data.Function
( (&) )
import Data.Generics.Internal.VL.Lens
( view, (^.) )
import Data.Maybe
Expand Down Expand Up @@ -153,6 +157,7 @@ import Test.Integration.Framework.TestData

import qualified Cardano.Address.Script as CA
import qualified Cardano.Address.Style.Shelley as CA
import qualified Cardano.Api as Cardano
import qualified Cardano.Wallet.Api.Link as Link
import qualified Cardano.Wallet.Primitive.Types.TokenMap as TokenMap
import qualified Data.ByteArray as BA
Expand Down Expand Up @@ -218,7 +223,8 @@ spec = describe "SHARED_TRANSACTIONS" $ do
, expectErrorMessage errMsg403SharedWalletPending
]

it "SHARED_TRANSACTIONS_CREATE_01 - Can create tx for an active shared wallet" $ \ctx -> runResourceT $ do
it "SHARED_TRANSACTIONS_CREATE_01 - Can create tx for an active shared wallet,\
\ typed metadata" $ \ctx -> runResourceT $ do
m15txt <- liftIO $ genMnemonics M15
m12txt <- liftIO $ genMnemonics M12
let payload = Json [json| {
Expand Down Expand Up @@ -329,6 +335,143 @@ spec = describe "SHARED_TRANSACTIONS" $ do
(#status . #getApiT) (`shouldBe` InLedger)
]

it "SHARED_TRANSACTIONS_CREATE_01 - Can create tx for an active shared wallet,\
\ untyped metadata" $ \ctx -> runResourceT $ do
m15txt <- liftIO $ genMnemonics M15
m12txt <- liftIO $ genMnemonics M12
let payload = Json [json| {
"name": "Shared Wallet",
"mnemonic_sentence": #{m15txt},
"mnemonic_second_factor": #{m12txt},
"passphrase": #{fixturePassphrase},
"account_index": "30H",
"payment_script_template":
{ "cosigners":
{ "cosigner#0": "self" },
"template":
{ "all":
[ "cosigner#0" ]
}
}
} |]
rPost <- postSharedWallet ctx Default payload
verify (fmap (swapEither . view #wallet) <$> rPost)
[ expectResponseCode HTTP.status201
]

let walShared@(ApiSharedWallet (Right wal)) =
getFromResponse Prelude.id rPost

let metadata = Json [json|{ "metadata": { "1": "hello" } }|]

let amt = 10 * minUTxOValue (_mainEra ctx)
fundSharedWallet ctx amt (NE.fromList [walShared])

rTx <- request @(ApiConstructTransaction n) ctx
(Link.createUnsignedTransaction @'Shared wal) Default metadata
verify rTx
[ expectResponseCode HTTP.status202
, expectField (#coinSelection . #metadata) (`shouldSatisfy` isJust)
, expectField (#fee . #getQuantity) (`shouldSatisfy` (>0))
]

-- checking metadata before signing using decodeTransaction
let txCbor1 = getFromResponse #transaction rTx
let decodePayload1 = Json (toJSON txCbor1)
rDecodedTx1 <- request @(ApiDecodedTransaction n) ctx
(Link.decodeTransaction @'Shared wal) Default decodePayload1
let expectedFee = getFromResponse (#fee . #getQuantity) rTx
let metadata' = ApiT (TxMetadata (Map.fromList [(1,TxMetaText "hello")]))
let decodedExpectations =
[ expectResponseCode HTTP.status202
, expectField (#fee . #getQuantity) (`shouldBe` expectedFee)
, expectField #withdrawals (`shouldBe` [])
, expectField #collateral (`shouldBe` [])
, expectField #metadata
(`shouldBe` (ApiTxMetadata (Just metadata')))
, expectField #scriptValidity (`shouldBe` (Just $ ApiT TxScriptValid))
]
verify rDecodedTx1 decodedExpectations

-- checking metadata before signing via directly inspecting serialized tx
let getMetadata (Cardano.InAnyCardanoEra _ tx) = Cardano.getTxBody tx &
\(Cardano.TxBody bodyContent) ->
Cardano.txMetadata bodyContent & \case
Cardano.TxMetadataNone ->
Nothing
Cardano.TxMetadataInEra _ (Cardano.TxMetadata m) ->
Just m

let era = fromApiEra $ _mainEra ctx
let txbinary1 = cardanoTxIdeallyNoLaterThan era $
getApiT (txCbor1 ^. #serialisedTxSealed)
case getMetadata txbinary1 of
Nothing -> error "Tx doesn't include metadata"
Just m -> case Map.lookup 1 m of
Nothing -> error "Tx doesn't include metadata"
Just (Cardano.TxMetaText "hello") -> pure ()
Just _ -> error "Tx metadata incorrect"

let (ApiSerialisedTransaction apiTx _) =
getFromResponse #transaction rTx
signedTx <-
signSharedTx ctx wal apiTx [ expectResponseCode HTTP.status202 ]

-- checking metadata after signing using decodeTransaction
let decodePayload2 = Json (toJSON signedTx)
rDecodedTx2 <- request @(ApiDecodedTransaction n) ctx
(Link.decodeTransaction @'Shared wal) Default decodePayload2
verify rDecodedTx2 decodedExpectations

-- checking metadata after signing via directly inspecting serialized tx
let txbinary2 = cardanoTxIdeallyNoLaterThan era $
getApiT (signedTx ^. #serialisedTxSealed)
case getMetadata txbinary2 of
Nothing -> error "Tx doesn't include metadata"
Just m -> case Map.lookup 1 m of
Nothing -> error "Tx doesn't include metadata"
Just (Cardano.TxMetaText "hello") -> pure ()
Just _ -> error "Tx metadata incorrect"

-- Submit tx
submittedTx <- submitSharedTxWithWid ctx wal signedTx
verify submittedTx
[ expectSuccess
, expectResponseCode HTTP.status202
]

let txid = getFromResponse #id submittedTx
let queryTx = Link.getTransaction @'Shared wal (ApiTxId txid)
rGetTx <- request @(ApiTransaction n) ctx queryTx Default Empty
verify rGetTx
[ expectResponseCode HTTP.status200
, expectField (#direction . #getApiT) (`shouldBe` Outgoing)
]

-- Make sure only fee is deducted from shared Wallet
eventually "Wallet balance is as expected" $ do
rWal <- getSharedWallet ctx walShared
verify (fmap (view #wallet) <$> rWal)
[ expectResponseCode HTTP.status200
, expectField
(traverse . #balance . #available . #getQuantity)
(`shouldBe` (amt - expectedFee))
]

eventually "Tx is in ledger finally" $ do
rGetTx' <- request @(ApiTransaction n) ctx queryTx Default Empty
verify rGetTx'
[ expectResponseCode HTTP.status200
, expectField (#status . #getApiT) (`shouldBe` InLedger)
]
let listTxEp = Link.listTransactions @'Shared wal
request @[ApiTransaction n] ctx listTxEp Default Empty >>= flip verify
[ expectListField 1
(#direction . #getApiT) (`shouldBe` Incoming)
, expectListField 1
(#status . #getApiT) (`shouldBe` InLedger)
]

it "SHARED_TRANSACTIONS_CREATE_01a - Empty payload is not allowed" $ \ctx -> runResourceT $ do
wa <- fixtureSharedWallet ctx
let emptyPayload = Json [json|{}|]
Expand Down

0 comments on commit bc6dbb6

Please sign in to comment.