diff --git a/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs b/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs index 4adb35ba9dd..311633adcfd 100644 --- a/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs +++ b/lib/wallet/api/http/Cardano/Wallet/Api/Http/Shelley/Server.hs @@ -144,6 +144,7 @@ import Cardano.Address.Script ( Cosigner (..) , KeyHash (KeyHash) , KeyRole (..) + , Script , ScriptTemplate (..) , ValidationLevel (..) , foldScript @@ -243,7 +244,7 @@ import Cardano.Wallet.Address.Discovery.Shared import Cardano.Wallet.Address.HasDelegation ( HasDelegation (..) ) import Cardano.Wallet.Address.Keys.MintBurn - ( toTokenMapAndScript, toTokenPolicyId ) + ( replaceCosigner, toTokenMapAndScript, toTokenPolicyId ) import Cardano.Wallet.Address.Keys.SequentialAny ( mkSeqStateFromRootXPrv ) import Cardano.Wallet.Address.Keys.Shared @@ -719,7 +720,6 @@ import qualified Network.Wai.Handler.Warp as Warp import qualified Network.Wai.Handler.WarpTLS as Warp - -- | Allow configuring which port the wallet server listen to in an integration -- setup. Crashes if the variable is not a number. walletListenFromEnv :: Show e @@ -2462,12 +2462,12 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d mintBurnData <- liftHandler $ except $ parseMintBurnData body validityInterval + mintBurnReferenceScriptTemplate <- + liftHandler $ except $ parseReferenceScript body + delegationRequest <- liftHandler $ traverse parseDelegationRequest $ body ^. #delegations - when (isJust $ body ^. #referencePolicyScriptTemplate) $ - liftHandler $ throwE ErrConstructTxNotImplemented - let metadata = body ^? #metadata . traverse . #txMetadataWithSchema_metadata @@ -2507,10 +2507,11 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d Just action -> transactionCtx0 { txDelegationAction = Just action } - (transactionCtx2, policyXPubM) <- + (policyXPub, _) <- + liftHandler $ W.readPolicyPublicKey wrk + + transactionCtx2 <- if isJust mintBurnData then do - (policyXPub, _) <- - liftHandler $ W.readPolicyPublicKey wrk let isMinting (ApiMintBurnDataFromScript _ _ (ApiMint _)) = True isMinting _ = False let getMinting = \case @@ -2551,13 +2552,22 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d map getBurning $ filter (not . isMinting) $ NE.toList $ fromJust mintBurnData - pure ( transactionCtx1 + pure transactionCtx1 { txAssetsToMint = mintingData , txAssetsToBurn = burningData } - , Just policyXPub) else - pure (transactionCtx1, Nothing) + pure transactionCtx1 + + let referenceScriptM = + replaceCosigner + ShelleyKeyS + (Map.singleton (Cosigner 0) policyXPub) + <$> mintBurnReferenceScriptTemplate + + let transactionCtx3 = transactionCtx2 + { txReferenceScript = referenceScriptM + } outs <- case body ^. #payments of Nothing -> pure [] @@ -2571,14 +2581,14 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d let mintingOuts = case mintBurnData of Just mintBurns -> coalesceTokensPerAddr $ - map (toMintTxOut (fromJust policyXPubM)) $ + map (toMintTxOut policyXPub) $ filter mintWithAddress $ NE.toList mintBurns Nothing -> [] unbalancedTx <- liftHandler $ W.constructTransaction @n @'CredFromKeyK @era - txLayer db transactionCtx2 + txLayer db transactionCtx3 PreSelection { outputs = outs <> mintingOuts } balancedTx <- @@ -2598,11 +2608,11 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d (_, _, rewardPath) <- handler $ W.readRewardAccount @s db - let deposits = case txDelegationAction transactionCtx2 of + let deposits = case txDelegationAction transactionCtx3 of Just (JoinRegisteringKey _poolId) -> [W.getStakeKeyDeposit pp] _ -> [] - let refunds = case txDelegationAction transactionCtx2 of + let refunds = case txDelegationAction transactionCtx3 of Just Quit -> [W.getStakeKeyDeposit pp] _ -> [] @@ -2611,7 +2621,7 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d , coinSelection = mkApiCoinSelection deposits refunds - ((,rewardPath) <$> transactionCtx2 ^. #txDelegationAction) + ((,rewardPath) <$> transactionCtx3 ^. #txDelegationAction) metadata (unsignedTx rewardPath (outs ++ mintingOuts) apiDecoded) , fee = apiDecoded ^. #fee @@ -2622,6 +2632,29 @@ constructTransaction api argGenChange knownPools poolStatus apiWalletId body = d walletId = getApiT apiWalletId + parseReferenceScript + :: ApiConstructTransactionData n + -> Either ErrConstructTx (Maybe (Script Cosigner)) + parseReferenceScript tx = do + let mbRefScript = tx ^. #referencePolicyScriptTemplate + for mbRefScript $ \(ApiT refScript) -> do + guardWrongScriptTemplate refScript + Right refScript + where + guardWrongScriptTemplate + :: Script Cosigner -> Either ErrConstructTx () + guardWrongScriptTemplate apiScript = + when (wrongMintingTemplate apiScript) + $ Left ErrConstructTxWrongMintingBurningTemplate + where + wrongMintingTemplate script = + isLeft (validateScriptOfTemplate RecommendedValidation script) + || countCosigners script /= (1 :: Int) + || existsNonZeroCosigner script + countCosigners = foldScript (const (+ 1)) 0 + existsNonZeroCosigner = + foldScript (\cosigner a -> a || cosigner /= Cosigner 0) False + parseMintBurnData :: ApiConstructTransactionData n -> (SlotNo, SlotNo) diff --git a/lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Transactions.hs b/lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Transactions.hs index c737b3c31c9..139750da768 100644 --- a/lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Transactions.hs +++ b/lib/wallet/integration/src/Test/Integration/Scenario/API/Shared/Transactions.hs @@ -21,8 +21,6 @@ module Test.Integration.Scenario.API.Shared.Transactions import Prelude -import Cardano.Address.Script - ( KeyHash (..), Script (..) ) import Cardano.Mnemonic ( MkSomeMnemonic (..) ) import Cardano.Wallet.Address.Derivation @@ -78,7 +76,11 @@ import Cardano.Wallet.Primitive.Types.Tx import Cardano.Wallet.Primitive.Types.Tx.TxMeta ( Direction (..), TxStatus (..) ) import Cardano.Wallet.Transaction - ( AnyExplicitScript (..), ScriptReference (..), WitnessCount (..) ) + ( AnyExplicitScript (..) + , ScriptReference (..) + , WitnessCount (..) + , changeRoleInAnyExplicitScript + ) import Control.Monad ( forM_ ) import Control.Monad.IO.Unlift @@ -926,7 +928,7 @@ spec = describe "SHARED_TRANSACTIONS" $ do -- it only is aware of its policy verification key let noVerKeyWitnessHex = mkApiWitnessCount WitnessCount { verificationKey = 0 - , scripts = [changeRole CA.Unknown paymentScript] + , scripts = [changeRoleInAnyExplicitScript CA.Unknown paymentScript] , bootstrap = 0 } let witsExp1hex = @@ -964,7 +966,7 @@ spec = describe "SHARED_TRANSACTIONS" $ do -- it only is aware of its policy verification key let oneVerKeyWitnessHex = mkApiWitnessCount WitnessCount { verificationKey = 1 - , scripts = [changeRole CA.Unknown paymentScript] + , scripts = [changeRoleInAnyExplicitScript CA.Unknown paymentScript] , bootstrap = 0 } let witsExp2hex = @@ -3301,22 +3303,3 @@ spec = describe "SHARED_TRANSACTIONS" $ do (#balance . #available . #getQuantity) (`shouldBe` amt) ] - - changeRole :: CA.KeyRole -> AnyExplicitScript -> AnyExplicitScript - changeRole role = \case - NativeExplicitScript script scriptRole -> - let changeRole' = \case - RequireSignatureOf (KeyHash _ p) -> - RequireSignatureOf $ KeyHash role p - RequireAllOf xs -> - RequireAllOf (map changeRole' xs) - RequireAnyOf xs -> - RequireAnyOf (map changeRole' xs) - RequireSomeOf m xs -> - RequireSomeOf m (map changeRole' xs) - ActiveFromSlot s -> - ActiveFromSlot s - ActiveUntilSlot s -> - ActiveUntilSlot s - in NativeExplicitScript (changeRole' script) scriptRole - PlutusExplicitScript _ _ -> error "wrong usage" diff --git a/lib/wallet/integration/src/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs b/lib/wallet/integration/src/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs index 94e82cb1632..00a25080d99 100644 --- a/lib/wallet/integration/src/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs +++ b/lib/wallet/integration/src/Test/Integration/Scenario/API/Shelley/TransactionsNew.hs @@ -125,6 +125,7 @@ import Cardano.Wallet.Transaction , ScriptReference (..) , ValidityIntervalExplicit (..) , WitnessCount (..) + , changeRoleInAnyExplicitScript ) import Cardano.Wallet.Unsafe ( unsafeFromHex, unsafeMkMnemonic ) @@ -228,6 +229,7 @@ import Test.Integration.Framework.TestData import UnliftIO.Exception ( fromEither ) +import qualified Cardano.Address.Script as CA import qualified Cardano.Api as Cardano import qualified Cardano.Ledger.Keys as Ledger import qualified Cardano.Wallet.Address.Derivation.Shelley as Shelley @@ -1148,6 +1150,76 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do , expectErrorMessage errMsg403NotEnoughMoney ] + it "TRANS_NEW_ASSETS_CREATE_02 - using reference script" $ \ctx -> runResourceT $ do + + let initialAmt = 1_000_000_000 + wa <- fixtureWalletWith @n ctx [initialAmt] + wb <- emptyWallet ctx + let amt = 10_000_000 :: Natural + + let policyWithHash = Link.getPolicyKey @'Shelley wa (Just True) + (_, policyKeyHashPayload) <- + unsafeRequest @ApiPolicyKey ctx policyWithHash Empty + let (Just policyKeyHash) = + keyHashFromBytes (Policy, getApiPolicyKey policyKeyHashPayload) + let scriptUsed = RequireAllOf + [ RequireSignatureOf policyKeyHash + ] + + addrs <- listAddresses @n ctx wb + let destination = (addrs !! 1) ^. #id + let payload = Json [json|{ + "reference_policy_script_template": + { "all": [ "cosigner#0" ] }, + "payments": [{ + "address": #{destination}, + "amount": { + "quantity": #{amt}, + "unit": "lovelace" + } + }] + }|] + + let expectedCreateTx = + [ expectSuccess + , expectResponseCode HTTP.status202 + , expectField (#coinSelection . #inputs) (`shouldSatisfy` (not . null)) + , expectField (#coinSelection . #outputs) (`shouldSatisfy` (not . null)) + , expectField (#coinSelection . #change) (`shouldSatisfy` (not . null)) + , expectField (#fee . #getQuantity) (`shouldSatisfy` (> 0)) + ] + + rTx <- request @(ApiConstructTransaction n) ctx + (Link.createUnsignedTransaction @'Shelley wa) Default payload + verify rTx expectedCreateTx + + let (ApiSerialisedTransaction apiTx _) = getFromResponse #transaction rTx + + signedTx <- signTx ctx wa apiTx [ expectResponseCode HTTP.status202 ] + + submittedTx <- submitTxWithWid ctx wa signedTx + verify submittedTx + [ expectSuccess + , expectResponseCode HTTP.status202 + ] + + let (ApiT txId) = getFromResponse #id submittedTx + let refInp = ReferenceInput $ TxIn txId 0 + let referenceScript = NativeExplicitScript scriptUsed (ViaReferenceInput refInp) + let witnessCountWithNativeScript = mkApiWitnessCount WitnessCount + { verificationKey = 1 + , scripts = [changeRoleInAnyExplicitScript CA.Unknown referenceScript] + , bootstrap = 0 + } + + let decodePayload = Json (toJSON signedTx) + rTx1 <- request @(ApiDecodedTransaction n) ctx + (Link.decodeTransaction @'Shelley wa) Default decodePayload + verify rTx1 + [ expectResponseCode HTTP.status202 + , expectField (#witnessCount) (`shouldBe` witnessCountWithNativeScript) + ] + it "TRANS_NEW_VALIDITY_INTERVAL_01a - \ \Validity interval with second" $ \ctx -> runResourceT $ do diff --git a/lib/wallet/src/Cardano/Wallet/Address/Keys/MintBurn.hs b/lib/wallet/src/Cardano/Wallet/Address/Keys/MintBurn.hs index b5ed65f017e..9bae8e75a65 100644 --- a/lib/wallet/src/Cardano/Wallet/Address/Keys/MintBurn.hs +++ b/lib/wallet/src/Cardano/Wallet/Address/Keys/MintBurn.hs @@ -7,6 +7,7 @@ module Cardano.Wallet.Address.Keys.MintBurn ( derivePolicyKeyAndHash , toTokenMapAndScript , toTokenPolicyId + , replaceCosigner ) where import Prelude diff --git a/lib/wallet/src/Cardano/Wallet/Shelley/Compatibility.hs b/lib/wallet/src/Cardano/Wallet/Shelley/Compatibility.hs index 0616be770ca..b568f6cdd8b 100644 --- a/lib/wallet/src/Cardano/Wallet/Shelley/Compatibility.hs +++ b/lib/wallet/src/Cardano/Wallet/Shelley/Compatibility.hs @@ -1297,13 +1297,17 @@ toCardanoLovelace (W.Coin c) = Cardano.Lovelace $ intCast c toCardanoUTxO :: ShelleyBasedEra era -> W.UTxO -> Cardano.UTxO era toCardanoUTxO era = Cardano.UTxO . Map.fromList - . map (bimap toCardanoTxIn (toCardanoTxOut era)) + . map (bimap toCardanoTxIn (toCardanoTxOut era Nothing)) . Map.toList . W.unUTxO -toCardanoTxOut :: HasCallStack - => ShelleyBasedEra era -> W.TxOut -> Cardano.TxOut ctx era -toCardanoTxOut era = case era of +toCardanoTxOut + :: HasCallStack + => ShelleyBasedEra era + -> Maybe (Script KeyHash) + -> W.TxOut + -> Cardano.TxOut ctx era +toCardanoTxOut era refScriptM = case era of ShelleyBasedEraShelley -> toShelleyTxOut ShelleyBasedEraAllegra -> toAllegraTxOut ShelleyBasedEraMary -> toMaryTxOut @@ -1402,7 +1406,14 @@ toCardanoTxOut era = case era of datumHash refScript where - refScript = Cardano.ReferenceScriptNone + refScript = case refScriptM of + Nothing -> + Cardano.ReferenceScriptNone + Just script -> + let aux = Cardano.ReferenceTxInsScriptsInlineDatumsInBabbageEra + scriptApi = Cardano.toScriptInAnyLang $ Cardano.SimpleScript $ + toCardanoSimpleScript script + in Cardano.ReferenceScript aux scriptApi datumHash = Cardano.TxOutDatumNone addrInEra = tina "toCardanoTxOut: malformed address" [ Cardano.AddressInEra @@ -1423,7 +1434,14 @@ toCardanoTxOut era = case era of datumHash refScript where - refScript = Cardano.ReferenceScriptNone + refScript = case refScriptM of + Nothing -> + Cardano.ReferenceScriptNone + Just script -> + let aux = Cardano.ReferenceTxInsScriptsInlineDatumsInConwayEra + scriptApi = Cardano.toScriptInAnyLang $ Cardano.SimpleScript $ + toCardanoSimpleScript script + in Cardano.ReferenceScript aux scriptApi datumHash = Cardano.TxOutDatumNone addrInEra = tina "toCardanoTxOut: malformed address" [ Cardano.AddressInEra diff --git a/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs b/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs index 9faa2694dff..f387869c6c6 100644 --- a/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs +++ b/lib/wallet/src/Cardano/Wallet/Shelley/Transaction.hs @@ -250,15 +250,17 @@ constructUnsignedTx -- ^ scripts for inputs -> Maybe (Script KeyHash) -- ^ Delegation script + -> Maybe (Script KeyHash) + -- ^ Reference script -> ShelleyBasedEra era -> Either ErrMkTransaction (Cardano.TxBody era) constructUnsignedTx networkId (md, certs) ttl wdrl - cs fee toMint toBurn inpScripts stakingScriptM era = + cs fee toMint toBurn inpScripts stakingScriptM refScriptM era = mkUnsignedTx era ttl cs md wdrls certs (toCardanoLovelace fee) (fst toMint) (fst toBurn) mintingScripts inpScripts - stakingScriptM + stakingScriptM refScriptM where wdrls = mkWithdrawals networkId wdrl mintingScripts = Map.union (snd toMint) (snd toBurn) @@ -291,7 +293,7 @@ mkTx keyF networkId payload ttl (rewardAcnt, pwdAcnt) addrResolver wdrl cs fees unsigned <- mkUnsignedTx era ttl (Right cs) md wdrls certs (toCardanoLovelace fees) - TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing + TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing Nothing let signed = signTransaction keyF networkId AnyWitnessCountCtx acctResolver (const Nothing) (const Nothing) addrResolver inputResolver (unsigned, mkExtraWits unsigned) @@ -546,6 +548,7 @@ newTransactionLayer keyF networkId = TransactionLayer let assetsToBeMinted = view #txAssetsToMint ctx let assetsToBeBurned = view #txAssetsToBurn ctx let inpsScripts = view #txNativeScriptInputs ctx + let refScriptM = view #txReferenceScript ctx let stakingScriptM = flip (replaceCosignersWithVerKeys CA.Stake) minBound <$> view #txStakingCredentialScriptTemplate ctx @@ -558,17 +561,17 @@ newTransactionLayer keyF networkId = TransactionLayer if ourRewardAcctM == Just rewardAcct then constructUnsignedTx networkId (md, []) ttl wdrl selection delta assetsToBeMinted assetsToBeBurned inpsScripts - stakingScriptM + stakingScriptM refScriptM (Write.shelleyBasedEraFromRecentEra Write.recentEra) else constructUnsignedTx networkId (md, []) ttl wdrl selection delta assetsToBeMinted assetsToBeBurned inpsScripts - Nothing + Nothing refScriptM (Write.shelleyBasedEraFromRecentEra Write.recentEra) _ -> constructUnsignedTx networkId (md, []) ttl wdrl selection delta assetsToBeMinted assetsToBeBurned inpsScripts - Nothing + Nothing refScriptM (Write.shelleyBasedEraFromRecentEra Write.recentEra) Just action -> do let certs = case stakeCred of @@ -582,7 +585,7 @@ newTransactionLayer keyF networkId = TransactionLayer let payload = (view #txMetadata ctx, certs) constructUnsignedTx networkId payload ttl wdrl selection delta assetsToBeMinted assetsToBeBurned inpsScripts - stakingScriptM + stakingScriptM refScriptM (Write.shelleyBasedEraFromRecentEra Write.recentEra) , decodeTx = _decodeSealedTx @@ -659,6 +662,7 @@ mkUnsignedTx -> Map AssetId (Script KeyHash) -> Map TxIn (Script KeyHash) -> Maybe (Script KeyHash) + -> Maybe (Script KeyHash) -> Either ErrMkTransaction (Cardano.TxBody era) mkUnsignedTx era @@ -672,14 +676,24 @@ mkUnsignedTx burnData mintingScripts inpsScripts - stakingScriptM = extractValidatedOutputs cs >>= \outs -> + stakingScriptM + refScriptM = extractValidatedOutputs cs >>= \outs -> left toErrMkTx $ fmap removeDummyInput $ Cardano.createAndValidateTransactionBody Cardano.TxBodyContent { Cardano.txIns = inputWits , txInsReference = Cardano.TxInsReferenceNone - , Cardano.txOuts = map (toCardanoTxOut era) outs + , Cardano.txOuts = case refScriptM of + Nothing -> + map (toCardanoTxOut era Nothing) outs + Just _ -> case outs of + firstOut:rest -> + let cardanoFirstTxOut = toCardanoTxOut era refScriptM firstOut + in cardanoFirstTxOut:(map (toCardanoTxOut era Nothing) rest) + _ -> + [] + , Cardano.txWithdrawals = case stakingScriptM of Nothing -> let ctx = Cardano.BuildTxWith diff --git a/lib/wallet/src/Cardano/Wallet/Transaction.hs b/lib/wallet/src/Cardano/Wallet/Transaction.hs index 72ffb95bae5..c3401b2bf84 100644 --- a/lib/wallet/src/Cardano/Wallet/Transaction.hs +++ b/lib/wallet/src/Cardano/Wallet/Transaction.hs @@ -36,6 +36,7 @@ module Cardano.Wallet.Transaction , TokenMapWithScripts (..) , emptyTokenMapWithScripts , AnyExplicitScript (..) + , changeRoleInAnyExplicitScript , AnyScript (..) , PlutusScriptInfo (..) , PlutusVersion (..) @@ -60,7 +61,7 @@ import Prelude import Cardano.Address.Derivation ( XPrv, XPub ) import Cardano.Address.Script - ( KeyHash (..), KeyRole (..), Script, ScriptHash, ScriptTemplate ) + ( KeyHash (..), KeyRole (..), Script (..), ScriptHash, ScriptTemplate ) import Cardano.Api ( AnyCardanoEra ) import Cardano.Api.Extra @@ -231,6 +232,8 @@ data TransactionCtx = TransactionCtx -- ^ Script template regulating delegation credentials , txNativeScriptInputs :: Map TxIn (Script KeyHash) -- ^ A map of script hashes related to inputs. Only for multisig wallets + , txReferenceScript :: Maybe (Script KeyHash) + -- ^ The reference script. } deriving Generic -- | Represents a preliminary selection of tx outputs typically made by user. @@ -308,6 +311,7 @@ defaultTransactionCtx = TransactionCtx , txPaymentCredentialScriptTemplate = Nothing , txStakingCredentialScriptTemplate = Nothing , txNativeScriptInputs = Map.empty + , txReferenceScript = Nothing } -- | User-requested action related to a delegation @@ -388,6 +392,28 @@ data AnyExplicitScript = deriving (Eq, Generic, Show) deriving anyclass NFData +changeRoleInAnyExplicitScript + :: KeyRole + -> AnyExplicitScript + -> AnyExplicitScript +changeRoleInAnyExplicitScript newrole = \case + NativeExplicitScript script scriptRole -> + let changeRole' = \case + RequireSignatureOf (KeyHash _ p) -> + RequireSignatureOf $ KeyHash newrole p + RequireAllOf xs -> + RequireAllOf (map changeRole' xs) + RequireAnyOf xs -> + RequireAnyOf (map changeRole' xs) + RequireSomeOf m xs -> + RequireSomeOf m (map changeRole' xs) + ActiveFromSlot s -> + ActiveFromSlot s + ActiveUntilSlot s -> + ActiveUntilSlot s + in NativeExplicitScript (changeRole' script) scriptRole + PlutusExplicitScript _ _ -> error "wrong usage" + data WitnessCount = WitnessCount { verificationKey :: Word8 , scripts :: [AnyExplicitScript] diff --git a/lib/wallet/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs b/lib/wallet/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs index 9c85ec5e54d..27d085fbfa3 100644 --- a/lib/wallet/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs +++ b/lib/wallet/test/unit/Cardano/Wallet/Shelley/TransactionSpec.hs @@ -1395,7 +1395,7 @@ binaryCalculationsSpec' era = describe ("calculateBinary - "+||era||+"") $ do unsigned = either (error . show) id $ mkUnsignedTx (shelleyBasedEraFromRecentEra era) (Nothing, slotNo) (Right cs) md mempty [] fee - TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing + TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing Nothing cs = Selection { inputs = NE.fromList inps , collateral = [] @@ -1450,7 +1450,7 @@ makeShelleyTx era testCase = Cardano.makeSignedTransaction addrWits unsigned fee = toCardanoLovelace $ selectionDelta cs unsigned = either (error . show) id $ mkUnsignedTx era (Nothing, slotNo) (Right cs) md mempty [] fee - TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing + TokenMap.empty TokenMap.empty Map.empty Map.empty Nothing Nothing addrWits = map (mkShelleyWitness unsigned) pairs cs = Selection { inputs = NE.fromList inps @@ -3808,6 +3808,7 @@ estimateSignedTxSizeSpec = describe "estimateSignedTxSize" $ do [ (i , Compatibility.toCardanoTxOut (shelleyBasedEra @era) + Nothing (TxOut addr mempty) ) | i <- allTxIns body diff --git a/specifications/api/mint-burn.md b/specifications/api/mint-burn.md index d2b4b8fd742..1b2437aa1a2 100644 --- a/specifications/api/mint-burn.md +++ b/specifications/api/mint-burn.md @@ -16,7 +16,7 @@ Specifically: 1. Creation of a transaction output that contains a minting script and is suitable for use as reference input. - In the `reference_policy_script_template` field, you can optionally add a script template. The HTTP endpoint will map this script template into a script using the wallet's policy public key, and this script will be included in the first transaction output (i.e. at index `0`) of the transaction. + In the `reference_policy_script_template` field, you can optionally add a script template. The HTTP endpoint will map this script template into a script using the wallet's policy public key, and this script will be included in the first transaction output (i.e. at index `0`) of the transaction. For Shelley-style wallets, the script template must contain a single cosigner only, but it may include time locks. Example `POST` data for the endpoint: diff --git a/specifications/api/swagger.yaml b/specifications/api/swagger.yaml index 127aaa3460f..b7e125046f0 100644 --- a/specifications/api/swagger.yaml +++ b/specifications/api/swagger.yaml @@ -2657,7 +2657,6 @@ components: coin_selection: *ApiCoinSelection fee: *amount - ApiInputsGeneral: &ApiInputsGeneral <<: *transactionInputsGeneral description: | @@ -3691,6 +3690,7 @@ components: In future transactions, the reference script can be used by any wallet multiple times by referencing the current transaction `id` and `index = 0`. + The script template must contain a single cosigner only, but it may include time locks. encoding: type: string enum: ["base16", "base64"]