From a8d0d02798373071980c91d23a3f3bb86de5b0c2 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 14 Nov 2025 20:50:27 +0100 Subject: [PATCH 1/8] Add DijkstraEra to transaction creation --- cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs index ce9346f4e5..4d367fcf43 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs @@ -35,7 +35,7 @@ import Cardano.Api.Plutus qualified as Shelley import Cardano.Api.Tx qualified as TxBody import Cardano.Ledger.Api qualified as Ledger -import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError, throwError, toMonadFail) +import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError, toMonadFail) import Control.Monad.Catch (MonadThrow) import Data.Aeson (ToJSON (toJSON), (.=)) @@ -85,8 +85,9 @@ newTxImpl :: UnsignedTxObject newTxImpl = newConwayTxImpl -- | Create a new unsigned transaction object for making a transaction in the current experimental era. -newExperimentalEraTxImpl :: (HasCallStack, MonadThrow m) => m UnsignedTxObject -newExperimentalEraTxImpl = throwError "newExperimentalEraTxImpl: No experimental era available" +newExperimentalEraTxImpl :: MonadThrow m => m UnsignedTxObject +newExperimentalEraTxImpl = + return $ UnsignedTxObject Exp.DijkstraEra (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) -- | Create a new unsigned transaction object for making a Conway era transaction. newConwayTxImpl :: UnsignedTxObject From 7bd8529dcecc22ae8b5497594a1e3b1e19dac4f6 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Mon, 10 Nov 2025 22:47:30 +0100 Subject: [PATCH 2/8] Implement stake certificate creation --- cardano-wasm/cardano-wasm.cabal | 1 + .../Wasm/Api/Certificate/StakeCertificate.hs | 127 ++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs diff --git a/cardano-wasm/cardano-wasm.cabal b/cardano-wasm/cardano-wasm.cabal index 026f0c2b10..900907de91 100644 --- a/cardano-wasm/cardano-wasm.cabal +++ b/cardano-wasm/cardano-wasm.cabal @@ -30,6 +30,7 @@ library cardano-wasi-lib src-lib exposed-modules: + Cardano.Wasm.Api.Certificate.StakeCertificate Cardano.Wasm.Api.GRPC Cardano.Wasm.Api.Info Cardano.Wasm.Api.InfoToTypeScript diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs new file mode 100644 index 0000000000..bf3b4c98e2 --- /dev/null +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs @@ -0,0 +1,127 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Cardano.Wasm.Api.Certificate.StakeCertificate + ( makeStakeAddressStakeDelegationCertificateImpl + , makeStakeAddressStakeDelegationCertificateExperimentalEraImpl + , makeStakeAddressRegistrationCertificateImpl + , makeStakeAddressRegistrationCertificateExperimentalEraImpl + , makeStakeAddressUnregistrationCertificateImpl + , makeStakeAddressUnregistrationCertificateExperimentalEraImpl + ) +where + +import Cardano.Api + ( Coin (..) + , Hash + , PoolId + , StakeKey + , serialiseToCBOR + , unStakePoolKeyHash + ) +import Cardano.Api.Address (StakeCredential (..)) +import Cardano.Api.Experimental (Era (..), obtainCommonConstraints) +import Cardano.Api.Experimental qualified as Exp +import Cardano.Api.Experimental.Certificate (Certificate (..)) +import Cardano.Api.Serialise.Raw qualified as Api + +import Cardano.Ledger.Api (Delegatee (DelegStake)) +import Cardano.Wasm.ExceptionHandling (rightOrError) + +import Control.Monad.Catch (MonadThrow) +import Data.ByteString.Base16 qualified as Base16 +import Data.Text qualified as Text +import Data.Text.Encoding qualified as Text + +-- | Make a certificate that delegates a stake address to a stake pool in Conway era. +makeStakeAddressStakeDelegationCertificateImpl :: MonadThrow m => String -> String -> m String +makeStakeAddressStakeDelegationCertificateImpl skHashStr poolIdStr = do + stakeCertHash <- readHash skHashStr + poolId <- readPoolId poolIdStr + makeStakeAddressStakeDelegationCertificate Exp.ConwayEra stakeCertHash poolId + +-- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. +makeStakeAddressStakeDelegationCertificateExperimentalEraImpl + :: MonadThrow m => String -> String -> m String +makeStakeAddressStakeDelegationCertificateExperimentalEraImpl skHashStr poolIdStr = do + stakeCertHash <- readHash skHashStr + poolId <- readPoolId poolIdStr + makeStakeAddressStakeDelegationCertificate Exp.DijkstraEra stakeCertHash poolId + +makeStakeAddressStakeDelegationCertificate + :: forall era m. MonadThrow m => Exp.Era era -> Hash StakeKey -> PoolId -> m String +makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId = + obtainCommonConstraints era $ do + let cert :: Certificate (Exp.LedgerEra era) = + Exp.makeStakeAddressDelegationCertificate + (StakeCredentialByKey stakeCertHash) + ( case era of + ConwayEra -> DelegStake $ unStakePoolKeyHash poolId + DijkstraEra -> DelegStake $ unStakePoolKeyHash poolId + ) + return $ serialiseCertificateToCBOR era cert + +-- | Make a stake address registration certificate in Conway era. +makeStakeAddressRegistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String +makeStakeAddressRegistrationCertificateImpl skHashStr deposit = do + skHash <- readHash skHashStr + makeStakeAddressRegistrationCertificateWrapper Exp.ConwayEra skHash deposit + +--  | Make a stake address registration certificate in the current experimental era. +makeStakeAddressRegistrationCertificateExperimentalEraImpl + :: MonadThrow m => String -> Integer -> m String +makeStakeAddressRegistrationCertificateExperimentalEraImpl skHashStr deposit = do + skHash <- readHash skHashStr + makeStakeAddressRegistrationCertificateWrapper Exp.DijkstraEra skHash deposit + +makeStakeAddressRegistrationCertificateWrapper + :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String +makeStakeAddressRegistrationCertificateWrapper era skHash deposit = + obtainCommonConstraints era $ do + let cert :: Certificate (Exp.LedgerEra era) = + Exp.makeStakeAddressRegistrationCertificate + (StakeCredentialByKey skHash) + (Coin deposit) + return $ serialiseCertificateToCBOR era cert + +-- | Make a stake address unregistration certificate in Conway era. +makeStakeAddressUnregistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String +makeStakeAddressUnregistrationCertificateImpl skHashStr deposit = do + skHash <- readHash skHashStr + makeStakeAddressUnregistrationCertificateWrapper Exp.ConwayEra skHash deposit + +-- | Make a stake address unregistration certificate in the current experimental era. +makeStakeAddressUnregistrationCertificateExperimentalEraImpl + :: MonadThrow m => String -> Integer -> m String +makeStakeAddressUnregistrationCertificateExperimentalEraImpl skHashStr deposit = do + skHash <- readHash skHashStr + makeStakeAddressUnregistrationCertificateWrapper Exp.DijkstraEra skHash deposit + +makeStakeAddressUnregistrationCertificateWrapper + :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String +makeStakeAddressUnregistrationCertificateWrapper era skHash deposit = + obtainCommonConstraints era $ do + let cert :: Certificate (Exp.LedgerEra era) = + Exp.makeStakeAddressUnregistrationCertificate + (StakeCredentialByKey skHash) + (Coin deposit) + return $ serialiseCertificateToCBOR era cert + +serialiseCertificateToCBOR :: Exp.Era era -> Certificate (Exp.LedgerEra era) -> String +serialiseCertificateToCBOR era cert = + obtainCommonConstraints era $ do + Text.unpack $ + Text.decodeUtf8 $ + Base16.encode $ + serialiseToCBOR + cert + +readHash :: MonadThrow m => String -> m (Hash StakeKey) +readHash = rightOrError . Api.deserialiseFromRawBytesHex . Text.encodeUtf8 . Text.pack + +readPoolId :: MonadThrow m => String -> m PoolId +readPoolId = rightOrError . Api.deserialiseFromRawBytesHex . Text.encodeUtf8 . Text.pack From a485f6f7bf31dbfb3df096e64f8cd4b208b53a4c Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Fri, 14 Nov 2025 20:57:36 +0100 Subject: [PATCH 3/8] Export methods in the JavaScript API --- cardano-wasm/js-test/basic-test.spec.ts | 2 +- cardano-wasm/lib-wrapper/cardano-api.d.ts | 65 +++++++++++++- cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs | 88 +++++++++++++++++++ .../Wasm/Internal/JavaScript/Bridge.hs | 79 +++++++++++++++++ 4 files changed, 232 insertions(+), 2 deletions(-) diff --git a/cardano-wasm/js-test/basic-test.spec.ts b/cardano-wasm/js-test/basic-test.spec.ts index 13a5cde6f3..ff747a4b6a 100644 --- a/cardano-wasm/js-test/basic-test.spec.ts +++ b/cardano-wasm/js-test/basic-test.spec.ts @@ -8,5 +8,5 @@ test('test output matches', async ({ page }) => { // Wait for the test to finish running (we signal this by creating a tag with id "finish-tag" and text "Finished test!") await expect(page.locator('#finish-tag')).toHaveText("Finished test!"); // Check the output of the test (from the example folder), which is displayed in the code element with id "test-output". The output contains information about the various objects and results of trying some of the functions. - await expect(page.locator('#test-output')).toHaveText("> \"Api object:\"> [object] { objectType: cardano-api tx: [object Object] newGrpcConnection: async function (...args) wallet: [object Object] }> \"Bech32 of address:\"> \"addr_test1vp93p9em3regvgylxuvet6fgr3e9sn259pcejgrk4ykystcs7v8j6\"> \"UnsignedTx object:\"> [object] { objectType: UnsignedTx addTxInput: function (txId,txIx) addSimpleTxOut: function (destAddr,lovelaceAmount) appendCertificateToTx: function (certCbor) setFee: function (lovelaceAmount) estimateMinFee: function (protocolParams,numKeyWitnesses,numByronKeyWitnesses,totalRefScriptSize) signWithPaymentKey: function (signingKey) }> \"Estimated fee:\"> 164005n> \"SignedTx object:\"> [object] { objectType: SignedTx alsoSignWithPaymentKey: function (signingKey) txToCbor: function () }> \"Tx CBOR:\"> \"84a300d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a00989680021a000280a5a100d9010281825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae005840a49259b5977aea523b46f01261fbff93e0899e8700319e11f5ab96b67eb628fca1a233ce2d50ee3227b591b84f27237d920d63974d65728362382f751c4d9400f5f6\""); + await expect(page.locator('#test-output')).toHaveText("> \"Api object:\"> [object] {    objectType: cardano-api    tx: [object Object]    newGrpcConnection: async function (...args)    certificate: [object Object]    wallet: [object Object]  }> \"Bech32 of address:\"> \"addr_test1vp93p9em3regvgylxuvet6fgr3e9sn259pcejgrk4ykystcs7v8j6\"> \"UnsignedTx object:\"> [object] {    objectType: UnsignedTx    addTxInput: function (txId,txIx)    addSimpleTxOut: function (destAddr,lovelaceAmount)    appendCertificateToTx: function (certCbor)    setFee: function (lovelaceAmount)    estimateMinFee: function (protocolParams,numKeyWitnesses,numByronKeyWitnesses,totalRefScriptSize)    signWithPaymentKey: function (signingKey)  }> \"Estimated fee:\"> 164005n> \"SignedTx object:\"> [object] {    objectType: SignedTx    alsoSignWithPaymentKey: function (signingKey)    txToCbor: function ()  }> \"Tx CBOR:\"> \"84a300d9010281825820be6efd42a3d7b9a00d09d77a5d41e55ceaf0bd093a8aa8a893ce70d9caafd97800018182581d6082935e44937e8b530f32ce672b5d600d0a286b4e8a52c6555f659b871a00989680021a000280a5a100d9010281825820adfc1c30385916da87db1ba3328f0690a57ebb2a6ac9f6f86b2d97f943adae005840a49259b5977aea523b46f01261fbff93e0899e8700319e11f5ab96b67eb628fca1a233ce2d50ee3227b591b84f27237d920d63974d65728362382f751c4d9400f5f6\""); }); diff --git a/cardano-wasm/lib-wrapper/cardano-api.d.ts b/cardano-wasm/lib-wrapper/cardano-api.d.ts index a9cae31b6e..37e9e7fc43 100644 --- a/cardano-wasm/lib-wrapper/cardano-api.d.ts +++ b/cardano-wasm/lib-wrapper/cardano-api.d.ts @@ -26,7 +26,7 @@ declare interface CardanoApi { newTx(): Promise; /** - * Create a new unsigned transaction in the current experimental era (currently unavailable). + * Create a new unsigned transaction in the current experimental era (currently Dijkstra). * @returns A promise that resolves to a new `UnsignedTx` object. */ newExperimentalEraTx(): Promise; @@ -45,6 +45,69 @@ declare interface CardanoApi { */ newGrpcConnection(webGrpcUrl: string): Promise; + /** + * Methods for creating certificates. + */ + certificate: { + /** + * Methods for creating certificates in Conway era. + */ + conway: { + /** + * Make a certificate that delegates a stake address to a stake pool in Conway era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param poolId The pool ID in base16 format. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressStakeDelegationCertificate(stakeKeyHash: string, poolId: string): Promise; + + /** + * Make a stake address registration certificate in Conway era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param deposit The deposit amount in lovelaces. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressRegistrationCertificate(stakeKeyHash: string, deposit: bigint): Promise; + + /** + * Make a stake address unregistration certificate in Conway era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param deposit The deposit amount in lovelaces. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressUnregistrationCertificate(stakeKeyHash: string, deposit: bigint): Promise; + } + + /** + * Methods for creating certificates in the current experimental era. + */ + experimentalEra: { + /** + * Make a certificate that delegates a stake address to a stake pool in the current experimental era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param poolId The pool ID in base16 format. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressStakeDelegationCertificateExperimentalEra(stakeKeyHash: string, poolId: string): Promise; + + /** + * Make a stake address registration certificate in the current experimental era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param deposit The deposit amount in lovelaces. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressRegistrationCertificateExperimentalEra(stakeKeyHash: string, deposit: bigint): Promise; + + /** + * Make a stake address unregistration certificate in the current experimental era. + * @param stakeKeyHash The stake key hash in base16 format. + * @param deposit The deposit amount in lovelaces. + * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. + */ + makeStakeAddressUnregistrationCertificateExperimentalEra(stakeKeyHash: string, deposit: bigint): Promise; + } + } + /** * Methods for generating and restoring wallets. */ diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs index 2a68eee2f7..f20fe6e73e 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs @@ -476,6 +476,94 @@ apiInfo = , methodReturnType = NewObject (virtualObjectName grpcConnection) , methodReturnDoc = "A promise that resolves to a new `GrpcConnection`." } + , MethodGroupEntry $ + MethodGroup + { groupName = "certificate" + , groupDoc = ["Methods for creating certificates."] + , groupMethods = + [ MethodGroupEntry $ + MethodGroup + { groupName = "conway" + , groupDoc = ["Methods for creating certificates in Conway era."] + , groupMethods = + [ MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressStakeDelegationCertificate" + , methodDoc = "Make a certificate that delegates a stake address to a stake pool in Conway era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "poolId" TSString "The pool ID in base16 format." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + , MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressRegistrationCertificate" + , methodDoc = "Make a stake address registration certificate in Conway era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + , MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressUnregistrationCertificate" + , methodDoc = "Make a stake address unregistration certificate in Conway era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + ] + } + , MethodGroupEntry $ + MethodGroup + { groupName = "experimentalEra" + , groupDoc = ["Methods for creating certificates in the current experimental era."] + , groupMethods = + [ MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressStakeDelegationCertificateExperimentalEra" + , methodDoc = + "Make a certificate that delegates a stake address to a stake pool in the current experimental era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "poolId" TSString "The pool ID in base16 format." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + , MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressRegistrationCertificateExperimentalEra" + , methodDoc = "Make a stake address registration certificate in the current experimental era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + , MethodInfoEntry $ + MethodInfo + { methodName = "makeStakeAddressUnregistrationCertificateExperimentalEra" + , methodDoc = "Make a stake address unregistration certificate in the current experimental era." + , methodParams = + [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." + , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." + ] + , methodReturnType = OtherType TSString + , methodReturnDoc = "A promise that resolves to the CBOR-encoded certificate as a hex string." + } + ] + } + ] + } , MethodGroupEntry $ MethodGroup { groupName = "wallet" diff --git a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs index 20a668d661..64986ed9dc 100644 --- a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs +++ b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs @@ -16,6 +16,7 @@ module Cardano.Wasm.Internal.JavaScript.Bridge where import Cardano.Api qualified as Api import Cardano.Api.Ledger qualified as Ledger +import Cardano.Wasm.Api.Certificate.StakeCertificate qualified as Wasm import Cardano.Wasm.Api.GRPC qualified as Wasm import Cardano.Wasm.Api.Info (apiInfo) import Cardano.Wasm.Api.Tx qualified as Wasm @@ -356,6 +357,24 @@ foreign export javascript "addSimpleTxOut" foreign export javascript "appendCertificateToTx" appendCertificateToTx :: JSUnsignedTx -> JSString -> IO JSUnsignedTx +foreign export javascript "makeStakeAddressStakeDelegationCertificate" + makeStakeAddressStakeDelegationCertificate :: JSString -> JSString -> IO JSString + +foreign export javascript "makeStakeAddressStakeDelegationCertificateExperimentalEra" + makeStakeAddressStakeDelegationCertificateExperimentalEra :: JSString -> JSString -> IO JSString + +foreign export javascript "makeStakeAddressRegistrationCertificate" + makeStakeAddressRegistrationCertificate :: JSString -> JSCoin -> IO JSString + +foreign export javascript "makeStakeAddressRegistrationCertificateExperimentalEra" + makeStakeAddressRegistrationCertificateExperimentalEra :: JSString -> JSCoin -> IO JSString + +foreign export javascript "makeStakeAddressUnregistrationCertificate" + makeStakeAddressUnregistrationCertificate :: JSString -> JSCoin -> IO JSString + +foreign export javascript "makeStakeAddressUnregistrationCertificateExperimentalEra" + makeStakeAddressUnregistrationCertificateExperimentalEra :: JSString -> JSCoin -> IO JSString + foreign export javascript "setFee" setFee :: JSUnsignedTx -> JSCoin -> IO JSUnsignedTx @@ -407,6 +426,66 @@ appendCertificateToTx jsUnsignedTx jsCertCbor = <*> fromJSVal jsCertCbor ) +-- | Make a certificate that delegates a stake address to a stake pool in Conway era. +makeStakeAddressStakeDelegationCertificate :: HasCallStack => JSString -> JSString -> IO JSString +makeStakeAddressStakeDelegationCertificate jsStakeKeyHash jsPoolId = + toJSVal + =<< join + ( Wasm.makeStakeAddressStakeDelegationCertificateImpl + <$> fromJSVal jsStakeKeyHash + <*> fromJSVal jsPoolId + ) + +-- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. +makeStakeAddressStakeDelegationCertificateExperimentalEra :: HasCallStack => JSString -> JSString -> IO JSString +makeStakeAddressStakeDelegationCertificateExperimentalEra jsStakeKeyHash jsPoolId = + toJSVal + =<< join + ( Wasm.makeStakeAddressStakeDelegationCertificateExperimentalEraImpl + <$> fromJSVal jsStakeKeyHash + <*> fromJSVal jsPoolId + ) + +-- | Make a stake address registration certificate in Conway era. +makeStakeAddressRegistrationCertificate :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressRegistrationCertificate jsStakeKeyHash jsDeposit = + toJSVal + =<< join + ( Wasm.makeStakeAddressRegistrationCertificateImpl + <$> fromJSVal jsStakeKeyHash + <*> (fromInteger <$> fromJSBigInt jsDeposit) + ) + +-- | Make a stake address registration certificate in the current experimental era. +makeStakeAddressRegistrationCertificateExperimentalEra :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressRegistrationCertificateExperimentalEra jsStakeKeyHash jsDeposit = + toJSVal + =<< join + ( Wasm.makeStakeAddressRegistrationCertificateExperimentalEraImpl + <$> fromJSVal jsStakeKeyHash + <*> (fromInteger <$> fromJSBigInt jsDeposit) + ) + +-- | Make a stake address unregistration certificate in Conway era. +makeStakeAddressUnregistrationCertificate :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressUnregistrationCertificate jsStakeKeyHash jsDeposit = + toJSVal + =<< join + ( Wasm.makeStakeAddressUnregistrationCertificateImpl + <$> fromJSVal jsStakeKeyHash + <*> (fromInteger <$> fromJSBigInt jsDeposit) + ) + +-- | Make a stake address unregistration certificate in the current experimental era. +makeStakeAddressUnregistrationCertificateExperimentalEra :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressUnregistrationCertificateExperimentalEra jsStakeKeyHash jsDeposit = + toJSVal + =<< join + ( Wasm.makeStakeAddressUnregistrationCertificateExperimentalEraImpl + <$> fromJSVal jsStakeKeyHash + <*> (fromInteger <$> fromJSBigInt jsDeposit) + ) + -- | Set the transaction fee for an unsigned transaction. setFee :: HasCallStack => JSUnsignedTx -> JSCoin -> IO JSUnsignedTx setFee jsUnsignedTx jsCoin = From 6c6cca90465d8d21eec840b206c305f752cbbe9f Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Mon, 17 Nov 2025 20:09:18 +0100 Subject: [PATCH 4/8] Remove mentions to explicit eras in `lib-wrapper` and the `newConwayTx` function --- cardano-wasm/cardano-wasm.cabal | 1 + cardano-wasm/lib-wrapper/cardano-api.d.ts | 24 +++---- .../Wasm/Api/Certificate/StakeCertificate.hs | 24 ++++--- cardano-wasm/src-lib/Cardano/Wasm/Api/GRPC.hs | 2 +- cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs | 64 ++++++++++++------- cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs | 13 ++-- .../src-lib/Cardano/Wasm/Internal/Api/Era.hs | 19 ++++++ .../Wasm/Internal/JavaScript/Bridge.hs | 17 ++--- 8 files changed, 94 insertions(+), 70 deletions(-) create mode 100644 cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs diff --git a/cardano-wasm/cardano-wasm.cabal b/cardano-wasm/cardano-wasm.cabal index 900907de91..cc09576470 100644 --- a/cardano-wasm/cardano-wasm.cabal +++ b/cardano-wasm/cardano-wasm.cabal @@ -40,6 +40,7 @@ library cardano-wasi-lib Cardano.Wasm.ExceptionHandling other-modules: + Cardano.Wasm.Internal.Api.Era Cardano.Wasm.Internal.Api.Random build-depends: diff --git a/cardano-wasm/lib-wrapper/cardano-api.d.ts b/cardano-wasm/lib-wrapper/cardano-api.d.ts index 37e9e7fc43..640f93cce6 100644 --- a/cardano-wasm/lib-wrapper/cardano-api.d.ts +++ b/cardano-wasm/lib-wrapper/cardano-api.d.ts @@ -30,12 +30,6 @@ declare interface CardanoApi { * @returns A promise that resolves to a new `UnsignedTx` object. */ newExperimentalEraTx(): Promise; - - /** - * Create a new unsigned transaction in the Conway era. - * @returns A promise that resolves to a new `UnsignedTx` object. - */ - newConwayTx(): Promise; } /** @@ -50,11 +44,11 @@ declare interface CardanoApi { */ certificate: { /** - * Methods for creating certificates in Conway era. + * Methods for creating certificates in the current era (currently Conway). */ - conway: { + currentEra: { /** - * Make a certificate that delegates a stake address to a stake pool in Conway era. + * Make a certificate that delegates a stake address to a stake pool in the current era (currently Conway). * @param stakeKeyHash The stake key hash in base16 format. * @param poolId The pool ID in base16 format. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. @@ -62,7 +56,7 @@ declare interface CardanoApi { makeStakeAddressStakeDelegationCertificate(stakeKeyHash: string, poolId: string): Promise; /** - * Make a stake address registration certificate in Conway era. + * Make a stake address registration certificate in the current era (currently Conway). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. @@ -70,7 +64,7 @@ declare interface CardanoApi { makeStakeAddressRegistrationCertificate(stakeKeyHash: string, deposit: bigint): Promise; /** - * Make a stake address unregistration certificate in Conway era. + * Make a stake address unregistration certificate in the current era (currently Conway). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. @@ -79,11 +73,11 @@ declare interface CardanoApi { } /** - * Methods for creating certificates in the current experimental era. + * Methods for creating certificates in the current experimental era (currently Dijkstra). */ experimentalEra: { /** - * Make a certificate that delegates a stake address to a stake pool in the current experimental era. + * Make a certificate that delegates a stake address to a stake pool in the current experimental era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param poolId The pool ID in base16 format. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. @@ -91,7 +85,7 @@ declare interface CardanoApi { makeStakeAddressStakeDelegationCertificateExperimentalEra(stakeKeyHash: string, poolId: string): Promise; /** - * Make a stake address registration certificate in the current experimental era. + * Make a stake address registration certificate in the current experimental era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. @@ -99,7 +93,7 @@ declare interface CardanoApi { makeStakeAddressRegistrationCertificateExperimentalEra(stakeKeyHash: string, deposit: bigint): Promise; /** - * Make a stake address unregistration certificate in the current experimental era. + * Make a stake address unregistration certificate in the current experimental era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs index bf3b4c98e2..0505868fed 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs @@ -30,19 +30,20 @@ import Cardano.Api.Experimental.Certificate (Certificate (..)) import Cardano.Api.Serialise.Raw qualified as Api import Cardano.Ledger.Api (Delegatee (DelegStake)) -import Cardano.Wasm.ExceptionHandling (rightOrError) +import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError) +import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) import Control.Monad.Catch (MonadThrow) import Data.ByteString.Base16 qualified as Base16 import Data.Text qualified as Text import Data.Text.Encoding qualified as Text --- | Make a certificate that delegates a stake address to a stake pool in Conway era. +-- | Make a certificate that delegates a stake address to a stake pool in the current era. makeStakeAddressStakeDelegationCertificateImpl :: MonadThrow m => String -> String -> m String makeStakeAddressStakeDelegationCertificateImpl skHashStr poolIdStr = do stakeCertHash <- readHash skHashStr poolId <- readPoolId poolIdStr - makeStakeAddressStakeDelegationCertificate Exp.ConwayEra stakeCertHash poolId + makeStakeAddressStakeDelegationCertificate currentEra stakeCertHash poolId -- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. makeStakeAddressStakeDelegationCertificateExperimentalEraImpl @@ -50,7 +51,8 @@ makeStakeAddressStakeDelegationCertificateExperimentalEraImpl makeStakeAddressStakeDelegationCertificateExperimentalEraImpl skHashStr poolIdStr = do stakeCertHash <- readHash skHashStr poolId <- readPoolId poolIdStr - makeStakeAddressStakeDelegationCertificate Exp.DijkstraEra stakeCertHash poolId + era <- justOrError "No experimental era available" experimentalEra + makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId makeStakeAddressStakeDelegationCertificate :: forall era m. MonadThrow m => Exp.Era era -> Hash StakeKey -> PoolId -> m String @@ -65,18 +67,19 @@ makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId = ) return $ serialiseCertificateToCBOR era cert --- | Make a stake address registration certificate in Conway era. +-- | Make a stake address registration certificate in the current era. makeStakeAddressRegistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String makeStakeAddressRegistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr - makeStakeAddressRegistrationCertificateWrapper Exp.ConwayEra skHash deposit + makeStakeAddressRegistrationCertificateWrapper currentEra skHash deposit --  | Make a stake address registration certificate in the current experimental era. makeStakeAddressRegistrationCertificateExperimentalEraImpl :: MonadThrow m => String -> Integer -> m String makeStakeAddressRegistrationCertificateExperimentalEraImpl skHashStr deposit = do skHash <- readHash skHashStr - makeStakeAddressRegistrationCertificateWrapper Exp.DijkstraEra skHash deposit + era <- justOrError "No experimental era available" experimentalEra + makeStakeAddressRegistrationCertificateWrapper era skHash deposit makeStakeAddressRegistrationCertificateWrapper :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String @@ -88,18 +91,19 @@ makeStakeAddressRegistrationCertificateWrapper era skHash deposit = (Coin deposit) return $ serialiseCertificateToCBOR era cert --- | Make a stake address unregistration certificate in Conway era. +-- | Make a stake address unregistration certificate in the current era. makeStakeAddressUnregistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String makeStakeAddressUnregistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr - makeStakeAddressUnregistrationCertificateWrapper Exp.ConwayEra skHash deposit + makeStakeAddressUnregistrationCertificateWrapper currentEra skHash deposit -- | Make a stake address unregistration certificate in the current experimental era. makeStakeAddressUnregistrationCertificateExperimentalEraImpl :: MonadThrow m => String -> Integer -> m String makeStakeAddressUnregistrationCertificateExperimentalEraImpl skHashStr deposit = do skHash <- readHash skHashStr - makeStakeAddressUnregistrationCertificateWrapper Exp.DijkstraEra skHash deposit + era <- justOrError "No experimental era available" experimentalEra + makeStakeAddressUnregistrationCertificateWrapper era skHash deposit makeStakeAddressUnregistrationCertificateWrapper :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/GRPC.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/GRPC.hs index 91bebe7ce9..a39fa16448 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/GRPC.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/GRPC.hs @@ -12,7 +12,7 @@ import Data.ByteString.Char8 qualified as BS newtype GrpcObject grpcClient = GrpcObject grpcClient --- | Create a new unsigned transaction object for making a Conway era transaction. +-- | Create a new gRPC or GRPC-web connection to the Cardano Node. newGrpcConnectionImpl :: (String -> IO grpcClient) -> String -> IO (GrpcObject grpcClient) newGrpcConnectionImpl createClientFunc host = GrpcObject <$> createClientFunc host diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs index f20fe6e73e..3a7966d1f1 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs @@ -15,8 +15,9 @@ module Cardano.Wasm.Api.Info where import Cardano.Api (pretty) +import Cardano.Api.Experimental.Era qualified as Exp -import Cardano.Wasm.Api.Tx (UnsignedTxObject (..), newExperimentalEraTxImpl, newTxImpl) +import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) import Data.Aeson qualified as Aeson import Data.Text qualified as Text @@ -196,10 +197,10 @@ instance Aeson.ToJSON ApiInfo where ] -- | Get a comment about the era for unsigned transaction creation methods. -getEraCommentForUnsignedTx :: Maybe UnsignedTxObject -> String -getEraCommentForUnsignedTx utxMonad = - case utxMonad of - Just (UnsignedTxObject era _) -> "(currently " ++ show (pretty era) ++ ")" +getEraCommentFor :: Maybe (Exp.Era era) -> String +getEraCommentFor era = + case era of + Just era' -> "(currently " ++ show (pretty era') ++ ")" Nothing -> "(currently unavailable)" -- | Provides metadata about the "virtual objects" and their methods. @@ -441,7 +442,7 @@ apiInfo = { methodName = "newTx" , methodDoc = "Create a new unsigned transaction in the current era " - ++ getEraCommentForUnsignedTx (Just newTxImpl) + ++ getEraCommentFor (Just currentEra) ++ "." , methodParams = [] , methodReturnType = NewObject (virtualObjectName unsignedTxObj) @@ -452,20 +453,12 @@ apiInfo = { methodName = "newExperimentalEraTx" , methodDoc = "Create a new unsigned transaction in the current experimental era " - ++ getEraCommentForUnsignedTx newExperimentalEraTxImpl + ++ getEraCommentFor experimentalEra ++ "." , methodParams = [] , methodReturnType = NewObject (virtualObjectName unsignedTxObj) , methodReturnDoc = "A promise that resolves to a new `UnsignedTx` object." } - , MethodInfoEntry $ - MethodInfo - { methodName = "newConwayTx" - , methodDoc = "Create a new unsigned transaction in the Conway era." - , methodParams = [] - , methodReturnType = NewObject (virtualObjectName unsignedTxObj) - , methodReturnDoc = "A promise that resolves to a new `UnsignedTx` object." - } ] } , MethodInfoEntry $ @@ -483,13 +476,18 @@ apiInfo = , groupMethods = [ MethodGroupEntry $ MethodGroup - { groupName = "conway" - , groupDoc = ["Methods for creating certificates in Conway era."] + { groupName = "currentEra" + , groupDoc = + [ "Methods for creating certificates in the current era " ++ getEraCommentFor (Just currentEra) ++ "." + ] , groupMethods = [ MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressStakeDelegationCertificate" - , methodDoc = "Make a certificate that delegates a stake address to a stake pool in Conway era." + , methodDoc = + "Make a certificate that delegates a stake address to a stake pool in the current era " + ++ getEraCommentFor (Just currentEra) + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "poolId" TSString "The pool ID in base16 format." @@ -500,7 +498,10 @@ apiInfo = , MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressRegistrationCertificate" - , methodDoc = "Make a stake address registration certificate in Conway era." + , methodDoc = + "Make a stake address registration certificate in the current era " + ++ getEraCommentFor (Just currentEra) + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." @@ -511,7 +512,10 @@ apiInfo = , MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressUnregistrationCertificate" - , methodDoc = "Make a stake address unregistration certificate in Conway era." + , methodDoc = + "Make a stake address unregistration certificate in the current era " + ++ getEraCommentFor (Just currentEra) + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." @@ -524,13 +528,19 @@ apiInfo = , MethodGroupEntry $ MethodGroup { groupName = "experimentalEra" - , groupDoc = ["Methods for creating certificates in the current experimental era."] + , groupDoc = + [ "Methods for creating certificates in the current experimental era " + ++ getEraCommentFor experimentalEra + ++ "." + ] , groupMethods = [ MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressStakeDelegationCertificateExperimentalEra" , methodDoc = - "Make a certificate that delegates a stake address to a stake pool in the current experimental era." + "Make a certificate that delegates a stake address to a stake pool in the current experimental era " + ++ getEraCommentFor experimentalEra + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "poolId" TSString "The pool ID in base16 format." @@ -541,7 +551,10 @@ apiInfo = , MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressRegistrationCertificateExperimentalEra" - , methodDoc = "Make a stake address registration certificate in the current experimental era." + , methodDoc = + "Make a stake address registration certificate in the current experimental era " + ++ getEraCommentFor experimentalEra + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." @@ -552,7 +565,10 @@ apiInfo = , MethodInfoEntry $ MethodInfo { methodName = "makeStakeAddressUnregistrationCertificateExperimentalEra" - , methodDoc = "Make a stake address unregistration certificate in the current experimental era." + , methodDoc = + "Make a stake address unregistration certificate in the current experimental era " + ++ getEraCommentFor experimentalEra + ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." , ParamInfo "deposit" TSBigInt "The deposit amount in lovelaces." diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs index 4d367fcf43..0bb921ee17 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs @@ -14,7 +14,6 @@ module Cardano.Wasm.Api.Tx , ProtocolParamsJSON (..) , newTxImpl , newExperimentalEraTxImpl - , newConwayTxImpl , addTxInputImpl , addSimpleTxOutImpl , appendCertificateToTxImpl @@ -36,6 +35,7 @@ import Cardano.Api.Tx qualified as TxBody import Cardano.Ledger.Api qualified as Ledger import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError, toMonadFail) +import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) import Control.Monad.Catch (MonadThrow) import Data.Aeson (ToJSON (toJSON), (.=)) @@ -82,16 +82,13 @@ instance FromJSON UnsignedTxObject where -- | Create a new unsigned transaction object for making a transaction in the current era. newTxImpl :: UnsignedTxObject -newTxImpl = newConwayTxImpl +newTxImpl = UnsignedTxObject currentEra (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) -- | Create a new unsigned transaction object for making a transaction in the current experimental era. newExperimentalEraTxImpl :: MonadThrow m => m UnsignedTxObject -newExperimentalEraTxImpl = - return $ UnsignedTxObject Exp.DijkstraEra (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) - --- | Create a new unsigned transaction object for making a Conway era transaction. -newConwayTxImpl :: UnsignedTxObject -newConwayTxImpl = UnsignedTxObject Exp.ConwayEra (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) +newExperimentalEraTxImpl = do + era <- justOrError "No experimental era available" experimentalEra + return $ UnsignedTxObject era (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) -- | Add a simple transaction input to an unsigned transaction object. addTxInputImpl :: UnsignedTxObject -> Api.TxId -> Api.TxIx -> UnsignedTxObject diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs b/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs new file mode 100644 index 0000000000..df8b844e81 --- /dev/null +++ b/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs @@ -0,0 +1,19 @@ +-- We disable missing signature because DijkstraEra type is not exported yet +{-# OPTIONS_GHC -Wno-missing-signatures #-} + +-- | Module providing constants for the current and experimental eras +-- used throughout the cardano-wasm library. +module Cardano.Wasm.Internal.Api.Era + ( currentEra + , experimentalEra + ) +where + +import Cardano.Api.Experimental qualified as Exp + +-- | The current era used in mainnet. +currentEra :: Exp.Era Exp.ConwayEra +currentEra = Exp.ConwayEra + +-- | The experimental era, still under development or testing. +experimentalEra = Just Exp.DijkstraEra diff --git a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs index 64986ed9dc..99ca4a32cb 100644 --- a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs +++ b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs @@ -345,9 +345,6 @@ foreign export javascript "newTx" foreign export javascript "newExperimentalEraTx" newExperimentalEraTx :: IO JSUnsignedTx -foreign export javascript "newConwayTx" - newConwayTx :: IO JSUnsignedTx - foreign export javascript "addTxInput" addTxInput :: JSUnsignedTx -> JSTxId -> JSTxIx -> IO JSUnsignedTx @@ -384,7 +381,7 @@ foreign export javascript "estimateMinFee" foreign export javascript "signWithPaymentKey" signWithPaymentKey :: JSUnsignedTx -> JSSigningKey -> IO JSSignedTx --- | Create a new unsigned transaction. +-- | Create a new unsigned transaction in the current era. newTx :: HasCallStack => IO JSUnsignedTx newTx = toJSVal Wasm.newTxImpl @@ -392,10 +389,6 @@ newTx = toJSVal Wasm.newTxImpl newExperimentalEraTx :: HasCallStack => IO JSUnsignedTx newExperimentalEraTx = toJSVal =<< Wasm.newExperimentalEraTxImpl --- | Create a new Conway era unsigned transaction. -newConwayTx :: HasCallStack => IO JSUnsignedTx -newConwayTx = toJSVal Wasm.newConwayTxImpl - -- | Add a transaction input to an unsigned transaction. addTxInput :: HasCallStack => JSUnsignedTx -> JSTxId -> JSTxIx -> IO JSUnsignedTx addTxInput jsUnsignedTx jsTxId jsTxIx = @@ -426,7 +419,7 @@ appendCertificateToTx jsUnsignedTx jsCertCbor = <*> fromJSVal jsCertCbor ) --- | Make a certificate that delegates a stake address to a stake pool in Conway era. +-- | Make a certificate that delegates a stake address to a stake pool in the current era. makeStakeAddressStakeDelegationCertificate :: HasCallStack => JSString -> JSString -> IO JSString makeStakeAddressStakeDelegationCertificate jsStakeKeyHash jsPoolId = toJSVal @@ -446,7 +439,7 @@ makeStakeAddressStakeDelegationCertificateExperimentalEra jsStakeKeyHash jsPoolI <*> fromJSVal jsPoolId ) --- | Make a stake address registration certificate in Conway era. +-- | Make a stake address registration certificate in the current era. makeStakeAddressRegistrationCertificate :: HasCallStack => JSString -> JSCoin -> IO JSString makeStakeAddressRegistrationCertificate jsStakeKeyHash jsDeposit = toJSVal @@ -466,7 +459,7 @@ makeStakeAddressRegistrationCertificateExperimentalEra jsStakeKeyHash jsDeposit <*> (fromInteger <$> fromJSBigInt jsDeposit) ) --- | Make a stake address unregistration certificate in Conway era. +-- | Make a stake address unregistration certificate in the current era. makeStakeAddressUnregistrationCertificate :: HasCallStack => JSString -> JSCoin -> IO JSString makeStakeAddressUnregistrationCertificate jsStakeKeyHash jsDeposit = toJSVal @@ -559,7 +552,7 @@ foreign export javascript "getUtxosForAddress" foreign export javascript "submitTx" submitTx :: JSGrpc -> JSString -> IO JSString --- | Create a new gRPC object for making Conway era transactions. +-- | Create a new gRPC object. newGrpcConnection :: HasCallStack => JSString -> IO JSGrpc newGrpcConnection webGrpcUrl = toJSVal =<< join (Wasm.newGrpcConnectionImpl js_newWebGrpcClient <$> fromJSVal webGrpcUrl) From 8112bd1b34c4c1d41620c02fe8b4c770ebbbbf1d Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Nov 2025 00:48:03 +0100 Subject: [PATCH 5/8] Add type aliases to improve clarity --- .../Wasm/Api/Certificate/StakeCertificate.hs | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs index 0505868fed..e63376b1d5 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs @@ -38,8 +38,25 @@ import Data.ByteString.Base16 qualified as Base16 import Data.Text qualified as Text import Data.Text.Encoding qualified as Text +-- * Type aliases for clarity + +-- | A stake key hash represented as a base16-encoded string. +type StakeKeyHashBase16 = String + +-- | A pool ID represented as a base16-encoded string. +type PoolIdBase16 = String + +-- | Deposit amount in lovelace. +type DepositLovelace = Integer + +-- | Certificate serialized to CBOR as a base16-encoded string. +type CertificateCBORBase16 = String + +-- * Stake Certificate function implementation + -- | Make a certificate that delegates a stake address to a stake pool in the current era. -makeStakeAddressStakeDelegationCertificateImpl :: MonadThrow m => String -> String -> m String +makeStakeAddressStakeDelegationCertificateImpl + :: MonadThrow m => StakeKeyHashBase16 -> PoolIdBase16 -> m CertificateCBORBase16 makeStakeAddressStakeDelegationCertificateImpl skHashStr poolIdStr = do stakeCertHash <- readHash skHashStr poolId <- readPoolId poolIdStr @@ -47,7 +64,7 @@ makeStakeAddressStakeDelegationCertificateImpl skHashStr poolIdStr = do -- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. makeStakeAddressStakeDelegationCertificateExperimentalEraImpl - :: MonadThrow m => String -> String -> m String + :: MonadThrow m => StakeKeyHashBase16 -> PoolIdBase16 -> m CertificateCBORBase16 makeStakeAddressStakeDelegationCertificateExperimentalEraImpl skHashStr poolIdStr = do stakeCertHash <- readHash skHashStr poolId <- readPoolId poolIdStr @@ -55,7 +72,7 @@ makeStakeAddressStakeDelegationCertificateExperimentalEraImpl skHashStr poolIdSt makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId makeStakeAddressStakeDelegationCertificate - :: forall era m. MonadThrow m => Exp.Era era -> Hash StakeKey -> PoolId -> m String + :: forall era m. MonadThrow m => Exp.Era era -> Hash StakeKey -> PoolId -> m CertificateCBORBase16 makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId = obtainCommonConstraints era $ do let cert :: Certificate (Exp.LedgerEra era) = @@ -68,21 +85,22 @@ makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId = return $ serialiseCertificateToCBOR era cert -- | Make a stake address registration certificate in the current era. -makeStakeAddressRegistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String +makeStakeAddressRegistrationCertificateImpl + :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressRegistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr makeStakeAddressRegistrationCertificateWrapper currentEra skHash deposit --  | Make a stake address registration certificate in the current experimental era. makeStakeAddressRegistrationCertificateExperimentalEraImpl - :: MonadThrow m => String -> Integer -> m String + :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressRegistrationCertificateExperimentalEraImpl skHashStr deposit = do skHash <- readHash skHashStr era <- justOrError "No experimental era available" experimentalEra makeStakeAddressRegistrationCertificateWrapper era skHash deposit makeStakeAddressRegistrationCertificateWrapper - :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String + :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressRegistrationCertificateWrapper era skHash deposit = obtainCommonConstraints era $ do let cert :: Certificate (Exp.LedgerEra era) = @@ -92,21 +110,22 @@ makeStakeAddressRegistrationCertificateWrapper era skHash deposit = return $ serialiseCertificateToCBOR era cert -- | Make a stake address unregistration certificate in the current era. -makeStakeAddressUnregistrationCertificateImpl :: MonadThrow m => String -> Integer -> m String +makeStakeAddressUnregistrationCertificateImpl + :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressUnregistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr makeStakeAddressUnregistrationCertificateWrapper currentEra skHash deposit -- | Make a stake address unregistration certificate in the current experimental era. makeStakeAddressUnregistrationCertificateExperimentalEraImpl - :: MonadThrow m => String -> Integer -> m String + :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressUnregistrationCertificateExperimentalEraImpl skHashStr deposit = do skHash <- readHash skHashStr era <- justOrError "No experimental era available" experimentalEra makeStakeAddressUnregistrationCertificateWrapper era skHash deposit makeStakeAddressUnregistrationCertificateWrapper - :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> Integer -> m String + :: forall era m. MonadThrow m => Era era -> Hash StakeKey -> DepositLovelace -> m CertificateCBORBase16 makeStakeAddressUnregistrationCertificateWrapper era skHash deposit = obtainCommonConstraints era $ do let cert :: Certificate (Exp.LedgerEra era) = @@ -115,7 +134,8 @@ makeStakeAddressUnregistrationCertificateWrapper era skHash deposit = (Coin deposit) return $ serialiseCertificateToCBOR era cert -serialiseCertificateToCBOR :: Exp.Era era -> Certificate (Exp.LedgerEra era) -> String +serialiseCertificateToCBOR + :: Exp.Era era -> Certificate (Exp.LedgerEra era) -> CertificateCBORBase16 serialiseCertificateToCBOR era cert = obtainCommonConstraints era $ do Text.unpack $ @@ -124,8 +144,8 @@ serialiseCertificateToCBOR era cert = serialiseToCBOR cert -readHash :: MonadThrow m => String -> m (Hash StakeKey) +readHash :: MonadThrow m => StakeKeyHashBase16 -> m (Hash StakeKey) readHash = rightOrError . Api.deserialiseFromRawBytesHex . Text.encodeUtf8 . Text.pack -readPoolId :: MonadThrow m => String -> m PoolId +readPoolId :: MonadThrow m => PoolIdBase16 -> m PoolId readPoolId = rightOrError . Api.deserialiseFromRawBytesHex . Text.encodeUtf8 . Text.pack From 889aa92c534a84425a8d15a7a19c0b6f77407cde Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Nov 2025 01:02:50 +0100 Subject: [PATCH 6/8] Rename references to "experimental" era to "upcoming" era --- cardano-wasm/lib-wrapper/cardano-api.d.ts | 20 ++++---- .../Wasm/Api/Certificate/StakeCertificate.hs | 32 ++++++------- cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs | 32 ++++++------- cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs | 12 ++--- .../src-lib/Cardano/Wasm/Internal/Api/Era.hs | 8 ++-- .../Wasm/Internal/JavaScript/Bridge.hs | 46 +++++++++---------- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/cardano-wasm/lib-wrapper/cardano-api.d.ts b/cardano-wasm/lib-wrapper/cardano-api.d.ts index 640f93cce6..2c14564952 100644 --- a/cardano-wasm/lib-wrapper/cardano-api.d.ts +++ b/cardano-wasm/lib-wrapper/cardano-api.d.ts @@ -26,10 +26,10 @@ declare interface CardanoApi { newTx(): Promise; /** - * Create a new unsigned transaction in the current experimental era (currently Dijkstra). + * Create a new unsigned transaction in the current upcoming era (currently Dijkstra). * @returns A promise that resolves to a new `UnsignedTx` object. */ - newExperimentalEraTx(): Promise; + newUpcomingEraTx(): Promise; } /** @@ -73,32 +73,32 @@ declare interface CardanoApi { } /** - * Methods for creating certificates in the current experimental era (currently Dijkstra). + * Methods for creating certificates in the current upcoming era (currently Dijkstra). */ - experimentalEra: { + upcomingEra: { /** - * Make a certificate that delegates a stake address to a stake pool in the current experimental era (currently Dijkstra). + * Make a certificate that delegates a stake address to a stake pool in the current upcoming era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param poolId The pool ID in base16 format. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. */ - makeStakeAddressStakeDelegationCertificateExperimentalEra(stakeKeyHash: string, poolId: string): Promise; + makeStakeAddressStakeDelegationCertificateUpcomingEra(stakeKeyHash: string, poolId: string): Promise; /** - * Make a stake address registration certificate in the current experimental era (currently Dijkstra). + * Make a stake address registration certificate in the current upcoming era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. */ - makeStakeAddressRegistrationCertificateExperimentalEra(stakeKeyHash: string, deposit: bigint): Promise; + makeStakeAddressRegistrationCertificateUpcomingEra(stakeKeyHash: string, deposit: bigint): Promise; /** - * Make a stake address unregistration certificate in the current experimental era (currently Dijkstra). + * Make a stake address unregistration certificate in the current upcoming era (currently Dijkstra). * @param stakeKeyHash The stake key hash in base16 format. * @param deposit The deposit amount in lovelaces. * @returns A promise that resolves to the CBOR-encoded certificate as a hex string. */ - makeStakeAddressUnregistrationCertificateExperimentalEra(stakeKeyHash: string, deposit: bigint): Promise; + makeStakeAddressUnregistrationCertificateUpcomingEra(stakeKeyHash: string, deposit: bigint): Promise; } } diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs index e63376b1d5..719dcc4289 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Certificate/StakeCertificate.hs @@ -7,11 +7,11 @@ module Cardano.Wasm.Api.Certificate.StakeCertificate ( makeStakeAddressStakeDelegationCertificateImpl - , makeStakeAddressStakeDelegationCertificateExperimentalEraImpl + , makeStakeAddressStakeDelegationCertificateUpcomingEraImpl , makeStakeAddressRegistrationCertificateImpl - , makeStakeAddressRegistrationCertificateExperimentalEraImpl + , makeStakeAddressRegistrationCertificateUpcomingEraImpl , makeStakeAddressUnregistrationCertificateImpl - , makeStakeAddressUnregistrationCertificateExperimentalEraImpl + , makeStakeAddressUnregistrationCertificateUpcomingEraImpl ) where @@ -31,7 +31,7 @@ import Cardano.Api.Serialise.Raw qualified as Api import Cardano.Ledger.Api (Delegatee (DelegStake)) import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError) -import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) +import Cardano.Wasm.Internal.Api.Era (currentEra, upcomingEra) import Control.Monad.Catch (MonadThrow) import Data.ByteString.Base16 qualified as Base16 @@ -62,13 +62,13 @@ makeStakeAddressStakeDelegationCertificateImpl skHashStr poolIdStr = do poolId <- readPoolId poolIdStr makeStakeAddressStakeDelegationCertificate currentEra stakeCertHash poolId --- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. -makeStakeAddressStakeDelegationCertificateExperimentalEraImpl +-- | Make a certificate that delegates a stake address to a stake pool in the current upcoming era. +makeStakeAddressStakeDelegationCertificateUpcomingEraImpl :: MonadThrow m => StakeKeyHashBase16 -> PoolIdBase16 -> m CertificateCBORBase16 -makeStakeAddressStakeDelegationCertificateExperimentalEraImpl skHashStr poolIdStr = do +makeStakeAddressStakeDelegationCertificateUpcomingEraImpl skHashStr poolIdStr = do stakeCertHash <- readHash skHashStr poolId <- readPoolId poolIdStr - era <- justOrError "No experimental era available" experimentalEra + era <- justOrError "No upcoming era available" upcomingEra makeStakeAddressStakeDelegationCertificate era stakeCertHash poolId makeStakeAddressStakeDelegationCertificate @@ -91,12 +91,12 @@ makeStakeAddressRegistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr makeStakeAddressRegistrationCertificateWrapper currentEra skHash deposit ---  | Make a stake address registration certificate in the current experimental era. -makeStakeAddressRegistrationCertificateExperimentalEraImpl +--  | Make a stake address registration certificate in the upcoming era. +makeStakeAddressRegistrationCertificateUpcomingEraImpl :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 -makeStakeAddressRegistrationCertificateExperimentalEraImpl skHashStr deposit = do +makeStakeAddressRegistrationCertificateUpcomingEraImpl skHashStr deposit = do skHash <- readHash skHashStr - era <- justOrError "No experimental era available" experimentalEra + era <- justOrError "No upcoming era available" upcomingEra makeStakeAddressRegistrationCertificateWrapper era skHash deposit makeStakeAddressRegistrationCertificateWrapper @@ -116,12 +116,12 @@ makeStakeAddressUnregistrationCertificateImpl skHashStr deposit = do skHash <- readHash skHashStr makeStakeAddressUnregistrationCertificateWrapper currentEra skHash deposit --- | Make a stake address unregistration certificate in the current experimental era. -makeStakeAddressUnregistrationCertificateExperimentalEraImpl +-- | Make a stake address unregistration certificate in the upcoming era. +makeStakeAddressUnregistrationCertificateUpcomingEraImpl :: MonadThrow m => StakeKeyHashBase16 -> DepositLovelace -> m CertificateCBORBase16 -makeStakeAddressUnregistrationCertificateExperimentalEraImpl skHashStr deposit = do +makeStakeAddressUnregistrationCertificateUpcomingEraImpl skHashStr deposit = do skHash <- readHash skHashStr - era <- justOrError "No experimental era available" experimentalEra + era <- justOrError "No upcoming era available" upcomingEra makeStakeAddressUnregistrationCertificateWrapper era skHash deposit makeStakeAddressUnregistrationCertificateWrapper diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs index 3a7966d1f1..b8d4317bdf 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs @@ -17,7 +17,7 @@ where import Cardano.Api (pretty) import Cardano.Api.Experimental.Era qualified as Exp -import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) +import Cardano.Wasm.Internal.Api.Era (currentEra, upcomingEra) import Data.Aeson qualified as Aeson import Data.Text qualified as Text @@ -450,10 +450,10 @@ apiInfo = } , MethodInfoEntry $ MethodInfo - { methodName = "newExperimentalEraTx" + { methodName = "newUpcomingEraTx" , methodDoc = - "Create a new unsigned transaction in the current experimental era " - ++ getEraCommentFor experimentalEra + "Create a new unsigned transaction in the current upcoming era " + ++ getEraCommentFor upcomingEra ++ "." , methodParams = [] , methodReturnType = NewObject (virtualObjectName unsignedTxObj) @@ -527,19 +527,19 @@ apiInfo = } , MethodGroupEntry $ MethodGroup - { groupName = "experimentalEra" + { groupName = "upcomingEra" , groupDoc = - [ "Methods for creating certificates in the current experimental era " - ++ getEraCommentFor experimentalEra + [ "Methods for creating certificates in the current upcoming era " + ++ getEraCommentFor upcomingEra ++ "." ] , groupMethods = [ MethodInfoEntry $ MethodInfo - { methodName = "makeStakeAddressStakeDelegationCertificateExperimentalEra" + { methodName = "makeStakeAddressStakeDelegationCertificateUpcomingEra" , methodDoc = - "Make a certificate that delegates a stake address to a stake pool in the current experimental era " - ++ getEraCommentFor experimentalEra + "Make a certificate that delegates a stake address to a stake pool in the current upcoming era " + ++ getEraCommentFor upcomingEra ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." @@ -550,10 +550,10 @@ apiInfo = } , MethodInfoEntry $ MethodInfo - { methodName = "makeStakeAddressRegistrationCertificateExperimentalEra" + { methodName = "makeStakeAddressRegistrationCertificateUpcomingEra" , methodDoc = - "Make a stake address registration certificate in the current experimental era " - ++ getEraCommentFor experimentalEra + "Make a stake address registration certificate in the current upcoming era " + ++ getEraCommentFor upcomingEra ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." @@ -564,10 +564,10 @@ apiInfo = } , MethodInfoEntry $ MethodInfo - { methodName = "makeStakeAddressUnregistrationCertificateExperimentalEra" + { methodName = "makeStakeAddressUnregistrationCertificateUpcomingEra" , methodDoc = - "Make a stake address unregistration certificate in the current experimental era " - ++ getEraCommentFor experimentalEra + "Make a stake address unregistration certificate in the current upcoming era " + ++ getEraCommentFor upcomingEra ++ "." , methodParams = [ ParamInfo "stakeKeyHash" TSString "The stake key hash in base16 format." diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs index 0bb921ee17..5fabec28a7 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Tx.hs @@ -13,7 +13,7 @@ module Cardano.Wasm.Api.Tx , SignedTxObject (..) , ProtocolParamsJSON (..) , newTxImpl - , newExperimentalEraTxImpl + , newUpcomingEraTxImpl , addTxInputImpl , addSimpleTxOutImpl , appendCertificateToTxImpl @@ -35,7 +35,7 @@ import Cardano.Api.Tx qualified as TxBody import Cardano.Ledger.Api qualified as Ledger import Cardano.Wasm.ExceptionHandling (justOrError, rightOrError, toMonadFail) -import Cardano.Wasm.Internal.Api.Era (currentEra, experimentalEra) +import Cardano.Wasm.Internal.Api.Era (currentEra, upcomingEra) import Control.Monad.Catch (MonadThrow) import Data.Aeson (ToJSON (toJSON), (.=)) @@ -84,10 +84,10 @@ instance FromJSON UnsignedTxObject where newTxImpl :: UnsignedTxObject newTxImpl = UnsignedTxObject currentEra (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) --- | Create a new unsigned transaction object for making a transaction in the current experimental era. -newExperimentalEraTxImpl :: MonadThrow m => m UnsignedTxObject -newExperimentalEraTxImpl = do - era <- justOrError "No experimental era available" experimentalEra +-- | Create a new unsigned transaction object for making a transaction in the current upcoming era. +newUpcomingEraTxImpl :: MonadThrow m => m UnsignedTxObject +newUpcomingEraTxImpl = do + era <- justOrError "No upcoming era available" upcomingEra return $ UnsignedTxObject era (Exp.UnsignedTx (Ledger.mkBasicTx Ledger.mkBasicTxBody)) -- | Add a simple transaction input to an unsigned transaction object. diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs b/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs index df8b844e81..4161401b0d 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Internal/Api/Era.hs @@ -1,11 +1,11 @@ -- We disable missing signature because DijkstraEra type is not exported yet {-# OPTIONS_GHC -Wno-missing-signatures #-} --- | Module providing constants for the current and experimental eras +-- | Module providing constants for the current and upcoming eras -- used throughout the cardano-wasm library. module Cardano.Wasm.Internal.Api.Era ( currentEra - , experimentalEra + , upcomingEra ) where @@ -15,5 +15,5 @@ import Cardano.Api.Experimental qualified as Exp currentEra :: Exp.Era Exp.ConwayEra currentEra = Exp.ConwayEra --- | The experimental era, still under development or testing. -experimentalEra = Just Exp.DijkstraEra +-- | The upcoming era, still under development or testing. +upcomingEra = Just Exp.DijkstraEra diff --git a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs index 99ca4a32cb..11b35b6f75 100644 --- a/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs +++ b/cardano-wasm/src-wasm/Cardano/Wasm/Internal/JavaScript/Bridge.hs @@ -342,8 +342,8 @@ getBase16ForStakeVerificationKeyHash jsWallet = foreign export javascript "newTx" newTx :: IO JSUnsignedTx -foreign export javascript "newExperimentalEraTx" - newExperimentalEraTx :: IO JSUnsignedTx +foreign export javascript "newUpcomingEraTx" + newUpcomingEraTx :: IO JSUnsignedTx foreign export javascript "addTxInput" addTxInput :: JSUnsignedTx -> JSTxId -> JSTxIx -> IO JSUnsignedTx @@ -357,20 +357,20 @@ foreign export javascript "appendCertificateToTx" foreign export javascript "makeStakeAddressStakeDelegationCertificate" makeStakeAddressStakeDelegationCertificate :: JSString -> JSString -> IO JSString -foreign export javascript "makeStakeAddressStakeDelegationCertificateExperimentalEra" - makeStakeAddressStakeDelegationCertificateExperimentalEra :: JSString -> JSString -> IO JSString +foreign export javascript "makeStakeAddressStakeDelegationCertificateUpcomingEra" + makeStakeAddressStakeDelegationCertificateUpcomingEra :: JSString -> JSString -> IO JSString foreign export javascript "makeStakeAddressRegistrationCertificate" makeStakeAddressRegistrationCertificate :: JSString -> JSCoin -> IO JSString -foreign export javascript "makeStakeAddressRegistrationCertificateExperimentalEra" - makeStakeAddressRegistrationCertificateExperimentalEra :: JSString -> JSCoin -> IO JSString +foreign export javascript "makeStakeAddressRegistrationCertificateUpcomingEra" + makeStakeAddressRegistrationCertificateUpcomingEra :: JSString -> JSCoin -> IO JSString foreign export javascript "makeStakeAddressUnregistrationCertificate" makeStakeAddressUnregistrationCertificate :: JSString -> JSCoin -> IO JSString -foreign export javascript "makeStakeAddressUnregistrationCertificateExperimentalEra" - makeStakeAddressUnregistrationCertificateExperimentalEra :: JSString -> JSCoin -> IO JSString +foreign export javascript "makeStakeAddressUnregistrationCertificateUpcomingEra" + makeStakeAddressUnregistrationCertificateUpcomingEra :: JSString -> JSCoin -> IO JSString foreign export javascript "setFee" setFee :: JSUnsignedTx -> JSCoin -> IO JSUnsignedTx @@ -385,9 +385,9 @@ foreign export javascript "signWithPaymentKey" newTx :: HasCallStack => IO JSUnsignedTx newTx = toJSVal Wasm.newTxImpl --- | Create a new experimental era unsigned transaction. -newExperimentalEraTx :: HasCallStack => IO JSUnsignedTx -newExperimentalEraTx = toJSVal =<< Wasm.newExperimentalEraTxImpl +-- | Create a new upcoming era unsigned transaction. +newUpcomingEraTx :: HasCallStack => IO JSUnsignedTx +newUpcomingEraTx = toJSVal =<< Wasm.newUpcomingEraTxImpl -- | Add a transaction input to an unsigned transaction. addTxInput :: HasCallStack => JSUnsignedTx -> JSTxId -> JSTxIx -> IO JSUnsignedTx @@ -429,12 +429,12 @@ makeStakeAddressStakeDelegationCertificate jsStakeKeyHash jsPoolId = <*> fromJSVal jsPoolId ) --- | Make a certificate that delegates a stake address to a stake pool in the current experimental era. -makeStakeAddressStakeDelegationCertificateExperimentalEra :: HasCallStack => JSString -> JSString -> IO JSString -makeStakeAddressStakeDelegationCertificateExperimentalEra jsStakeKeyHash jsPoolId = +-- | Make a certificate that delegates a stake address to a stake pool in the upcoming era. +makeStakeAddressStakeDelegationCertificateUpcomingEra :: HasCallStack => JSString -> JSString -> IO JSString +makeStakeAddressStakeDelegationCertificateUpcomingEra jsStakeKeyHash jsPoolId = toJSVal =<< join - ( Wasm.makeStakeAddressStakeDelegationCertificateExperimentalEraImpl + ( Wasm.makeStakeAddressStakeDelegationCertificateUpcomingEraImpl <$> fromJSVal jsStakeKeyHash <*> fromJSVal jsPoolId ) @@ -449,12 +449,12 @@ makeStakeAddressRegistrationCertificate jsStakeKeyHash jsDeposit = <*> (fromInteger <$> fromJSBigInt jsDeposit) ) --- | Make a stake address registration certificate in the current experimental era. -makeStakeAddressRegistrationCertificateExperimentalEra :: HasCallStack => JSString -> JSCoin -> IO JSString -makeStakeAddressRegistrationCertificateExperimentalEra jsStakeKeyHash jsDeposit = +-- | Make a stake address registration certificate in the upcoming era. +makeStakeAddressRegistrationCertificateUpcomingEra :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressRegistrationCertificateUpcomingEra jsStakeKeyHash jsDeposit = toJSVal =<< join - ( Wasm.makeStakeAddressRegistrationCertificateExperimentalEraImpl + ( Wasm.makeStakeAddressRegistrationCertificateUpcomingEraImpl <$> fromJSVal jsStakeKeyHash <*> (fromInteger <$> fromJSBigInt jsDeposit) ) @@ -469,12 +469,12 @@ makeStakeAddressUnregistrationCertificate jsStakeKeyHash jsDeposit = <*> (fromInteger <$> fromJSBigInt jsDeposit) ) --- | Make a stake address unregistration certificate in the current experimental era. -makeStakeAddressUnregistrationCertificateExperimentalEra :: HasCallStack => JSString -> JSCoin -> IO JSString -makeStakeAddressUnregistrationCertificateExperimentalEra jsStakeKeyHash jsDeposit = +-- | Make a stake address unregistration certificate in the upcoming era. +makeStakeAddressUnregistrationCertificateUpcomingEra :: HasCallStack => JSString -> JSCoin -> IO JSString +makeStakeAddressUnregistrationCertificateUpcomingEra jsStakeKeyHash jsDeposit = toJSVal =<< join - ( Wasm.makeStakeAddressUnregistrationCertificateExperimentalEraImpl + ( Wasm.makeStakeAddressUnregistrationCertificateUpcomingEraImpl <$> fromJSVal jsStakeKeyHash <*> (fromInteger <$> fromJSBigInt jsDeposit) ) From 89fd9e3e1c074b33d32a4f9028ced578b011f69a Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Wed, 19 Nov 2025 01:39:48 +0100 Subject: [PATCH 7/8] Elaborate when are upcoming eras not available --- cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs index b8d4317bdf..5ebfbc3e2b 100644 --- a/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs +++ b/cardano-wasm/src-lib/Cardano/Wasm/Api/Info.hs @@ -201,7 +201,8 @@ getEraCommentFor :: Maybe (Exp.Era era) -> String getEraCommentFor era = case era of Just era' -> "(currently " ++ show (pretty era') ++ ")" - Nothing -> "(currently unavailable)" + Nothing -> + "(currently unavailable, upcoming era will only be available during late development and testing phases)" -- | Provides metadata about the "virtual objects" and their methods. -- This is intended to help generate JavaScript wrappers. From 3bb641fe01a6e25503c5d65c38f31e72f1485fe2 Mon Sep 17 00:00:00 2001 From: Pablo Lamela Date: Thu, 20 Nov 2025 03:31:57 +0100 Subject: [PATCH 8/8] Update pure WASI API --- cardano-wasm/cardano-wasm.cabal | 3 +- .../Api/Certificate/StakeCertificate.hs | 101 ++++++++++++++++++ .../src-wasi/Cardano/Wasi/Internal/Api/Tx.hs | 25 ++--- 3 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Certificate/StakeCertificate.hs diff --git a/cardano-wasm/cardano-wasm.cabal b/cardano-wasm/cardano-wasm.cabal index cc09576470..38900fba43 100644 --- a/cardano-wasm/cardano-wasm.cabal +++ b/cardano-wasm/cardano-wasm.cabal @@ -79,8 +79,9 @@ executable cardano-wasi if arch(wasm32) ghc-options: -no-hs-main - "-optl-Wl,--strip-all,--export=hs_init,--export=newTx,--export=newExperimentalEraTx,--export=newConwayTx,--export=addTxInput,--export=addSimpleTxOut,--export=appendCertificateToTx,--export=setFee,--export=estimateMinFee,--export=signWithPaymentKey,--export=alsoSignWithPaymentKey,--export=toCbor,--export=generatePaymentWallet,--export=generateStakeWallet,--export=restorePaymentWalletFromSigningKeyBech32,--export=restoreStakeWalletFromSigningKeyBech32,--export=generateTestnetPaymentWallet,--export=generateTestnetStakeWallet,--export=restoreTestnetPaymentWalletFromSigningKeyBech32,--export=restoreTestnetStakeWalletFromSigningKeyBech32,--export=getAddressBech32,--export=getBech32ForPaymentVerificationKey,--export=getBech32ForPaymentSigningKey,--export=getBech32ForStakeVerificationKey,--export=getBech32ForStakeSigningKey,--export=getBase16ForPaymentVerificationKeyHash,--export=getBase16ForStakeVerificationKeyHash,--export=mallocNBytes,--export=getStrLen,--export=freeMemory" + "-optl-Wl,--strip-all,--export=hs_init,--export=newTx,--export=newUpcomingEraTx,--export=addTxInput,--export=addSimpleTxOut,--export=appendCertificateToTx,--export=setFee,--export=estimateMinFee,--export=signWithPaymentKey,--export=alsoSignWithPaymentKey,--export=toCbor,--export=makeStakeAddressStakeDelegationCertificate,--export=makeStakeAddressStakeDelegationCertificateUpcomingEra,--export=makeStakeAddressRegistrationCertificate,--export=makeStakeAddressRegistrationCertificateUpcomingEra,--export=makeStakeAddressUnregistrationCertificate,--export=makeStakeAddressUnregistrationCertificateUpcomingEra,--export=generatePaymentWallet,--export=generateStakeWallet,--export=restorePaymentWalletFromSigningKeyBech32,--export=restoreStakeWalletFromSigningKeyBech32,--export=generateTestnetPaymentWallet,--export=generateTestnetStakeWallet,--export=restoreTestnetPaymentWalletFromSigningKeyBech32,--export=restoreTestnetStakeWalletFromSigningKeyBech32,--export=getAddressBech32,--export=getBech32ForPaymentVerificationKey,--export=getBech32ForPaymentSigningKey,--export=getBech32ForStakeVerificationKey,--export=getBech32ForStakeSigningKey,--export=getBase16ForPaymentVerificationKeyHash,--export=getBase16ForStakeVerificationKeyHash,--export=mallocNBytes,--export=getStrLen,--export=freeMemory" other-modules: + Cardano.Wasi.Internal.Api.Certificate.StakeCertificate Cardano.Wasi.Internal.Api.GRPC Cardano.Wasi.Internal.Api.Memory Cardano.Wasi.Internal.Api.Tx diff --git a/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Certificate/StakeCertificate.hs b/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Certificate/StakeCertificate.hs new file mode 100644 index 0000000000..28d89a8958 --- /dev/null +++ b/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Certificate/StakeCertificate.hs @@ -0,0 +1,101 @@ +{-# LANGUAGE CPP #-} + +module Cardano.Wasi.Internal.Api.Certificate.StakeCertificate + ( makeStakeAddressStakeDelegationCertificate + , makeStakeAddressStakeDelegationCertificateUpcomingEra + , makeStakeAddressRegistrationCertificate + , makeStakeAddressRegistrationCertificateUpcomingEra + , makeStakeAddressUnregistrationCertificate + , makeStakeAddressUnregistrationCertificateUpcomingEra + ) +where + +import Cardano.Wasi.Internal.Conversion (cstrToInt) +import Cardano.Wasm.Api.Certificate.StakeCertificate qualified as Wasm + +import Control.Monad (join) + +import Foreign.C (CString) +import Foreign.C.String (newCString, peekCString) + +#if defined(wasm32_HOST_ARCH) + +foreign export ccall "makeStakeAddressStakeDelegationCertificate" + makeStakeAddressStakeDelegationCertificate :: CString -> CString -> IO CString + +foreign export ccall "makeStakeAddressStakeDelegationCertificateUpcomingEra" + makeStakeAddressStakeDelegationCertificateUpcomingEra :: CString -> CString -> IO CString + +foreign export ccall "makeStakeAddressRegistrationCertificate" + makeStakeAddressRegistrationCertificate :: CString -> CString -> IO CString + +foreign export ccall "makeStakeAddressRegistrationCertificateUpcomingEra" + makeStakeAddressRegistrationCertificateUpcomingEra :: CString -> CString -> IO CString + +foreign export ccall "makeStakeAddressUnregistrationCertificate" + makeStakeAddressUnregistrationCertificate :: CString -> CString -> IO CString + +foreign export ccall "makeStakeAddressUnregistrationCertificateUpcomingEra" + makeStakeAddressUnregistrationCertificateUpcomingEra :: CString -> CString -> IO CString + +#endif + +-- | Make a certificate that delegates a stake address to a stake pool in the current era. +makeStakeAddressStakeDelegationCertificate :: CString -> CString -> IO CString +makeStakeAddressStakeDelegationCertificate stakeKeyHashCStr poolIdCStr = + newCString + =<< join + ( Wasm.makeStakeAddressStakeDelegationCertificateImpl + <$> peekCString stakeKeyHashCStr + <*> peekCString poolIdCStr + ) + +-- | Make a certificate that delegates a stake address to a stake pool in the upcoming era. +makeStakeAddressStakeDelegationCertificateUpcomingEra :: CString -> CString -> IO CString +makeStakeAddressStakeDelegationCertificateUpcomingEra stakeKeyHashCStr poolIdCStr = + newCString + =<< join + ( Wasm.makeStakeAddressStakeDelegationCertificateUpcomingEraImpl + <$> peekCString stakeKeyHashCStr + <*> peekCString poolIdCStr + ) + +-- | Make a stake address registration certificate in the current era. +makeStakeAddressRegistrationCertificate :: CString -> CString -> IO CString +makeStakeAddressRegistrationCertificate stakeKeyHashCStr depositCStr = + newCString + =<< join + ( Wasm.makeStakeAddressRegistrationCertificateImpl + <$> peekCString stakeKeyHashCStr + <*> (toInteger <$> cstrToInt "deposit" depositCStr) + ) + +-- | Make a stake address registration certificate in the upcoming era. +makeStakeAddressRegistrationCertificateUpcomingEra :: CString -> CString -> IO CString +makeStakeAddressRegistrationCertificateUpcomingEra stakeKeyHashCStr depositCStr = + newCString + =<< join + ( Wasm.makeStakeAddressRegistrationCertificateUpcomingEraImpl + <$> peekCString stakeKeyHashCStr + <*> (toInteger <$> cstrToInt "deposit" depositCStr) + ) + +-- | Make a stake address unregistration certificate in the current era. +makeStakeAddressUnregistrationCertificate :: CString -> CString -> IO CString +makeStakeAddressUnregistrationCertificate stakeKeyHashCStr depositCStr = + newCString + =<< join + ( Wasm.makeStakeAddressUnregistrationCertificateImpl + <$> peekCString stakeKeyHashCStr + <*> (toInteger <$> cstrToInt "deposit" depositCStr) + ) + +-- | Make a stake address unregistration certificate in the upcoming era. +makeStakeAddressUnregistrationCertificateUpcomingEra :: CString -> CString -> IO CString +makeStakeAddressUnregistrationCertificateUpcomingEra stakeKeyHashCStr depositCStr = + newCString + =<< join + ( Wasm.makeStakeAddressUnregistrationCertificateUpcomingEraImpl + <$> peekCString stakeKeyHashCStr + <*> (toInteger <$> cstrToInt "deposit" depositCStr) + ) diff --git a/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs b/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs index e829c3b68a..0a1ce46216 100644 --- a/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs +++ b/cardano-wasm/src-wasi/Cardano/Wasi/Internal/Api/Tx.hs @@ -2,8 +2,7 @@ module Cardano.Wasi.Internal.Api.Tx ( newTx - , newExperimentalEraTx - , newConwayTx + , newUpcomingEraTx , addTxInput , addSimpleTxOut , appendCertificateToTx @@ -39,11 +38,8 @@ import Foreign.C.String (newCString, peekCString) foreign export ccall "newTx" newTx :: IO UnsignedTxObjectJSON -foreign export ccall "newExperimentalEraTx" - newExperimentalEraTx :: IO UnsignedTxObjectJSON - -foreign export ccall "newConwayTx" - newConwayTx :: IO UnsignedTxObjectJSON +foreign export ccall "newUpcomingEraTx" + newUpcomingEraTx :: IO UnsignedTxObjectJSON foreign export ccall "addTxInput" addTxInput :: UnsignedTxObjectJSON -> CString -> Int -> IO UnsignedTxObjectJSON @@ -70,11 +66,8 @@ type UnsignedTxObjectJSON = CString newTx :: IO UnsignedTxObjectJSON newTx = toCJSON newTxImpl -newExperimentalEraTx :: IO UnsignedTxObjectJSON -newExperimentalEraTx = toCJSON =<< newExperimentalEraTxImpl - -newConwayTx :: IO UnsignedTxObjectJSON -newConwayTx = toCJSON newConwayTxImpl +newUpcomingEraTx :: IO UnsignedTxObjectJSON +newUpcomingEraTx = toCJSON =<< newUpcomingEraTxImpl addTxInput :: UnsignedTxObjectJSON -> CString -> Int -> IO UnsignedTxObjectJSON addTxInput unsignedTxObject txId txIx = @@ -113,15 +106,15 @@ setFee unsignedTxObject feeStr = ) estimateMinFee :: UnsignedTxObjectJSON -> CString -> Int -> Int -> Int -> IO CString -estimateMinFee ptrUnsignedTxObject pparams numInputs numOutputs numShelleyKeyWitnesses = do +estimateMinFee ptrUnsignedTxObject pparams numExtraKeyWitnesses numExtraByronKeyWitnesses totalRefScriptSize = do (intToCStr . Api.unCoin) =<< join ( estimateMinFeeImpl <$> fromCJSON False "UnsignedTx" ptrUnsignedTxObject <*> (ProtocolParamsJSON <$> fromCJSON False "ProtocolParameters" pparams) - <*> pure (fromIntegral numInputs) - <*> pure (fromIntegral numOutputs) - <*> pure (fromIntegral numShelleyKeyWitnesses) + <*> pure (fromIntegral numExtraKeyWitnesses) + <*> pure (fromIntegral numExtraByronKeyWitnesses) + <*> pure (fromIntegral totalRefScriptSize) ) signWithPaymentKey :: UnsignedTxObjectJSON -> CString -> IO SignedTxObjectJSON