mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
feat(cardano): add key hash stake credentials
This commit is contained in:
parent
2262602967
commit
9f9535abb3
@ -311,6 +311,7 @@ message CardanoPoolParametersType {
|
||||
optional bytes pool = 3; // pool hash
|
||||
optional CardanoPoolParametersType pool_parameters = 4; // used for stake pool registration certificate
|
||||
optional bytes script_hash = 5; // stake credential script hash
|
||||
optional bytes key_hash = 6; // stake credential key hash
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,6 +322,7 @@ message CardanoTxWithdrawal {
|
||||
repeated uint32 path = 1; // stake credential key path
|
||||
required uint64 amount = 2;
|
||||
optional bytes script_hash = 3; // stake credential script hash
|
||||
optional bytes key_hash = 4; // stake credential key hash
|
||||
}
|
||||
|
||||
/**
|
||||
|
162
common/tests/fixtures/cardano/sign_tx.failed.json
vendored
162
common/tests/fixtures/cardano/sign_tx.failed.json
vendored
@ -692,6 +692,46 @@
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Certificate has key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "ORDINARY_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Certificate has both path and script_hash",
|
||||
"parameters": {
|
||||
@ -733,6 +773,47 @@
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Certificate has both path and key_hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 0,
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "ORDINARY_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Certificate has invalid pool size",
|
||||
"parameters": {
|
||||
@ -894,6 +975,46 @@
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Withdrawal has key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd",
|
||||
"amount": "1000"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "ORDINARY_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Withdrawal amount is too large",
|
||||
"parameters": {
|
||||
@ -975,6 +1096,47 @@
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Withdrawal contains both path and key_hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/2/0",
|
||||
"amount": "1000",
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "Ae2tdPwUPEZCanmBz5g2GEwFqKTKpNJcGYPKfDxoNeKZ8bRHr8366kseiK2",
|
||||
"amount": "3003112"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "ORDINARY_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Auxiliary data hash has incorrect length",
|
||||
"parameters": {
|
||||
|
@ -14,7 +14,50 @@
|
||||
"certificates": [
|
||||
{
|
||||
"type": 0,
|
||||
"path": "m/1852'/1815'/0'/0/0"
|
||||
"path": "m/1852'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "MULTISIG_TRANSACTION",
|
||||
"additional_witness_requests": [
|
||||
{
|
||||
"path": "m/1854'/1815'/0'/0/0"
|
||||
}
|
||||
],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with stake registration certificate containing a key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 0,
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
@ -57,7 +100,53 @@
|
||||
"certificates": [
|
||||
{
|
||||
"type": 1,
|
||||
"path": "m/1852'/1815'/0'/0/0"
|
||||
"path": "m/1852'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "MULTISIG_TRANSACTION",
|
||||
"additional_witness_requests": [
|
||||
{
|
||||
"path": "m/1854'/1815'/0'/0/0"
|
||||
},
|
||||
{
|
||||
"path": "m/1854'/1815'/2'/0/0"
|
||||
}
|
||||
],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with stake deregistration certificate containing a key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 1,
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
@ -103,7 +192,7 @@
|
||||
"certificates": [
|
||||
{
|
||||
"type": 2,
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"path": "m/1852'/1815'/0'/2/0",
|
||||
"pool": "f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973"
|
||||
}
|
||||
],
|
||||
@ -137,6 +226,136 @@
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with stake delegation certificate containing a key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 2,
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd",
|
||||
"pool": "f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973"
|
||||
}
|
||||
],
|
||||
"withdrawals": [],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "MULTISIG_TRANSACTION",
|
||||
"additional_witness_requests": [
|
||||
{
|
||||
"path": "m/1854'/1815'/0'/0/0"
|
||||
}
|
||||
],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid certificate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with withdrawal containing a path",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/2/0",
|
||||
"amount": "1000"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "MULTISIG_TRANSACTION",
|
||||
"additional_witness_requests": [
|
||||
{
|
||||
"path": "m/1854'/1815'/0'/0/0"
|
||||
}
|
||||
],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with withdrawal containing a key hash",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [],
|
||||
"withdrawals": [
|
||||
{
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd",
|
||||
"amount": "1000"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1w9rhu54nz94k9l5v6d9rzfs47h7dv7xffcwkekuxcx3evnqpvuxu0",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": null,
|
||||
"collateral_inputs": [],
|
||||
"required_signers": [],
|
||||
"signing_mode": "MULTISIG_TRANSACTION",
|
||||
"additional_witness_requests": [
|
||||
{
|
||||
"path": "m/1854'/1815'/0'/0/0"
|
||||
}
|
||||
],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"error_message": "Invalid withdrawal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Multisig transaction with repeated withdrawal",
|
||||
"parameters": {
|
||||
|
160
common/tests/fixtures/cardano/sign_tx.plutus.json
vendored
160
common/tests/fixtures/cardano/sign_tx.plutus.json
vendored
@ -731,6 +731,166 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Plutus transaction with stake credentials given as key paths",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 1,
|
||||
"path": "m/1852'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "1000",
|
||||
"path": "m/1852'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
|
||||
"collateral_inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"required_signers": [
|
||||
{
|
||||
"key_path": "m/1852'/1815'/0'/0/1"
|
||||
},
|
||||
{
|
||||
"key_path": "m/1854'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"signing_mode": "PLUTUS_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"tx_hash": "717e9b63b08fda304bf7625d5df4149200b28b740db9b66082961a1d2f938ccd",
|
||||
"witnesses": [
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
|
||||
"signature": "f92cc207742fd8303112edaffbac243dfc433778a6711d90f8eaad22b207253c0268226c4895311df975354804d3351403cbc06a01886e954903e71af3d15d06",
|
||||
"chain_code": null
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "36a8ef21d5b98fdf23a27325cf643deaac35e912c835e35037f23d1061ae5b16",
|
||||
"signature": "f606a56f775ed61b67d89be664d2111841251f141cfdc4995567dd6f355d79d77f5160f1053ba74b541d52f12360ae1747b4991c34d1228f47cdef3e72384a05",
|
||||
"chain_code": null
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "bc65be1b0b9d7531778a1317c2aa6de936963c3f9ac7d5ee9e9eda25e0c97c5e",
|
||||
"signature": "c776b7ec00819b9e37501013309b41ecb10e0235db064e0f7b22d8c230d56cfc14a48330b1ee60675578c30cb79466fa4ade86d049670601fc9dd5f7e310df07",
|
||||
"chain_code": null
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "f2ef4ecd21ad28a8d270ca7be7e96c87f60dc821e13c0d0c5870344e9693637c",
|
||||
"signature": "1697e336ca218344e9f9f82c19ddbdba6009eebee76b9602ecd43a7d79824c7030d80cb31a363c39d0e520888dc4135bd9b1d647ebef76ba3a816a0e1b45ad07",
|
||||
"chain_code": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Plutus transaction with stake credentials given as key hashes",
|
||||
"parameters": {
|
||||
"protocol_magic": 764824073,
|
||||
"network_id": 1,
|
||||
"fee": 42,
|
||||
"ttl": 10,
|
||||
"certificates": [
|
||||
{
|
||||
"type": 1,
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"withdrawals": [
|
||||
{
|
||||
"amount": "1000",
|
||||
"key_hash": "29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
}
|
||||
],
|
||||
"auxiliary_data": null,
|
||||
"inputs": [
|
||||
{
|
||||
"prev_hash": "3b40265111d8bb3c3c608d95b3a0bf83461ace32d79336579a1939b3aad1c0b7",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"address": "addr1q84sh2j72ux0l03fxndjnhctdg7hcppsaejafsa84vh7lwgmcs5wgus8qt4atk45lvt4xfxpjtwfhdmvchdf2m3u3hlsd5tq5r",
|
||||
"amount": "1"
|
||||
}
|
||||
],
|
||||
"mint": [],
|
||||
"script_data_hash": "d593fd793c377ac50a3169bb8378ffc257c944da31aa8f355dfa5a4f6ff89e02",
|
||||
"collateral_inputs": [
|
||||
{
|
||||
"path": "m/1852'/1815'/0'/0/0",
|
||||
"prev_hash": "1af8fa0b754ff99253d983894e63a2b09cbb56c833ba18c3384210163f63dcfc",
|
||||
"prev_index": 0
|
||||
}
|
||||
],
|
||||
"required_signers": [
|
||||
{
|
||||
"key_path": "m/1852'/1815'/0'/0/1"
|
||||
},
|
||||
{
|
||||
"key_path": "m/1854'/1815'/0'/2/0"
|
||||
}
|
||||
],
|
||||
"signing_mode": "PLUTUS_TRANSACTION",
|
||||
"additional_witness_requests": [],
|
||||
"include_network_id": false
|
||||
},
|
||||
"result": {
|
||||
"tx_hash": "baabb4e6dced60de330a089590ea38b7bbe505bbf9c785ef88078242f0ea9860",
|
||||
"witnesses": [
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "5d010cf16fdeff40955633d6c565f3844a288a24967cf6b76acbeb271b4f13c1",
|
||||
"signature": "38b39e71cf45c0bfa0754ab4fa24443fc09cd936f0180a37b4bca9ef72d5a431680d50e02afd93518caa868428d784bbf30b01bfcb55fc0d51e7d2616006510b",
|
||||
"chain_code": null
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "36a8ef21d5b98fdf23a27325cf643deaac35e912c835e35037f23d1061ae5b16",
|
||||
"signature": "c0f3c3c3c8034041e9273bd856f33f2523c6b347b996da58ef7732a0a780a4696846fc6de08662d36581027a0a72d9981c41f0e7cf69afd52990991b69468e07",
|
||||
"chain_code": null
|
||||
},
|
||||
{
|
||||
"type": 1,
|
||||
"pub_key": "f2ef4ecd21ad28a8d270ca7be7e96c87f60dc821e13c0d0c5870344e9693637c",
|
||||
"signature": "14251ec24c089371cecafd2a54e430b560a0bc029cdb8579368730d1376f911a653722d850e6ce3fb4ae820d02b8771d905d13aea8b5ea23b5045d3b2685f507",
|
||||
"chain_code": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Plutus transaction with output datum hash",
|
||||
"parameters": {
|
||||
|
@ -65,7 +65,11 @@ def validate_certificate(
|
||||
CardanoCertificateType.STAKE_DEREGISTRATION,
|
||||
):
|
||||
validate_stake_credential(
|
||||
certificate.path, certificate.script_hash, signing_mode, INVALID_CERTIFICATE
|
||||
certificate.path,
|
||||
certificate.script_hash,
|
||||
certificate.key_hash,
|
||||
signing_mode,
|
||||
INVALID_CERTIFICATE,
|
||||
)
|
||||
|
||||
if certificate.type == CardanoCertificateType.STAKE_DELEGATION:
|
||||
@ -83,8 +87,6 @@ def validate_certificate(
|
||||
|
||||
|
||||
def _validate_certificate_structure(certificate: CardanoTxCertificate) -> None:
|
||||
path = certificate.path
|
||||
script_hash = certificate.script_hash
|
||||
pool = certificate.pool
|
||||
pool_parameters = certificate.pool_parameters
|
||||
|
||||
@ -92,7 +94,12 @@ def _validate_certificate_structure(certificate: CardanoTxCertificate) -> None:
|
||||
CardanoCertificateType.STAKE_REGISTRATION: (pool, pool_parameters),
|
||||
CardanoCertificateType.STAKE_DELEGATION: (pool_parameters,),
|
||||
CardanoCertificateType.STAKE_DEREGISTRATION: (pool, pool_parameters),
|
||||
CardanoCertificateType.STAKE_POOL_REGISTRATION: (path, script_hash, pool),
|
||||
CardanoCertificateType.STAKE_POOL_REGISTRATION: (
|
||||
certificate.path,
|
||||
certificate.script_hash,
|
||||
certificate.key_hash,
|
||||
pool,
|
||||
),
|
||||
}
|
||||
|
||||
if certificate.type not in fields_to_be_empty or any(
|
||||
@ -111,14 +118,20 @@ def cborize_certificate(
|
||||
return (
|
||||
certificate.type,
|
||||
cborize_certificate_stake_credential(
|
||||
keychain, certificate.path, certificate.script_hash
|
||||
keychain,
|
||||
certificate.path,
|
||||
certificate.script_hash,
|
||||
certificate.key_hash,
|
||||
),
|
||||
)
|
||||
elif certificate.type == CardanoCertificateType.STAKE_DELEGATION:
|
||||
return (
|
||||
certificate.type,
|
||||
cborize_certificate_stake_credential(
|
||||
keychain, certificate.path, certificate.script_hash
|
||||
keychain,
|
||||
certificate.path,
|
||||
certificate.script_hash,
|
||||
certificate.key_hash,
|
||||
),
|
||||
certificate.pool,
|
||||
)
|
||||
@ -127,10 +140,13 @@ def cborize_certificate(
|
||||
|
||||
|
||||
def cborize_certificate_stake_credential(
|
||||
keychain: seed.Keychain, path: list[int], script_hash: bytes | None
|
||||
keychain: seed.Keychain,
|
||||
path: list[int],
|
||||
script_hash: bytes | None,
|
||||
key_hash: bytes | None,
|
||||
) -> tuple[int, bytes]:
|
||||
if path:
|
||||
return 0, get_public_key_hash(keychain, path)
|
||||
if key_hash or path:
|
||||
return 0, key_hash or get_public_key_hash(keychain, path)
|
||||
|
||||
if script_hash:
|
||||
return 1, script_hash
|
||||
|
@ -12,6 +12,8 @@ HRP_JORMUN_PUBLIC_KEY = "ed25519_pk"
|
||||
HRP_SCRIPT_HASH = "script"
|
||||
HRP_KEY_HASH = "addr_vkh"
|
||||
HRP_SHARED_KEY_HASH = "addr_shared_vkh"
|
||||
HRP_STAKE_KEY_HASH = "stake_vkh"
|
||||
HRP_STAKE_SHARED_KEY_HASH = "stake_shared_vkh"
|
||||
HRP_REQUIRED_SIGNER_KEY_HASH = "req_signer_vkh"
|
||||
HRP_OUTPUT_DATUM_HASH = "datum"
|
||||
HRP_SCRIPT_DATA_HASH = "script_data"
|
||||
|
@ -4,7 +4,7 @@ from trezor.enums import CardanoAddressType
|
||||
|
||||
from ...common.paths import address_n_to_str
|
||||
from .paths import CHAIN_STAKING_KEY, SCHEMA_PAYMENT, SCHEMA_STAKING
|
||||
from .utils import format_key_hash, format_script_hash, to_account_path
|
||||
from .utils import bech32, to_account_path
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from trezor.messages import (
|
||||
@ -13,6 +13,9 @@ if TYPE_CHECKING:
|
||||
)
|
||||
from trezor.ui.layouts import PropertyType
|
||||
|
||||
CREDENTIAL_TYPE_PAYMENT: str = "payment"
|
||||
CREDENTIAL_TYPE_STAKE: str = "stake"
|
||||
|
||||
|
||||
class Credential:
|
||||
"""
|
||||
@ -57,12 +60,12 @@ class Credential:
|
||||
) -> "Credential":
|
||||
address_type = address_params.address_type
|
||||
credential = cls(
|
||||
"payment",
|
||||
address_type,
|
||||
address_params.address_n,
|
||||
None,
|
||||
address_params.script_payment_hash,
|
||||
None,
|
||||
type_name=CREDENTIAL_TYPE_PAYMENT,
|
||||
address_type=address_type,
|
||||
path=address_params.address_n,
|
||||
key_hash=None,
|
||||
script_hash=address_params.script_payment_hash,
|
||||
pointer=None,
|
||||
)
|
||||
|
||||
if address_type in (
|
||||
@ -100,12 +103,12 @@ class Credential:
|
||||
) -> "Credential":
|
||||
address_type = address_params.address_type
|
||||
credential = cls(
|
||||
"stake",
|
||||
address_type,
|
||||
address_params.address_n_staking,
|
||||
address_params.staking_key_hash,
|
||||
address_params.script_staking_hash,
|
||||
address_params.certificate_pointer,
|
||||
type_name=CREDENTIAL_TYPE_STAKE,
|
||||
address_type=address_type,
|
||||
path=address_params.address_n_staking,
|
||||
key_hash=address_params.staking_key_hash,
|
||||
script_hash=address_params.script_staking_hash,
|
||||
pointer=address_params.certificate_pointer,
|
||||
)
|
||||
|
||||
if address_type == CardanoAddressType.BASE:
|
||||
@ -185,9 +188,14 @@ class Credential:
|
||||
if self.path:
|
||||
return [(None, address_n_to_str(self.path))]
|
||||
elif self.key_hash:
|
||||
return [(None, format_key_hash(self.key_hash, False))]
|
||||
hrp = (
|
||||
bech32.HRP_KEY_HASH
|
||||
if self.type_name == CREDENTIAL_TYPE_PAYMENT
|
||||
else bech32.HRP_STAKE_KEY_HASH
|
||||
)
|
||||
return [(None, bech32.encode(hrp, self.key_hash))]
|
||||
elif self.script_hash:
|
||||
return [(None, format_script_hash(self.script_hash))]
|
||||
return [(None, bech32.encode(bech32.HRP_SCRIPT_HASH, self.script_hash))]
|
||||
elif self.pointer:
|
||||
return [
|
||||
(f"Block: {self.pointer.block_index}", None),
|
||||
|
@ -67,27 +67,6 @@ def format_asset_fingerprint(policy_id: bytes, asset_name_bytes: bytes) -> str:
|
||||
return bech32.encode("asset", fingerprint)
|
||||
|
||||
|
||||
def format_script_hash(script_hash: bytes) -> str:
|
||||
return bech32.encode(bech32.HRP_SCRIPT_HASH, script_hash)
|
||||
|
||||
|
||||
def format_key_hash(key_hash: bytes, is_shared_key: bool) -> str:
|
||||
hrp = bech32.HRP_SHARED_KEY_HASH if is_shared_key else bech32.HRP_KEY_HASH
|
||||
return bech32.encode(hrp, key_hash)
|
||||
|
||||
|
||||
def format_required_signer_key_hash(required_signer_key_hash: bytes) -> str:
|
||||
return bech32.encode(bech32.HRP_REQUIRED_SIGNER_KEY_HASH, required_signer_key_hash)
|
||||
|
||||
|
||||
def format_output_datum_hash(output_datum_hash: bytes) -> str:
|
||||
return bech32.encode(bech32.HRP_OUTPUT_DATUM_HASH, output_datum_hash)
|
||||
|
||||
|
||||
def format_script_data_hash(script_data_hash: bytes) -> str:
|
||||
return bech32.encode(bech32.HRP_SCRIPT_DATA_HASH, script_data_hash)
|
||||
|
||||
|
||||
def get_public_key_hash(keychain: seed.Keychain, path: list[int]) -> bytes:
|
||||
public_key = derive_public_key(keychain, path)
|
||||
return hashlib.blake2b(data=public_key, outlen=ADDRESS_KEY_HASH_SIZE).digest()
|
||||
@ -104,14 +83,18 @@ def derive_public_key(
|
||||
def validate_stake_credential(
|
||||
path: list[int],
|
||||
script_hash: bytes | None,
|
||||
key_hash: bytes | None,
|
||||
signing_mode: CardanoTxSigningMode,
|
||||
error: wire.ProcessError,
|
||||
) -> None:
|
||||
if path and script_hash:
|
||||
if sum(bool(k) for k in (path, script_hash, key_hash)) != 1:
|
||||
raise error
|
||||
|
||||
if path:
|
||||
if signing_mode != CardanoTxSigningMode.ORDINARY_TRANSACTION:
|
||||
if signing_mode not in (
|
||||
CardanoTxSigningMode.ORDINARY_TRANSACTION,
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
):
|
||||
raise error
|
||||
if not SCHEMA_STAKING_ANY_ACCOUNT.match(path):
|
||||
raise error
|
||||
@ -123,5 +106,10 @@ def validate_stake_credential(
|
||||
raise error
|
||||
if len(script_hash) != SCRIPT_HASH_SIZE:
|
||||
raise error
|
||||
elif key_hash:
|
||||
if signing_mode != CardanoTxSigningMode.PLUTUS_TRANSACTION:
|
||||
raise error
|
||||
if len(key_hash) != ADDRESS_KEY_HASH_SIZE:
|
||||
raise error
|
||||
else:
|
||||
raise error
|
||||
|
@ -25,16 +25,11 @@ from apps.common.paths import address_n_to_str
|
||||
|
||||
from . import seed
|
||||
from .address import derive_human_readable_address
|
||||
from .helpers import protocol_magics
|
||||
from .helpers import bech32, protocol_magics
|
||||
from .helpers.utils import (
|
||||
format_account_number,
|
||||
format_asset_fingerprint,
|
||||
format_key_hash,
|
||||
format_optional_int,
|
||||
format_output_datum_hash,
|
||||
format_required_signer_key_hash,
|
||||
format_script_data_hash,
|
||||
format_script_hash,
|
||||
format_stake_pool_id,
|
||||
to_account_path,
|
||||
)
|
||||
@ -126,7 +121,9 @@ async def show_native_script(
|
||||
if script.type == CardanoNativeScriptType.PUB_KEY:
|
||||
assert script.key_hash is not None or script.key_path # validate_script
|
||||
if script.key_hash:
|
||||
props.append((None, format_key_hash(script.key_hash, True)))
|
||||
props.append(
|
||||
(None, bech32.encode(bech32.HRP_SHARED_KEY_HASH, script.key_hash))
|
||||
)
|
||||
elif script.key_path:
|
||||
props.append((address_n_to_str(script.key_path), None))
|
||||
elif script.type == CardanoNativeScriptType.N_OF_K:
|
||||
@ -179,7 +176,9 @@ async def show_script_hash(
|
||||
ctx,
|
||||
"verify_script",
|
||||
title="Verify script",
|
||||
props=[("Script hash:", format_script_hash(script_hash))],
|
||||
props=[
|
||||
("Script hash:", bech32.encode(bech32.HRP_SCRIPT_HASH, script_hash))
|
||||
],
|
||||
br_code=ButtonRequestType.Other,
|
||||
)
|
||||
elif display_format == CardanoNativeScriptHashDisplayFormat.POLICY_ID:
|
||||
@ -380,7 +379,7 @@ async def show_warning_tx_output_contains_datum_hash(
|
||||
props=[
|
||||
(
|
||||
"The following transaction output contains datum hash:",
|
||||
format_output_datum_hash(datum_hash),
|
||||
bech32.encode(bech32.HRP_OUTPUT_DATUM_HASH, datum_hash),
|
||||
),
|
||||
("\nContinue?", None),
|
||||
],
|
||||
@ -476,18 +475,10 @@ async def confirm_certificate(
|
||||
|
||||
props: list[PropertyType] = [
|
||||
("Confirm:", CERTIFICATE_TYPE_NAMES[certificate.type]),
|
||||
]
|
||||
|
||||
if certificate.path:
|
||||
props.append(
|
||||
(
|
||||
f"for account {format_account_number(certificate.path)}:",
|
||||
address_n_to_str(to_account_path(certificate.path)),
|
||||
_format_stake_credential(
|
||||
certificate.path, certificate.script_hash, certificate.key_hash
|
||||
),
|
||||
)
|
||||
else:
|
||||
assert certificate.script_hash is not None # validate_certificate
|
||||
props.append(("for script:", format_script_hash(certificate.script_hash)))
|
||||
]
|
||||
|
||||
if certificate.type == CardanoCertificateType.STAKE_DELEGATION:
|
||||
assert certificate.pool is not None # validate_certificate
|
||||
@ -632,21 +623,12 @@ async def confirm_withdrawal(
|
||||
) -> None:
|
||||
props: list[PropertyType] = [
|
||||
("Confirm withdrawal", None),
|
||||
_format_stake_credential(
|
||||
withdrawal.path, withdrawal.script_hash, withdrawal.key_hash
|
||||
),
|
||||
("Amount:", format_coin_amount(withdrawal.amount)),
|
||||
]
|
||||
|
||||
if withdrawal.path:
|
||||
props.append(
|
||||
(
|
||||
f"for account {format_account_number(withdrawal.path)}:",
|
||||
address_n_to_str(to_account_path(withdrawal.path)),
|
||||
)
|
||||
)
|
||||
else:
|
||||
assert withdrawal.script_hash is not None # validate_withdrawal
|
||||
props.append(("for script:", format_script_hash(withdrawal.script_hash)))
|
||||
|
||||
props.append(("Amount:", format_coin_amount(withdrawal.amount)))
|
||||
|
||||
await confirm_properties(
|
||||
ctx,
|
||||
"confirm_withdrawal",
|
||||
@ -656,6 +638,23 @@ async def confirm_withdrawal(
|
||||
)
|
||||
|
||||
|
||||
def _format_stake_credential(
|
||||
path: list[int], script_hash: bytes | None, key_hash: bytes | None
|
||||
) -> tuple[str, str]:
|
||||
if path:
|
||||
return (
|
||||
f"for account {format_account_number(path)}:",
|
||||
address_n_to_str(to_account_path(path)),
|
||||
)
|
||||
elif key_hash:
|
||||
return ("for key hash:", bech32.encode(bech32.HRP_STAKE_KEY_HASH, key_hash))
|
||||
elif script_hash:
|
||||
return ("for script:", bech32.encode(bech32.HRP_SCRIPT_HASH, script_hash))
|
||||
else:
|
||||
# should be unreachable unless there's a bug in validation
|
||||
raise ValueError
|
||||
|
||||
|
||||
async def confirm_catalyst_registration(
|
||||
ctx: wire.Context,
|
||||
public_key: str,
|
||||
@ -734,7 +733,12 @@ async def confirm_script_data_hash(ctx: wire.Context, script_data_hash: bytes) -
|
||||
ctx,
|
||||
"confirm_script_data_hash",
|
||||
title="Confirm transaction",
|
||||
props=[("Script data hash:", format_script_data_hash(script_data_hash))],
|
||||
props=[
|
||||
(
|
||||
"Script data hash:",
|
||||
bech32.encode(bech32.HRP_SCRIPT_DATA_HASH, script_data_hash),
|
||||
)
|
||||
],
|
||||
br_code=ButtonRequestType.Other,
|
||||
)
|
||||
|
||||
@ -761,7 +765,7 @@ async def confirm_required_signer(
|
||||
required_signer.key_hash is not None or required_signer.key_path
|
||||
) # _validate_required_signer
|
||||
formatted_signer = (
|
||||
format_required_signer_key_hash(required_signer.key_hash)
|
||||
bech32.encode(bech32.HRP_REQUIRED_SIGNER_KEY_HASH, required_signer.key_hash)
|
||||
if required_signer.key_hash is not None
|
||||
else address_n_to_str(required_signer.key_path)
|
||||
)
|
||||
|
@ -524,9 +524,6 @@ async def _process_certificates(
|
||||
account_path_checker: AccountPathChecker,
|
||||
) -> None:
|
||||
"""Read, validate, confirm and serialize the certificates."""
|
||||
if certificates_count == 0:
|
||||
return
|
||||
|
||||
for _ in range(certificates_count):
|
||||
certificate: CardanoTxCertificate = await ctx.call(
|
||||
CardanoTxItemAck(), CardanoTxCertificate
|
||||
@ -1021,7 +1018,6 @@ async def _show_certificate(
|
||||
CardanoTxSigningMode.MULTISIG_TRANSACTION,
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
):
|
||||
assert certificate.script_hash # validate_certificate
|
||||
await confirm_certificate(ctx, certificate)
|
||||
elif signing_mode == CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER:
|
||||
await _show_stake_pool_registration_certificate(ctx, certificate)
|
||||
@ -1039,15 +1035,16 @@ def _validate_withdrawal(
|
||||
previous_reward_address: bytes,
|
||||
) -> None:
|
||||
validate_stake_credential(
|
||||
withdrawal.path, withdrawal.script_hash, signing_mode, INVALID_WITHDRAWAL
|
||||
withdrawal.path,
|
||||
withdrawal.script_hash,
|
||||
withdrawal.key_hash,
|
||||
signing_mode,
|
||||
INVALID_WITHDRAWAL,
|
||||
)
|
||||
|
||||
if not 0 <= withdrawal.amount < LOVELACE_MAX_SUPPLY:
|
||||
raise INVALID_WITHDRAWAL
|
||||
|
||||
credential = tuple(withdrawal.path) if withdrawal.path else withdrawal.script_hash
|
||||
assert credential # validate_stake_credential
|
||||
|
||||
reward_address = _derive_withdrawal_reward_address_bytes(
|
||||
keychain, withdrawal, protocol_magic, network_id
|
||||
)
|
||||
@ -1093,7 +1090,7 @@ def _derive_withdrawal_reward_address_bytes(
|
||||
) -> bytes:
|
||||
reward_address_type = (
|
||||
CardanoAddressType.REWARD
|
||||
if withdrawal.path
|
||||
if withdrawal.path or withdrawal.key_hash
|
||||
else CardanoAddressType.REWARD_SCRIPT
|
||||
)
|
||||
return derive_address_bytes(
|
||||
@ -1101,6 +1098,7 @@ def _derive_withdrawal_reward_address_bytes(
|
||||
CardanoAddressParametersType(
|
||||
address_type=reward_address_type,
|
||||
address_n_staking=withdrawal.path,
|
||||
staking_key_hash=withdrawal.key_hash,
|
||||
script_staking_hash=withdrawal.script_hash,
|
||||
),
|
||||
protocol_magic,
|
||||
|
@ -1528,6 +1528,7 @@ if TYPE_CHECKING:
|
||||
pool: "bytes | None"
|
||||
pool_parameters: "CardanoPoolParametersType | None"
|
||||
script_hash: "bytes | None"
|
||||
key_hash: "bytes | None"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -1537,6 +1538,7 @@ if TYPE_CHECKING:
|
||||
pool: "bytes | None" = None,
|
||||
pool_parameters: "CardanoPoolParametersType | None" = None,
|
||||
script_hash: "bytes | None" = None,
|
||||
key_hash: "bytes | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@ -1548,6 +1550,7 @@ if TYPE_CHECKING:
|
||||
path: "list[int]"
|
||||
amount: "int"
|
||||
script_hash: "bytes | None"
|
||||
key_hash: "bytes | None"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -1555,6 +1558,7 @@ if TYPE_CHECKING:
|
||||
amount: "int",
|
||||
path: "list[int] | None" = None,
|
||||
script_hash: "bytes | None" = None,
|
||||
key_hash: "bytes | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
@ -40,6 +40,15 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_REGISTRATION,
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DELEGATION,
|
||||
@ -74,6 +83,18 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DELEGATION,
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
pool=unhexlify(
|
||||
"f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DEREGISTRATION,
|
||||
@ -99,6 +120,15 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DEREGISTRATION,
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_POOL_REGISTRATION,
|
||||
@ -142,6 +172,19 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.ORDINARY_TRANSACTION,
|
||||
),
|
||||
# STAKE_REGISTRATION both script_hash and key_hash are set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_REGISTRATION,
|
||||
script_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
# STAKE_REGISTRATION pool is set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
@ -200,6 +243,22 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.ORDINARY_TRANSACTION,
|
||||
),
|
||||
# STAKE_DELEGATION both script_hash and key_hash are set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DELEGATION,
|
||||
script_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
pool=unhexlify(
|
||||
"f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
# STAKE_DELEGATION pool parameters are set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
@ -244,6 +303,19 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.ORDINARY_TRANSACTION,
|
||||
),
|
||||
# STAKE_DEREGISTRATION both script_hash and key_hash are set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_DEREGISTRATION,
|
||||
script_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.PLUTUS_TRANSACTION,
|
||||
),
|
||||
# STAKE_DEREGISTRATION pool is set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
@ -333,6 +405,31 @@ class TestCardanoCertificate(unittest.TestCase):
|
||||
),
|
||||
CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER,
|
||||
),
|
||||
# STAKE_POOL_REGISTRATION key hash is set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
type=CardanoCertificateType.STAKE_POOL_REGISTRATION,
|
||||
key_hash=unhexlify(
|
||||
"29fb5fd4aa8cadd6705acc8263cee0fc62edca5ac38db593fec2f9fd"
|
||||
),
|
||||
pool_parameters=CardanoPoolParametersType(
|
||||
pool_id=unhexlify(
|
||||
"f61c42cbf7c8c53af3f520508212ad3e72f674f957fe23ff0acb4973"
|
||||
),
|
||||
vrf_key_hash=unhexlify(
|
||||
"198890ad6c92e80fbdab554dda02da9fb49d001bbd96181f3e07f7a6ab0d0640"
|
||||
),
|
||||
pledge=500000000,
|
||||
cost=340000000,
|
||||
margin_numerator=1,
|
||||
margin_denominator=2,
|
||||
reward_account="stake1uya87zwnmax0v6nnn8ptqkl6ydx4522kpsc3l3wmf3yswygwx45el",
|
||||
owners_count=1,
|
||||
relays_count=1,
|
||||
),
|
||||
),
|
||||
CardanoTxSigningMode.POOL_REGISTRATION_AS_OWNER,
|
||||
),
|
||||
# STAKE_POOL_REGISTRATION pool is set
|
||||
(
|
||||
CardanoTxCertificate(
|
||||
|
@ -330,7 +330,7 @@ def parse_certificate(certificate: dict) -> CertificateWithPoolOwnersAndRelays:
|
||||
if "pool" not in certificate:
|
||||
raise CERTIFICATE_MISSING_FIELDS_ERROR
|
||||
|
||||
path, script_hash = _parse_path_or_script_hash(
|
||||
path, script_hash, key_hash = _parse_credential(
|
||||
certificate, CERTIFICATE_MISSING_FIELDS_ERROR
|
||||
)
|
||||
|
||||
@ -340,6 +340,7 @@ def parse_certificate(certificate: dict) -> CertificateWithPoolOwnersAndRelays:
|
||||
path=path,
|
||||
pool=bytes.fromhex(certificate["pool"]),
|
||||
script_hash=script_hash,
|
||||
key_hash=key_hash,
|
||||
),
|
||||
None,
|
||||
)
|
||||
@ -347,13 +348,16 @@ def parse_certificate(certificate: dict) -> CertificateWithPoolOwnersAndRelays:
|
||||
messages.CardanoCertificateType.STAKE_REGISTRATION,
|
||||
messages.CardanoCertificateType.STAKE_DEREGISTRATION,
|
||||
):
|
||||
path, script_hash = _parse_path_or_script_hash(
|
||||
path, script_hash, key_hash = _parse_credential(
|
||||
certificate, CERTIFICATE_MISSING_FIELDS_ERROR
|
||||
)
|
||||
|
||||
return (
|
||||
messages.CardanoTxCertificate(
|
||||
type=certificate_type, path=path, script_hash=script_hash
|
||||
type=certificate_type,
|
||||
path=path,
|
||||
script_hash=script_hash,
|
||||
key_hash=key_hash,
|
||||
),
|
||||
None,
|
||||
)
|
||||
@ -406,16 +410,17 @@ def parse_certificate(certificate: dict) -> CertificateWithPoolOwnersAndRelays:
|
||||
raise ValueError("Unknown certificate type")
|
||||
|
||||
|
||||
def _parse_path_or_script_hash(
|
||||
def _parse_credential(
|
||||
obj: dict, error: ValueError
|
||||
) -> Tuple[List[int], Optional[bytes]]:
|
||||
if "path" not in obj and "script_hash" not in obj:
|
||||
) -> Tuple[List[int], Optional[bytes], Optional[bytes]]:
|
||||
if not any(k in obj for k in ("path", "script_hash", "key_hash")):
|
||||
raise error
|
||||
|
||||
path = tools.parse_path(obj.get("path", ""))
|
||||
script_hash = parse_optional_bytes(obj.get("script_hash"))
|
||||
key_hash = parse_optional_bytes(obj.get("key_hash"))
|
||||
|
||||
return path, script_hash
|
||||
return path, script_hash, key_hash
|
||||
|
||||
|
||||
def _parse_pool_owner(pool_owner: dict) -> messages.CardanoPoolOwner:
|
||||
@ -473,7 +478,7 @@ def parse_withdrawal(withdrawal: dict) -> messages.CardanoTxWithdrawal:
|
||||
if "amount" not in withdrawal:
|
||||
raise WITHDRAWAL_MISSING_FIELDS_ERROR
|
||||
|
||||
path, script_hash = _parse_path_or_script_hash(
|
||||
path, script_hash, key_hash = _parse_credential(
|
||||
withdrawal, WITHDRAWAL_MISSING_FIELDS_ERROR
|
||||
)
|
||||
|
||||
@ -481,6 +486,7 @@ def parse_withdrawal(withdrawal: dict) -> messages.CardanoTxWithdrawal:
|
||||
path=path,
|
||||
amount=int(withdrawal["amount"]),
|
||||
script_hash=script_hash,
|
||||
key_hash=key_hash,
|
||||
)
|
||||
|
||||
|
||||
|
@ -2490,6 +2490,7 @@ class CardanoTxCertificate(protobuf.MessageType):
|
||||
3: protobuf.Field("pool", "bytes", repeated=False, required=False),
|
||||
4: protobuf.Field("pool_parameters", "CardanoPoolParametersType", repeated=False, required=False),
|
||||
5: protobuf.Field("script_hash", "bytes", repeated=False, required=False),
|
||||
6: protobuf.Field("key_hash", "bytes", repeated=False, required=False),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@ -2500,12 +2501,14 @@ class CardanoTxCertificate(protobuf.MessageType):
|
||||
pool: Optional["bytes"] = None,
|
||||
pool_parameters: Optional["CardanoPoolParametersType"] = None,
|
||||
script_hash: Optional["bytes"] = None,
|
||||
key_hash: Optional["bytes"] = None,
|
||||
) -> None:
|
||||
self.path: Sequence["int"] = path if path is not None else []
|
||||
self.type = type
|
||||
self.pool = pool
|
||||
self.pool_parameters = pool_parameters
|
||||
self.script_hash = script_hash
|
||||
self.key_hash = key_hash
|
||||
|
||||
|
||||
class CardanoTxWithdrawal(protobuf.MessageType):
|
||||
@ -2514,6 +2517,7 @@ class CardanoTxWithdrawal(protobuf.MessageType):
|
||||
1: protobuf.Field("path", "uint32", repeated=True, required=False),
|
||||
2: protobuf.Field("amount", "uint64", repeated=False, required=True),
|
||||
3: protobuf.Field("script_hash", "bytes", repeated=False, required=False),
|
||||
4: protobuf.Field("key_hash", "bytes", repeated=False, required=False),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
@ -2522,10 +2526,12 @@ class CardanoTxWithdrawal(protobuf.MessageType):
|
||||
amount: "int",
|
||||
path: Optional[Sequence["int"]] = None,
|
||||
script_hash: Optional["bytes"] = None,
|
||||
key_hash: Optional["bytes"] = None,
|
||||
) -> None:
|
||||
self.path: Sequence["int"] = path if path is not None else []
|
||||
self.amount = amount
|
||||
self.script_hash = script_hash
|
||||
self.key_hash = key_hash
|
||||
|
||||
|
||||
class CardanoCatalystRegistrationParametersType(protobuf.MessageType):
|
||||
|
Loading…
Reference in New Issue
Block a user