diff --git a/core/src/apps/cardano/helpers/protocol_magics.py b/core/src/apps/cardano/helpers/protocol_magics.py
index cc5c567e8a..e0a30fc9bc 100644
--- a/core/src/apps/cardano/helpers/protocol_magics.py
+++ b/core/src/apps/cardano/helpers/protocol_magics.py
@@ -1,9 +1,14 @@
+# https://book.world.dev.cardano.org/environments.html
 MAINNET = 764824073
-TESTNET = 1097911063
+TESTNET_PREPROD = 1
+TESTNET_PREVIEW = 2
+TESTNET_LEGACY = 1097911063
 
 NAMES = {
     MAINNET: "Mainnet",
-    TESTNET: "Testnet",
+    TESTNET_PREPROD: "Preprod Testnet",
+    TESTNET_PREVIEW: "Preview Testnet",
+    TESTNET_LEGACY: "Legacy Testnet",
 }
 
 
diff --git a/core/tests/test_apps.cardano.address.py b/core/tests/test_apps.cardano.address.py
index f74e4fa6a3..61be57b659 100644
--- a/core/tests/test_apps.cardano.address.py
+++ b/core/tests/test_apps.cardano.address.py
@@ -290,7 +290,7 @@ class TestCardanoAddress(unittest.TestCase):
                 address_type=CardanoAddressType.BYRON,
                 address_n=[0x80000000 | 44, 0x80000000 | 1815, 0x80000000, 0, i],
             )
-            address = derive_human_readable(self.keychain, address_parameters, protocol_magics.TESTNET, 0)
+            address = derive_human_readable(self.keychain, address_parameters, protocol_magics.TESTNET_LEGACY, 0)
             self.assertEqual(expected, address)
 
     def test_derive_address(self):
diff --git a/python/src/trezorlib/cardano.py b/python/src/trezorlib/cardano.py
index 3aa8692a15..70983e13d0 100644
--- a/python/src/trezorlib/cardano.py
+++ b/python/src/trezorlib/cardano.py
@@ -38,7 +38,12 @@ if TYPE_CHECKING:
     from .client import TrezorClient
     from .protobuf import MessageType
 
-PROTOCOL_MAGICS = {"mainnet": 764824073, "testnet": 1097911063}
+PROTOCOL_MAGICS = {
+    "mainnet": 764824073,
+    "testnet_preprod": 1,
+    "testnet_preview": 2,
+    "testnet_legacy": 1097911063,
+}
 NETWORK_IDS = {"mainnet": 1, "testnet": 0}
 
 MAX_CHUNK_SIZE = 1024
diff --git a/python/src/trezorlib/cli/cardano.py b/python/src/trezorlib/cli/cardano.py
index 23fe7e17bd..216419e648 100644
--- a/python/src/trezorlib/cli/cardano.py
+++ b/python/src/trezorlib/cli/cardano.py
@@ -27,6 +27,12 @@ if TYPE_CHECKING:
 
 PATH_HELP = "BIP-32 path to key, e.g. m/44'/1815'/0'/0/0"
 
+TESTNET_CHOICES = {
+    "preprod": "testnet_preprod",
+    "preview": "testnet_preview",
+    "legacy": "testnet_legacy",
+}
+
 
 @click.group(name="cardano")
 def cli() -> None:
@@ -46,7 +52,7 @@ def cli() -> None:
     "-p", "--protocol-magic", type=int, default=cardano.PROTOCOL_MAGICS["mainnet"]
 )
 @click.option("-N", "--network-id", type=int, default=cardano.NETWORK_IDS["mainnet"])
-@click.option("-t", "--testnet", is_flag=True)
+@click.option("-t", "--testnet", type=ChoiceType(TESTNET_CHOICES))
 @click.option(
     "-D",
     "--derivation-type",
@@ -61,7 +67,7 @@ def sign_tx(
     signing_mode: messages.CardanoTxSigningMode,
     protocol_magic: int,
     network_id: int,
-    testnet: bool,
+    testnet: str,
     derivation_type: messages.CardanoDerivationType,
     include_network_id: bool,
 ) -> cardano.SignTxResponse:
@@ -69,7 +75,7 @@ def sign_tx(
     transaction = json.load(file)
 
     if testnet:
-        protocol_magic = cardano.PROTOCOL_MAGICS["testnet"]
+        protocol_magic = cardano.PROTOCOL_MAGICS[testnet]
         network_id = cardano.NETWORK_IDS["testnet"]
 
     inputs = [cardano.parse_input(input) for input in transaction["inputs"]]
@@ -185,7 +191,7 @@ def sign_tx(
     "-p", "--protocol-magic", type=int, default=cardano.PROTOCOL_MAGICS["mainnet"]
 )
 @click.option("-N", "--network-id", type=int, default=cardano.NETWORK_IDS["mainnet"])
-@click.option("-e", "--testnet", is_flag=True)
+@click.option("-e", "--testnet", type=ChoiceType(TESTNET_CHOICES))
 @click.option(
     "-D",
     "--derivation-type",
@@ -207,7 +213,7 @@ def get_address(
     protocol_magic: int,
     network_id: int,
     show_display: bool,
-    testnet: bool,
+    testnet: str,
     derivation_type: messages.CardanoDerivationType,
 ) -> str:
     """
@@ -225,7 +231,7 @@ def get_address(
     Byron, enterprise and reward addresses only require the general parameters.
     """
     if testnet:
-        protocol_magic = cardano.PROTOCOL_MAGICS["testnet"]
+        protocol_magic = cardano.PROTOCOL_MAGICS[testnet]
         network_id = cardano.NETWORK_IDS["testnet"]
 
     staking_key_hash_bytes = cardano.parse_optional_bytes(staking_key_hash)