mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-12 16:30:56 +00:00
feat(core/cardano): add support for catalyst voting registration
This commit is contained in:
parent
2c503b16f5
commit
2313293477
@ -116,17 +116,19 @@ message CardanoPublicKey {
|
||||
* @next Failure
|
||||
*/
|
||||
message CardanoSignTx {
|
||||
repeated CardanoTxInputType inputs = 1; // inputs to be used in transaction
|
||||
repeated CardanoTxOutputType outputs = 2; // outputs to be used in transaction
|
||||
// optional uint32 transactions_count = 3; // left as a comment so we know to skip the id 3 in the future
|
||||
required uint32 protocol_magic = 5; // network's protocol magic
|
||||
required uint64 fee = 6; // transaction fee - added in shelley
|
||||
optional uint64 ttl = 7; // transaction ttl - added in shelley
|
||||
required uint32 network_id = 8; // network id - mainnet or testnet
|
||||
repeated CardanoTxCertificateType certificates = 9; // transaction certificates - added in shelley
|
||||
repeated CardanoTxWithdrawalType withdrawals = 10; // transaction withdrawals - added in shelley
|
||||
optional bytes metadata = 11; // transaction metadata - added in shelley
|
||||
optional uint64 validity_interval_start = 12; // transaction validity start - added in allegra
|
||||
repeated CardanoTxInputType inputs = 1; // inputs to be used in transaction
|
||||
repeated CardanoTxOutputType outputs = 2; // outputs to be used in transaction
|
||||
// optional uint32 transactions_count = 3; // left as a comment so we know to skip the id 3 in the future
|
||||
// optional uint32 network = 4; // replaced with protocol_magic
|
||||
required uint32 protocol_magic = 5; // network's protocol magic
|
||||
required uint64 fee = 6; // transaction fee - added in shelley
|
||||
optional uint64 ttl = 7; // transaction ttl - added in shelley
|
||||
required uint32 network_id = 8; // network id - mainnet or testnet
|
||||
repeated CardanoTxCertificateType certificates = 9; // transaction certificates - added in shelley
|
||||
repeated CardanoTxWithdrawalType withdrawals = 10; // transaction withdrawals - added in shelley
|
||||
// optional bytes metadata = 11; // replaced in Mary era with auxiliary data below
|
||||
optional uint64 validity_interval_start = 12; // transaction validity start - added in allegra
|
||||
optional CardanoTxAuxiliaryDataType auxiliary_data = 13; // transaction auxiliary data
|
||||
|
||||
/**
|
||||
* Structure representing cardano transaction input
|
||||
@ -218,6 +220,18 @@ message CardanoSignTx {
|
||||
repeated uint32 path = 1;
|
||||
required uint64 amount = 2;
|
||||
}
|
||||
|
||||
message CardanoCatalystRegistrationParametersType {
|
||||
required bytes voting_public_key = 1;
|
||||
repeated uint32 staking_path = 2;
|
||||
required CardanoAddressParametersType reward_address_parameters = 3;
|
||||
required uint64 nonce = 4;
|
||||
}
|
||||
|
||||
message CardanoTxAuxiliaryDataType {
|
||||
optional bytes blob = 1;
|
||||
optional CardanoCatalystRegistrationParametersType catalyst_registration_parameters = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
|
108
common/tests/fixtures/cardano/sign_tx.failed.json
vendored
108
common/tests/fixtures/cardano/sign_tx.failed.json
vendored
@ -13,7 +13,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -41,7 +41,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -69,7 +69,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -97,7 +97,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -125,7 +125,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -153,7 +153,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -181,7 +181,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -214,7 +214,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -242,7 +242,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/44'/1815'/0'/0/1",
|
||||
@ -270,7 +270,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -298,7 +298,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -326,7 +326,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -354,7 +354,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -382,7 +382,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -412,7 +412,7 @@
|
||||
{"type": 0, "path": "m/1852'/1815'/0'/0/0"}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -446,7 +446,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -474,7 +474,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [{"path": "m/1852'/1815'/0'/0/0", "amount": "1000"}],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -505,7 +505,7 @@
|
||||
"path": "m/1852'/1815'/0'/2/0",
|
||||
"amount": "449999999199999999"
|
||||
}],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -525,7 +525,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Metadata too large",
|
||||
"description": "Auxiliary data blob is incomplete",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
@ -533,7 +533,9 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "a200a11864a118c843aa00ff01a119012c590202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"auxiliary_data": {
|
||||
"blob": "a200a11864a118c843aa00ff01"
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -549,11 +551,11 @@
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid metadata"
|
||||
"error_message": "Invalid auxiliary data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Metadata is a list",
|
||||
"description": "Auxiliary data blob has leftover data",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
@ -561,7 +563,9 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "82a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0A",
|
||||
"auxiliary_data": {
|
||||
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000"
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -577,11 +581,11 @@
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid metadata"
|
||||
"error_message": "Invalid auxiliary data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Metadata is incomplete",
|
||||
"description": "transaction with catalyst registration containing byron reward address",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
@ -589,27 +593,37 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "a200a11864a118c843aa00ff01",
|
||||
"auxiliary_data": {
|
||||
"catalyst_registration_parameters": {
|
||||
"voting_public_key": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"staking_path": "m/1852'/1815'/0'/2/0",
|
||||
"nonce": 22634813,
|
||||
"reward_address_parameters": {
|
||||
"addressType": 8,
|
||||
"path": "m/44'/1815'/0'/0/0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid metadata"
|
||||
"error_message": "Invalid auxiliary data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Metadata has leftover data",
|
||||
"description": "transaction with both auxiliary data blob and catalyst registration",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
@ -617,23 +631,35 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa000000",
|
||||
"auxiliary_data": {
|
||||
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"catalyst_registration_parameters": {
|
||||
"voting_public_key": "38DA0B509D45BF6C87BD55594B92F97081D3923B8C1334B9B8D0BF13FC1C12D0",
|
||||
"staking_path": "m/1852'/1815'/0'/2/0",
|
||||
"reward_address_parameters": {
|
||||
"addressType": 0,
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"stakingPath": "m/1852'/1815'/0'/2/0"
|
||||
},
|
||||
"nonce": 140
|
||||
}
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid metadata"
|
||||
"error_message": "Invalid auxiliary data"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -645,7 +671,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -680,7 +706,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -720,7 +746,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -749,7 +775,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -792,7 +818,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
|
91
common/tests/fixtures/cardano/sign_tx.json
vendored
91
common/tests/fixtures/cardano/sign_tx.json
vendored
@ -13,7 +13,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -43,7 +43,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -78,7 +78,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -114,7 +114,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -159,7 +159,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -196,7 +196,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -233,7 +233,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -269,7 +269,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -305,7 +305,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -343,7 +343,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -383,7 +383,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -418,7 +418,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -454,7 +454,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -486,7 +486,7 @@
|
||||
{"type": 1, "path": "m/1852'/1815'/0'/2/0"}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -526,7 +526,7 @@
|
||||
"amount": "1000"
|
||||
}
|
||||
],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -562,7 +562,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -584,7 +584,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "transaction with metadata",
|
||||
"description": "transaction with auxiliary data blob",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
@ -592,8 +592,10 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"auxiliary_data": {
|
||||
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
},
|
||||
"input_flow": [["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -613,6 +615,47 @@
|
||||
"serialized_tx": "83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff0102182a030a075820ea4c91860dd5ec5449f8f985d227946ff39086b17f10b5afb93d12ee87050b6aa100818258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c15840b2015772a91043aeb04b98111744a098afdade0db5e30206538d7f2814965a5800d45240137f4d0dc81845a71e67cda38beaf816a520d73c4decbf7cbf0f6d08a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "transaction with catalyst registration",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": {
|
||||
"catalyst_registration_parameters": {
|
||||
"voting_public_key": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
|
||||
"staking_path": "m/1852'/1815'/0'/2/0",
|
||||
"reward_address_parameters": {
|
||||
"addressType": 0,
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"stakingPath": "m/1852'/1815'/0'/2/0"
|
||||
},
|
||||
"nonce": 22634813
|
||||
}
|
||||
},
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "SWIPE", "SWIPE", "SWIPE", "SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"tx_hash": "839a587109358e0aa81b8fb3d5fa74665fac303425ec544a4db7f6ba4e882dff",
|
||||
"serialized_tx": "83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff0102182a030a075820a943e9166f1bb6d767b175384d3bd7d23645170df36fc1861fbf344135d8e120a100818258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c15840187ecd899e01390272a8d8289088199b3453945fa076819b5b5df60c325c10315477cc801044dfb553e780a300d79627ef5c09e64c6f953cc33bbc59152c900282a219ef64a40158201af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc025820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e0358390180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277041a0159613d19ef65a101584074f27d877bbb4a5fc4f7c56869905c11f70bad0af3de24b23afaa1d024e750930f434ecc4b73e5d1723c2cb8548e8bf6098ac876487b3a6ed0891cb76994d40980"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Testnet transaction",
|
||||
"parameters": {
|
||||
@ -622,7 +665,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -662,7 +705,7 @@
|
||||
"validity_interval_start": 47,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -710,7 +753,7 @@
|
||||
"validity_interval_start": 47,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -769,7 +812,7 @@
|
||||
"fee": 42,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -800,7 +843,7 @@
|
||||
"fee": 42,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -47,7 +47,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -82,7 +82,7 @@
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["YES"], ["YES"], ["SWIPE", "YES"], ["YES"], ["SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
|
@ -35,7 +35,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -87,7 +87,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -136,7 +136,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -185,7 +185,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -238,7 +238,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -292,7 +292,7 @@
|
||||
"amount": "1000"
|
||||
}
|
||||
],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -340,7 +340,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
@ -389,7 +389,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -437,7 +437,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
@ -518,7 +518,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
|
@ -67,7 +67,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -151,7 +151,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -236,7 +236,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -287,7 +287,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["YES"], ["YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -338,7 +338,7 @@
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"metadata": "",
|
||||
"auxiliary_data": null,
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["YES"], ["YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
@ -358,6 +358,93 @@
|
||||
"tx_hash": "12921b4f8e77f815e0c8ed97c541fbd5ba38a6d3323f4ff1af0cb934b8ac6b39",
|
||||
"serialized_tx": "83a500818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182581d60cb03849e268f989b5a843107bad7fa2908246986a8f3d643f8c184800102182a030a04818a03581cf61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb49735820198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d06401a1dcd65001a1443fd00d81e820102581de03a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c49071181581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b427780f6a10081825820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e584027cab81902d04b2491d7aa2bf57bd9db59d33c2df1502dae0412d5225c6b0b8f7b057de6a7e7eae25016ed6ea1f6e6239fb36a285216c6ee4a3cb3376287a300f6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Sample stake pool registration certificate with auxiliary data",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 3,
|
||||
"pool_parameters": {
|
||||
"pool_id": "f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973",
|
||||
"vrf_key_hash": "198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d0640",
|
||||
"pledge": 500000000,
|
||||
"cost": 340000000,
|
||||
"margin": {
|
||||
"numerator": 1,
|
||||
"denominator": 2
|
||||
},
|
||||
"reward_account": "stake1uya87zwnmax0v6nnn8ptqkl6ydx4522kpsc3l3wmf3yswygwx45el",
|
||||
"owners": [
|
||||
{
|
||||
"staking_key_path": "m/1852'/1815'/0'/2/0"
|
||||
},
|
||||
{
|
||||
"staking_key_hash": "3a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c490711"
|
||||
}
|
||||
],
|
||||
"relays": [
|
||||
{
|
||||
"type": 0,
|
||||
"ipv4_address": "192.168.0.1",
|
||||
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"port": 1234
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"ipv6_address": "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
"port": 1234
|
||||
},
|
||||
{
|
||||
"type": 0,
|
||||
"ipv4_address": "192.168.0.1",
|
||||
"port": 1234
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"host_name": "www.test.test",
|
||||
"port": 1234
|
||||
},
|
||||
{
|
||||
"type": 2,
|
||||
"host_name": "www.test2.test"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"url": "https://www.test.test",
|
||||
"hash": "914c57c1f12bbf4a82b12d977d4f274674856a11ed4b9b95bd70f5d41c5064a6"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": {
|
||||
"type": 0,
|
||||
"blob": "a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
},
|
||||
"input_flow": [["SWIPE", "SWIPE", "YES"], ["SWIPE", "YES"], ["SWIPE", "YES"], ["YES"], ["YES"], ["YES"]],
|
||||
"inputs": [
|
||||
{
|
||||
"path": null,
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"result": {
|
||||
"tx_hash": "880fafab19a36407e9af300c2905e2f6bc8a8debd8b625005f56994d242ba460",
|
||||
"serialized_tx": "83a600818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018182583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff0102182a030a04818a03581cf61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb49735820198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d06401a1dcd65001a1443fd00d81e820102581de13a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c49071182581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277581c3a7f09d3df4cf66a7399c2b05bfa234d5a29560c311fc5db4c4907118584001904d244c0a8000150b80d01200000a3852e8a00003473700384001904d2f650b80d01200000a3852e8a00003473700384001904d244c0a80001f683011904d26d7777772e746573742e7465737482026e7777772e74657374322e74657374827568747470733a2f2f7777772e746573742e746573745820914c57c1f12bbf4a82b12d977d4f274674856a11ed4b9b95bd70f5d41c5064a6075820ea4c91860dd5ec5449f8f985d227946ff39086b17f10b5afb93d12ee87050b6aa10081825820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e584073dbc58bd6f6bc0d91a2b5852706dde05da7acbfde035481b88b1219518ea8609dc045ea3309b1ffb01830ec64578e80c70db37a1041e72d52649be20ff80009a200a11864a118c843aa00ff01a119012c590100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -20,8 +20,6 @@ REVIEWER = Jan Matejek <jan.matejek@satoshilabs.com>, Tomas Susanka <tomas.susan
|
||||
|
||||
## Important notes
|
||||
|
||||
Unfortunately we are aware of the fact that currently at most ~14 inputs are supported per transaction. To resolve this, the cardano app will have to be rewritten to support transaction streaming.
|
||||
|
||||
Cardano requires a custom `seed.py` file and `Keychain` class. This is because the original Cardano derivation schemes don't separate seed generation from key tree derivation and also because we need to support both Byron (44') and Shelley (1852') purposes. More on this can be found [here](https://github.com/satoshilabs/slips/blob/master/slip-0023.md) and [here](https://github.com/input-output-hk/implementation-decisions/blob/e2d1bed5e617f0907bc5e12cf1c3f3302a4a7c42/text/1852-hd-chimeric.md).
|
||||
|
||||
Cardano uses extended public keys. This also means that the transaction signature is built using the `ed25519.sign_ext` function.
|
||||
@ -126,8 +124,6 @@ Transaction outputs may include custom tokens on top of ADA tokens:
|
||||
|
||||
Please see the transaction below for more details.
|
||||
|
||||
**The serialized transaction output size is currently limited to 512 bytes. This limitation is a mitigation measure to prevent sending large (especially change) outputs containing many tokens that Trezor would not be able to spend given that currently the full Cardano transaction is held in-memory. Once Cardano-transaction signing is refactored to be streamed, this limit can be lifted**
|
||||
|
||||
#### Certificates
|
||||
|
||||
Certificates are posted to the blockchain via transactions and they mark a certain action, thus there are multiple certificate types:
|
||||
@ -151,11 +147,17 @@ Withdrawals are posted to the blockchain via transactions and they are used to w
|
||||
|
||||
You can read more on withdrawals in the [delegation design spec](https://hydra.iohk.io/build/2006688/download/1/delegation_design_spec.pdf) (there is not a dedicated section to withdrawals, simply search for 'withdrawal').
|
||||
|
||||
#### Metadata
|
||||
#### Auxiliary data
|
||||
|
||||
Each transaction may contain metadata. Metadata format can be found [here](https://github.com/input-output-hk/cardano-ledger-specs/blob/097890495cbb0e8b62106bcd090a5721c3f4b36f/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L212). It's basically a CBOR serialized map and can contain numbers, bytes, strings or nested maps/lists.
|
||||
_Auxiliary data have replaced metadata in the Cardano Mary era_
|
||||
|
||||
Due to memory limitations we currently enforce a maximum size of 500 bytes for metadata.
|
||||
Each transaction may contain auxiliary data. Auxiliary data format can be found [here](https://github.com/input-output-hk/cardano-ledger-specs/blob/57c27d168b8d4288534ce74e77c1df33870e756a/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L212).
|
||||
|
||||
Auxiliary data can be sent to Trezor as a blob or as an object with parameters. The blob will be included in the transaction as is.
|
||||
|
||||
The only object currently supported is Catalyst voting key registration. To be in compliance with the CDDL and other Cardano tools, Catalyst voting key registration object is being wrapped in a tuple and an empty tuple follows it. The empty tuple represents `auxiliary_scripts` which are not yet supported on Trezor and are thus always empty. Byron addresses are not supported as Catalyst reward addresses.
|
||||
|
||||
[Catalyst Registration Transaction Metadata Format](https://github.com/cardano-foundation/CIPs/blob/749f22eccd78e05fcdc4552c49639bb3bbd0a458/CIP-0015/CIP-0015.md)
|
||||
|
||||
#### Transaction Explorer
|
||||
|
||||
@ -170,7 +172,7 @@ Cardano uses [CBOR](https://www.rfc-editor.org/info/rfc7049) as a serialization
|
||||
|
||||
#### Raw transaction example
|
||||
```
|
||||
83a700818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018282583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff821904d2a1581c95a292ffee938be03e9bae5657982a74e9014eb4960108c9e23a5b39a14874652474436f696e1910e18258390180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b427719115c02182a030a048182008200581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b427705a1581de1122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b42771903e80814a10082825820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e5840c6e85c7eec254f765ddc119b1f40ef50944dcb1882822c3d61641785bbc312d1049ed0a92ded74745986f5d464d0d0caafc9f0c66285a056309d3d39cf19b20e8258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c158401feabb9e56bca7d3cb75f0942d1ebaec92f167193c70fb9b416e9ae3d3e0f368f49fde3f4a862eb6a02f9a27834d0b7c1f6dd689616809432c99f3ab7249ad0ef6
|
||||
83a800818258203b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b700018282583901eb0baa5e570cffbe2934db29df0b6a3d7c0430ee65d4c3a7ab2fefb91bc428e4720702ebd5dab4fb175324c192dc9bb76cc5da956e3c8dff821904d2a1581c95a292ffee938be03e9bae5657982a74e9014eb4960108c9e23a5b39a14874652474436f696e1910e18258390180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b427719115c02182a030a048182008200581c122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b427705a1581de1122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b42771903e80758205410cfffe33d9da8b3ab789068f12e0464fad13f586f92d8c8c2fcac68c1a9c00814a100828258205d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c158406478ca1a1d1bab66688a19e983fbff9e7f9120f0035d9663ae8eb917cf01ce1c4b47834d06f41cf0c7c5218be0224ab1d88de97b20572d6fdc3cb1e40b662300825820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e584023ddaf5c9f5c9a22fd646f1c1c5a3f1a84c3a43d90d2211e919450c35df53bcded772e0badb33a898c03f3c227765bc21e678d85b716e0055ca9d89274d6660e82a219ef64a4015820cdea4080a301fdfda7a6b9c8b5283273f51af5f34ae587e05c5492f90a2ae54f025820bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e0358390180f9e2c88e6c817008f3a812ed889b4a4da8e0bd103f86e7335422aa122a946b9ad3d2ddf029d3a828f0468aece76895f15c9efbd69b4277041a015d76c419ef65a101584017ed3f6a8ef2d0f1212e3aa49766fcf22b087c6cfa5cf247ecbc6c27069d7c17f189f2ca0acf6f1d54e1999e12fc37ac695c693982df96430896b54e0bcff10780
|
||||
```
|
||||
|
||||
#### The same transactions with structure description
|
||||
@ -220,6 +222,9 @@ Cardano uses [CBOR](https://www.rfc-editor.org/info/rfc7049) as a serialization
|
||||
# uint(5), map(1), bytes(29), uint(7204944340)
|
||||
5: {h'E11...': 1000},
|
||||
|
||||
# auxiliary data hash
|
||||
7: h'541...',
|
||||
|
||||
# validity_interval_start
|
||||
# uint(8), uint(20)
|
||||
8: 20
|
||||
@ -231,14 +236,30 @@ Cardano uses [CBOR](https://www.rfc-editor.org/info/rfc7049) as a serialization
|
||||
# uint(0), array(2)
|
||||
0: [
|
||||
# array(2), bytes(32), bytes(64)
|
||||
[h'BC6...', h'C6E...'],
|
||||
[h'5D0...', h'647...'],
|
||||
# array(2), bytes(32), bytes(64)
|
||||
[h'5D0...', h'1FE...']
|
||||
[h'BC6...', h'23D...']
|
||||
]
|
||||
},
|
||||
|
||||
# metadata
|
||||
# primitive(22)
|
||||
null
|
||||
# auxiliary data - catalyst voting key registration
|
||||
# array(2)
|
||||
[
|
||||
# map(2)
|
||||
{
|
||||
# uint(61284), map(4), uint(1), bytes(32), uint(2), bytes(32), uint(3), bytes(57), uint(4), uint(22902468)
|
||||
61284: {
|
||||
1: h'CDE...',
|
||||
2: h'BC6...',
|
||||
3: h'018...',
|
||||
4: 22902468
|
||||
},
|
||||
# uint(61285), map(1), bytes(64)
|
||||
61285: {
|
||||
1:h'17E...'
|
||||
}
|
||||
},
|
||||
# array(0)
|
||||
[]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
241
core/src/apps/cardano/auxiliary_data.py
Normal file
241
core/src/apps/cardano/auxiliary_data.py
Normal file
@ -0,0 +1,241 @@
|
||||
from trezor.crypto import hashlib
|
||||
from trezor.crypto.curve import ed25519
|
||||
from trezor.messages import CardanoAddressType
|
||||
|
||||
from apps.common import cbor
|
||||
|
||||
from ..common.seed import remove_ed25519_prefix
|
||||
from .address import derive_address_bytes, derive_human_readable_address
|
||||
from .helpers import INVALID_AUXILIARY_DATA, bech32
|
||||
from .helpers.bech32 import HRP_JORMUN_PUBLIC_KEY
|
||||
from .helpers.paths import SCHEMA_STAKING_ANY_ACCOUNT
|
||||
from .layout import confirm_catalyst_registration, show_auxiliary_data_hash
|
||||
|
||||
if False:
|
||||
from typing import Union
|
||||
from trezor import wire
|
||||
|
||||
from trezor.messages.CardanoCatalystRegistrationParametersType import (
|
||||
CardanoCatalystRegistrationParametersType,
|
||||
)
|
||||
from trezor.messages.CardanoTxAuxiliaryDataType import CardanoTxAuxiliaryDataType
|
||||
|
||||
CatalystRegistrationPayload = dict[int, Union[bytes, int]]
|
||||
CatalystRegistrationSignature = dict[int, bytes]
|
||||
CatalystRegistration = dict[
|
||||
int, Union[CatalystRegistrationPayload, CatalystRegistrationSignature]
|
||||
]
|
||||
|
||||
from . import seed
|
||||
|
||||
AUXILIARY_DATA_HASH_SIZE = 32
|
||||
CATALYST_VOTING_PUBLIC_KEY_LENGTH = 32
|
||||
CATALYST_REGISTRATION_HASH_SIZE = 32
|
||||
|
||||
METADATA_KEY_CATALYST_REGISTRATION = 61284
|
||||
METADATA_KEY_CATALYST_REGISTRATION_SIGNATURE = 61285
|
||||
|
||||
|
||||
def validate_auxiliary_data(
|
||||
keychain: seed.Keychain,
|
||||
auxiliary_data: CardanoTxAuxiliaryDataType | None,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> None:
|
||||
if not auxiliary_data:
|
||||
return
|
||||
|
||||
fields_provided = 0
|
||||
if auxiliary_data.blob:
|
||||
fields_provided += 1
|
||||
_validate_auxiliary_data_blob(auxiliary_data.blob)
|
||||
if auxiliary_data.catalyst_registration_parameters:
|
||||
fields_provided += 1
|
||||
_validate_catalyst_registration_parameters(
|
||||
keychain,
|
||||
auxiliary_data.catalyst_registration_parameters,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
)
|
||||
|
||||
if fields_provided != 1:
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
|
||||
def _validate_auxiliary_data_blob(auxiliary_data_blob: bytes) -> None:
|
||||
try:
|
||||
# validation to prevent CBOR injection and invalid CBOR
|
||||
# we don't validate data format, just that it's a valid CBOR
|
||||
cbor.decode(auxiliary_data_blob)
|
||||
except Exception:
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
|
||||
def _validate_catalyst_registration_parameters(
|
||||
keychain: seed.Keychain,
|
||||
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> None:
|
||||
if (
|
||||
len(catalyst_registration_parameters.voting_public_key)
|
||||
!= CATALYST_VOTING_PUBLIC_KEY_LENGTH
|
||||
):
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
if not SCHEMA_STAKING_ANY_ACCOUNT.match(
|
||||
catalyst_registration_parameters.staking_path
|
||||
):
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
address_parameters = catalyst_registration_parameters.reward_address_parameters
|
||||
if address_parameters.address_type == CardanoAddressType.BYRON:
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
# try to derive the address to validate it
|
||||
derive_address_bytes(keychain, address_parameters, protocol_magic, network_id)
|
||||
|
||||
|
||||
async def show_auxiliary_data(
|
||||
ctx: wire.Context,
|
||||
keychain: seed.Keychain,
|
||||
auxiliary_data: CardanoTxAuxiliaryDataType | None,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> None:
|
||||
if not auxiliary_data:
|
||||
return
|
||||
|
||||
if auxiliary_data.catalyst_registration_parameters:
|
||||
await _show_catalyst_registration(
|
||||
ctx,
|
||||
keychain,
|
||||
auxiliary_data.catalyst_registration_parameters,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
)
|
||||
|
||||
auxiliary_data_bytes = get_auxiliary_data_cbor(
|
||||
keychain, auxiliary_data, protocol_magic, network_id
|
||||
)
|
||||
|
||||
auxiliary_data_hash = hash_auxiliary_data(bytes(auxiliary_data_bytes))
|
||||
await show_auxiliary_data_hash(ctx, auxiliary_data_hash)
|
||||
|
||||
|
||||
async def _show_catalyst_registration(
|
||||
ctx: wire.Context,
|
||||
keychain: seed.Keychain,
|
||||
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> None:
|
||||
public_key = catalyst_registration_parameters.voting_public_key
|
||||
encoded_public_key = bech32.encode(HRP_JORMUN_PUBLIC_KEY, public_key)
|
||||
staking_path = catalyst_registration_parameters.staking_path
|
||||
reward_address = derive_human_readable_address(
|
||||
keychain,
|
||||
catalyst_registration_parameters.reward_address_parameters,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
)
|
||||
nonce = catalyst_registration_parameters.nonce
|
||||
|
||||
await confirm_catalyst_registration(
|
||||
ctx, encoded_public_key, staking_path, reward_address, nonce
|
||||
)
|
||||
|
||||
|
||||
def get_auxiliary_data_cbor(
|
||||
keychain: seed.Keychain,
|
||||
auxiliary_data: CardanoTxAuxiliaryDataType,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> bytes:
|
||||
if auxiliary_data.blob:
|
||||
return auxiliary_data.blob
|
||||
elif auxiliary_data.catalyst_registration_parameters:
|
||||
cborized_catalyst_registration = _cborize_catalyst_registration(
|
||||
keychain,
|
||||
auxiliary_data.catalyst_registration_parameters,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
)
|
||||
return cbor.encode(_wrap_metadata(cborized_catalyst_registration))
|
||||
else:
|
||||
raise INVALID_AUXILIARY_DATA
|
||||
|
||||
|
||||
def _cborize_catalyst_registration(
|
||||
keychain: seed.Keychain,
|
||||
catalyst_registration_parameters: CardanoCatalystRegistrationParametersType,
|
||||
protocol_magic: int,
|
||||
network_id: int,
|
||||
) -> CatalystRegistration:
|
||||
staking_node = keychain.derive(catalyst_registration_parameters.staking_path)
|
||||
staking_key = remove_ed25519_prefix(staking_node.public_key())
|
||||
|
||||
catalyst_registration_payload: CatalystRegistrationPayload = {
|
||||
1: catalyst_registration_parameters.voting_public_key,
|
||||
2: staking_key,
|
||||
3: derive_address_bytes(
|
||||
keychain,
|
||||
catalyst_registration_parameters.reward_address_parameters,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
),
|
||||
4: catalyst_registration_parameters.nonce,
|
||||
}
|
||||
|
||||
catalyst_registration_payload_signature = (
|
||||
_create_catalyst_registration_payload_signature(
|
||||
keychain,
|
||||
catalyst_registration_payload,
|
||||
catalyst_registration_parameters.staking_path,
|
||||
)
|
||||
)
|
||||
catalyst_registration_signature = {1: catalyst_registration_payload_signature}
|
||||
|
||||
return {
|
||||
METADATA_KEY_CATALYST_REGISTRATION: catalyst_registration_payload,
|
||||
METADATA_KEY_CATALYST_REGISTRATION_SIGNATURE: catalyst_registration_signature,
|
||||
}
|
||||
|
||||
|
||||
def _create_catalyst_registration_payload_signature(
|
||||
keychain: seed.Keychain,
|
||||
catalyst_registration_payload: CatalystRegistrationPayload,
|
||||
path: list[int],
|
||||
) -> bytes:
|
||||
node = keychain.derive(path)
|
||||
|
||||
encoded_catalyst_registration = cbor.encode(
|
||||
{METADATA_KEY_CATALYST_REGISTRATION: catalyst_registration_payload}
|
||||
)
|
||||
|
||||
catalyst_registration_hash = hashlib.blake2b(
|
||||
data=encoded_catalyst_registration,
|
||||
outlen=CATALYST_REGISTRATION_HASH_SIZE,
|
||||
).digest()
|
||||
|
||||
return ed25519.sign_ext(
|
||||
node.private_key(), node.private_key_ext(), catalyst_registration_hash
|
||||
)
|
||||
|
||||
|
||||
def _wrap_metadata(metadata: dict) -> tuple[dict, tuple]:
|
||||
"""
|
||||
A new structure of metadata is used after Cardano Mary era. The metadata
|
||||
is wrapped in a tuple and auxiliary_scripts may follow it. Cardano
|
||||
tooling uses this new format of "wrapped" metadata even if no
|
||||
auxiliary_scripts are included. So we do the same here.
|
||||
|
||||
https://github.com/input-output-hk/cardano-ledger-specs/blob/f7deb22be14d31b535f56edc3ca542c548244c67/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L212
|
||||
"""
|
||||
return metadata, ()
|
||||
|
||||
|
||||
def hash_auxiliary_data(auxiliary_data: bytes) -> bytes:
|
||||
return hashlib.blake2b(
|
||||
data=auxiliary_data, outlen=AUXILIARY_DATA_HASH_SIZE
|
||||
).digest()
|
@ -5,7 +5,7 @@ NETWORK_MISMATCH = wire.ProcessError("Output address network mismatch!")
|
||||
INVALID_CERTIFICATE = wire.ProcessError("Invalid certificate")
|
||||
INVALID_WITHDRAWAL = wire.ProcessError("Invalid withdrawal")
|
||||
INVALID_TOKEN_BUNDLE_OUTPUT = wire.ProcessError("Invalid token bundle in output")
|
||||
INVALID_METADATA = wire.ProcessError("Invalid metadata")
|
||||
INVALID_AUXILIARY_DATA = wire.ProcessError("Invalid auxiliary data")
|
||||
INVALID_STAKE_POOL_REGISTRATION_TX_STRUCTURE = wire.ProcessError(
|
||||
"Stakepool registration transaction cannot contain other certificates nor withdrawals"
|
||||
)
|
||||
|
@ -2,10 +2,13 @@ from trezor.crypto import bech32
|
||||
|
||||
HRP_SEPARATOR = "1"
|
||||
|
||||
# CIP-0005 prefixes - https://github.com/cardano-foundation/CIPs/blob/master/CIP-0005/CIP-0005.md
|
||||
HRP_ADDRESS = "addr"
|
||||
HRP_TESTNET_ADDRESS = "addr_test"
|
||||
HRP_REWARD_ADDRESS = "stake"
|
||||
HRP_TESTNET_REWARD_ADDRESS = "stake_test"
|
||||
# Jormungandr public key prefix - https://github.com/input-output-hk/voting-tools-lib/blob/18dae637e80db72444476606ab264b973bcf1a9d/src/Cardano/API/Extended.hs#L226
|
||||
HRP_JORMUN_PUBLIC_KEY = "ed25519_pk"
|
||||
|
||||
|
||||
def encode(hrp: str, data: bytes) -> str:
|
||||
|
@ -215,7 +215,6 @@ async def confirm_transaction(
|
||||
protocol_magic: int,
|
||||
ttl: int | None,
|
||||
validity_interval_start: int | None,
|
||||
has_metadata: bool,
|
||||
is_network_id_verifiable: bool,
|
||||
) -> None:
|
||||
pages: list[ui.Component] = []
|
||||
@ -235,12 +234,6 @@ async def confirm_transaction(
|
||||
page2.normal("TTL: %s" % format_optional_int(ttl))
|
||||
pages.append(page2)
|
||||
|
||||
if has_metadata:
|
||||
page3 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page3.normal("Transaction contains")
|
||||
page3.normal("metadata")
|
||||
pages.append(page3)
|
||||
|
||||
await require_hold_to_confirm(ctx, Paginated(pages))
|
||||
|
||||
|
||||
@ -393,6 +386,69 @@ async def confirm_withdrawal(
|
||||
await require_confirm(ctx, page1)
|
||||
|
||||
|
||||
async def confirm_catalyst_registration(
|
||||
ctx: wire.Context,
|
||||
public_key: str,
|
||||
staking_path: list[int],
|
||||
reward_address: str,
|
||||
nonce: int,
|
||||
) -> None:
|
||||
pages: list[ui.Component] = []
|
||||
|
||||
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page1.bold("Catalyst voting key")
|
||||
page1.bold("registration")
|
||||
pages.append(page1)
|
||||
|
||||
page2 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page2.normal("Voting public key:")
|
||||
page2.bold(*chunks(public_key, 17))
|
||||
pages.append(page2)
|
||||
|
||||
page3 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page3.normal("Staking key for")
|
||||
page3.normal("account %s:" % format_account_number(staking_path))
|
||||
page3.bold(address_n_to_str(staking_path))
|
||||
pages.append(page3)
|
||||
|
||||
page4 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page4.normal("Rewards go to:")
|
||||
|
||||
lines_per_page = 5
|
||||
lines_used_on_first_page = 1
|
||||
address_lines = list(chunks(reward_address, 17))
|
||||
|
||||
for address_line in address_lines[: lines_per_page - lines_used_on_first_page]:
|
||||
page4.bold(address_line)
|
||||
pages.append(page4)
|
||||
|
||||
pages.extend(
|
||||
_paginate_lines(
|
||||
address_lines,
|
||||
lines_per_page - lines_used_on_first_page,
|
||||
"Confirm transaction",
|
||||
ui.ICON_SEND,
|
||||
5,
|
||||
)
|
||||
)
|
||||
|
||||
last_page = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
last_page.normal("Nonce: %s" % nonce)
|
||||
pages.append(last_page)
|
||||
|
||||
await require_confirm(ctx, Paginated(pages))
|
||||
|
||||
|
||||
async def show_auxiliary_data_hash(
|
||||
ctx: wire.Context, auxiliary_data_hash: bytes
|
||||
) -> None:
|
||||
page1 = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
page1.normal("Auxiliary data hash:")
|
||||
page1.bold(hexlify(auxiliary_data_hash).decode())
|
||||
|
||||
await require_confirm(ctx, page1)
|
||||
|
||||
|
||||
async def show_address(
|
||||
ctx: wire.Context,
|
||||
address: str,
|
||||
|
@ -18,10 +18,15 @@ from .address import (
|
||||
get_address_bytes_unsafe,
|
||||
validate_output_address,
|
||||
)
|
||||
from .auxiliary_data import (
|
||||
get_auxiliary_data_cbor,
|
||||
hash_auxiliary_data,
|
||||
show_auxiliary_data,
|
||||
validate_auxiliary_data,
|
||||
)
|
||||
from .byron_address import get_address_attributes
|
||||
from .certificates import cborize_certificate, validate_certificate
|
||||
from .helpers import (
|
||||
INVALID_METADATA,
|
||||
INVALID_STAKE_POOL_REGISTRATION_TX_STRUCTURE,
|
||||
INVALID_STAKEPOOL_REGISTRATION_TX_INPUTS,
|
||||
INVALID_TOKEN_BUNDLE_OUTPUT,
|
||||
@ -83,9 +88,7 @@ if False:
|
||||
CborizedSignedTx = tuple[dict, dict, Optional[cbor.Raw]]
|
||||
TxHash = bytes
|
||||
|
||||
METADATA_HASH_SIZE = 32
|
||||
MINTING_POLICY_ID_LENGTH = 28
|
||||
MAX_METADATA_LENGTH = 500
|
||||
MAX_ASSET_NAME_LENGTH = 32
|
||||
MAX_TX_CHUNK_SIZE = 256
|
||||
|
||||
@ -132,7 +135,9 @@ async def _sign_ordinary_tx(
|
||||
_validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id)
|
||||
_validate_certificates(msg.certificates, msg.protocol_magic, msg.network_id)
|
||||
_validate_withdrawals(msg.withdrawals)
|
||||
_validate_metadata(msg.metadata)
|
||||
validate_auxiliary_data(
|
||||
keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
|
||||
# display the transaction in UI
|
||||
await _show_standard_tx(ctx, keychain, msg)
|
||||
@ -160,7 +165,9 @@ async def _sign_stake_pool_registration_tx(
|
||||
_ensure_no_signing_inputs(msg.inputs)
|
||||
_validate_outputs(keychain, msg.outputs, msg.protocol_magic, msg.network_id)
|
||||
_validate_certificates(msg.certificates, msg.protocol_magic, msg.network_id)
|
||||
_validate_metadata(msg.metadata)
|
||||
validate_auxiliary_data(
|
||||
keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
|
||||
await _show_stake_pool_registration_tx(ctx, keychain, msg)
|
||||
|
||||
@ -274,23 +281,6 @@ def _validate_withdrawals(withdrawals: list[CardanoTxWithdrawalType]) -> None:
|
||||
raise INVALID_WITHDRAWAL
|
||||
|
||||
|
||||
def _validate_metadata(metadata: bytes | None) -> None:
|
||||
if not metadata:
|
||||
return
|
||||
|
||||
if len(metadata) > MAX_METADATA_LENGTH:
|
||||
raise INVALID_METADATA
|
||||
|
||||
try:
|
||||
# this also raises an error if there's some data remaining
|
||||
decoded = cbor.decode(metadata)
|
||||
except Exception:
|
||||
raise INVALID_METADATA
|
||||
|
||||
if not isinstance(decoded, dict):
|
||||
raise INVALID_METADATA
|
||||
|
||||
|
||||
def _cborize_signed_tx(
|
||||
keychain: seed.Keychain, msg: CardanoSignTx
|
||||
) -> tuple[CborizedSignedTx, TxHash]:
|
||||
@ -306,11 +296,14 @@ def _cborize_signed_tx(
|
||||
msg.protocol_magic,
|
||||
)
|
||||
|
||||
metadata = None
|
||||
if msg.metadata:
|
||||
metadata = cbor.Raw(bytes(msg.metadata))
|
||||
auxiliary_data = None
|
||||
if msg.auxiliary_data:
|
||||
auxiliary_data_cbor = get_auxiliary_data_cbor(
|
||||
keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
auxiliary_data = cbor.Raw(auxiliary_data_cbor)
|
||||
|
||||
return (tx_body, witnesses, metadata), tx_hash
|
||||
return (tx_body, witnesses, auxiliary_data), tx_hash
|
||||
|
||||
|
||||
def _cborize_tx_body(keychain: seed.Keychain, msg: CardanoSignTx) -> dict:
|
||||
@ -340,8 +333,11 @@ def _cborize_tx_body(keychain: seed.Keychain, msg: CardanoSignTx) -> dict:
|
||||
|
||||
# tx_body[6] is for protocol updates, which we don't support
|
||||
|
||||
if msg.metadata:
|
||||
tx_body[7] = _hash_metadata(bytes(msg.metadata))
|
||||
if msg.auxiliary_data:
|
||||
auxiliary_data_cbor = get_auxiliary_data_cbor(
|
||||
keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
tx_body[7] = hash_auxiliary_data(bytes(auxiliary_data_cbor))
|
||||
|
||||
if msg.validity_interval_start:
|
||||
tx_body[8] = msg.validity_interval_start
|
||||
@ -432,10 +428,6 @@ def _cborize_withdrawals(
|
||||
return result
|
||||
|
||||
|
||||
def _hash_metadata(metadata: bytes) -> bytes:
|
||||
return hashlib.blake2b(data=metadata, outlen=METADATA_HASH_SIZE).digest()
|
||||
|
||||
|
||||
def _hash_tx_body(tx_body: dict) -> bytes:
|
||||
tx_body_cbor_chunks = cbor.encode_streamed(tx_body)
|
||||
|
||||
@ -573,7 +565,10 @@ async def _show_standard_tx(
|
||||
for withdrawal in msg.withdrawals:
|
||||
await confirm_withdrawal(ctx, withdrawal)
|
||||
|
||||
has_metadata = bool(msg.metadata)
|
||||
await show_auxiliary_data(
|
||||
ctx, keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
|
||||
await confirm_transaction(
|
||||
ctx=ctx,
|
||||
amount=total_amount,
|
||||
@ -581,7 +576,6 @@ async def _show_standard_tx(
|
||||
protocol_magic=msg.protocol_magic,
|
||||
ttl=msg.ttl,
|
||||
validity_interval_start=msg.validity_interval_start,
|
||||
has_metadata=has_metadata,
|
||||
is_network_id_verifiable=is_network_id_verifiable,
|
||||
)
|
||||
|
||||
@ -616,6 +610,9 @@ async def _show_stake_pool_registration_tx(
|
||||
await confirm_transaction_network_ttl(
|
||||
ctx, msg.protocol_magic, msg.ttl, msg.validity_interval_start
|
||||
)
|
||||
await show_auxiliary_data(
|
||||
ctx, keychain, msg.auxiliary_data, msg.protocol_magic, msg.network_id
|
||||
)
|
||||
await confirm_stake_pool_registration_final(ctx)
|
||||
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
# Automatically generated by pb2py
|
||||
# fmt: off
|
||||
import protobuf as p
|
||||
|
||||
from .CardanoAddressParametersType import CardanoAddressParametersType
|
||||
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import Dict, List, Optional # noqa: F401
|
||||
from typing_extensions import Literal # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class CardanoCatalystRegistrationParametersType(p.MessageType):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
voting_public_key: bytes,
|
||||
reward_address_parameters: CardanoAddressParametersType,
|
||||
nonce: int,
|
||||
staking_path: Optional[List[int]] = None,
|
||||
) -> None:
|
||||
self.staking_path = staking_path if staking_path is not None else []
|
||||
self.voting_public_key = voting_public_key
|
||||
self.reward_address_parameters = reward_address_parameters
|
||||
self.nonce = nonce
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
return {
|
||||
1: ('voting_public_key', p.BytesType, p.FLAG_REQUIRED),
|
||||
2: ('staking_path', p.UVarintType, p.FLAG_REPEATED),
|
||||
3: ('reward_address_parameters', CardanoAddressParametersType, p.FLAG_REQUIRED),
|
||||
4: ('nonce', p.UVarintType, p.FLAG_REQUIRED),
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
# fmt: off
|
||||
import protobuf as p
|
||||
|
||||
from .CardanoTxAuxiliaryDataType import CardanoTxAuxiliaryDataType
|
||||
from .CardanoTxCertificateType import CardanoTxCertificateType
|
||||
from .CardanoTxInputType import CardanoTxInputType
|
||||
from .CardanoTxOutputType import CardanoTxOutputType
|
||||
@ -29,8 +30,8 @@ class CardanoSignTx(p.MessageType):
|
||||
certificates: Optional[List[CardanoTxCertificateType]] = None,
|
||||
withdrawals: Optional[List[CardanoTxWithdrawalType]] = None,
|
||||
ttl: Optional[int] = None,
|
||||
metadata: Optional[bytes] = None,
|
||||
validity_interval_start: Optional[int] = None,
|
||||
auxiliary_data: Optional[CardanoTxAuxiliaryDataType] = None,
|
||||
) -> None:
|
||||
self.inputs = inputs if inputs is not None else []
|
||||
self.outputs = outputs if outputs is not None else []
|
||||
@ -40,8 +41,8 @@ class CardanoSignTx(p.MessageType):
|
||||
self.fee = fee
|
||||
self.network_id = network_id
|
||||
self.ttl = ttl
|
||||
self.metadata = metadata
|
||||
self.validity_interval_start = validity_interval_start
|
||||
self.auxiliary_data = auxiliary_data
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
@ -54,6 +55,6 @@ class CardanoSignTx(p.MessageType):
|
||||
8: ('network_id', p.UVarintType, p.FLAG_REQUIRED),
|
||||
9: ('certificates', CardanoTxCertificateType, p.FLAG_REPEATED),
|
||||
10: ('withdrawals', CardanoTxWithdrawalType, p.FLAG_REPEATED),
|
||||
11: ('metadata', p.BytesType, None),
|
||||
12: ('validity_interval_start', p.UVarintType, None),
|
||||
13: ('auxiliary_data', CardanoTxAuxiliaryDataType, None),
|
||||
}
|
||||
|
@ -2,13 +2,14 @@
|
||||
# fmt: off
|
||||
import protobuf as p
|
||||
|
||||
from .CardanoTxMetadataType import CardanoTxMetadataType
|
||||
from .CardanoCatalystRegistrationParametersType import (
|
||||
CardanoCatalystRegistrationParametersType,
|
||||
)
|
||||
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import Dict, List, Optional # noqa: F401
|
||||
from typing_extensions import Literal # noqa: F401
|
||||
EnumTypeCardanoAuxiliaryDataType = Literal[0, 1]
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@ -18,18 +19,15 @@ class CardanoTxAuxiliaryDataType(p.MessageType):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: EnumTypeCardanoAuxiliaryDataType,
|
||||
blob: Optional[bytes] = None,
|
||||
metadata: Optional[CardanoTxMetadataType] = None,
|
||||
catalyst_registration_parameters: Optional[CardanoCatalystRegistrationParametersType] = None,
|
||||
) -> None:
|
||||
self.type = type
|
||||
self.blob = blob
|
||||
self.metadata = metadata
|
||||
self.catalyst_registration_parameters = catalyst_registration_parameters
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
return {
|
||||
1: ('type', p.EnumType("CardanoAuxiliaryDataType", (0, 1,)), p.FLAG_REQUIRED),
|
||||
2: ('blob', p.BytesType, None),
|
||||
3: ('metadata', CardanoTxMetadataType, None),
|
||||
1: ('blob', p.BytesType, None),
|
||||
2: ('catalyst_registration_parameters', CardanoCatalystRegistrationParametersType, None),
|
||||
}
|
||||
|
@ -38,6 +38,12 @@ REQUIRED_FIELDS_POOL_PARAMETERS = (
|
||||
REQUIRED_FIELDS_WITHDRAWAL = ("path", "amount")
|
||||
REQUIRED_FIELDS_TOKEN_GROUP = ("policy_id", "tokens")
|
||||
REQUIRED_FIELDS_TOKEN = ("asset_name_bytes", "amount")
|
||||
REQUIRED_FIELDS_CATALYST_REGISTRATION = (
|
||||
"voting_public_key",
|
||||
"staking_path",
|
||||
"nonce",
|
||||
"reward_address_parameters",
|
||||
)
|
||||
|
||||
INCOMPLETE_OUTPUT_ERROR_MESSAGE = "The output is missing some fields"
|
||||
|
||||
@ -118,7 +124,7 @@ def create_output(output) -> messages.CardanoTxOutputType:
|
||||
if contains_address:
|
||||
address = output["address"]
|
||||
else:
|
||||
address_parameters = _create_change_output_address_parameters(output)
|
||||
address_parameters = _create_address_parameters_internal(output)
|
||||
|
||||
if "token_bundle" in output:
|
||||
token_bundle = _create_token_bundle(output["token_bundle"])
|
||||
@ -163,24 +169,24 @@ def _create_tokens(tokens) -> List[messages.CardanoTokenType]:
|
||||
return result
|
||||
|
||||
|
||||
def _create_change_output_address_parameters(
|
||||
output,
|
||||
def _create_address_parameters_internal(
|
||||
address_parameters,
|
||||
) -> messages.CardanoAddressParametersType:
|
||||
if "path" not in output:
|
||||
if "path" not in address_parameters:
|
||||
raise ValueError(INCOMPLETE_OUTPUT_ERROR_MESSAGE)
|
||||
|
||||
staking_key_hash_bytes = None
|
||||
if "stakingKeyHash" in output:
|
||||
staking_key_hash_bytes = bytes.fromhex(output.get("stakingKeyHash"))
|
||||
if "stakingKeyHash" in address_parameters:
|
||||
staking_key_hash_bytes = bytes.fromhex(address_parameters.get("stakingKeyHash"))
|
||||
|
||||
return create_address_parameters(
|
||||
int(output["addressType"]),
|
||||
tools.parse_path(output["path"]),
|
||||
tools.parse_path(output.get("stakingPath")),
|
||||
int(address_parameters["addressType"]),
|
||||
tools.parse_path(address_parameters["path"]),
|
||||
tools.parse_path(address_parameters.get("stakingPath")),
|
||||
staking_key_hash_bytes,
|
||||
output.get("blockIndex"),
|
||||
output.get("txIndex"),
|
||||
output.get("certificateIndex"),
|
||||
address_parameters.get("blockIndex"),
|
||||
address_parameters.get("txIndex"),
|
||||
address_parameters.get("certificateIndex"),
|
||||
)
|
||||
|
||||
|
||||
@ -315,6 +321,49 @@ def create_withdrawal(withdrawal) -> messages.CardanoTxWithdrawalType:
|
||||
)
|
||||
|
||||
|
||||
def create_auxiliary_data(auxiliary_data) -> messages.CardanoTxAuxiliaryDataType:
|
||||
if auxiliary_data is None:
|
||||
return None
|
||||
|
||||
AUXILIARY_DATA_MISSING_FIELDS_ERROR = ValueError(
|
||||
"Auxiliary data is missing some fields"
|
||||
)
|
||||
|
||||
# include all provided fields so we can test validation in FW
|
||||
blob = None
|
||||
if "blob" in auxiliary_data:
|
||||
blob = bytes.fromhex(auxiliary_data["blob"])
|
||||
|
||||
catalyst_registration_parameters = None
|
||||
if "catalyst_registration_parameters" in auxiliary_data:
|
||||
catalyst_registration = auxiliary_data["catalyst_registration_parameters"]
|
||||
if not all(
|
||||
k in catalyst_registration for k in REQUIRED_FIELDS_CATALYST_REGISTRATION
|
||||
):
|
||||
raise AUXILIARY_DATA_MISSING_FIELDS_ERROR
|
||||
|
||||
catalyst_registration_parameters = (
|
||||
messages.CardanoCatalystRegistrationParametersType(
|
||||
voting_public_key=bytes.fromhex(
|
||||
catalyst_registration["voting_public_key"]
|
||||
),
|
||||
staking_path=tools.parse_path(catalyst_registration["staking_path"]),
|
||||
nonce=catalyst_registration["nonce"],
|
||||
reward_address_parameters=_create_address_parameters_internal(
|
||||
catalyst_registration["reward_address_parameters"]
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if blob is None and catalyst_registration_parameters is None:
|
||||
raise AUXILIARY_DATA_MISSING_FIELDS_ERROR
|
||||
|
||||
return messages.CardanoTxAuxiliaryDataType(
|
||||
blob=blob,
|
||||
catalyst_registration_parameters=catalyst_registration_parameters,
|
||||
)
|
||||
|
||||
|
||||
# ====== Client functions ====== #
|
||||
|
||||
|
||||
@ -351,9 +400,9 @@ def sign_tx(
|
||||
validity_interval_start: Optional[int],
|
||||
certificates: List[messages.CardanoTxCertificateType] = (),
|
||||
withdrawals: List[messages.CardanoTxWithdrawalType] = (),
|
||||
metadata: bytes = None,
|
||||
protocol_magic: int = PROTOCOL_MAGICS["mainnet"],
|
||||
network_id: int = NETWORK_IDS["mainnet"],
|
||||
auxiliary_data: messages.CardanoTxAuxiliaryDataType = None,
|
||||
) -> messages.CardanoSignedTx:
|
||||
response = client.call(
|
||||
messages.CardanoSignTx(
|
||||
@ -364,9 +413,9 @@ def sign_tx(
|
||||
validity_interval_start=validity_interval_start,
|
||||
certificates=certificates,
|
||||
withdrawals=withdrawals,
|
||||
metadata=metadata,
|
||||
protocol_magic=protocol_magic,
|
||||
network_id=network_id,
|
||||
auxiliary_data=auxiliary_data,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -67,9 +67,7 @@ def sign_tx(client, file, protocol_magic, network_id, testnet):
|
||||
cardano.create_withdrawal(withdrawal)
|
||||
for withdrawal in transaction.get("withdrawals", ())
|
||||
]
|
||||
metadata = None
|
||||
if "metadata" in transaction:
|
||||
metadata = bytes.fromhex(transaction["metadata"])
|
||||
auxiliary_data = cardano.create_auxiliary_data(transaction.get("auxiliary_data"))
|
||||
|
||||
signed_transaction = cardano.sign_tx(
|
||||
client,
|
||||
@ -80,9 +78,9 @@ def sign_tx(client, file, protocol_magic, network_id, testnet):
|
||||
validity_interval_start,
|
||||
certificates,
|
||||
withdrawals,
|
||||
metadata,
|
||||
protocol_magic,
|
||||
network_id,
|
||||
auxiliary_data,
|
||||
)
|
||||
|
||||
return {
|
||||
|
@ -0,0 +1,37 @@
|
||||
# Automatically generated by pb2py
|
||||
# fmt: off
|
||||
from .. import protobuf as p
|
||||
|
||||
from .CardanoAddressParametersType import CardanoAddressParametersType
|
||||
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import Dict, List, Optional # noqa: F401
|
||||
from typing_extensions import Literal # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class CardanoCatalystRegistrationParametersType(p.MessageType):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
voting_public_key: bytes,
|
||||
reward_address_parameters: CardanoAddressParametersType,
|
||||
nonce: int,
|
||||
staking_path: Optional[List[int]] = None,
|
||||
) -> None:
|
||||
self.staking_path = staking_path if staking_path is not None else []
|
||||
self.voting_public_key = voting_public_key
|
||||
self.reward_address_parameters = reward_address_parameters
|
||||
self.nonce = nonce
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
return {
|
||||
1: ('voting_public_key', p.BytesType, p.FLAG_REQUIRED),
|
||||
2: ('staking_path', p.UVarintType, p.FLAG_REPEATED),
|
||||
3: ('reward_address_parameters', CardanoAddressParametersType, p.FLAG_REQUIRED),
|
||||
4: ('nonce', p.UVarintType, p.FLAG_REQUIRED),
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
# fmt: off
|
||||
from .. import protobuf as p
|
||||
|
||||
from .CardanoTxAuxiliaryDataType import CardanoTxAuxiliaryDataType
|
||||
from .CardanoTxCertificateType import CardanoTxCertificateType
|
||||
from .CardanoTxInputType import CardanoTxInputType
|
||||
from .CardanoTxOutputType import CardanoTxOutputType
|
||||
@ -29,8 +30,8 @@ class CardanoSignTx(p.MessageType):
|
||||
certificates: Optional[List[CardanoTxCertificateType]] = None,
|
||||
withdrawals: Optional[List[CardanoTxWithdrawalType]] = None,
|
||||
ttl: Optional[int] = None,
|
||||
metadata: Optional[bytes] = None,
|
||||
validity_interval_start: Optional[int] = None,
|
||||
auxiliary_data: Optional[CardanoTxAuxiliaryDataType] = None,
|
||||
) -> None:
|
||||
self.inputs = inputs if inputs is not None else []
|
||||
self.outputs = outputs if outputs is not None else []
|
||||
@ -40,8 +41,8 @@ class CardanoSignTx(p.MessageType):
|
||||
self.fee = fee
|
||||
self.network_id = network_id
|
||||
self.ttl = ttl
|
||||
self.metadata = metadata
|
||||
self.validity_interval_start = validity_interval_start
|
||||
self.auxiliary_data = auxiliary_data
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
@ -54,6 +55,6 @@ class CardanoSignTx(p.MessageType):
|
||||
8: ('network_id', p.UVarintType, p.FLAG_REQUIRED),
|
||||
9: ('certificates', CardanoTxCertificateType, p.FLAG_REPEATED),
|
||||
10: ('withdrawals', CardanoTxWithdrawalType, p.FLAG_REPEATED),
|
||||
11: ('metadata', p.BytesType, None),
|
||||
12: ('validity_interval_start', p.UVarintType, None),
|
||||
13: ('auxiliary_data', CardanoTxAuxiliaryDataType, None),
|
||||
}
|
||||
|
@ -2,13 +2,12 @@
|
||||
# fmt: off
|
||||
from .. import protobuf as p
|
||||
|
||||
from .CardanoTxMetadataType import CardanoTxMetadataType
|
||||
from .CardanoCatalystRegistrationParametersType import CardanoCatalystRegistrationParametersType
|
||||
|
||||
if __debug__:
|
||||
try:
|
||||
from typing import Dict, List, Optional # noqa: F401
|
||||
from typing_extensions import Literal # noqa: F401
|
||||
EnumTypeCardanoAuxiliaryDataType = Literal[0, 1]
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@ -18,18 +17,15 @@ class CardanoTxAuxiliaryDataType(p.MessageType):
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: EnumTypeCardanoAuxiliaryDataType,
|
||||
blob: Optional[bytes] = None,
|
||||
metadata: Optional[CardanoTxMetadataType] = None,
|
||||
catalyst_registration_parameters: Optional[CardanoCatalystRegistrationParametersType] = None,
|
||||
) -> None:
|
||||
self.type = type
|
||||
self.blob = blob
|
||||
self.metadata = metadata
|
||||
self.catalyst_registration_parameters = catalyst_registration_parameters
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls) -> Dict:
|
||||
return {
|
||||
1: ('type', p.EnumType("CardanoAuxiliaryDataType", (0, 1,)), p.FLAG_REQUIRED),
|
||||
2: ('blob', p.BytesType, None),
|
||||
3: ('metadata', CardanoTxMetadataType, None),
|
||||
1: ('blob', p.BytesType, None),
|
||||
2: ('catalyst_registration_parameters', CardanoCatalystRegistrationParametersType, None),
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ from .CardanoAddress import CardanoAddress
|
||||
from .CardanoAddressParametersType import CardanoAddressParametersType
|
||||
from .CardanoAssetGroupType import CardanoAssetGroupType
|
||||
from .CardanoBlockchainPointerType import CardanoBlockchainPointerType
|
||||
from .CardanoCatalystRegistrationParametersType import CardanoCatalystRegistrationParametersType
|
||||
from .CardanoGetAddress import CardanoGetAddress
|
||||
from .CardanoGetPublicKey import CardanoGetPublicKey
|
||||
from .CardanoPoolMetadataType import CardanoPoolMetadataType
|
||||
@ -38,6 +39,7 @@ from .CardanoSignedTx import CardanoSignedTx
|
||||
from .CardanoSignedTxChunk import CardanoSignedTxChunk
|
||||
from .CardanoSignedTxChunkAck import CardanoSignedTxChunkAck
|
||||
from .CardanoTokenType import CardanoTokenType
|
||||
from .CardanoTxAuxiliaryDataType import CardanoTxAuxiliaryDataType
|
||||
from .CardanoTxCertificateType import CardanoTxCertificateType
|
||||
from .CardanoTxInputType import CardanoTxInputType
|
||||
from .CardanoTxOutputType import CardanoTxOutputType
|
||||
|
@ -38,6 +38,7 @@ def test_cardano_sign_tx(client, parameters, result):
|
||||
outputs = [cardano.create_output(o) for o in parameters["outputs"]]
|
||||
certificates = [cardano.create_certificate(c) for c in parameters["certificates"]]
|
||||
withdrawals = [cardano.create_withdrawal(w) for w in parameters["withdrawals"]]
|
||||
auxiliary_data = cardano.create_auxiliary_data(parameters["auxiliary_data"])
|
||||
|
||||
input_flow = parameters.get("input_flow", ())
|
||||
|
||||
@ -60,9 +61,9 @@ def test_cardano_sign_tx(client, parameters, result):
|
||||
validity_interval_start=parameters.get("validity_interval_start"),
|
||||
certificates=certificates,
|
||||
withdrawals=withdrawals,
|
||||
metadata=bytes.fromhex(parameters["metadata"]),
|
||||
protocol_magic=parameters["protocol_magic"],
|
||||
network_id=parameters["network_id"],
|
||||
auxiliary_data=auxiliary_data,
|
||||
)
|
||||
assert response.tx_hash.hex() == result["tx_hash"]
|
||||
assert response.serialized_tx.hex() == result["serialized_tx"]
|
||||
@ -76,6 +77,7 @@ def test_cardano_sign_tx_failed(client, parameters, result):
|
||||
outputs = [cardano.create_output(o) for o in parameters["outputs"]]
|
||||
certificates = [cardano.create_certificate(c) for c in parameters["certificates"]]
|
||||
withdrawals = [cardano.create_withdrawal(w) for w in parameters["withdrawals"]]
|
||||
auxiliary_data = cardano.create_auxiliary_data(parameters["auxiliary_data"])
|
||||
|
||||
input_flow = parameters.get("input_flow", ())
|
||||
|
||||
@ -92,9 +94,9 @@ def test_cardano_sign_tx_failed(client, parameters, result):
|
||||
validity_interval_start=parameters.get("validity_interval_start"),
|
||||
certificates=certificates,
|
||||
withdrawals=withdrawals,
|
||||
metadata=bytes.fromhex(parameters["metadata"]),
|
||||
protocol_magic=parameters["protocol_magic"],
|
||||
network_id=parameters["network_id"],
|
||||
auxiliary_data=auxiliary_data,
|
||||
)
|
||||
|
||||
|
||||
@ -104,6 +106,7 @@ def test_cardano_sign_tx_with_multiple_chunks(client, parameters, result):
|
||||
outputs = [cardano.create_output(o) for o in parameters["outputs"]]
|
||||
certificates = [cardano.create_certificate(c) for c in parameters["certificates"]]
|
||||
withdrawals = [cardano.create_withdrawal(w) for w in parameters["withdrawals"]]
|
||||
auxiliary_data = cardano.create_auxiliary_data(parameters["auxiliary_data"])
|
||||
|
||||
input_flow = parameters.get("input_flow", ())
|
||||
|
||||
@ -133,9 +136,9 @@ def test_cardano_sign_tx_with_multiple_chunks(client, parameters, result):
|
||||
validity_interval_start=parameters.get("validity_interval_start"),
|
||||
certificates=certificates,
|
||||
withdrawals=withdrawals,
|
||||
metadata=bytes.fromhex(parameters["metadata"]),
|
||||
protocol_magic=parameters["protocol_magic"],
|
||||
network_id=parameters["network_id"],
|
||||
auxiliary_data=auxiliary_data,
|
||||
)
|
||||
assert response.tx_hash.hex() == result["tx_hash"]
|
||||
assert response.serialized_tx.hex() == result["serialized_tx"]
|
||||
|
@ -9,6 +9,7 @@
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_multiasset_output]": "d0a58ab8b68fcd9f1191f309de52efb6be9157383357f5f9c0e0d116fccc08e4",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[mary_era_transaction_with_no_ttl-validity_start]": "db76676358164a3b3dab5148f09ba5515d079212366b79c44f95e2ba613abc71",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_certificate]": "f56482d4a0f2c07fe04291a7d9c29ed4aedfd31e6a80fed1563d80e3a4c4005c",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_certificate_wi-336f4a44": "6acd2406b1013917c859482bce3ae9b457f406537734398037e20784116c18f2",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_certificate_wi-d3427614": "629ccaa5b660247843b366582c1bc505831c1800e028474a784b0f8b35fc473a",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[sample_stake_pool_registration_with_zero_margin]": "802c6f1fcf232cf05ed64868d39913449918bc70fda39fcf9735f2d5db51ef3f",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[simple_transaction_with_base_address_change_o-0c37e6dc": "a9bbc7137d32d71acc1b4d4b7c19aacf7ec8b63c06fe53c16759bf81f5d0ad96",
|
||||
@ -20,9 +21,10 @@
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[stake_pool_registration_on_testnet]": "998043271c02cb725b27ba335efebf4895365d602b84df0fe04e26fa3c0bd3fa",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[testnet_transaction0]": "7178cb7c264c15ab13152a87fe14c39fbdfa8571c166ddcda6e7c65680bbc784",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[testnet_transaction1]": "fcd2bfb85ff1b0ec7a204b2d525c8adf4204afbdcc726d4485820ff36ded4b2c",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_auxiliary_data_blob]": "75934c7942a85a1adfaafb44570e102c57c3e66d45bb73cd09df269145ac0212",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_base_address_change_output_p-3c7243e1": "32458c03d03f4cfc2d83369a7b4a766a7b410452cb27682d5959a09a78d19b90",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_base_address_change_output_s-20438873": "e1dba216b8ff68de35ff87c1c430bc5170d4a9a3c09047d8f9f7e12982f93139",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_metadata]": "466a7245ae2d643bc35061321e28ff6d80cbe42faabb10ea613cfc92fee31c06",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_catalyst_registration]": "e3b4acd594c894b139a6e66b33fc9cfb81c759a4777524019d1502dc4a46f8c1",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_stake_deregistration]": "555219b1572cd91037379ebd95e2a979c5e0486148cb0c00f837277820cb4cbe",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_stake_deregistration_and_withdrawal]": "7d7915b4300974d5f45a8308da218b7e4bac938a2d033a6db2b6dccdbec5e4d8",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_stake_deregistration_with_ac-9ca046f0": "e5b8662ef9abe58a835d6d5765e413ee1dc63cc870e2c6627f9da6a93c5ead9f",
|
||||
@ -30,6 +32,8 @@
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_stake_registration_certifica-e7bd462a": "5a983375390be55cb4fca80a58546cc333148101a02ccfc8c80e1a64b9f47b57",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx[transaction_with_stake_registration_certificate]": "367088bed7ede0e6f317d3662f990b4300f93fcff2ccd6309c6c4f50fd8da6f9",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[all_tx_inputs_must_be_external_(without_path)]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[auxiliary_data_blob_has_leftover_data]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[auxiliary_data_blob_is_incomplete]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[certificate_has_invalid_pool_size]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[certificate_has_non_staking_path]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[change_output_path_larger_than_100]": "ffae5d78193ba3e989f025b67c544ce77ac4fde9d547e4588a9fe6f90354a4c2",
|
||||
@ -41,10 +45,6 @@
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[mainnet_protocol_magic_with_testnet_network_id]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[mainnet_transaction_with_testnet_output]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[margin_higher_than_1]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[metadata_has_leftover_data]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[metadata_is_a_list]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[metadata_is_incomplete]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[metadata_too_large]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[missing_owner_with_path]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[output_address_has_invalid_crc]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[output_address_is_a_valid_cbor_but_inv-ea3da215": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
@ -62,6 +62,8 @@
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[stake_deregistration_account_larger_than_100]": "ffae5d78193ba3e989f025b67c544ce77ac4fde9d547e4588a9fe6f90354a4c2",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[testnet_protocol_magic_with_mainnet_network_id]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[testnet_transaction_with_mainnet_output]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[transaction_with_both_auxiliary_data_b-64274ac4": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[transaction_with_catalyst_registration-11533421": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[two_owners_with_path]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[unsupported_address_type]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
"cardano-test_sign_tx.py::test_cardano_sign_tx_failed[withdrawal_amount_is_too_large]": "612dad8ab8762162a186ec9279d7de0bdfc589c52b4e4f4eba0545a00f21c3f0",
|
||||
|
Loading…
Reference in New Issue
Block a user