feat(solana): migrate to off-chain message signing v1
What changed, and why it matters
This commit updates Trezor's Solana off-chain message signing feature from an older version (v0) to a newer version (v1). It changes how messages are packaged and sent to the device: instead of the computer app formatting the message and sending raw bytes, the device now receives a structured message and formats it itself. This is a feature migration, not a fix for an active security bug, but it removes support for the older format and changes the command-line interface. The change is described as following Solana Foundation's direction because v0 was considered flawed.
Review the new OCMS v1 serialization implementation for canonical encoding, signer sorting, duplicate handling, and length limits; verify that deprecated v0 fields cannot be misused by older clients; confirm UI still clearly displays the message and signer set before signing; and update integration tests and documentation to reflect the breaking protobuf/CLI change.
Security signals we found
Protocol version migration removes OCMS v0 parsing and envelope handling
Firmware now performs its own serialization of off-chain signing payloads, reducing trust in host-side formatting
Old protobuf field 2 (raw OCMS v0 bytes) is reserved/deprecated
Old SolanaVerifyMessage envelope field is reserved/deprecated
No explicit security bug or vulnerability is stated in the commit message or diff
Evidence from the diff
The commit replaces Solana Off-Chain Message Signing (OCMS) v0 with v1. The protobuf interface is changed: SolanaSignMessage.message is now a structured SolanaOffchainMessageV1 (string message + repeated signer public keys) instead of raw OCMS v0 bytes; SolanaVerifyMessage now takes the same structured message plus a repeated signatures field, instead of a pre-built envelope. The firmware now serializes the OCMS v1 payload itself (domain prefix, version 1, signer count, sorted signers, UTF-8 message). The CLI raw mode is removed, and the Python/Rust client libraries are updated accordingly. Tests and translation strings are updated to match. The commit does not describe a CVE or credit an external researcher; it is presented as a protocol-version migration.
Changed components
common/protob/messages-solana.protocore/src/apps/solana/offchain_message.pycore/src/apps/solana/sign_message.pycore/src/apps/solana/verify_message.pycore/src/apps/solana/layout.pypython/src/trezorlib/cli/solana.pypython/src/trezorlib/solana.pypython/src/trezorlib/messages.pyrust/trezor-client/src/protos/generated/messages_solana.rscore/tests/test_apps.solana.offchain_message.pyInspect captured patch +1378 / −1508
diff --git a/common/protob/messages-solana.proto b/common/protob/messages-solana.proto
index 3a7f44bd..68f64a68 100644
--- a/common/protob/messages-solana.proto
+++ b/common/protob/messages-solana.proto
@@ -87,6 +87,14 @@ message SolanaTxSignature {
required bytes signature = 1; // tx signature
}
+/**
+ * @embed
+ */
+message SolanaOffchainMessageV1 {
+ required string message = 1;
+ repeated bytes signers = 2;
+}
+
/**
* Request: Ask device to sign a Solana off-chain message
* @start
@@ -95,8 +103,9 @@ message SolanaTxSignature {
*/
message SolanaSignMessage {
repeated uint32 address_n = 1; // BIP-32 path to derive the key to sign with
- required bytes message = 2; // message to be signed, in OCMS format
+ reserved 2; // deprecated: message in OCMS v0 format
optional bool chunkify = 3; // display the address in chunks of 4 characters
+ required SolanaOffchainMessageV1 message = 4;
}
/**
@@ -104,7 +113,8 @@ message SolanaSignMessage {
* @end
*/
message SolanaMessageSignature {
- required bytes signature = 1; // message signature
+ required bytes signature = 1; // message signature
+ optional bytes signed_data = 2; // serialized message that was signed
}
/**
@@ -114,6 +124,8 @@ message SolanaMessageSignature {
* @next Failure
*/
message SolanaVerifyMessage {
- required bytes envelope = 1; // OCMS envelope containing the signatures and the message
- optional bool chunkify = 2; // display the address in chunks of 4 characters
+ reserved 1; // deprecated: message in OCMS v0 format with an envelope
+ optional bool chunkify = 2; // display the address in chunks of 4 characters
+ required SolanaOffchainMessageV1 message = 3;
+ repeated bytes signatures = 4; // signatures to verify, order must match the order of message.signers
}
diff --git a/core/.changelog.d/7053.added b/core/.changelog.d/7053.added
new file mode 100644
index 00000000..6e20d293
--- /dev/null
+++ b/core/.changelog.d/7053.added
@@ -0,0 +1 @@
+Solana: add support for off-chain message signing (OCMS) v1.
diff --git a/core/.changelog.d/7053.removed b/core/.changelog.d/7053.removed
new file mode 100644
index 00000000..03d40d91
--- /dev/null
+++ b/core/.changelog.d/7053.removed
@@ -0,0 +1 @@
+Solana: remove support for off-chain message signing (OCMS) v0.
diff --git a/core/embed/rust/librust_qstr.h b/core/embed/rust/librust_qstr.h
index 136a129f..784be6b9 100644
--- a/core/embed/rust/librust_qstr.h
+++ b/core/embed/rust/librust_qstr.h
@@ -1455,7 +1455,6 @@ static void _librust_qstrs(void) {
MP_QSTR_ripple__destination_tag_missing;
MP_QSTR_ripple__destination_tag_template;
MP_QSTR_solana__account_index;
- MP_QSTR_solana__app_domain;
MP_QSTR_solana__associated_token_account;
MP_QSTR_solana__base_fee;
MP_QSTR_solana__claim;
diff --git a/core/embed/rust/src/translations/generated/translated_string.rs b/core/embed/rust/src/translations/generated/translated_string.rs
index eeda8b72..9740da29 100644
--- a/core/embed/rust/src/translations/generated/translated_string.rs
+++ b/core/embed/rust/src/translations/generated/translated_string.rs
@@ -1609,62 +1609,60 @@ pub enum TranslatedString {
words__account_deletion = 1228, // "Account deletion"
words__tap_to_wake = 1229, // {"Bolt": "", "Caesar": "", "Delizia": "", "Eckhart": "Tap to wake"}
words__made_in = 1230, // {"Bolt": "", "Caesar": "", "Delizia": "", "Eckhart": "Made in"}
+ address__title_cosigner_template = 1231, // "Cosigner {0}"
+ address__warning_not_yours = 1232, // {"Bolt": "", "Caesar": "", "Delizia": "", "Eckhart": "This is NOT your address"}
+ coinjoin__max_coordinator_fee_pct = 1233, // "Max coordinator fee"
#[cfg(feature = "universal_fw")]
- solana__app_domain = 1231, // "Application domain"
+ ethereum__all_evms = 1234, // "All EVMs"
#[cfg(feature = "universal_fw")]
- solana__offchain_is_multisig = 1232, // "The following message requires multiple signers."
- words__comm_continue = 1233, // "Communication with your connected device failed. It's safe to continue."
- address__title_cosigner_template = 1234, // "Cosigner {0}"
+ ethereum__auth_done = 1235, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 authorization signed.", "Eckhart": "EIP-7702 authorization signed."}
#[cfg(feature = "universal_fw")]
- tron__claim_unfrozen_balance = 1235, // "Claim unfrozen balance?"
+ ethereum__auth_title = 1236, // "EIP-7702 Authorization"
#[cfg(feature = "universal_fw")]
- tron__claim_voting_rewards = 1236, // "Claim voting rewards?"
- address__warning_not_yours = 1237, // {"Bolt": "", "Caesar": "", "Delizia": "", "Eckhart": "This is NOT your address"}
+ ethereum__auth_warn = 1237, // "Authorize your account to a third-party contract using EIP-7702?"
#[cfg(feature = "universal_fw")]
- tron__owner_address = 1238, // "Owner address"
+ ethereum__calldata_digest = 1238, // "ERC-8213 digest"
#[cfg(feature = "universal_fw")]
- ethereum__eip_712_empty_domain = 1239, // "dApp did not identify itself!"
- coinjoin__max_coordinator_fee_pct = 1240, // "Max coordinator fee"
+ ethereum__delegate_done = 1239, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 delegation signed.", "Eckhart": "EIP-7702 delegation signed."}
#[cfg(feature = "universal_fw")]
- ethereum__all_evms = 1241, // "All EVMs"
+ ethereum__delegate_title = 1240, // "EIP-7702 Delegation"
#[cfg(feature = "universal_fw")]
- ethereum__auth_done = 1242, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 authorization signed.", "Eckhart": "EIP-7702 authorization signed."}
+ ethereum__delegate_warn = 1241, // "Delegate your account to a third-party contract?"
#[cfg(feature = "universal_fw")]
- ethereum__auth_title = 1243, // "EIP-7702 Authorization"
+ ethereum__delegating = 1242, // "Delegating"
#[cfg(feature = "universal_fw")]
- ethereum__auth_warn = 1244, // "Authorize your account to a third-party contract using EIP-7702?"
+ ethereum__eip_712_empty_domain = 1243, // "dApp did not identify itself!"
#[cfg(feature = "universal_fw")]
- ethereum__calldata_digest = 1245, // "ERC-8213 digest"
+ ethereum__network = 1244, // "Network"
#[cfg(feature = "universal_fw")]
- ethereum__delegate_done = 1246, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 delegation signed.", "Eckhart": "EIP-7702 delegation signed."}
+ ethereum__revoke_done = 1245, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 revocation signed.", "Eckhart": "EIP-7702 revocation signed."}
#[cfg(feature = "universal_fw")]
- ethereum__delegate_title = 1247, // "EIP-7702 Delegation"
+ ethereum__revoke_title = 1246, // "EIP-7702 Revocation"
#[cfg(feature = "universal_fw")]
- ethereum__delegate_warn = 1248, // "Delegate your account to a third-party contract?"
+ ethereum__revoke_warn = 1247, // "Revoke {0} from smart account delegation?"
#[cfg(feature = "universal_fw")]
- ethereum__delegating = 1249, // "Delegating"
+ ethereum__smart_info = 1248, // "Smart account contract info"
#[cfg(feature = "universal_fw")]
- ethereum__network = 1250, // "Network"
+ ethereum__to = 1249, // "To"
+ pin__reenter_new_description = 1250, // {"Bolt": "", "Caesar": "", "Delizia": "Re-enter new PIN.", "Eckhart": ""}
#[cfg(feature = "universal_fw")]
- ethereum__revoke_done = 1251, // {"Bolt": "", "Caesar": "", "Delizia": "EIP-7702 revocation signed.", "Eckhart": "EIP-7702 revocation signed."}
+ solana__offchain_is_multisig = 1251, // "The following message requires multiple signers."
#[cfg(feature = "universal_fw")]
- ethereum__revoke_title = 1252, // "EIP-7702 Revocation"
+ stellar__ext_auth = 1252, // "External Authorizations"
#[cfg(feature = "universal_fw")]
- ethereum__revoke_warn = 1253, // "Revoke {0} from smart account delegation?"
+ stellar__ext_auth_message = 1253, // "Transaction contains additional invocations authorized by external means."
#[cfg(feature = "universal_fw")]
- ethereum__smart_info = 1254, // "Smart account contract info"
+ stellar__invoke_contract = 1254, // "Invoke Contract"
#[cfg(feature = "universal_fw")]
- ethereum__to = 1255, // "To"
- pin__reenter_new_description = 1256, // {"Bolt": "", "Caesar": "", "Delizia": "Re-enter new PIN.", "Eckhart": ""}
+ tron__claim_unfrozen_balance = 1255, // "Claim unfrozen balance?"
#[cfg(feature = "universal_fw")]
- stellar__ext_auth = 1257, // "External Authorizations"
+ tron__claim_voting_rewards = 1256, // "Claim voting rewards?"
#[cfg(feature = "universal_fw")]
- stellar__ext_auth_message = 1258, // "Transaction contains additional invocations authorized by external means."
- #[cfg(feature = "universal_fw")]
- stellar__invoke_contract = 1259, // "Invoke Contract"
- words__arguments = 1260, // "Arguments"
- words__authorization = 1261, // "Authorization"
- words__function = 1262, // "Function"
+ tron__owner_address = 1257, // "Owner address"
+ words__arguments = 1258, // "Arguments"
+ words__authorization = 1259, // "Authorization"
+ words__comm_continue = 1260, // "Communication with your connected device failed. It's safe to continue."
+ words__function = 1261, // "Function"
}
impl TranslatedString {
@@ -2903,15 +2901,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -2922,6 +2913,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -2929,11 +2921,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -4171,38 +4168,37 @@ impl TranslatedString {
18415,
18415,
18415,
- 18433,
- 18481,
- 18552,
- 18564,
- 18587,
- 18608,
- 18608,
- 18621,
- 18650,
- 18669,
- 18677,
- 18677,
- 18699,
- 18763,
- 18778,
- 18778,
- 18797,
- 18845,
- 18855,
- 18862,
- 18862,
- 18881,
- 18922,
- 18949,
- 18951,
- 18951,
- 18974,
- 19047,
- 19062,
- 19071,
- 19084,
- 19092,
+ 18427,
+ 18427,
+ 18446,
+ 18454,
+ 18454,
+ 18476,
+ 18540,
+ 18555,
+ 18555,
+ 18574,
+ 18622,
+ 18632,
+ 18661,
+ 18668,
+ 18668,
+ 18687,
+ 18728,
+ 18755,
+ 18757,
+ 18757,
+ 18805,
+ 18828,
+ 18901,
+ 18916,
+ 18939,
+ 18960,
+ 18973,
+ 18982,
+ 18995,
+ 19066,
+ 19074,
];
#[cfg(all(feature = "debug", not(feature = "universal_fw")))]
@@ -5438,15 +5434,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -5457,6 +5446,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -5464,11 +5454,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -6706,38 +6701,37 @@ impl TranslatedString {
18415,
18415,
18415,
- 18433,
- 18481,
- 18552,
- 18564,
- 18587,
- 18608,
- 18608,
- 18621,
- 18650,
- 18669,
- 18677,
- 18677,
- 18699,
- 18763,
- 18778,
- 18778,
- 18797,
- 18845,
- 18855,
- 18862,
- 18862,
- 18881,
- 18922,
- 18949,
- 18951,
- 18951,
- 18974,
- 19047,
- 19062,
- 19071,
- 19084,
- 19092,
+ 18427,
+ 18427,
+ 18446,
+ 18454,
+ 18454,
+ 18476,
+ 18540,
+ 18555,
+ 18555,
+ 18574,
+ 18622,
+ 18632,
+ 18661,
+ 18668,
+ 18668,
+ 18687,
+ 18728,
+ 18755,
+ 18757,
+ 18757,
+ 18805,
+ 18828,
+ 18901,
+ 18916,
+ 18939,
+ 18960,
+ 18973,
+ 18982,
+ 18995,
+ 19066,
+ 19074,
];
#[cfg(all(not(feature = "debug"), feature = "universal_fw"))]
@@ -7973,15 +7967,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -7992,6 +7979,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -7999,11 +7987,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -9241,38 +9234,37 @@ impl TranslatedString {
18415,
18415,
18415,
- 18433,
- 18481,
- 18552,
- 18564,
- 18587,
- 18608,
- 18608,
- 18621,
- 18650,
- 18669,
- 18677,
- 18677,
- 18699,
- 18763,
- 18778,
- 18778,
- 18797,
- 18845,
- 18855,
- 18862,
- 18862,
- 18881,
- 18922,
- 18949,
- 18951,
- 18951,
- 18974,
- 19047,
- 19062,
- 19071,
- 19084,
- 19092,
+ 18427,
+ 18427,
+ 18446,
+ 18454,
+ 18454,
+ 18476,
+ 18540,
+ 18555,
+ 18555,
+ 18574,
+ 18622,
+ 18632,
+ 18661,
+ 18668,
+ 18668,
+ 18687,
+ 18728,
+ 18755,
+ 18757,
+ 18757,
+ 18805,
+ 18828,
+ 18901,
+ 18916,
+ 18939,
+ 18960,
+ 18973,
+ 18982,
+ 18995,
+ 19066,
+ 19074,
];
#[cfg(all(not(feature = "debug"), not(feature = "universal_fw")))]
@@ -10508,15 +10500,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -10527,6 +10512,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -10534,11 +10520,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -11776,38 +11767,37 @@ impl TranslatedString {
18415,
18415,
18415,
- 18433,
- 18481,
- 18552,
- 18564,
- 18587,
- 18608,
- 18608,
- 18621,
- 18650,
- 18669,
- 18677,
- 18677,
- 18699,
- 18763,
- 18778,
- 18778,
- 18797,
- 18845,
- 18855,
- 18862,
- 18862,
- 18881,
- 18922,
- 18949,
- 18951,
- 18951,
- 18974,
- 19047,
- 19062,
- 19071,
- 19084,
- 19092,
+ 18427,
+ 18427,
+ 18446,
+ 18454,
+ 18454,
+ 18476,
+ 18540,
+ 18555,
+ 18555,
+ 18574,
+ 18622,
+ 18632,
+ 18661,
+ 18668,
+ 18668,
+ 18687,
+ 18728,
+ 18755,
+ 18757,
+ 18757,
+ 18805,
+ 18828,
+ 18901,
+ 18916,
+ 18939,
+ 18960,
+ 18973,
+ 18982,
+ 18995,
+ 19066,
+ 19074,
];
} else if #[cfg(feature = "layout_caesar")] {
@@ -13044,15 +13034,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -13063,6 +13046,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -13070,11 +13054,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -14312,38 +14301,37 @@ impl TranslatedString {
16206,
16206,
16206,
- 16224,
- 16272,
- 16343,
- 16355,
- 16378,
- 16399,
- 16399,
- 16412,
- 16441,
- 16460,
- 16468,
- 16468,
- 16490,
- 16554,
- 16569,
- 16569,
- 16588,
- 16636,
- 16646,
- 16653,
- 16653,
- 16672,
- 16713,
- 16740,
- 16742,
- 16742,
- 16765,
- 16838,
- 16853,
- 16862,
- 16875,
- 16883,
+ 16218,
+ 16218,
+ 16237,
+ 16245,
+ 16245,
+ 16267,
+ 16331,
+ 16346,
+ 16346,
+ 16365,
+ 16413,
+ 16423,
+ 16452,
+ 16459,
+ 16459,
+ 16478,
+ 16519,
+ 16546,
+ 16548,
+ 16548,
+ 16596,
+ 16619,
+ 16692,
+ 16707,
+ 16730,
+ 16751,
+ 16764,
+ 16773,
+ 16786,
+ 16857,
+ 16865,
];
#[cfg(all(feature = "debug", not(feature = "universal_fw")))]
@@ -15579,15 +15567,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -15598,6 +15579,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -15605,11 +15587,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -16847,38 +16834,37 @@ impl TranslatedString {
16206,
16206,
16206,
- 16224,
- 16272,
- 16343,
- 16355,
- 16378,
- 16399,
- 16399,
- 16412,
- 16441,
- 16460,
- 16468,
- 16468,
- 16490,
- 16554,
- 16569,
- 16569,
- 16588,
- 16636,
- 16646,
- 16653,
- 16653,
- 16672,
- 16713,
- 16740,
- 16742,
- 16742,
- 16765,
- 16838,
- 16853,
- 16862,
- 16875,
- 16883,
+ 16218,
+ 16218,
+ 16237,
+ 16245,
+ 16245,
+ 16267,
+ 16331,
+ 16346,
+ 16346,
+ 16365,
+ 16413,
+ 16423,
+ 16452,
+ 16459,
+ 16459,
+ 16478,
+ 16519,
+ 16546,
+ 16548,
+ 16548,
+ 16596,
+ 16619,
+ 16692,
+ 16707,
+ 16730,
+ 16751,
+ 16764,
+ 16773,
+ 16786,
+ 16857,
+ 16865,
];
#[cfg(all(not(feature = "debug"), feature = "universal_fw"))]
@@ -18114,15 +18100,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -18133,6 +18112,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -18140,11 +18120,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -19382,38 +19367,37 @@ impl TranslatedString {
16206,
16206,
16206,
- 16224,
- 16272,
- 16343,
- 16355,
- 16378,
- 16399,
- 16399,
- 16412,
- 16441,
- 16460,
- 16468,
- 16468,
- 16490,
- 16554,
- 16569,
- 16569,
- 16588,
- 16636,
- 16646,
- 16653,
- 16653,
- 16672,
- 16713,
- 16740,
- 16742,
- 16742,
- 16765,
- 16838,
- 16853,
- 16862,
- 16875,
- 16883,
+ 16218,
+ 16218,
+ 16237,
+ 16245,
+ 16245,
+ 16267,
+ 16331,
+ 16346,
+ 16346,
+ 16365,
+ 16413,
+ 16423,
+ 16452,
+ 16459,
+ 16459,
+ 16478,
+ 16519,
+ 16546,
+ 16548,
+ 16548,
+ 16596,
+ 16619,
+ 16692,
+ 16707,
+ 16730,
+ 16751,
+ 16764,
+ 16773,
+ 16786,
+ 16857,
+ 16865,
];
#[cfg(all(not(feature = "debug"), not(feature = "universal_fw")))]
@@ -20649,15 +20633,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"",
@@ -20668,6 +20645,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"",
"EIP-7702 Revocation",
@@ -20675,11 +20653,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -21917,38 +21900,37 @@ impl TranslatedString {
16206,
16206,
16206,
- 16224,
- 16272,
- 16343,
- 16355,
- 16378,
- 16399,
- 16399,
- 16412,
- 16441,
- 16460,
- 16468,
- 16468,
- 16490,
- 16554,
- 16569,
- 16569,
- 16588,
- 16636,
- 16646,
- 16653,
- 16653,
- 16672,
- 16713,
- 16740,
- 16742,
- 16742,
- 16765,
- 16838,
- 16853,
- 16862,
- 16875,
- 16883,
+ 16218,
+ 16218,
+ 16237,
+ 16245,
+ 16245,
+ 16267,
+ 16331,
+ 16346,
+ 16346,
+ 16365,
+ 16413,
+ 16423,
+ 16452,
+ 16459,
+ 16459,
+ 16478,
+ 16519,
+ 16546,
+ 16548,
+ 16548,
+ 16596,
+ 16619,
+ 16692,
+ 16707,
+ 16730,
+ 16751,
+ 16764,
+ 16773,
+ 16786,
+ 16857,
+ 16865,
];
} else if #[cfg(feature = "layout_delizia")] {
@@ -23185,15 +23167,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -23204,6 +23179,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -23211,11 +23187,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"Re-enter new PIN.",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -24453,38 +24434,37 @@ impl TranslatedString {
18203,
18203,
18203,
- 18221,
- 18269,
- 18340,
- 18352,
- 18375,
- 18396,
- 18396,
- 18409,
- 18438,
- 18457,
- 18465,
- 18495,
- 18517,
- 18581,
- 18596,
- 18623,
- 18642,
- 18690,
- 18700,
- 18707,
- 18734,
- 18753,
- 18794,
- 18821,
- 18823,
- 18840,
- 18863,
- 18936,
- 18951,
- 18960,
- 18973,
- 18981,
+ 18215,
+ 18215,
+ 18234,
+ 18242,
+ 18272,
+ 18294,
+ 18358,
+ 18373,
+ 18400,
+ 18419,
+ 18467,
+ 18477,
+ 18506,
+ 18513,
+ 18540,
+ 18559,
+ 18600,
+ 18627,
+ 18629,
+ 18646,
+ 18694,
+ 18717,
+ 18790,
+ 18805,
+ 18828,
+ 18849,
+ 18862,
+ 18871,
+ 18884,
+ 18955,
+ 18963,
];
#[cfg(all(feature = "debug", not(feature = "universal_fw")))]
@@ -25720,15 +25700,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -25739,6 +25712,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -25746,11 +25720,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"Re-enter new PIN.",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -26988,38 +26967,37 @@ impl TranslatedString {
18203,
18203,
18203,
- 18221,
- 18269,
- 18340,
- 18352,
- 18375,
- 18396,
- 18396,
- 18409,
- 18438,
- 18457,
- 18465,
- 18495,
- 18517,
- 18581,
- 18596,
- 18623,
- 18642,
- 18690,
- 18700,
- 18707,
- 18734,
- 18753,
- 18794,
- 18821,
- 18823,
- 18840,
- 18863,
- 18936,
- 18951,
- 18960,
- 18973,
- 18981,
+ 18215,
+ 18215,
+ 18234,
+ 18242,
+ 18272,
+ 18294,
+ 18358,
+ 18373,
+ 18400,
+ 18419,
+ 18467,
+ 18477,
+ 18506,
+ 18513,
+ 18540,
+ 18559,
+ 18600,
+ 18627,
+ 18629,
+ 18646,
+ 18694,
+ 18717,
+ 18790,
+ 18805,
+ 18828,
+ 18849,
+ 18862,
+ 18871,
+ 18884,
+ 18955,
+ 18963,
];
#[cfg(all(not(feature = "debug"), feature = "universal_fw"))]
@@ -28255,15 +28233,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -28274,6 +28245,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -28281,11 +28253,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"Re-enter new PIN.",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -29523,38 +29500,37 @@ impl TranslatedString {
18203,
18203,
18203,
- 18221,
- 18269,
- 18340,
- 18352,
- 18375,
- 18396,
- 18396,
- 18409,
- 18438,
- 18457,
- 18465,
- 18495,
- 18517,
- 18581,
- 18596,
- 18623,
- 18642,
- 18690,
- 18700,
- 18707,
- 18734,
- 18753,
- 18794,
- 18821,
- 18823,
- 18840,
- 18863,
- 18936,
- 18951,
- 18960,
- 18973,
- 18981,
+ 18215,
+ 18215,
+ 18234,
+ 18242,
+ 18272,
+ 18294,
+ 18358,
+ 18373,
+ 18400,
+ 18419,
+ 18467,
+ 18477,
+ 18506,
+ 18513,
+ 18540,
+ 18559,
+ 18600,
+ 18627,
+ 18629,
+ 18646,
+ 18694,
+ 18717,
+ 18790,
+ 18805,
+ 18828,
+ 18849,
+ 18862,
+ 18871,
+ 18884,
+ 18955,
+ 18963,
];
#[cfg(all(not(feature = "debug"), not(feature = "universal_fw")))]
@@ -30790,15 +30766,8 @@ impl TranslatedString {
"Account deletion",
"",
"",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -30809,6 +30778,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -30816,11 +30786,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"Re-enter new PIN.",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -32058,38 +32033,37 @@ impl TranslatedString {
18203,
18203,
18203,
- 18221,
- 18269,
- 18340,
- 18352,
- 18375,
- 18396,
- 18396,
- 18409,
- 18438,
- 18457,
- 18465,
- 18495,
- 18517,
- 18581,
- 18596,
- 18623,
- 18642,
- 18690,
- 18700,
- 18707,
- 18734,
- 18753,
- 18794,
- 18821,
- 18823,
- 18840,
- 18863,
- 18936,
- 18951,
- 18960,
- 18973,
- 18981,
+ 18215,
+ 18215,
+ 18234,
+ 18242,
+ 18272,
+ 18294,
+ 18358,
+ 18373,
+ 18400,
+ 18419,
+ 18467,
+ 18477,
+ 18506,
+ 18513,
+ 18540,
+ 18559,
+ 18600,
+ 18627,
+ 18629,
+ 18646,
+ 18694,
+ 18717,
+ 18790,
+ 18805,
+ 18828,
+ 18849,
+ 18862,
+ 18871,
+ 18884,
+ 18955,
+ 18963,
];
} else if #[cfg(feature = "layout_eckhart")] {
@@ -33326,15 +33300,8 @@ impl TranslatedString {
"Account deletion",
"Tap to wake",
"Made in",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"This is NOT your address",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -33345,6 +33312,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -33352,11 +33320,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -34594,38 +34567,37 @@ impl TranslatedString {
19539,
19550,
19557,
- 19575,
- 19623,
- 19694,
- 19706,
- 19729,
- 19750,
- 19774,
- 19787,
- 19816,
- 19835,
- 19843,
- 19873,
- 19895,
- 19959,
- 19974,
- 20001,
- 20020,
- 20068,
+ 19569,
+ 19593,
+ 19612,
+ 19620,
+ 19650,
+ 19672,
+ 19736,
+ 19751,
+ 19778,
+ 19797,
+ 19845,
+ 19855,
+ 19884,
+ 19891,
+ 19918,
+ 19937,
+ 19978,
+ 20005,
+ 20007,
+ 20007,
+ 20055,
20078,
- 20085,
- 20112,
- 20131,
- 20172,
- 20199,
- 20201,
- 20201,
- 20224,
- 20297,
- 20312,
- 20321,
- 20334,
- 20342,
+ 20151,
+ 20166,
+ 20189,
+ 20210,
+ 20223,
+ 20232,
+ 20245,
+ 20316,
+ 20324,
];
#[cfg(all(feature = "debug", not(feature = "universal_fw")))]
@@ -35861,15 +35833,8 @@ impl TranslatedString {
"Account deletion",
"Tap to wake",
"Made in",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"This is NOT your address",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -35880,6 +35845,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -35887,11 +35853,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -37129,38 +37100,37 @@ impl TranslatedString {
19539,
19550,
19557,
- 19575,
- 19623,
- 19694,
- 19706,
- 19729,
- 19750,
- 19774,
- 19787,
- 19816,
- 19835,
- 19843,
- 19873,
- 19895,
- 19959,
- 19974,
- 20001,
- 20020,
- 20068,
+ 19569,
+ 19593,
+ 19612,
+ 19620,
+ 19650,
+ 19672,
+ 19736,
+ 19751,
+ 19778,
+ 19797,
+ 19845,
+ 19855,
+ 19884,
+ 19891,
+ 19918,
+ 19937,
+ 19978,
+ 20005,
+ 20007,
+ 20007,
+ 20055,
20078,
- 20085,
- 20112,
- 20131,
- 20172,
- 20199,
- 20201,
- 20201,
- 20224,
- 20297,
- 20312,
- 20321,
- 20334,
- 20342,
+ 20151,
+ 20166,
+ 20189,
+ 20210,
+ 20223,
+ 20232,
+ 20245,
+ 20316,
+ 20324,
];
#[cfg(all(not(feature = "debug"), feature = "universal_fw"))]
@@ -38396,15 +38366,8 @@ impl TranslatedString {
"Account deletion",
"Tap to wake",
"Made in",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"This is NOT your address",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -38415,6 +38378,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -38422,11 +38386,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -39664,38 +39633,37 @@ impl TranslatedString {
19539,
19550,
19557,
- 19575,
- 19623,
- 19694,
- 19706,
- 19729,
- 19750,
- 19774,
- 19787,
- 19816,
- 19835,
- 19843,
- 19873,
- 19895,
- 19959,
- 19974,
- 20001,
- 20020,
- 20068,
+ 19569,
+ 19593,
+ 19612,
+ 19620,
+ 19650,
+ 19672,
+ 19736,
+ 19751,
+ 19778,
+ 19797,
+ 19845,
+ 19855,
+ 19884,
+ 19891,
+ 19918,
+ 19937,
+ 19978,
+ 20005,
+ 20007,
+ 20007,
+ 20055,
20078,
- 20085,
- 20112,
- 20131,
- 20172,
- 20199,
- 20201,
- 20201,
- 20224,
- 20297,
- 20312,
- 20321,
- 20334,
- 20342,
+ 20151,
+ 20166,
+ 20189,
+ 20210,
+ 20223,
+ 20232,
+ 20245,
+ 20316,
+ 20324,
];
#[cfg(all(not(feature = "debug"), not(feature = "universal_fw")))]
@@ -40931,15 +40899,8 @@ impl TranslatedString {
"Account deletion",
"Tap to wake",
"Made in",
- "Application domain",
- "The following message requires multiple signers.",
- "Communication with your connected device failed. It's safe to continue.",
"Cosigner {0}",
- "Claim unfrozen balance?",
- "Claim voting rewards?",
"This is NOT your address",
- "Owner address",
- "dApp did not identify itself!",
"Max coordinator fee",
"All EVMs",
"EIP-7702 authorization signed.",
@@ -40950,6 +40911,7 @@ impl TranslatedString {
"EIP-7702 Delegation",
"Delegate your account to a third-party contract?",
"Delegating",
+ "dApp did not identify itself!",
"Network",
"EIP-7702 revocation signed.",
"EIP-7702 Revocation",
@@ -40957,11 +40919,16 @@ impl TranslatedString {
"Smart account contract info",
"To",
"",
+ "The following message requires multiple signers.",
"External Authorizations",
"Transaction contains additional invocations authorized by external means.",
"Invoke Contract",
+ "Claim unfrozen balance?",
+ "Claim voting rewards?",
+ "Owner address",
"Arguments",
"Authorization",
+ "Communication with your connected device failed. It's safe to continue.",
"Function",
);
@@ -42199,38 +42166,37 @@ impl TranslatedString {
19539,
19550,
19557,
- 19575,
- 19623,
- 19694,
- 19706,
- 19729,
- 19750,
- 19774,
- 19787,
- 19816,
- 19835,
- 19843,
- 19873,
- 19895,
- 19959,
- 19974,
- 20001,
- 20020,
- 20068,
+ 19569,
+ 19593,
+ 19612,
+ 19620,
+ 19650,
+ 19672,
+ 19736,
+ 19751,
+ 19778,
+ 19797,
+ 19845,
+ 19855,
+ 19884,
+ 19891,
+ 19918,
+ 19937,
+ 19978,
+ 20005,
+ 20007,
+ 20007,
+ 20055,
20078,
- 20085,
- 20112,
- 20131,
- 20172,
- 20199,
- 20201,
- 20201,
- 20224,
- 20297,
- 20312,
- 20321,
- 20334,
- 20342,
+ 20151,
+ 20166,
+ 20189,
+ 20210,
+ 20223,
+ 20232,
+ 20245,
+ 20316,
+ 20324,
];
}
@@ -43472,8 +43438,6 @@ impl TranslatedString {
#[cfg(feature = "universal_fw")]
(Qstr::MP_QSTR_solana__account_index, Self::solana__account_index),
#[cfg(feature = "universal_fw")]
- (Qstr::MP_QSTR_solana__app_domain, Self::solana__app_domain),
- #[cfg(feature = "universal_fw")]
(Qstr::MP_QSTR_solana__associated_token_account, Self::solana__associated_token_account),
#[cfg(feature = "universal_fw")]
(Qstr::MP_QSTR_solana__base_fee, Self::solana__base_fee),
diff --git a/core/mocks/trezortranslate_keys.pyi b/core/mocks/trezortranslate_keys.pyi
index be2fba9c..a85ab9f8 100644
--- a/core/mocks/trezortranslate_keys.pyi
+++ b/core/mocks/trezortranslate_keys.pyi
@@ -887,7 +887,6 @@ class TR:
sn__action: str = "Allow connected device to get serial number of your Trezor Safe 7?"
sn__title: str = "Serial number"
solana__account_index: str = "Account index"
- solana__app_domain: str = "Application domain"
solana__associated_token_account: str = "Associated token account"
solana__base_fee: str = "Base fee"
solana__claim: str = "Claim"
diff --git a/core/src/apps/solana/README.md b/core/src/apps/solana/README.md
index 219a35b9..469e148a 100644
--- a/core/src/apps/solana/README.md
+++ b/core/src/apps/solana/README.md
@@ -196,6 +196,4 @@ The presence of multisig instructions within the Token program adds an additiona
## Off-Chain Message Signing
-We support signing and verifying off-chain messages as defined by the [Solana off-chain message signing spec v0](https://docs.anza.xyz/proposals/off-chain-message-signing). The firmware expects messages already formatted according to the spec (i.e., prefixed with `\xffsolana offchain`); [trezorlib](../../../../python/src/trezorlib/solana.py) provides utilities to do so. For verification, the firmware expects the message wrapped in an [envelope](https://docs.anza.xyz/proposals/off-chain-message-signing#envelope) (signatures concatenated with the formatted message). Also see [messages-solana.proto](../../../../common/protob/messages-solana.proto).
-
-The spec requires that HW wallets clear-sign format 0 (ASCII), blind-sign format 1 (short UTF-8), and reject format 2 (long UTF-8) messages. We deviate from this and clear-sign all formats, since Trezor can display longer messages including non-ASCII characters, making the restriction arbitrary. This limitation is also removed in the newer [v1 spec](https://github.com/solana-foundation/SRFCs/discussions/3).
+We support signing and verifying off-chain messages as defined by the [Solana off-chain message signing spec v1](https://docs.anza.xyz/proposals/off-chain-message-signing). Also see [messages-solana.proto](../../../../common/protob/messages-solana.proto).
diff --git a/core/src/apps/solana/constants.py b/core/src/apps/solana/constants.py
index 768a4e7e..9bafad79 100644
--- a/core/src/apps/solana/constants.py
+++ b/core/src/apps/solana/constants.py
@@ -1,7 +1,6 @@
from micropython import const
ADDRESS_SIZE = const(32)
-SIGNATURE_SIZE = const(64)
SOLANA_BASE_FEE_LAMPORTS = const(5000)
SOLANA_COMPUTE_UNIT_LIMIT = const(200000)
diff --git a/core/src/apps/solana/layout.py b/core/src/apps/solana/layout.py
index c6afbeb1..4798b6d1 100644
--- a/core/src/apps/solana/layout.py
+++ b/core/src/apps/solana/layout.py
@@ -21,11 +21,10 @@ from .types import AddressType, is_address_reference
if TYPE_CHECKING:
from typing import Sequence
- from trezor.messages import PaymentRequest, SolanaTokenInfo
+ from trezor.messages import PaymentRequest, SolanaOffchainMessageV1, SolanaTokenInfo
from trezor.ui.layouts import PropertyType, StrPropertyType
from .definitions import Definitions
- from .offchain_message import OffchainMessage
from .transaction import Fee
from .transaction.instructions import Instruction, SystemProgramTransferInstruction
from .types import AddressReference
@@ -637,7 +636,7 @@ async def confirm_payment_request(
async def confirm_offchain_signverify(
- offchain_message: OffchainMessage,
+ offchain_message: SolanaOffchainMessageV1,
verify: bool,
signer_index: int = 0,
signer_path: list[int] | None = None,
@@ -645,16 +644,6 @@ async def confirm_offchain_signverify(
) -> None:
from trezor.ui.layouts import confirm_address, confirm_signverify
- from .offchain_message import OffchainMessageV0
-
- if isinstance(offchain_message, OffchainMessageV0):
- await confirm_address(
- TR.solana__app_domain,
- base58.encode(offchain_message.app),
- verb=TR.buttons__continue,
- chunkify=chunkify,
- )
-
if len(offchain_message.signers) > 1:
await confirm_metadata(
"confirm_multisig",
diff --git a/core/src/apps/solana/offchain_message.py b/core/src/apps/solana/offchain_message.py
index d1cc4ac6..ca0ed026 100644
--- a/core/src/apps/solana/offchain_message.py
+++ b/core/src/apps/solana/offchain_message.py
@@ -1,143 +1,40 @@
-from micropython import const
-from typing import TYPE_CHECKING, Sequence
+from typing import TYPE_CHECKING
-from trezor.utils import BufferReader
+from trezor.utils import empty_bytearray
from trezor.wire import DataError
+from .constants import ADDRESS_SIZE
+
if TYPE_CHECKING:
from buffer_types import AnyBytes
- from enum import IntEnum
-
- from typing_extensions import Self
-else:
- IntEnum = object
-
-
-class OffchainMessage:
- SIGNING_DOMAIN = b"\xffsolana offchain"
-
- def __init__(self, signers: Sequence[AnyBytes], message: str) -> None:
- self.signers = signers
- self.message = message
-
- @classmethod
- def _from_reader(cls, reader: BufferReader) -> "OffchainMessage":
- if reader.read_memoryview(len(cls.SIGNING_DOMAIN)) != cls.SIGNING_DOMAIN:
- raise DataError("Invalid signing domain")
-
- version = reader.get()
- if version == 0:
- return OffchainMessageV0._from_reader(reader)
- raise DataError(f"Unsupported version: {version}")
-
- @classmethod
- def from_bytes(cls, data: AnyBytes) -> "OffchainMessage":
- try:
- return cls._from_reader(BufferReader(data))
- except EOFError:
- raise DataError("Message too short")
-
-
-class OffchainMessageV0(OffchainMessage):
-
- APP_DOMAIN_LEN = const(32)
- MAX_COMBINED_MSG_LEN_SHORT = const(1232)
- MAX_COMBINED_MSG_LEN = const(65535)
-
- def __init__(
- self, signers: Sequence[AnyBytes], message: str, app: AnyBytes, format: int
- ) -> None:
- super().__init__(signers, message)
- self.app = app
- self.format = format
-
- class MessageFormat(IntEnum):
- ASCII_SHORT = const(0)
- UTF8_SHORT = const(1)
- UTF8_LONG = const(2)
-
- @classmethod
- def max_len(cls, format: int) -> int:
- if format in (cls.ASCII_SHORT, cls.UTF8_SHORT):
- return OffchainMessageV0.MAX_COMBINED_MSG_LEN_SHORT
- if format == cls.UTF8_LONG:
- return OffchainMessageV0.MAX_COMBINED_MSG_LEN
- raise DataError(f"Invalid message format: {format}")
-
- @classmethod
- def _from_reader(cls, reader: BufferReader) -> Self:
- from apps.common.readers import read_uint16_le
- from apps.common.signverify import is_printable_ascii
-
- from .constants import ADDRESS_SIZE
-
- app = reader.read_memoryview(cls.APP_DOMAIN_LEN)
-
- format = reader.get()
- combined_len = len(reader.buffer)
- if combined_len > cls.MessageFormat.max_len(format):
- raise DataError("Message is too long")
-
- n_signers = reader.get()
- if n_signers == 0:
- raise DataError("At least one signer is required")
- signers = [reader.read_memoryview(ADDRESS_SIZE) for _ in range(n_signers)]
-
- message_len = read_uint16_le(reader)
- if message_len == 0:
- raise DataError("Message cannot be empty")
- message_bytes = reader.read_memoryview(message_len)
- if reader.remaining_count() != 0:
- raise DataError("Invalid message length")
- if format == cls.MessageFormat.ASCII_SHORT and not is_printable_ascii(
- message_bytes
- ):
- raise DataError("Invalid message format")
- try:
- message = str(message_bytes, "utf-8")
- except UnicodeError:
- raise DataError("Invalid message encoding")
-
- return cls(signers, message, app, format)
-
-class Envelope:
- def __init__(
- self,
- signatures: Sequence[AnyBytes],
- message_bytes: AnyBytes,
- ) -> None:
- self.signatures = signatures
- self.message = OffchainMessage.from_bytes(message_bytes)
- # we keep the raw bytes around for signature verification
- self._message_bytes = message_bytes
+ from trezor.messages import SolanaOffchainMessageV1
- if len(self.signatures) != len(self.message.signers):
- raise DataError("Number of signatures must match number of signers")
+_SIGNING_DOMAIN = b"\xffsolana offchain"
- @classmethod
- def _from_reader(cls, reader: BufferReader) -> Self:
- from .constants import SIGNATURE_SIZE
- n_signatures = reader.get()
- signatures = [
- reader.read_memoryview(SIGNATURE_SIZE) for _ in range(n_signatures)
- ]
+def serialize_offchain_message(message: SolanaOffchainMessageV1) -> AnyBytes:
+ if not 0 < len(message.signers) < 256:
+ raise DataError("Invalid number of signers")
+ if not all(len(signer) == ADDRESS_SIZE for signer in message.signers):
+ raise DataError("Invalid signer address length")
+ signers = sorted(set(map(bytes, message.signers)))
+ if len(signers) != len(message.signers):
+ raise DataError("Signer list must not contain duplicates")
- message_bytes = reader.read_memoryview()
+ if not message.message:
+ raise DataError("Message cannot be empty")
- return cls(signatures, message_bytes)
+ msg_bytes = message.message.encode()
- @classmethod
- def from_bytes(cls, data: AnyBytes) -> Self:
- try:
- return cls._from_reader(BufferReader(data))
- except EOFError:
- raise DataError("Envelope too short")
+ size = len(_SIGNING_DOMAIN) + 2 + ADDRESS_SIZE * len(signers) + len(msg_bytes)
+ buf = empty_bytearray(size)
- def verify(self) -> None:
- from trezor.crypto.curve import ed25519
+ buf.extend(_SIGNING_DOMAIN)
+ buf.append(1) # version
+ buf.append(len(signers))
+ for signer in signers:
+ buf.extend(signer)
+ buf.extend(msg_bytes)
- for signature, signer in zip(self.signatures, self.message.signers):
- if not ed25519.verify(signer, signature, self._message_bytes):
- raise DataError("Invalid signature")
+ return buf
diff --git a/core/src/apps/solana/sign_message.py b/core/src/apps/solana/sign_message.py
index 228ebb81..bb08c2f0 100644
--- a/core/src/apps/solana/sign_message.py
+++ b/core/src/apps/solana/sign_message.py
@@ -21,9 +21,10 @@ async def sign_message(
from apps.common import seed
from .layout import confirm_offchain_signverify
- from .offchain_message import OffchainMessage
+ from .offchain_message import serialize_offchain_message
- offchain_message = OffchainMessage.from_bytes(msg.message)
+ offchain_message = msg.message
+ serialized = serialize_offchain_message(offchain_message)
node = keychain.derive(msg.address_n)
public_key = seed.remove_ed25519_prefix(node.public_key())
@@ -40,5 +41,5 @@ async def sign_message(
chunkify=bool(msg.chunkify),
)
- signature = ed25519.sign(node.private_key(), msg.message)
- return SolanaMessageSignature(signature=signature)
+ signature = ed25519.sign(node.private_key(), serialized)
+ return SolanaMessageSignature(signature=signature, signed_data=serialized)
diff --git a/core/src/apps/solana/verify_message.py b/core/src/apps/solana/verify_message.py
index 9f35fa2c..4cbe87a8 100644
--- a/core/src/apps/solana/verify_message.py
+++ b/core/src/apps/solana/verify_message.py
@@ -6,18 +6,24 @@ if TYPE_CHECKING:
async def verify_message(msg: SolanaVerifyMessage) -> Success:
from trezor import TR
+ from trezor.crypto.curve import ed25519
from trezor.messages import Success
from trezor.ui.layouts import show_success
+ from trezor.wire import DataError
from .layout import confirm_offchain_signverify
- from .offchain_message import Envelope
+ from .offchain_message import serialize_offchain_message
- envelope = Envelope.from_bytes(msg.envelope)
+ serialized = serialize_offchain_message(msg.message)
- envelope.verify()
+ if len(msg.signatures) != len(msg.message.signers):
+ raise DataError("Number of signatures must match number of signers")
+ for signature, signer in zip(msg.signatures, msg.message.signers):
+ if not ed25519.verify(signer, signature, serialized):
+ raise DataError("Invalid signature")
await confirm_offchain_signverify(
- envelope.message, verify=True, chunkify=bool(msg.chunkify)
+ msg.message, verify=True, chunkify=bool(msg.chunkify)
)
# TODO: add a generic (not specific to any coin) valid signature message
diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py
index a037f886..62043346 100644
--- a/core/src/trezor/messages.py
+++ b/core/src/trezor/messages.py
@@ -6106,15 +6106,31 @@ if TYPE_CHECKING:
def is_type_of(cls, msg: Any) -> TypeGuard["SolanaTxSignature"]:
return isinstance(msg, cls)
+ class SolanaOffchainMessageV1(protobuf.MessageType):
+ message: "str"
+ signers: "list[AnyBytes]"
+
+ def __init__(
+ self,
+ *,
+ message: "str",
+ signers: "list[AnyBytes] | None" = None,
+ ) -> None:
+ pass
+
+ @classmethod
+ def is_type_of(cls, msg: Any) -> TypeGuard["SolanaOffchainMessageV1"]:
+ return isinstance(msg, cls)
+
class SolanaSignMessage(protobuf.MessageType):
address_n: "list[int]"
- message: "AnyBytes"
chunkify: "bool | None"
+ message: "SolanaOffchainMessageV1"
def __init__(
self,
*,
- message: "AnyBytes",
+ message: "SolanaOffchainMessageV1",
address_n: "list[int] | None" = None,
chunkify: "bool | None" = None,
) -> None:
@@ -6126,11 +6142,13 @@ if TYPE_CHECKING:
class SolanaMessageSignature(protobuf.MessageType):
signature: "AnyBytes"
+ signed_data: "AnyBytes | None"
def __init__(
self,
*,
signature: "AnyBytes",
+ signed_data: "AnyBytes | None" = None,
) -> None:
pass
@@ -6139,13 +6157,15 @@ if TYPE_CHECKING:
return isinstance(msg, cls)
class SolanaVerifyMessage(protobuf.MessageType):
- envelope: "AnyBytes"
chunkify: "bool | None"
+ message: "SolanaOffchainMessageV1"
+ signatures: "list[AnyBytes]"
def __init__(
self,
*,
- envelope: "AnyBytes",
+ message: "SolanaOffchainMessageV1",
+ signatures: "list[AnyBytes] | None" = None,
chunkify: "bool | None" = None,
) -> None:
pass
diff --git a/core/tests/test_apps.solana.offchain_message.py b/core/tests/test_apps.solana.offchain_message.py
index 66d90371..8751eafb 100644
--- a/core/tests/test_apps.solana.offchain_message.py
+++ b/core/tests/test_apps.solana.offchain_message.py
@@ -7,26 +7,14 @@ from trezor.wire import DataError
from common import unittest, utils
if not utils.BITCOIN_ONLY:
+ from trezor.messages import SolanaOffchainMessageV1
+
from apps.solana.constants import *
from apps.solana.offchain_message import *
-
- DOM = OffchainMessage.SIGNING_DOMAIN
- APP = b"a" * OffchainMessageV0.APP_DOMAIN_LEN
else:
- DOM = b""
- APP = b""
ADDRESS_SIZE = 0
-
-VER_0 = b"\x00"
-
-FORM_ASCII = b"\x00"
-FORM_UTF8_S = b"\x01"
-FORM_UTF8_L = b"\x02"
-
-MSG_ASCII = b"Hello, world!"
-MSG_UTF8_S = "Hello, 🌍!".encode()
-MSG_UTF8_L = MSG_UTF8_S * 1000
+MSG = "Hello, world!"
PUB0 = b"p" * ADDRESS_SIZE
PUB1 = b"q" * ADDRESS_SIZE
@@ -35,168 +23,72 @@ PUB1 = b"q" * ADDRESS_SIZE
# https://www.solanakit.com/docs/advanced-guides/offchain-messages
TEST_VECTORS = [
{
- "app": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",
"signers": ["11111111111111111111111111111111"],
"message": "Hello, world!",
- "format": 0,
- "hex": "ff736f6c616e61206f6666636861696e00054a535a992921064d24e87160da387c7c35b5ddbc92bb81e41fa8404105448d000100000000000000000000000000000000000000000000000000000000000000000d0048656c6c6f2c20776f726c6421",
+ "hex": "ff736f6c616e61206f6666636861696e0101000000000000000000000000000000000000000000000000000000000000000048656c6c6f2c20776f726c6421",
},
{
- "app": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",
"signers": ["11111111111111111111111111111111"],
"message": "Solana off-chain message with émojis ☀️🏖️ and spëcial châräctérs! 日本語テスト ",
- "format": 1,
- "hex": "ff736f6c616e61206f6666636861696e00054a535a992921064d24e87160da387c7c35b5ddbc92bb81e41fa8404105448d010100000000000000000000000000000000000000000000000000000000000000006300536f6c616e61206f66662d636861696e206d657373616765207769746820c3a96d6f6a697320e29880efb88ff09f8f96efb88f20616e64207370c3ab6369616c206368c3a272c3a46374c3a972732120e697a5e69cace8aa9ee38386e382b9e3838820",
- },
- {
- "app": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",
- "signers": ["11111111111111111111111111111111"],
- "message": "This uses the extended UTF-8 format allowing up to 65535 bytes.",
- "format": 2,
- "hex": "ff736f6c616e61206f6666636861696e00054a535a992921064d24e87160da387c7c35b5ddbc92bb81e41fa8404105448d020100000000000000000000000000000000000000000000000000000000000000003f005468697320757365732074686520657874656e646564205554462d3820666f726d617420616c6c6f77696e6720757020746f2036353533352062797465732e",
+ "hex": "ff736f6c616e61206f6666636861696e01010000000000000000000000000000000000000000000000000000000000000000536f6c616e61206f66662d636861696e206d657373616765207769746820c3a96d6f6a697320e29880efb88ff09f8f96efb88f20616e64207370c3ab6369616c206368c3a272c3a46374c3a972732120e697a5e69cace8aa9ee38386e382b9e3838820",
},
{
- "app": "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",
"signers": [
"11111111111111111111111111111111",
"Vote111111111111111111111111111111111111111",
"Stake11111111111111111111111111111111111111",
],
"message": "Multi-party agreement.",
- "format": 0,
- "hex": "ff736f6c616e61206f6666636861696e00054a535a992921064d24e87160da387c7c35b5ddbc92bb81e41fa8404105448d000300000000000000000000000000000000000000000000000000000000000000000761481d357474bb7c4d7624ebd3bdb3d8355e73d11043fc0da353800000000006a1d8179137542a983437bdfe2a7ab2557f535c8a78722b68a49dc00000000016004d756c74692d70617274792061677265656d656e742e",
+ "hex": "ff736f6c616e61206f6666636861696e0103000000000000000000000000000000000000000000000000000000000000000006a1d8179137542a983437bdfe2a7ab2557f535c8a78722b68a49dc0000000000761481d357474bb7c4d7624ebd3bdb3d8355e73d11043fc0da35380000000004d756c74692d70617274792061677265656d656e742e",
},
]
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
-class TestMessageV0(unittest.TestCase):
-
- def assertMsgEqual(self, offchain, app, signers, form, message):
- self.assertEqual(offchain.app, app)
- self.assertListEqual(offchain.signers, signers)
- self.assertEqual(offchain.format, form)
- self.assertEqual(offchain.message, message)
-
- def try_parse(
- self,
- dom=DOM,
- ver=VER_0,
- app=APP,
- pubs=(PUB0,),
- n_pubs=None,
- form=FORM_ASCII,
- msg=MSG_ASCII,
- msg_len=None,
- ):
- if n_pubs is None:
- n_pubs = len(pubs).to_bytes(1, "little")
- if msg_len is None:
- msg_len = len(msg).to_bytes(2, "little")
-
- data = dom + ver + app + form + n_pubs + b"".join(pubs) + msg_len + msg
- offchain = OffchainMessage.from_bytes(data)
-
- self.assertMsgEqual(offchain, app, pubs, form[0], msg.decode())
-
- return data, offchain
+class TestMessageV1(unittest.TestCase):
- def test_vectors(self):
- for vector in TEST_VECTORS:
- offchain = OffchainMessage.from_bytes(unhexlify(vector["hex"]))
-
- self.assertMsgEqual(
- offchain,
- base58.decode(vector["app"]),
- [base58.decode(s) for s in vector["signers"]],
- vector["format"],
- vector["message"],
- )
-
- def test_basic(self):
- configs = (
- (FORM_ASCII, MSG_ASCII),
- (FORM_UTF8_S, MSG_ASCII),
- (FORM_UTF8_S, MSG_UTF8_S),
- (FORM_UTF8_L, MSG_ASCII),
- (FORM_UTF8_L, MSG_UTF8_S),
- (FORM_UTF8_L, MSG_UTF8_L),
+ def serialize(self, signers=None, message=MSG):
+ msg = SolanaOffchainMessageV1(
+ message=message,
+ signers=signers if signers is not None else [PUB0],
)
+ return serialize_offchain_message(msg)
- for form, msg in configs:
- self.try_parse(form=form, msg=msg)
-
- def test_multi(self):
- self.try_parse(pubs=[PUB0, PUB1])
-
- def test_domain_invalid(self):
- with self.assertRaises(DataError):
- self.try_parse(dom=b"\x00solana offchain")
-
- def test_version_unsupported(self):
- with self.assertRaises(DataError):
- self.try_parse(ver=b"\xff")
-
- def test_format_mismatch(self):
- with self.assertRaises(DataError):
- self.try_parse(form=FORM_ASCII, msg=MSG_UTF8_S)
- with self.assertRaises(DataError):
- self.try_parse(form=FORM_UTF8_S, msg=MSG_UTF8_L)
-
- def test_format_invalid(self):
- with self.assertRaises(DataError):
- self.try_parse(form=b"\x03")
-
- def test_ascii_restricted(self):
- self.try_parse(form=FORM_ASCII, msg=bytes(range(0x20, 0x7F)))
-
- def test_ascii_unrestricted(self):
- with self.assertRaises(DataError):
- self.try_parse(form=FORM_ASCII, msg=b"\x1f")
- with self.assertRaises(DataError):
- self.try_parse(form=FORM_ASCII, msg=b"\x7f")
+ def test_vectors(self):
+ for vector in TEST_VECTORS:
+ signers = [base58.decode(signer) for signer in vector["signers"]]
+ serialized = self.serialize(signers, vector["message"])
+ self.assertEqual(serialized, unhexlify(vector["hex"]))
- def test_utf8_invalid(self):
+ def test_signers_empty(self):
with self.assertRaises(DataError):
- self.try_parse(form=FORM_UTF8_S, msg=b"\xff\xfe")
+ self.serialize(signers=[])
- def test_signer_count_zero(self):
+ def test_signers_too_many(self):
with self.assertRaises(DataError):
- self.try_parse(pubs=[], n_pubs=b"\x00")
+ self.serialize(signers=[PUB0] * 256)
- def test_signer_count_mismatch(self):
+ def test_signer_length_invalid(self):
with self.assertRaises(DataError):
- self.try_parse(pubs=[PUB0, PUB1], n_pubs=b"\x01")
+ self.serialize(signers=[PUB0[:-1]])
with self.assertRaises(DataError):
- self.try_parse(pubs=[PUB0], n_pubs=b"\x02")
-
- def test_message_length_zero(self):
+ self.serialize(signers=[PUB0, PUB0[:-1]])
with self.assertRaises(DataError):
- self.try_parse(msg=b"", msg_len=b"\x00\x00")
+ self.serialize(signers=[PUB0 + b"\x00"])
- def test_message_length_mismatch(self):
- with self.assertRaises(DataError):
- self.try_parse(msg=b"12345", msg_len=b"\x06\x00")
+ def test_signers_duplicated(self):
with self.assertRaises(DataError):
- self.try_parse(msg=b"12345", msg_len=b"\x04\x00")
+ self.serialize(signers=[PUB0, PUB0])
- def test_message_length_limits(self):
- configs = (
- (FORM_ASCII, OffchainMessageV0.MAX_COMBINED_MSG_LEN_SHORT),
- (FORM_UTF8_S, OffchainMessageV0.MAX_COMBINED_MSG_LEN_SHORT),
- (FORM_UTF8_L, OffchainMessageV0.MAX_COMBINED_MSG_LEN),
+ def test_signers_sorted(self):
+ self.assertEqual(
+ self.serialize(signers=[PUB0, PUB1]),
+ self.serialize(signers=[PUB1, PUB0]),
)
- PREAMBLE_LEN = 0x35 + ADDRESS_SIZE # for 1 signer
- for form, max_len in configs:
- max_msg_len = max_len - PREAMBLE_LEN
- msg = b"m" * max_msg_len
-
- msg_bytes, _ = self.try_parse(form=form, msg=msg)
- self.assertEqual(len(msg_bytes), max_len)
-
- with self.assertRaises(DataError):
- self.try_parse(form=form, msg=msg + b"m")
+ def test_message_empty(self):
+ with self.assertRaises(DataError):
+ self.serialize(message="")
if __name__ == "__main__":
diff --git a/core/translations/en.json b/core/translations/en.json
index 2f7a53ad..3b12aaad 100644
--- a/core/translations/en.json
+++ b/core/translations/en.json
@@ -2769,7 +2769,6 @@
"Eckhart": "Serial number"
},
"solana__account_index": "Account index",
- "solana__app_domain": "Application domain",
"solana__associated_token_account": "Associated token account",
"solana__base_fee": "Base fee",
"solana__claim": "Claim",
diff --git a/core/translations/order.json b/core/translations/order.json
index 234a1062..00c5a55b 100644
--- a/core/translations/order.json
+++ b/core/translations/order.json
@@ -1230,36 +1230,35 @@
"1228": "words__account_deletion",
"1229": "words__tap_to_wake",
"1230": "words__made_in",
- "1231": "solana__app_domain",
- "1232": "solana__offchain_is_multisig",
- "1233": "words__comm_continue",
- "1234": "address__title_cosigner_template",
- "1235": "tron__claim_unfrozen_balance",
- "1236": "tron__claim_voting_rewards",
- "1237": "address__warning_not_yours",
- "1238": "tron__owner_address",
- "1239": "ethereum__eip_712_empty_domain",
- "1240": "coinjoin__max_coordinator_fee_pct",
- "1241": "ethereum__all_evms",
- "1242": "ethereum__auth_done",
- "1243": "ethereum__auth_title",
- "1244": "ethereum__auth_warn",
- "1245": "ethereum__calldata_digest",
- "1246": "ethereum__delegate_done",
- "1247": "ethereum__delegate_title",
- "1248": "ethereum__delegate_warn",
- "1249": "ethereum__delegating",
- "1250": "ethereum__network",
- "1251": "ethereum__revoke_done",
- "1252": "ethereum__revoke_title",
- "1253": "ethereum__revoke_warn",
- "1254": "ethereum__smart_info",
- "1255": "ethereum__to",
- "1256": "pin__reenter_new_description",
- "1257": "stellar__ext_auth",
- "1258": "stellar__ext_auth_message",
- "1259": "stellar__invoke_contract",
- "1260": "words__arguments",
- "1261": "words__authorization",
- "1262": "words__function"
+ "1231": "address__title_cosigner_template",
+ "1232": "address__warning_not_yours",
+ "1233": "coinjoin__max_coordinator_fee_pct",
+ "1234": "ethereum__all_evms",
+ "1235": "ethereum__auth_done",
+ "1236": "ethereum__auth_title",
+ "1237": "ethereum__auth_warn",
+ "1238": "ethereum__calldata_digest",
+ "1239": "ethereum__delegate_done",
+ "1240": "ethereum__delegate_title",
+ "1241": "ethereum__delegate_warn",
+ "1242": "ethereum__delegating",
+ "1243": "ethereum__eip_712_empty_domain",
+ "1244": "ethereum__network",
+ "1245": "ethereum__revoke_done",
+ "1246": "ethereum__revoke_title",
+ "1247": "ethereum__revoke_warn",
+ "1248": "ethereum__smart_info",
+ "1249": "ethereum__to",
+ "1250": "pin__reenter_new_description",
+ "1251": "solana__offchain_is_multisig",
+ "1252": "stellar__ext_auth",
+ "1253": "stellar__ext_auth_message",
+ "1254": "stellar__invoke_contract",
+ "1255": "tron__claim_unfrozen_balance",
+ "1256": "tron__claim_voting_rewards",
+ "1257": "tron__owner_address",
+ "1258": "words__arguments",
+ "1259": "words__authorization",
+ "1260": "words__comm_continue",
+ "1261": "words__function"
}
diff --git a/core/translations/signatures.json b/core/translations/signatures.json
index 00f59ae6..6a3f7b58 100644
--- a/core/translations/signatures.json
+++ b/core/translations/signatures.json
@@ -1,8 +1,8 @@
{
"current": {
- "merkle_root": "067156bf0f3a04b74361af3386777212f3e6d41edde7cadb29e535a93ce1bcd4",
- "datetime": "2026-07-23T19:30:49.795793+00:00",
- "commit": "74d3b04801aaaf9f5c509d9b8104aa38ac616516"
+ "merkle_root": "74a2af9c3fbfacac8a434365e2d3aea74301e881b39ebaf91658fb818ebb399d",
+ "datetime": "2026-07-24T09:30:32.338781+00:00",
+ "commit": "4941ceac6671cbb7de07b1f6d49614331cafa222"
},
"history": [
{
diff --git a/python/.changelog.d/7053.incompatible b/python/.changelog.d/7053.incompatible
new file mode 100644
index 00000000..5d80d2ee
--- /dev/null
+++ b/python/.changelog.d/7053.incompatible
@@ -0,0 +1 @@
+Solana: add support for off-chain message signing (OCMS) v1 and remove v0.
diff --git a/python/src/trezorlib/cli/solana.py b/python/src/trezorlib/cli/solana.py
index c284e116..4fc87013 100644
--- a/python/src/trezorlib/cli/solana.py
+++ b/python/src/trezorlib/cli/solana.py
@@ -138,14 +138,9 @@ def sign_tx(
return signature.hex()
-DEFAULT_APP_DOMAIN = b"\x00" * solana.OffchainMessageV0.APP_LEN
-
-
@cli.command()
@click.argument("message", type=str)
@click.option("-n", "--address", default=DEFAULT_PATH, help=PATH_HELP)
-@click.option("-t", "--text", is_flag=True, help="Interpret message as text")
-@click.option("-a", "--app", type=str, help="Application domain (base58, 32 B)")
@click.option(
"-s",
"--signer",
@@ -159,95 +154,64 @@ def sign_message(
session: "Session",
address: str,
message: str,
- text: bool,
- app: str | None,
signer: tuple[str, ...],
chunkify: bool,
) -> str:
"""Sign a Solana off-chain message.
- There are two ways to specify the MESSAGE argument:
-
- 1. Raw mode (Default)
-
- sign-message [--address PATH] MESSAGE
-
- The provided MESSAGE is treated as a hex string representing a
- pre-formatted off-chain message. Only the --address option is
- allowed in this mode [1]. The specified address must correspond
- to one of the public keys in the message.
-
- 2. Format mode
-
- sign-message [--address PATH] [--app APP] [--signer SIGNER]... --text MESSAGE
-
- The provided MESSAGE is treated as a plain text string. The
- formatted message will be constructed based on the supplied
- arguments. The --signer option can be used multiple times. The
- final list of signers will consist of the public key derived
+ The --signer option can be used multiple times. The final
+ list of signers will consist of the public key derived
from --address, plus any public keys provided via --signer.
Also see: https://docs.anza.xyz/proposals/off-chain-message-signing
-
- [1] The --chunkify flag is always applicable.
"""
address_n = tools.parse_path(address)
- if text:
- app_bytes = tools.b58decode(app) if app else DEFAULT_APP_DOMAIN
-
- signers = [solana.get_public_key(session, address_n, show_display=False)]
- signers.extend(tools.b58decode(s) for s in signer)
+ signers = [solana.get_public_key(session, address_n, show_display=False)]
+ signers.extend(tools.b58decode(s) for s in signer)
- offchain_msg = solana.OffchainMessageV0(app_bytes, signers, message).to_bytes()
- else:
- if app or signer:
- raise click.UsageError("Only the --address option can be used in raw mode")
+ offchain_msg = messages.SolanaOffchainMessageV1(
+ signers=signers,
+ message=message,
+ )
- offchain_msg = bytes.fromhex(message)
+ result = solana.sign_message(session, address_n, offchain_msg, chunkify=chunkify)
- click.echo(f"Message: {offchain_msg.hex()}")
+ if result.signed_data is not None:
+ click.echo(f"Signed data: {result.signed_data.hex()}")
- signature = solana.sign_message(session, address_n, offchain_msg, chunkify=chunkify)
- return signature.hex()
+ return result.signature.hex()
@cli.command()
@click.argument("message", type=str)
-@click.option("-s", "--signature", type=str, multiple=True, help="Signature (hex)")
+@click.option(
+ "-s", "--signer", type=str, multiple=True, help="Public key of a signer (base58)"
+)
+@click.option("-S", "--signature", type=str, multiple=True, help="Signature (hex)")
@click.option("-C", "--chunkify", is_flag=True)
@with_session
def verify_message(
session: "Session",
message: str,
+ signer: tuple[str, ...],
signature: tuple[str, ...],
chunkify: bool,
) -> bool:
"""Verify a signed Solana off-chain message.
- This command operates in two modes depending on whether the
- --signature option is provided; in either case, the provided MESSAGE
- must be a hex string:
-
- If the --signature option is not used, the provided MESSAGE must
- be wrapped in an envelope containing signatures from all signers
- specified in the message header.
-
- If the --signature option is used, the provided MESSAGE must be a
- pre-formatted off-chain message without an envelope. You must provide
- all signatures in the correct order as specified by the message header
- (by using the --signature option multiple times if necessary). The
- envelope will be constructed automatically.
-
- Also see: https://docs.anza.xyz/proposals/off-chain-message-signing#envelope
+ The --signer and --signature options can be used multiple times.
+ Signatures must be provided in the order in which the corresponding
+ signers are listed.
"""
- if signature:
- signatures = [bytes.fromhex(s) for s in signature]
- msg_bytes = bytes.fromhex(message)
- envelope = solana.Envelope(signatures, msg_bytes).to_bytes()
- else:
- envelope = bytes.fromhex(message)
+ signers = [tools.b58decode(s) for s in signer]
+ signatures = [bytes.fromhex(s) for s in signature]
+
+ offchain_msg = messages.SolanaOffchainMessageV1(
+ signers=signers,
+ message=message,
+ )
- return solana.verify_message(session, envelope, chunkify=chunkify)
+ return solana.verify_message(session, offchain_msg, signatures, chunkify=chunkify)
diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py
index 9b10da80..0b726ac6 100644
--- a/python/src/trezorlib/messages.py
+++ b/python/src/trezorlib/messages.py
@@ -7906,18 +7906,35 @@ class SolanaTxSignature(protobuf.MessageType):
self.signature = signature
+class SolanaOffchainMessageV1(protobuf.MessageType):
+ MESSAGE_WIRE_TYPE = None
+ FIELDS = {
+ 1: protobuf.Field("message", "string", repeated=False, required=True),
+ 2: protobuf.Field("signers", "bytes", repeated=True, required=False, default=None),
+ }
+
+ def __init__(
+ self,
+ *,
+ message: "str",
+ signers: Optional[Sequence["bytes"]] = None,
+ ) -> None:
+ self.signers: Sequence["bytes"] = signers if signers is not None else []
+ self.message = message
+
+
class SolanaSignMessage(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 906
FIELDS = {
1: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None),
- 2: protobuf.Field("message", "bytes", repeated=False, required=True),
3: protobuf.Field("chunkify", "bool", repeated=False, required=False, default=None),
+ 4: protobuf.Field("message", "SolanaOffchainMessageV1", repeated=False, required=True),
}
def __init__(
self,
*,
- message: "bytes",
+ message: "SolanaOffchainMessageV1",
address_n: Optional[Sequence["int"]] = None,
chunkify: Optional["bool"] = None,
) -> None:
@@ -7930,30 +7947,36 @@ class SolanaMessageSignature(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 907
FIELDS = {
1: protobuf.Field("signature", "bytes", repeated=False, required=True),
+ 2: protobuf.Field("signed_data", "bytes", repeated=False, required=False, default=None),
}
def __init__(
self,
*,
signature: "bytes",
+ signed_data: Optional["bytes"] = None,
) -> None:
self.signature = signature
+ self.signed_data = signed_data
class SolanaVerifyMessage(protobuf.MessageType):
MESSAGE_WIRE_TYPE = 908
FIELDS = {
- 1: protobuf.Field("envelope", "bytes", repeated=False, required=True),
2: protobuf.Field("chunkify", "bool", repeated=False, required=False, default=None),
+ 3: protobuf.Field("message", "SolanaOffchainMessageV1", repeated=False, required=True),
+ 4: protobuf.Field("signatures", "bytes", repeated=True, required=False, default=None),
}
def __init__(
self,
*,
- envelope: "bytes",
+ message: "SolanaOffchainMessageV1",
+ signatures: Optional[Sequence["bytes"]] = None,
chunkify: Optional["bool"] = None,
) -> None:
- self.envelope = envelope
+ self.signatures: Sequence["bytes"] = signatures if signatures is not None else []
+ self.message = message
self.chunkify = chunkify
diff --git a/python/src/trezorlib/solana.py b/python/src/trezorlib/solana.py
index dfe30d8f..29cd5da9 100644
--- a/python/src/trezorlib/solana.py
+++ b/python/src/trezorlib/solana.py
@@ -14,9 +14,7 @@
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
-from abc import ABC, abstractmethod
-from enum import IntEnum
-from typing import TYPE_CHECKING, Any, ClassVar, List, Optional
+from typing import TYPE_CHECKING, Any, List, Optional
from . import exceptions, messages
from .tools import workflow
@@ -79,120 +77,33 @@ def sign_tx(
).signature
-class OffchainMessage(ABC):
- """Off-Chain Message Signing Base Class
-
- This implementation below is optimistic: for incorrect arguments,
- it will produce incorrect message. We leave it up to the wallet
- to verify the message conforms to the spec.
- """
-
- SIGNING_DOMAIN = b"\xffsolana offchain"
- VERSION: ClassVar[int]
-
- def __init__(self, signers: list[bytes], message: str) -> None:
- self.signers = signers
- self.message = message
-
- @abstractmethod
- def _write_preamble(self, buf: bytearray) -> None: ...
-
- def to_bytes(self) -> bytes:
- buf = bytearray(self.SIGNING_DOMAIN)
- buf.append(self.VERSION)
- self._write_preamble(buf)
- buf.extend(self.message.encode("utf-8"))
- return bytes(buf)
-
-
-class OffchainMessageV0(OffchainMessage):
- """Off-Chain Message Signing v0
-
- https://docs.anza.xyz/proposals/off-chain-message-signing
- """
-
- VERSION = 0
-
- APP_LEN = 32
- PUB_KEY_LEN = 32
- MAX_MSG_LEN_SHORT = 1232
-
- def __init__(self, app: bytes, signers: list[bytes], message: str) -> None:
- super().__init__(signers, message)
- self.app = app
-
- class MessageFormat(IntEnum):
- RESTRICTED_ASCII = 0
- UTF8_SHORT = 1
- UTF8_LONG = 2
-
- def message_format(self) -> MessageFormat:
- preamble_len = 0x35 + len(self.signers) * self.PUB_KEY_LEN
- combined_len = preamble_len + len(self.message.encode("utf-8"))
-
- if combined_len <= self.MAX_MSG_LEN_SHORT:
- if all(0x20 <= ord(c) <= 0x7E for c in self.message):
- return self.MessageFormat.RESTRICTED_ASCII
- return self.MessageFormat.UTF8_SHORT
- return self.MessageFormat.UTF8_LONG
-
- def _write_preamble(self, buf: bytearray) -> None:
- buf.extend(self.app)
- buf.append(self.message_format())
- buf.append(len(self.signers))
- for signer in self.signers:
- buf.extend(signer)
- msg_len = len(self.message.encode("utf-8"))
- buf.extend(msg_len.to_bytes(2, "little"))
-
-
@workflow(capability=messages.Capability.Solana)
def sign_message(
session: "Session",
address_n: List[int],
- message: bytes,
+ message: messages.SolanaOffchainMessageV1,
chunkify: bool = False,
-) -> bytes:
+) -> messages.SolanaMessageSignature:
return session.call(
messages.SolanaSignMessage(
address_n=address_n, message=message, chunkify=chunkify
),
expect=messages.SolanaMessageSignature,
- ).signature
-
-
-class Envelope:
- """Signed Off-Chain Message Envelope
-
- Common format for spec v0 and v1:
- * https://docs.anza.xyz/proposals/off-chain-message-signing#envelope
- * https://github.com/solana-foundation/SRFCs/discussions/3
- """
-
- SIG_LEN = 64
-
- def __init__(self, signatures: list[bytes], message: bytes) -> None:
- self.signatures = signatures
- self.message = message
-
- def to_bytes(self) -> bytes:
- buf = bytearray()
- buf.append(len(self.signatures))
- for signature in self.signatures:
- buf.extend(signature)
- buf.extend(self.message)
- return bytes(buf)
+ )
@workflow(capability=messages.Capability.Solana)
def verify_message(
session: "Session",
- envelope: bytes,
+ message: messages.SolanaOffchainMessageV1,
+ signatures: list[bytes],
chunkify: bool = False,
) -> bool:
try:
session.call(
- messages.SolanaVerifyMessage(envelope=envelope, chunkify=chunkify),
+ messages.SolanaVerifyMessage(
+ message=message, signatures=signatures, chunkify=chunkify
+ ),
expect=messages.Success,
)
return True
diff --git a/rust/trezor-client/src/protos/generated/messages_solana.rs b/rust/trezor-client/src/protos/generated/messages_solana.rs
index 0189f8c1..35fcc7dd 100644
--- a/rust/trezor-client/src/protos/generated/messages_solana.rs
+++ b/rust/trezor-client/src/protos/generated/messages_solana.rs
@@ -1703,38 +1703,36 @@ impl ::protobuf::reflect::ProtobufValue for SolanaTxSignature {
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
}
-// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaSignMessage)
+// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaOffchainMessageV1)
#[derive(PartialEq,Clone,Default,Debug)]
-pub struct SolanaSignMessage {
+pub struct SolanaOffchainMessageV1 {
// message fields
- // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.address_n)
- pub address_n: ::std::vec::Vec<u32>,
- // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.message)
- pub message: ::std::option::Option<::std::vec::Vec<u8>>,
- // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.chunkify)
- pub chunkify: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaOffchainMessageV1.message)
+ pub message: ::std::option::Option<::std::string::String>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaOffchainMessageV1.signers)
+ pub signers: ::std::vec::Vec<::std::vec::Vec<u8>>,
// special fields
- // @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaSignMessage.special_fields)
+ // @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaOffchainMessageV1.special_fields)
pub special_fields: ::protobuf::SpecialFields,
}
-impl<'a> ::std::default::Default for &'a SolanaSignMessage {
- fn default() -> &'a SolanaSignMessage {
- <SolanaSignMessage as ::protobuf::Message>::default_instance()
+impl<'a> ::std::default::Default for &'a SolanaOffchainMessageV1 {
+ fn default() -> &'a SolanaOffchainMessageV1 {
+ <SolanaOffchainMessageV1 as ::protobuf::Message>::default_instance()
}
}
-impl SolanaSignMessage {
- pub fn new() -> SolanaSignMessage {
+impl SolanaOffchainMessageV1 {
+ pub fn new() -> SolanaOffchainMessageV1 {
::std::default::Default::default()
}
- // required bytes message = 2;
+ // required string message = 1;
- pub fn message(&self) -> &[u8] {
+ pub fn message(&self) -> &str {
match self.message.as_ref() {
Some(v) => v,
- None => &[],
+ None => "",
}
}
@@ -1747,22 +1745,167 @@ impl SolanaSignMessage {
}
// Param is passed by value, moved
- pub fn set_message(&mut self, v: ::std::vec::Vec<u8>) {
+ pub fn set_message(&mut self, v: ::std::string::String) {
self.message = ::std::option::Option::Some(v);
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
- pub fn mut_message(&mut self) -> &mut ::std::vec::Vec<u8> {
+ pub fn mut_message(&mut self) -> &mut ::std::string::String {
if self.message.is_none() {
- self.message = ::std::option::Option::Some(::std::vec::Vec::new());
+ self.message = ::std::option::Option::Some(::std::string::String::new());
}
self.message.as_mut().unwrap()
}
// Take field
- pub fn take_message(&mut self) -> ::std::vec::Vec<u8> {
- self.message.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ pub fn take_message(&mut self) -> ::std::string::String {
+ self.message.take().unwrap_or_else(|| ::std::string::String::new())
+ }
+
+ fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
+ let mut fields = ::std::vec::Vec::with_capacity(2);
+ let mut oneofs = ::std::vec::Vec::with_capacity(0);
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "message",
+ |m: &SolanaOffchainMessageV1| { &m.message },
+ |m: &mut SolanaOffchainMessageV1| { &mut m.message },
+ ));
+ fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
+ "signers",
+ |m: &SolanaOffchainMessageV1| { &m.signers },
+ |m: &mut SolanaOffchainMessageV1| { &mut m.signers },
+ ));
+ ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaOffchainMessageV1>(
+ "SolanaOffchainMessageV1",
+ fields,
+ oneofs,
+ )
+ }
+}
+
+impl ::protobuf::Message for SolanaOffchainMessageV1 {
+ const NAME: &'static str = "SolanaOffchainMessageV1";
+
+ fn is_initialized(&self) -> bool {
+ if self.message.is_none() {
+ return false;
+ }
+ true
+ }
+
+ fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
+ while let Some(tag) = is.read_raw_tag_or_eof()? {
+ match tag {
+ 10 => {
+ self.message = ::std::option::Option::Some(is.read_string()?);
+ },
+ 18 => {
+ self.signers.push(is.read_bytes()?);
+ },
+ tag => {
+ ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
+ },
+ };
+ }
+ ::std::result::Result::Ok(())
+ }
+
+ // Compute sizes of nested messages
+ #[allow(unused_variables)]
+ fn compute_size(&self) -> u64 {
+ let mut my_size = 0;
+ if let Some(v) = self.message.as_ref() {
+ my_size += ::protobuf::rt::string_size(1, &v);
+ }
+ for value in &self.signers {
+ my_size += ::protobuf::rt::bytes_size(2, &value);
+ };
+ my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
+ self.special_fields.cached_size().set(my_size as u32);
+ my_size
+ }
+
+ fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
+ if let Some(v) = self.message.as_ref() {
+ os.write_string(1, v)?;
+ }
+ for v in &self.signers {
+ os.write_bytes(2, &v)?;
+ };
+ os.write_unknown_fields(self.special_fields.unknown_fields())?;
+ ::std::result::Result::Ok(())
+ }
+
+ fn special_fields(&self) -> &::protobuf::SpecialFields {
+ &self.special_fields
+ }
+
+ fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields {
+ &mut self.special_fields
+ }
+
+ fn new() -> SolanaOffchainMessageV1 {
+ SolanaOffchainMessageV1::new()
+ }
+
+ fn clear(&mut self) {
+ self.message = ::std::option::Option::None;
+ self.signers.clear();
+ self.special_fields.clear();
+ }
+
+ fn default_instance() -> &'static SolanaOffchainMessageV1 {
+ static instance: SolanaOffchainMessageV1 = SolanaOffchainMessageV1 {
+ message: ::std::option::Option::None,
+ signers: ::std::vec::Vec::new(),
+ special_fields: ::protobuf::SpecialFields::new(),
+ };
+ &instance
+ }
+}
+
+impl ::protobuf::MessageFull for SolanaOffchainMessageV1 {
+ fn descriptor() -> ::protobuf::reflect::MessageDescriptor {
+ static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new();
+ descriptor.get(|| file_descriptor().message_by_package_relative_name("SolanaOffchainMessageV1").unwrap()).clone()
+ }
+}
+
+impl ::std::fmt::Display for SolanaOffchainMessageV1 {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::protobuf::text_format::fmt(self, f)
+ }
+}
+
+impl ::protobuf::reflect::ProtobufValue for SolanaOffchainMessageV1 {
+ type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
+}
+
+// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaSignMessage)
+#[derive(PartialEq,Clone,Default,Debug)]
+pub struct SolanaSignMessage {
+ // message fields
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.address_n)
+ pub address_n: ::std::vec::Vec<u32>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.chunkify)
+ pub chunkify: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaSignMessage.message)
+ pub message: ::protobuf::MessageField<SolanaOffchainMessageV1>,
+ // special fields
+ // @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaSignMessage.special_fields)
+ pub special_fields: ::protobuf::SpecialFields,
+}
+
+impl<'a> ::std::default::Default for &'a SolanaSignMessage {
+ fn default() -> &'a SolanaSignMessage {
+ <SolanaSignMessage as ::protobuf::Message>::default_instance()
+ }
+}
+
+impl SolanaSignMessage {
+ pub fn new() -> SolanaSignMessage {
+ ::std::default::Default::default()
}
// optional bool chunkify = 3;
@@ -1792,16 +1935,16 @@ impl SolanaSignMessage {
|m: &SolanaSignMessage| { &m.address_n },
|m: &mut SolanaSignMessage| { &mut m.address_n },
));
- fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
- "message",
- |m: &SolanaSignMessage| { &m.message },
- |m: &mut SolanaSignMessage| { &mut m.message },
- ));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &SolanaSignMessage| { &m.chunkify },
|m: &mut SolanaSignMessage| { &mut m.chunkify },
));
+ fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, SolanaOffchainMessageV1>(
+ "message",
+ |m: &SolanaSignMessage| { &m.message },
+ |m: &mut SolanaSignMessage| { &mut m.message },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaSignMessage>(
"SolanaSignMessage",
fields,
@@ -1817,6 +1960,11 @@ impl ::protobuf::Message for SolanaSignMessage {
if self.message.is_none() {
return false;
}
+ for v in &self.message {
+ if !v.is_initialized() {
+ return false;
+ }
+ };
true
}
@@ -1829,12 +1977,12 @@ impl ::protobuf::Message for SolanaSignMessage {
8 => {
self.address_n.push(is.read_uint32()?);
},
- 18 => {
- self.message = ::std::option::Option::Some(is.read_bytes()?);
- },
24 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
+ 34 => {
+ ::protobuf::rt::read_singular_message_into_field(is, &mut self.message)?;
+ },
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@@ -1850,12 +1998,13 @@ impl ::protobuf::Message for SolanaSignMessage {
for value in &self.address_n {
my_size += ::protobuf::rt::uint32_size(1, *value);
};
- if let Some(v) = self.message.as_ref() {
- my_size += ::protobuf::rt::bytes_size(2, &v);
- }
if let Some(v) = self.chunkify {
my_size += 1 + 1;
}
+ if let Some(v) = self.message.as_ref() {
+ let len = v.compute_size();
+ my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
+ }
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
self.special_fields.cached_size().set(my_size as u32);
my_size
@@ -1865,12 +2014,12 @@ impl ::protobuf::Message for SolanaSignMessage {
for v in &self.address_n {
os.write_uint32(1, *v)?;
};
- if let Some(v) = self.message.as_ref() {
- os.write_bytes(2, v)?;
- }
if let Some(v) = self.chunkify {
os.write_bool(3, v)?;
}
+ if let Some(v) = self.message.as_ref() {
+ ::protobuf::rt::write_message_field_with_cached_size(4, v, os)?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -1889,16 +2038,16 @@ impl ::protobuf::Message for SolanaSignMessage {
fn clear(&mut self) {
self.address_n.clear();
- self.message = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
+ self.message.clear();
self.special_fields.clear();
}
fn default_instance() -> &'static SolanaSignMessage {
static instance: SolanaSignMessage = SolanaSignMessage {
address_n: ::std::vec::Vec::new(),
- message: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
+ message: ::protobuf::MessageField::none(),
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -1928,6 +2077,8 @@ pub struct SolanaMessageSignature {
// message fields
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaMessageSignature.signature)
pub signature: ::std::option::Option<::std::vec::Vec<u8>>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaMessageSignature.signed_data)
+ pub signed_data: ::std::option::Option<::std::vec::Vec<u8>>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaMessageSignature.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -1980,14 +2131,55 @@ impl SolanaMessageSignature {
self.signature.take().unwrap_or_else(|| ::std::vec::Vec::new())
}
+ // optional bytes signed_data = 2;
+
+ pub fn signed_data(&self) -> &[u8] {
+ match self.signed_data.as_ref() {
+ Some(v) => v,
+ None => &[],
+ }
+ }
+
+ pub fn clear_signed_data(&mut self) {
+ self.signed_data = ::std::option::Option::None;
+ }
+
+ pub fn has_signed_data(&self) -> bool {
+ self.signed_data.is_some()
+ }
+
+ // Param is passed by value, moved
+ pub fn set_signed_data(&mut self, v: ::std::vec::Vec<u8>) {
+ self.signed_data = ::std::option::Option::Some(v);
+ }
+
+ // Mutable pointer to the field.
+ // If field is not initialized, it is initialized with default value first.
+ pub fn mut_signed_data(&mut self) -> &mut ::std::vec::Vec<u8> {
+ if self.signed_data.is_none() {
+ self.signed_data = ::std::option::Option::Some(::std::vec::Vec::new());
+ }
+ self.signed_data.as_mut().unwrap()
+ }
+
+ // Take field
+ pub fn take_signed_data(&mut self) -> ::std::vec::Vec<u8> {
+ self.signed_data.take().unwrap_or_else(|| ::std::vec::Vec::new())
+ }
+
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
- let mut fields = ::std::vec::Vec::with_capacity(1);
+ let mut fields = ::std::vec::Vec::with_capacity(2);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"signature",
|m: &SolanaMessageSignature| { &m.signature },
|m: &mut SolanaMessageSignature| { &mut m.signature },
));
+ fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
+ "signed_data",
+ |m: &SolanaMessageSignature| { &m.signed_data },
+ |m: &mut SolanaMessageSignature| { &mut m.signed_data },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaMessageSignature>(
"SolanaMessageSignature",
fields,
@@ -2012,6 +2204,9 @@ impl ::protobuf::Message for SolanaMessageSignature {
10 => {
self.signature = ::std::option::Option::Some(is.read_bytes()?);
},
+ 18 => {
+ self.signed_data = ::std::option::Option::Some(is.read_bytes()?);
+ },
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@@ -2027,6 +2222,9 @@ impl ::protobuf::Message for SolanaMessageSignature {
if let Some(v) = self.signature.as_ref() {
my_size += ::protobuf::rt::bytes_size(1, &v);
}
+ if let Some(v) = self.signed_data.as_ref() {
+ my_size += ::protobuf::rt::bytes_size(2, &v);
+ }
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
self.special_fields.cached_size().set(my_size as u32);
my_size
@@ -2036,6 +2234,9 @@ impl ::protobuf::Message for SolanaMessageSignature {
if let Some(v) = self.signature.as_ref() {
os.write_bytes(1, v)?;
}
+ if let Some(v) = self.signed_data.as_ref() {
+ os.write_bytes(2, v)?;
+ }
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -2054,12 +2255,14 @@ impl ::protobuf::Message for SolanaMessageSignature {
fn clear(&mut self) {
self.signature = ::std::option::Option::None;
+ self.signed_data = ::std::option::Option::None;
self.special_fields.clear();
}
fn default_instance() -> &'static SolanaMessageSignature {
static instance: SolanaMessageSignature = SolanaMessageSignature {
signature: ::std::option::Option::None,
+ signed_data: ::std::option::Option::None,
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -2087,10 +2290,12 @@ impl ::protobuf::reflect::ProtobufValue for SolanaMessageSignature {
#[derive(PartialEq,Clone,Default,Debug)]
pub struct SolanaVerifyMessage {
// message fields
- // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaVerifyMessage.envelope)
- pub envelope: ::std::option::Option<::std::vec::Vec<u8>>,
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaVerifyMessage.chunkify)
pub chunkify: ::std::option::Option<bool>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaVerifyMessage.message)
+ pub message: ::protobuf::MessageField<SolanaOffchainMessageV1>,
+ // @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaVerifyMessage.signatures)
+ pub signatures: ::std::vec::Vec<::std::vec::Vec<u8>>,
// special fields
// @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaVerifyMessage.special_fields)
pub special_fields: ::protobuf::SpecialFields,
@@ -2107,42 +2312,6 @@ impl SolanaVerifyMessage {
::std::default::Default::default()
}
- // required bytes envelope = 1;
-
- pub fn envelope(&self) -> &[u8] {
- match self.envelope.as_ref() {
- Some(v) => v,
- None => &[],
- }
- }
-
- pub fn clear_envelope(&mut self) {
- self.envelope = ::std::option::Option::None;
- }
-
- pub fn has_envelope(&self) -> bool {
- self.envelope.is_some()
- }
-
- // Param is passed by value, moved
- pub fn set_envelope(&mut self, v: ::std::vec::Vec<u8>) {
- self.envelope = ::std::option::Option::Some(v);
- }
-
- // Mutable pointer to the field.
- // If field is not initialized, it is initialized with default value first.
- pub fn mut_envelope(&mut self) -> &mut ::std::vec::Vec<u8> {
- if self.envelope.is_none() {
- self.envelope = ::std::option::Option::Some(::std::vec::Vec::new());
- }
- self.envelope.as_mut().unwrap()
- }
-
- // Take field
- pub fn take_envelope(&mut self) -> ::std::vec::Vec<u8> {
- self.envelope.take().unwrap_or_else(|| ::std::vec::Vec::new())
- }
-
// optional bool chunkify = 2;
pub fn chunkify(&self) -> bool {
@@ -2163,18 +2332,23 @@ impl SolanaVerifyMessage {
}
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
- let mut fields = ::std::vec::Vec::with_capacity(2);
+ let mut fields = ::std::vec::Vec::with_capacity(3);
let mut oneofs = ::std::vec::Vec::with_capacity(0);
- fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
- "envelope",
- |m: &SolanaVerifyMessage| { &m.envelope },
- |m: &mut SolanaVerifyMessage| { &mut m.envelope },
- ));
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
"chunkify",
|m: &SolanaVerifyMessage| { &m.chunkify },
|m: &mut SolanaVerifyMessage| { &mut m.chunkify },
));
+ fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, SolanaOffchainMessageV1>(
+ "message",
+ |m: &SolanaVerifyMessage| { &m.message },
+ |m: &mut SolanaVerifyMessage| { &mut m.message },
+ ));
+ fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
+ "signatures",
+ |m: &SolanaVerifyMessage| { &m.signatures },
+ |m: &mut SolanaVerifyMessage| { &mut m.signatures },
+ ));
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaVerifyMessage>(
"SolanaVerifyMessage",
fields,
@@ -2187,21 +2361,29 @@ impl ::protobuf::Message for SolanaVerifyMessage {
const NAME: &'static str = "SolanaVerifyMessage";
fn is_initialized(&self) -> bool {
- if self.envelope.is_none() {
+ if self.message.is_none() {
return false;
}
+ for v in &self.message {
+ if !v.is_initialized() {
+ return false;
+ }
+ };
true
}
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> {
while let Some(tag) = is.read_raw_tag_or_eof()? {
match tag {
- 10 => {
- self.envelope = ::std::option::Option::Some(is.read_bytes()?);
- },
16 => {
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
},
+ 26 => {
+ ::protobuf::rt::read_singular_message_into_field(is, &mut self.message)?;
+ },
+ 34 => {
+ self.signatures.push(is.read_bytes()?);
+ },
tag => {
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
},
@@ -2214,24 +2396,31 @@ impl ::protobuf::Message for SolanaVerifyMessage {
#[allow(unused_variables)]
fn compute_size(&self) -> u64 {
let mut my_size = 0;
- if let Some(v) = self.envelope.as_ref() {
- my_size += ::protobuf::rt::bytes_size(1, &v);
- }
if let Some(v) = self.chunkify {
my_size += 1 + 1;
}
+ if let Some(v) = self.message.as_ref() {
+ let len = v.compute_size();
+ my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
+ }
+ for value in &self.signatures {
+ my_size += ::protobuf::rt::bytes_size(4, &value);
+ };
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
self.special_fields.cached_size().set(my_size as u32);
my_size
}
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
- if let Some(v) = self.envelope.as_ref() {
- os.write_bytes(1, v)?;
- }
if let Some(v) = self.chunkify {
os.write_bool(2, v)?;
}
+ if let Some(v) = self.message.as_ref() {
+ ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?;
+ }
+ for v in &self.signatures {
+ os.write_bytes(4, &v)?;
+ };
os.write_unknown_fields(self.special_fields.unknown_fields())?;
::std::result::Result::Ok(())
}
@@ -2249,15 +2438,17 @@ impl ::protobuf::Message for SolanaVerifyMessage {
}
fn clear(&mut self) {
- self.envelope = ::std::option::Option::None;
self.chunkify = ::std::option::Option::None;
+ self.message.clear();
+ self.signatures.clear();
self.special_fields.clear();
}
fn default_instance() -> &'static SolanaVerifyMessage {
static instance: SolanaVerifyMessage = SolanaVerifyMessage {
- envelope: ::std::option::Option::None,
chunkify: ::std::option::Option::None,
+ message: ::protobuf::MessageField::none(),
+ signatures: ::std::vec::Vec::new(),
special_fields: ::protobuf::SpecialFields::new(),
};
&instance
@@ -2304,14 +2495,19 @@ static file_descriptor_proto_data: &'static [u8] = b"\
\x0eadditionalInfo\x12J\n\x0bpayment_req\x18\x04\x20\x01(\x0b2).hw.trezo\
r.messages.common.PaymentRequestR\npaymentReq\x12\x1a\n\x08chunkify\x18\
\x05\x20\x01(\x08R\x08chunkify\"1\n\x11SolanaTxSignature\x12\x1c\n\tsign\
- ature\x18\x01\x20\x02(\x0cR\tsignature\"f\n\x11SolanaSignMessage\x12\x1b\
- \n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x18\n\x07message\x18\
- \x02\x20\x02(\x0cR\x07message\x12\x1a\n\x08chunkify\x18\x03\x20\x01(\x08\
- R\x08chunkify\"6\n\x16SolanaMessageSignature\x12\x1c\n\tsignature\x18\
- \x01\x20\x02(\x0cR\tsignature\"M\n\x13SolanaVerifyMessage\x12\x1a\n\x08e\
- nvelope\x18\x01\x20\x02(\x0cR\x08envelope\x12\x1a\n\x08chunkify\x18\x02\
- \x20\x01(\x08R\x08chunkifyB:\n#com.satoshilabs.trezor.lib.protobufB\x13T\
- rezorMessageSolana\
+ ature\x18\x01\x20\x02(\x0cR\tsignature\"M\n\x17SolanaOffchainMessageV1\
+ \x12\x18\n\x07message\x18\x01\x20\x02(\tR\x07message\x12\x18\n\x07signer\
+ s\x18\x02\x20\x03(\x0cR\x07signers\"\xa0\x01\n\x11SolanaSignMessage\x12\
+ \x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12\x1a\n\x08chunkify\
+ \x18\x03\x20\x01(\x08R\x08chunkify\x12L\n\x07message\x18\x04\x20\x02(\
+ \x0b22.hw.trezor.messages.solana.SolanaOffchainMessageV1R\x07messageJ\
+ \x04\x08\x02\x10\x03\"W\n\x16SolanaMessageSignature\x12\x1c\n\tsignature\
+ \x18\x01\x20\x02(\x0cR\tsignature\x12\x1f\n\x0bsigned_data\x18\x02\x20\
+ \x01(\x0cR\nsignedData\"\xa5\x01\n\x13SolanaVerifyMessage\x12\x1a\n\x08c\
+ hunkify\x18\x02\x20\x01(\x08R\x08chunkify\x12L\n\x07message\x18\x03\x20\
+ \x02(\x0b22.hw.trezor.messages.solana.SolanaOffchainMessageV1R\x07messag\
+ e\x12\x1e\n\nsignatures\x18\x04\x20\x03(\x0cR\nsignaturesJ\x04\x08\x01\
+ \x10\x02B:\n#com.satoshilabs.trezor.lib.protobufB\x13TrezorMessageSolana\
";
/// `FileDescriptorProto` object which was a source for this generated file
@@ -2330,7 +2526,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
let generated_file_descriptor = generated_file_descriptor_lazy.get(|| {
let mut deps = ::std::vec::Vec::with_capacity(1);
deps.push(super::messages_common::file_descriptor().clone());
- let mut messages = ::std::vec::Vec::with_capacity(11);
+ let mut messages = ::std::vec::Vec::with_capacity(12);
messages.push(SolanaGetPublicKey::generated_message_descriptor_data());
messages.push(SolanaPublicKey::generated_message_descriptor_data());
messages.push(SolanaGetAddress::generated_message_descriptor_data());
@@ -2339,6 +2535,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor {
messages.push(SolanaTxAdditionalInfo::generated_message_descriptor_data());
messages.push(SolanaSignTx::generated_message_descriptor_data());
messages.push(SolanaTxSignature::generated_message_descriptor_data());
+ messages.push(SolanaOffchainMessageV1::generated_message_descriptor_data());
messages.push(SolanaSignMessage::generated_message_descriptor_data());
messages.push(SolanaMessageSignature::generated_message_descriptor_data());
messages.push(SolanaVerifyMessage::generated_message_descriptor_data());
diff --git a/tests/device_tests/solana/test_sign_message.py b/tests/device_tests/solana/test_sign_message.py
index fd330fbd..5c68cf76 100644
--- a/tests/device_tests/solana/test_sign_message.py
+++ b/tests/device_tests/solana/test_sign_message.py
@@ -14,6 +14,8 @@ pytestmark = [pytest.mark.altcoin, pytest.mark.solana, pytest.mark.models("core"
ADDRESS_N = parse_path("m/44h/501h/0h/0h")
ED25519_PRIV_SIZE = 32
+ED25519_PUB_SIZE = 32
+ED25519_SIG_SIZE = 64
@pytest.mark.parametrize(
@@ -40,29 +42,27 @@ def test_sign_verify(session: Session, n_cosigners: int, message: str) -> None:
pubs = cosigner_pubs + [signer_pub]
- offchain_message = solana.OffchainMessageV0(
- app=b"\x00" * solana.OffchainMessageV0.APP_LEN,
+ offchain_message = solana.messages.SolanaOffchainMessageV1(
signers=[pub.public_bytes_raw() for pub in pubs],
message=message,
- ).to_bytes()
+ )
- signatures = [priv.sign(offchain_message) for priv in cosigner_privs]
- signatures.append(solana.sign_message(session, ADDRESS_N, offchain_message))
+ result = solana.sign_message(session, ADDRESS_N, offchain_message)
+ assert result.signed_data is not None
+ signatures = [priv.sign(result.signed_data) for priv in cosigner_privs]
+ signatures.append(result.signature)
for pub, sig in zip(pubs, signatures):
- pub.verify(sig, offchain_message)
-
- envelope = solana.Envelope(signatures, offchain_message).to_bytes()
+ pub.verify(sig, result.signed_data)
- assert solana.verify_message(session, envelope)
+ assert solana.verify_message(session, offchain_message, signatures)
def test_missing_signer(session: Session) -> None:
- offchain_message = solana.OffchainMessageV0(
- app=b"\x00" * solana.OffchainMessageV0.APP_LEN,
- signers=[b"\x00" * solana.OffchainMessageV0.PUB_KEY_LEN],
+ offchain_message = solana.messages.SolanaOffchainMessageV1(
+ signers=[b"\x00" * ED25519_PUB_SIZE],
message="Missing signer!",
- ).to_bytes()
+ )
with pytest.raises(
exceptions.TrezorFailure, match="Requested key not among signers"
@@ -74,20 +74,18 @@ def test_missing_signer(session: Session) -> None:
"signatures",
[
pytest.param([], id="missing"),
- pytest.param([b"\x00" * (solana.Envelope.SIG_LEN - 1)], id="malformed"),
- pytest.param([b"\x00" * solana.Envelope.SIG_LEN], id="invalid"),
- pytest.param([b"\x00" * solana.Envelope.SIG_LEN] * 2, id="extra"),
+ pytest.param([b"\x00" * (ED25519_SIG_SIZE - 1)], id="malformed"),
+ pytest.param([b"\x00" * ED25519_SIG_SIZE], id="invalid"),
+ pytest.param([b"\x00" * ED25519_SIG_SIZE] * 2, id="extra"),
],
)
-def test_invalid_envelope(session: Session, signatures: list[bytes]) -> None:
- offchain_message = solana.OffchainMessageV0(
- app=b"\x00" * solana.OffchainMessageV0.APP_LEN,
+def test_invalid_signed(session: Session, signatures: list[bytes]) -> None:
+ offchain_message = solana.messages.SolanaOffchainMessageV1(
signers=[solana.get_public_key(session, ADDRESS_N, show_display=False)],
- message="Invalid envelope!",
- ).to_bytes()
+ message="Invalid signed message!",
+ )
+ # verify that the message itself is valid and can be signed
solana.sign_message(session, ADDRESS_N, offchain_message)
- envelope = solana.Envelope(signatures, offchain_message).to_bytes()
-
- assert not solana.verify_message(session, envelope)
+ assert not solana.verify_message(session, offchain_message, signatures)
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index 6567ccec..41961aec 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -2542,16 +2542,16 @@
"T2T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "4b48d2d6131bdf3a0d6a27a3ea5a4a050de7df7512466a6b2fb8648b0a7d4516",
"T2T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "557f9b32f0198a05ff85f1426c37e189f232f113ea95b1b2c2a33d4f9b16a6c4",
"T2T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "c69fcf2acb60b5e057fa5e4ebcb0f9780463e44882ffeb8588206a537e51b5a0",
-"T2T1_cs_solana-test_sign_message.py::test_invalid_envelope[extra]": "c43930f673266a303698f7e03c2a6ebbafcc928b23ea533fe42308669790168d",
-"T2T1_cs_solana-test_sign_message.py::test_invalid_envelope[invalid]": "c43930f673266a303698f7e03c2a6ebbafcc928b23ea533fe42308669790168d",
-"T2T1_cs_solana-test_sign_message.py::test_invalid_envelope[malformed]": "c43930f673266a303698f7e03c2a6ebbafcc928b23ea533fe42308669790168d",
-"T2T1_cs_solana-test_sign_message.py::test_invalid_envelope[missing]": "c43930f673266a303698f7e03c2a6ebbafcc928b23ea533fe42308669790168d",
+"T2T1_cs_solana-test_sign_message.py::test_invalid_signed[extra]": "91d4d528741cafa9a1d19052608ead1320306200329df33f13e49dcfb04a3332",
+"T2T1_cs_solana-test_sign_message.py::test_invalid_signed[invalid]": "91d4d528741cafa9a1d19052608ead1320306200329df33f13e49dcfb04a3332",
+"T2T1_cs_solana-test_sign_message.py::test_invalid_signed[malformed]": "91d4d528741cafa9a1d19052608ead1320306200329df33f13e49dcfb04a3332",
+"T2T1_cs_solana-test_sign_message.py::test_invalid_signed[missing]": "91d4d528741cafa9a1d19052608ead1320306200329df33f13e49dcfb04a3332",
"T2T1_cs_solana-test_sign_message.py::test_missing_signer": "f2b80196c81ce473b7f24f16f6192ac76d9d2ca23fb0b40053c00d02b53d5111",
-"T2T1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "8527a96d2a68315f971aa886e9f6352a692bbe10d847ddc5028ec02895c04c65",
-"T2T1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "fce87b99d97d34a8fe3d36582e0298e1f29f510be66249d4c8c355b7dd86fc4e",
-"T2T1_cs_solana-test_sign_message.py::test_sign_verify[long]": "6b1030ae00db5fe1b2606a114e4688339d804cdd790c35430a68d212dfecc225",
-"T2T1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "0869d014fcaf1003dbab5a22e96139f2e447c701605796d56ec6a041b743d9f4",
-"T2T1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "586a8ed14616bb870d90adb3d97a439ffc639af4bfd7c84a2efcbd939130b5c3",
+"T2T1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "604d5a07db86404e43a06b4f2736389a3bf08c6e47af81a8dc1b4f072d890341",
+"T2T1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "cf82ea13404a905320c6363f4535b9b53736d3d4cf92b4e30da6342231acff5f",
+"T2T1_cs_solana-test_sign_message.py::test_sign_verify[long]": "3d544aa4413a7a1170b56ac68e730fef05ec1170e419c0d34387a78b3270f0af",
+"T2T1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "c81a413a86e4023c35e5c41d9c62f9e1ea4014f4de6cd7e5937d7abcad892246",
+"T2T1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "8e66e7b041802606bdb776f57207a2ee25458eef3f9b2fd388375da92d0cfa12",
"T2T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "dc9bc49ba53e7409d78fc1f39c555564ad07e4309d4a272db9d07ba5db9c3adc",
"T2T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "c16385c9ceab9bf9b53de3cbc8ffb87154fd27abb9263bb69ba5cabfb532bf47",
"T2T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "d1642ea82387014dd29b5f650debfb64ac76bf9a8e34be199acf65625c1c7bee",
@@ -4347,16 +4347,16 @@
"T2T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "f9db1e405c434e2ab9db2eb847437284fafd47925ce9669b076693bb5c8269be",
"T2T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "1c11071a029a71bcb059500559fbbe63f6b514123b17aff214271404c2319405",
"T2T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "65f6d46ed269f9a742f562c80c64a4a26d9f7be252fd59d63d7c0b0cac034dd4",
-"T2T1_de_solana-test_sign_message.py::test_invalid_envelope[extra]": "f198e4ef2aca96d02e3da0327bbf118b4c77831dfdb33425336ceaa489bd2247",
-"T2T1_de_solana-test_sign_message.py::test_invalid_envelope[invalid]": "f198e4ef2aca96d02e3da0327bbf118b4c77831dfdb33425336ceaa489bd2247",
-"T2T1_de_solana-test_sign_message.py::test_invalid_envelope[malformed]": "f198e4ef2aca96d02e3da0327bbf118b4c77831dfdb33425336ceaa489bd2247",
-"T2T1_de_solana-test_sign_message.py::test_invalid_envelope[missing]": "f198e4ef2aca96d02e3da0327bbf118b4c77831dfdb33425336ceaa489bd2247",
+"T2T1_de_solana-test_sign_message.py::test_invalid_signed[extra]": "4249c71847efc1203d3021da2ced1ee28ffc6658f83a2d2ca2116fbd580d2805",
+"T2T1_de_solana-test_sign_message.py::test_invalid_signed[invalid]": "4249c71847efc1203d3021da2ced1ee28ffc6658f83a2d2ca2116fbd580d2805",
+"T2T1_de_solana-test_sign_message.py::test_invalid_signed[malformed]": "4249c71847efc1203d3021da2ced1ee28ffc6658f83a2d2ca2116fbd580d2805",
+"T2T1_de_solana-test_sign_message.py::test_invalid_signed[missing]": "4249c71847efc1203d3021da2ced1ee28ffc6658f83a2d2ca2116fbd580d2805",
"T2T1_de_solana-test_sign_message.py::test_missing_signer": "efeaf51fe18b983e9b1a6947a939ad305a92e57798fe07110bb61c0f65755881",
-"T2T1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "3745604932b5b15c4154a963dd60bed45172eb054ea833e423ff275750eacd6e",
-"T2T1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "e34c27f12c8b4b558cfa05b7f4a897b33b273e00b1e1e1c47cd0a55ff83b59cc",
-"T2T1_de_solana-test_sign_message.py::test_sign_verify[long]": "2edae9af5cf58e2720d3456c2430f8a1fe3107f4c4f8cb5a1fb9e3c9d47aceb0",
-"T2T1_de_solana-test_sign_message.py::test_sign_verify[multi]": "2e8b9a3597484f2ed1a3650d4d027d0dc59fe177bafb8520e41e45f563a53dd1",
-"T2T1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "3ac406b98374cffb303b15f60a977742c8abefb0dc7ace34e2d7687c25973919",
+"T2T1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "7cb56683a0140c4af3250f16c52ae88ef629365c8544f74d7e2ff8021f246ebc",
+"T2T1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "ef654ec12a6489f1cdeee36f775cfda747578232a24e592e07dc496adb51b4a3",
+"T2T1_de_solana-test_sign_message.py::test_sign_verify[long]": "4fb0c180a2d6b7893c00aca14f39578be828ff4d05230dff94f72a970e278b9b",
+"T2T1_de_solana-test_sign_message.py::test_sign_verify[multi]": "78ab31c0eeec4e68d4c6b2ccc72e658904e7c20a12326705546cda76a27a74f3",
+"T2T1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "97c1a96c5f9fc72e96ced8f7f0df5e7c3b889991329e073209de4b9a267739df",
"T2T1_de_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "cbbfff10c7b86b6631ba7873f2364ed9bf589583fd7f238a2a9672512d32fb9e",
"T2T1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "d6bd38341b32d670b9121bdba57505922dadcaf8234cce9463baf47083600a5e",
"T2T1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "f91de368548465cee0bc1e4bf9c0d90eb79c020947fe7e7d03c0e3fba7847d5d",
@@ -6152,16 +6152,16 @@
"T2T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "63b0de3b9e52ab4667c4d8b8dea83b548fa846954274ff56d4ddbaf0d99bfad4",
"T2T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "e1bdbbdef5914cd69e257a1cce610d7d6f0af73f8aaf1a6ba1de26a8ac614568",
"T2T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "5d3769564e5669fad4df6ddb507ad16f6138864dc69752cc792cb3d9ed7506cc",
-"T2T1_en_solana-test_sign_message.py::test_invalid_envelope[extra]": "435d2dc1164b3a3dc3e3e08cb50582e5a697a44d79fb472ef8bfcfe7531d3552",
-"T2T1_en_solana-test_sign_message.py::test_invalid_envelope[invalid]": "435d2dc1164b3a3dc3e3e08cb50582e5a697a44d79fb472ef8bfcfe7531d3552",
-"T2T1_en_solana-test_sign_message.py::test_invalid_envelope[malformed]": "435d2dc1164b3a3dc3e3e08cb50582e5a697a44d79fb472ef8bfcfe7531d3552",
-"T2T1_en_solana-test_sign_message.py::test_invalid_envelope[missing]": "435d2dc1164b3a3dc3e3e08cb50582e5a697a44d79fb472ef8bfcfe7531d3552",
+"T2T1_en_solana-test_sign_message.py::test_invalid_signed[extra]": "9dfaf0685336eca3be4161c40a53f709a12ccc7a013af06159c1f6c741e300fe",
+"T2T1_en_solana-test_sign_message.py::test_invalid_signed[invalid]": "9dfaf0685336eca3be4161c40a53f709a12ccc7a013af06159c1f6c741e300fe",
+"T2T1_en_solana-test_sign_message.py::test_invalid_signed[malformed]": "9dfaf0685336eca3be4161c40a53f709a12ccc7a013af06159c1f6c741e300fe",
+"T2T1_en_solana-test_sign_message.py::test_invalid_signed[missing]": "9dfaf0685336eca3be4161c40a53f709a12ccc7a013af06159c1f6c741e300fe",
"T2T1_en_solana-test_sign_message.py::test_missing_signer": "8aa7c68cd09e700e8c6903dcfc39c4a66214481c12c34dc56762829478399b79",
-"T2T1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "d78bfc00591a2cbe4cc119f164c9951a1963f681947e15977c867ddb009197db",
-"T2T1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "0045d40e3d3ae05ac79dc9b2447fb166e072511f7fd872a4b3877257357eafb1",
-"T2T1_en_solana-test_sign_message.py::test_sign_verify[long]": "4c7a6fd5acba80f6b02d5c59e55e2b0ec7b291581a0a904d54c02a8907564440",
-"T2T1_en_solana-test_sign_message.py::test_sign_verify[multi]": "967bcb52d6af5a72c629fb77557a33babd29ffbf98358fa27372d5d3936f3456",
-"T2T1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "9e3a971c0ec15023b7ec1e4a51bba659ff04e7c079b923ca8e50e1e0f19403bd",
+"T2T1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "53e6666dde378c0b2fe704ba9f19a6afd5e5b833ae19f578af009b196c4831d7",
+"T2T1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "a899aae11972a71ac8308bbe8c9b9c9f6de0147e83d7af310c16302bd15fd8af",
+"T2T1_en_solana-test_sign_message.py::test_sign_verify[long]": "bbdd489fb2a478d5988be226916c8d5af9225f061bc241ecba56337bc097d4f0",
+"T2T1_en_solana-test_sign_message.py::test_sign_verify[multi]": "45619e74f2fc2c0a4f34736e589eedd605138e96b09089935643940badeec0f4",
+"T2T1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "116a90fa93537db5cd08055e5cfc0ddb52ab5e44bcf523a524b3171fc770d1ca",
"T2T1_en_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "e1d1a05823decc59da87ea70f6290c72ac0d13d8d632242918d991c69984d4dc",
"T2T1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "81f090cef716976fdf487d727b10c7573ade37e3f200981e6870d84383850c92",
"T2T1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "c1eaf8cca71aa11207db852c7e8fd1a7a710505f24610227c2a099d591bc7b78",
@@ -7975,16 +7975,16 @@
"T2T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "ac7f8a01dcb3665e51562e12c9187ba48c3f67bf03226c356b733e288bb3c8f7",
"T2T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "9d7aa88fb67588abf11b19385a07e1b5e4f1e3e1ea96a8614517dd8623007208",
"T2T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "a29cea492b18f3bb6b99d414ff533e26d62f107121e1dacd5f366c24a2a4f255",
-"T2T1_es_solana-test_sign_message.py::test_invalid_envelope[extra]": "e1ac8441259ba4d05afcac5c4012e5e843f724caeb89bbfc8fc839901647a940",
-"T2T1_es_solana-test_sign_message.py::test_invalid_envelope[invalid]": "e1ac8441259ba4d05afcac5c4012e5e843f724caeb89bbfc8fc839901647a940",
-"T2T1_es_solana-test_sign_message.py::test_invalid_envelope[malformed]": "e1ac8441259ba4d05afcac5c4012e5e843f724caeb89bbfc8fc839901647a940",
-"T2T1_es_solana-test_sign_message.py::test_invalid_envelope[missing]": "e1ac8441259ba4d05afcac5c4012e5e843f724caeb89bbfc8fc839901647a940",
+"T2T1_es_solana-test_sign_message.py::test_invalid_signed[extra]": "0b8850db1febd32f14020abc6152e99d460cae2735a8898199fa0efd8564714a",
+"T2T1_es_solana-test_sign_message.py::test_invalid_signed[invalid]": "0b8850db1febd32f14020abc6152e99d460cae2735a8898199fa0efd8564714a",
+"T2T1_es_solana-test_sign_message.py::test_invalid_signed[malformed]": "0b8850db1febd32f14020abc6152e99d460cae2735a8898199fa0efd8564714a",
+"T2T1_es_solana-test_sign_message.py::test_invalid_signed[missing]": "0b8850db1febd32f14020abc6152e99d460cae2735a8898199fa0efd8564714a",
"T2T1_es_solana-test_sign_message.py::test_missing_signer": "17d836396f272c01cafa175aa87b0c076aedf7698c935d1921c7d3d7e8911903",
-"T2T1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "62ad1427541856978fcfb1866ffbd4444fb0c1fb6325bdba20be77cba33dbdfd",
-"T2T1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "e48d895c524300da78ec04b0d6839d4ec5b3148fd8fda268ee8a781b976273b6",
-"T2T1_es_solana-test_sign_message.py::test_sign_verify[long]": "95d53d773ed3c51c2360da1b4fb82b70c5f91858e249cd7c2f0eaf39b5616bcf",
-"T2T1_es_solana-test_sign_message.py::test_sign_verify[multi]": "b7200adf199594f116af773232d31e0db026db002586093e1e24825bb72249ab",
-"T2T1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "551d0044ef2dad51f4e9ec32b9a0172960c659324112e35783ea010828f8a696",
+"T2T1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "74f9488009690cef3c801998b6933ad87e1d84d11dd29488b96d1d42f2f7e35f",
+"T2T1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "de9ef2367a4e9e3f574d881fd6ccfa6aae2936721622d7018ba1c2502eb862d8",
+"T2T1_es_solana-test_sign_message.py::test_sign_verify[long]": "80295bd766c991833c5a188cdbdde994af25e10df03d16b680f1e3a245bcad60",
+"T2T1_es_solana-test_sign_message.py::test_sign_verify[multi]": "8e5b4b302b26c8a7a0747162b3a8c9fc7f197deea874c959941df030c9dfc763",
+"T2T1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "c1439778034fe74497852cd068cdfcb3fb1b754caac1c35515693d7cfb249b9e",
"T2T1_es_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "89cc3db13bd0312197b2b6ed59dbdf02e7a280d0f66b4096988526fc4078725b",
"T2T1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "3f8db4b2df40fdfa8b2640b154005809c07aca8b29299d1f67479c4de978a94d",
"T2T1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "948fd893d37635521193bc163ce45602b49b5cbd66ffe1430255e762c37da609",
@@ -9780,16 +9780,16 @@
"T2T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "f00be270e549cf8c6a4646d4ef1fe97a3feb452a4ed90f31c5ec7e2fc7b54c0a",
"T2T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "55499fe8f27d690b4ae3d0f59a2fb43e93fd0aedab863a8ce2f79abb2f7a1eb4",
"T2T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "4c905e07b2cc71fc23ebcd4d751a6d62b9b3ada569bec1e211a2db41e26816af",
-"T2T1_fr_solana-test_sign_message.py::test_invalid_envelope[extra]": "43c8dc2c94980b2455917b62eb9b30ce342571be4b4a95659c7d036ac80a240c",
-"T2T1_fr_solana-test_sign_message.py::test_invalid_envelope[invalid]": "43c8dc2c94980b2455917b62eb9b30ce342571be4b4a95659c7d036ac80a240c",
-"T2T1_fr_solana-test_sign_message.py::test_invalid_envelope[malformed]": "43c8dc2c94980b2455917b62eb9b30ce342571be4b4a95659c7d036ac80a240c",
-"T2T1_fr_solana-test_sign_message.py::test_invalid_envelope[missing]": "43c8dc2c94980b2455917b62eb9b30ce342571be4b4a95659c7d036ac80a240c",
+"T2T1_fr_solana-test_sign_message.py::test_invalid_signed[extra]": "6495f820b4461d2f751ef414463e40bd334c25b077ebabf0bc1dc17efb566758",
+"T2T1_fr_solana-test_sign_message.py::test_invalid_signed[invalid]": "6495f820b4461d2f751ef414463e40bd334c25b077ebabf0bc1dc17efb566758",
+"T2T1_fr_solana-test_sign_message.py::test_invalid_signed[malformed]": "6495f820b4461d2f751ef414463e40bd334c25b077ebabf0bc1dc17efb566758",
+"T2T1_fr_solana-test_sign_message.py::test_invalid_signed[missing]": "6495f820b4461d2f751ef414463e40bd334c25b077ebabf0bc1dc17efb566758",
"T2T1_fr_solana-test_sign_message.py::test_missing_signer": "7e5a99a4b6aad4cdf7a9f9aecf483faa381108ee2108efaba88f261e29ac1f8a",
-"T2T1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "812a072077ecf7cc9365d4b37d5d55e5eddaf627e499376b5f9c493b4a4da11b",
-"T2T1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "e402ef3cd5424971e08e3c39cd7863ab458545d532b34153c00f44930c9ab689",
-"T2T1_fr_solana-test_sign_message.py::test_sign_verify[long]": "a83635cac9a760d6642dff9c172e0cfd12ea853a7b151074d5df4a89996ea765",
-"T2T1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "cd053abc88ab53141c96273c1d97b93739750997182acc02519da99d9b00637a",
-"T2T1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "57ec040ae7e3e3bb8d4ba3600d84cf85c6f50c99f0b108b2315e98dd4913f1f9",
+"T2T1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "808f5cf2f71e042fd182d4ffeceb94100e457d5fdcbae17e1d880e4f5110c5a8",
+"T2T1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "da551b253d5df8cfb3763d94052502ded22ebac97e1143908df413526e05b01c",
+"T2T1_fr_solana-test_sign_message.py::test_sign_verify[long]": "e6892fb4c512d766e12bef57332400079a2afdf62de4d8ce75355dff00897729",
+"T2T1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "8d7d38b0f7c5cd60651d409ac5d62dffa13c495246f7260bb6fbc78eee48d6b8",
+"T2T1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "d686f79f5be4e3afe33dd3dbba373f7562ffd01cf832c6d95cdc7a6774febaf1",
"T2T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "e7111a5742c14d71d81dfa177685987400e11a66fb9a372d93231a51d9bef6b2",
"T2T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "13e8f246a26644935d29acb68e7d4964e4fa72ba48a75b9638743fb8c774641e",
"T2T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "242d35b180eaef317b487e9fb01f3949c93b6d153909d2ed2618d8c3dc002709",
@@ -11585,16 +11585,16 @@
"T2T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "529ea5306f84f73a629903a5bd147c116d742463b7948b8c2c9b1767046a721b",
"T2T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "49240470d19934a7e3c3f6a74c1b24c989dd8e1351938b02f670d47e98accc85",
"T2T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "a4695d0bf35a63d0ebfea78cb81a7f15c4352538cd0085e71ffbc1b58bcfdfc8",
-"T2T1_pt_solana-test_sign_message.py::test_invalid_envelope[extra]": "2543461170d60e2513382a6cdf55ab255b6ac241603cf76b3d8b205666728e60",
-"T2T1_pt_solana-test_sign_message.py::test_invalid_envelope[invalid]": "2543461170d60e2513382a6cdf55ab255b6ac241603cf76b3d8b205666728e60",
-"T2T1_pt_solana-test_sign_message.py::test_invalid_envelope[malformed]": "2543461170d60e2513382a6cdf55ab255b6ac241603cf76b3d8b205666728e60",
-"T2T1_pt_solana-test_sign_message.py::test_invalid_envelope[missing]": "2543461170d60e2513382a6cdf55ab255b6ac241603cf76b3d8b205666728e60",
+"T2T1_pt_solana-test_sign_message.py::test_invalid_signed[extra]": "92dc8ecc6de780c470363976911a396fda0a54f20d92d8d3bc23543582113354",
+"T2T1_pt_solana-test_sign_message.py::test_invalid_signed[invalid]": "92dc8ecc6de780c470363976911a396fda0a54f20d92d8d3bc23543582113354",
+"T2T1_pt_solana-test_sign_message.py::test_invalid_signed[malformed]": "92dc8ecc6de780c470363976911a396fda0a54f20d92d8d3bc23543582113354",
+"T2T1_pt_solana-test_sign_message.py::test_invalid_signed[missing]": "92dc8ecc6de780c470363976911a396fda0a54f20d92d8d3bc23543582113354",
"T2T1_pt_solana-test_sign_message.py::test_missing_signer": "020b255e04b59e53d2aa87ae960038f4538d350de28df15a1ac41b376e9d04f2",
-"T2T1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "96f66ad7982b97f24d2e1542c0f24be2822ee401a2c728c20c5dcbefa6f5e8dd",
-"T2T1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "796af1eb6cd654d85cdb4f68e9d4367c7d65e857e6cd314f6c816783aa02b2f5",
-"T2T1_pt_solana-test_sign_message.py::test_sign_verify[long]": "6dce297efaa7a7149ec4b08a00b6817ff1cda6317462b0e9c6bfe49bbc170f21",
-"T2T1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "3b6a62b0ce202c5681c9cda38557b2f7ac5f5143869d759ed203ec8b8241fde3",
-"T2T1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "99a63cc6196351d9c2533aed8fa15e8cef2d66b7e69a375ecc05e8a506c602ef",
+"T2T1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "7f4876be8f733cdbb200910f98745fd3bf14a2fc8a67c06b4b9870413ad202b1",
+"T2T1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "d8e8e9e3be879bd4178ae9c6d2d5ae6376b1cbd879264ce1d121089032a2cb19",
+"T2T1_pt_solana-test_sign_message.py::test_sign_verify[long]": "4b1f79dd3efc1c2634e431138d96b530e4d50e592ad5f623fcb21206bdb2be3b",
+"T2T1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "9f98a1e8446a746d0b09973a07032ccb66c32c21cfc3eff32b9bb8b72db3076c",
+"T2T1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "35f989fb57e02527acef35b0aff484c865fd420418bffb50c7bdc21899f7d1f6",
"T2T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "a240fb97bea561c2dee8a0c7b789e25ed470eac167886854608db07bfa9adf6e",
"T2T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "2d5978ecab9da0897791c1e0906881397f06a40209cea49cdc527a34fdb3cbb9",
"T2T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "765087f2ed57a465d0de25ef6803e20828db5f1d5e86d2a008760185c69331f4",
@@ -13630,16 +13630,16 @@
"T3B1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "6629717ba225dc056b3cc45d7a075779f38af52eba86e693f34116e2a1f5c7aa",
"T3B1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "479e8921ba426a639fe0c0c12c6f5a117299b1ad7b3e44d3e8a91d8977534ab0",
"T3B1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "6b157b9b1380068c033fd915510483f90666ed6addfe58b002d049e9a2893a22",
-"T3B1_cs_solana-test_sign_message.py::test_invalid_envelope[extra]": "5c2cc103e0aed88253d3e27593208eb836f17e67c1a4188a76e70b811c498ffd",
-"T3B1_cs_solana-test_sign_message.py::test_invalid_envelope[invalid]": "5c2cc103e0aed88253d3e27593208eb836f17e67c1a4188a76e70b811c498ffd",
-"T3B1_cs_solana-test_sign_message.py::test_invalid_envelope[malformed]": "5c2cc103e0aed88253d3e27593208eb836f17e67c1a4188a76e70b811c498ffd",
-"T3B1_cs_solana-test_sign_message.py::test_invalid_envelope[missing]": "5c2cc103e0aed88253d3e27593208eb836f17e67c1a4188a76e70b811c498ffd",
+"T3B1_cs_solana-test_sign_message.py::test_invalid_signed[extra]": "dfc48bfc5d4cb8666086d748de74baa62abd60cf8858817ed51184837cd84f62",
+"T3B1_cs_solana-test_sign_message.py::test_invalid_signed[invalid]": "dfc48bfc5d4cb8666086d748de74baa62abd60cf8858817ed51184837cd84f62",
+"T3B1_cs_solana-test_sign_message.py::test_invalid_signed[malformed]": "dfc48bfc5d4cb8666086d748de74baa62abd60cf8858817ed51184837cd84f62",
+"T3B1_cs_solana-test_sign_message.py::test_invalid_signed[missing]": "dfc48bfc5d4cb8666086d748de74baa62abd60cf8858817ed51184837cd84f62",
"T3B1_cs_solana-test_sign_message.py::test_missing_signer": "aec89f6952811bcfa54db3842b2e2e24d7ae162a65bf19424b4e6b6620fe70bb",
-"T3B1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "49864253bf034ae386e389263b727710f95294c142342e8cacb161788ae2c74d",
-"T3B1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "18da86d9eb669472bca62480e43b62e6d2278ab8181acfd0c4843c475000277b",
-"T3B1_cs_solana-test_sign_message.py::test_sign_verify[long]": "2a1568d0714b77d626e7e12a0920a436224da20535d12e3f4c06aa6a6ec26e43",
-"T3B1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "387407ffbae7c50477818fb18b59767da198a249f745380770fae63b462870dc",
-"T3B1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "4a293c5b02cf83478f9c63124f71d02cde7288cc4df93e6ff1ed50d819db8146",
+"T3B1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "327e6a4aed88321ea515b5986122e391960c4ba0d823da717b4c64a4d5e3fa10",
+"T3B1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "486e2217171b32685937b6db8008f051f51944e4a016b4bac8fb75db62648207",
+"T3B1_cs_solana-test_sign_message.py::test_sign_verify[long]": "53c9b4d317421cee63992f95797eb47be999466972d15699ac45bf49a1d98703",
+"T3B1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "c25ba2885a97d0fd10157180b363d3139d3ac35a410bb0a1e8e13f0d1f941d3e",
+"T3B1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "c6100b666abf7641579ca19311e88fed1c2d872542b837d30d95f333046650b2",
"T3B1_cs_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "301c96ebe40fd5965e7134a6cc7f375e9ecc891172de868527c873a498b580c6",
"T3B1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "3b9d6ca443f77c6aaca190a612ff424af38eec35a4392b14a3b9e64b1d673e2c",
"T3B1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "b9dc44d7658033233c21ab906567dba33e4c322c122e549405cf97ca7d51b86e",
@@ -15374,16 +15374,16 @@
"T3B1_de_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "31a5aa53651f5124027ed1d530355dd40c429f0d256776527008237d3ce69df2",
"T3B1_de_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "258f41ee7bb6b00289f42a68dde441bae98f65e52e71a0606cf01547a9523dab",
"T3B1_de_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "d855cb1dc8ac08ea021f9b144efd401fb15c685b2d5ea3503cbefe33ecc68155",
-"T3B1_de_solana-test_sign_message.py::test_invalid_envelope[extra]": "45007d5ea40b2c87bff811b796d3107be406d2f32eb91c2da41193e05ee65bd2",
-"T3B1_de_solana-test_sign_message.py::test_invalid_envelope[invalid]": "45007d5ea40b2c87bff811b796d3107be406d2f32eb91c2da41193e05ee65bd2",
-"T3B1_de_solana-test_sign_message.py::test_invalid_envelope[malformed]": "45007d5ea40b2c87bff811b796d3107be406d2f32eb91c2da41193e05ee65bd2",
-"T3B1_de_solana-test_sign_message.py::test_invalid_envelope[missing]": "45007d5ea40b2c87bff811b796d3107be406d2f32eb91c2da41193e05ee65bd2",
+"T3B1_de_solana-test_sign_message.py::test_invalid_signed[extra]": "8ca4e5341b66e47ed57ebf354fa0d3a3925f70d839fc185fa3d1d64f43a12fbd",
+"T3B1_de_solana-test_sign_message.py::test_invalid_signed[invalid]": "8ca4e5341b66e47ed57ebf354fa0d3a3925f70d839fc185fa3d1d64f43a12fbd",
+"T3B1_de_solana-test_sign_message.py::test_invalid_signed[malformed]": "8ca4e5341b66e47ed57ebf354fa0d3a3925f70d839fc185fa3d1d64f43a12fbd",
+"T3B1_de_solana-test_sign_message.py::test_invalid_signed[missing]": "8ca4e5341b66e47ed57ebf354fa0d3a3925f70d839fc185fa3d1d64f43a12fbd",
"T3B1_de_solana-test_sign_message.py::test_missing_signer": "14dfefb39e3707b5294815085c5d94626e4e632f7fd9ca60df4b28e57d015dde",
-"T3B1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "87fb98a5f1e63bdcf16fecce41ff1b8f7a2755bace0949e055d2ff44d61e050f",
-"T3B1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "e2c8196b8075677da4b6c319013cd24d5aba2941d7cba00a456426733348cfbf",
-"T3B1_de_solana-test_sign_message.py::test_sign_verify[long]": "a55da296f2d2a87b781f7e7b1aeffbd5b2c50c4fbc91061d61466cecb7653c0f",
-"T3B1_de_solana-test_sign_message.py::test_sign_verify[multi]": "a44e3e56a00fe1249bb58d05f33212197975ad212896a407c91f79319a6b53c1",
-"T3B1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "035e0ed75f6be3b344cca8434dca129714a41697776a8a1b70633888f8afbe2b",
+"T3B1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "9f4d961d554dd879196965470c4a7f779aedeac2c33c17f928e53b0de689beff",
+"T3B1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "04605b786eca7330256a52ec0e339b46a9a0c0adc8d7508d9cefd1ad66fd7b23",
+"T3B1_de_solana-test_sign_message.py::test_sign_verify[long]": "6ca4009bca1f1e079f412293c297511b1f2b66f330aac4711f07d63fc14e2fca",
+"T3B1_de_solana-test_sign_message.py::test_sign_verify[multi]": "d9c68ab625ecada6875a55c7eae059416778cba9975fa3fbf0e36d06f7f6fd5d",
+"T3B1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "e22efb276b69f0919860ea7115a24791b64da3e3077f43432a262aa3e7b61302",
"T3B1_de_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "09de31846c3c5d341191298aec29ac5fcca0f438e7f8a33fe59c4fb9348c194a",
"T3B1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "b26231d7e2bdabdfa93e372ea455f2ed5a40951ebf8b29fe00f88506a3fbdd69",
"T3B1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "d6448e83a2509e249150b1da55322d94632a287863d76c2726e46761511fd722",
@@ -17118,16 +17118,16 @@
"T3B1_en_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "7227c2e86fbd9c5e7b804a84ef5e538242dbb6108dfc7b1fa54c3a6bde89a8d6",
"T3B1_en_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "a4a463c8397938ddbe0446bc1ecbbab877e2adf16eeecee6ed287f1aec72815a",
"T3B1_en_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "73fb90ac4115808f72a5968d5a4fac008b119c96ce1e4c28f2e6c408fd05f702",
-"T3B1_en_solana-test_sign_message.py::test_invalid_envelope[extra]": "1d1372507083cf29fe446bbe75f89d2346e6f24f4bcafaf4b6923ec2369beae5",
-"T3B1_en_solana-test_sign_message.py::test_invalid_envelope[invalid]": "1d1372507083cf29fe446bbe75f89d2346e6f24f4bcafaf4b6923ec2369beae5",
-"T3B1_en_solana-test_sign_message.py::test_invalid_envelope[malformed]": "1d1372507083cf29fe446bbe75f89d2346e6f24f4bcafaf4b6923ec2369beae5",
-"T3B1_en_solana-test_sign_message.py::test_invalid_envelope[missing]": "1d1372507083cf29fe446bbe75f89d2346e6f24f4bcafaf4b6923ec2369beae5",
+"T3B1_en_solana-test_sign_message.py::test_invalid_signed[extra]": "04c4d1e60b34f14acf1d9bc048c483e91d24b5e0905d4a90df98d1df83547100",
+"T3B1_en_solana-test_sign_message.py::test_invalid_signed[invalid]": "04c4d1e60b34f14acf1d9bc048c483e91d24b5e0905d4a90df98d1df83547100",
+"T3B1_en_solana-test_sign_message.py::test_invalid_signed[malformed]": "04c4d1e60b34f14acf1d9bc048c483e91d24b5e0905d4a90df98d1df83547100",
+"T3B1_en_solana-test_sign_message.py::test_invalid_signed[missing]": "04c4d1e60b34f14acf1d9bc048c483e91d24b5e0905d4a90df98d1df83547100",
"T3B1_en_solana-test_sign_message.py::test_missing_signer": "7945fdf0623a34efada654fe62a57fa06c6ab0cf4383bc14c6b7acd594b10596",
-"T3B1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "f6297e791630bf84fdb679e5e55138ada9a26ffcf7a04744186e4f97e17c6bb6",
-"T3B1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "6aed09825b5a5bf492ddc9e0aa490c0f0ae2778e12805d7d3961e0ee3e725141",
-"T3B1_en_solana-test_sign_message.py::test_sign_verify[long]": "6b8f99f4cdb98f44ab29dfcbb883d2d50e1848a0118056ade9ad88feb18a3ba5",
-"T3B1_en_solana-test_sign_message.py::test_sign_verify[multi]": "9f60687c3408d3b211adb0f83bd61d1bc3241468a41450109bf69d424367967e",
-"T3B1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "e645fce51e75ee290ce17bb38ffcad10b78e189e837bec68f951e6e85f188d31",
+"T3B1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "32444ae3d2b636c551b825e41aef6e98b057df6d97ebcff9f7afdc741bed978f",
+"T3B1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "66144b0010c0d3cc481178a9bd29cb5d99c09d5467b7897ca98e2cbc93b2dc9a",
+"T3B1_en_solana-test_sign_message.py::test_sign_verify[long]": "42333511ebb945d1d22347676443f50b62453de1df4a3f988b2a4ea29a886412",
+"T3B1_en_solana-test_sign_message.py::test_sign_verify[multi]": "3708fcdd3de808855805696a62d43c066ad2e483bdf65da3bf84560d78bdb3e1",
+"T3B1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "b58a05b27127b0bac51c454c78b2a382ddfb9a49dda3285fb9c7706dd908d0c0",
"T3B1_en_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "cfd1fffc8a6561d89647318482d009db30d52a66eecca8189118c85e5c394b29",
"T3B1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "46a8a7920704b4cc94e6b7fb80dc236aa4e2c0722e8d1fffc412003b59af11b8",
"T3B1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "5485a03a033b8cfc3b29986b4635d8a32e2e12f71af329c1f167a5020396186e",
@@ -18862,16 +18862,16 @@
"T3B1_es_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "de5dab9ef0ae19f446164d314205926dc555b9a295afdd66f29f3a4d8a2a33c8",
"T3B1_es_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "ed1a938b25667089d175eee4f5fb45189f8fb344de2fb0e1eda0ac47897571f6",
"T3B1_es_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "e9afb7e582034f2242fa3801dd072912f526f29fe10037d4844789d88e09d461",
-"T3B1_es_solana-test_sign_message.py::test_invalid_envelope[extra]": "189af34fda5c9f6f23eebc3bc7f3f192ef3a24e79e7a30b4e311812c80e5352b",
-"T3B1_es_solana-test_sign_message.py::test_invalid_envelope[invalid]": "189af34fda5c9f6f23eebc3bc7f3f192ef3a24e79e7a30b4e311812c80e5352b",
-"T3B1_es_solana-test_sign_message.py::test_invalid_envelope[malformed]": "189af34fda5c9f6f23eebc3bc7f3f192ef3a24e79e7a30b4e311812c80e5352b",
-"T3B1_es_solana-test_sign_message.py::test_invalid_envelope[missing]": "189af34fda5c9f6f23eebc3bc7f3f192ef3a24e79e7a30b4e311812c80e5352b",
+"T3B1_es_solana-test_sign_message.py::test_invalid_signed[extra]": "37bf4bf0905241f3ffd56ae5fe15ff06a9500a8fa0761dcaabe402fbb32238e1",
+"T3B1_es_solana-test_sign_message.py::test_invalid_signed[invalid]": "37bf4bf0905241f3ffd56ae5fe15ff06a9500a8fa0761dcaabe402fbb32238e1",
+"T3B1_es_solana-test_sign_message.py::test_invalid_signed[malformed]": "37bf4bf0905241f3ffd56ae5fe15ff06a9500a8fa0761dcaabe402fbb32238e1",
+"T3B1_es_solana-test_sign_message.py::test_invalid_signed[missing]": "37bf4bf0905241f3ffd56ae5fe15ff06a9500a8fa0761dcaabe402fbb32238e1",
"T3B1_es_solana-test_sign_message.py::test_missing_signer": "1c43a01a3864c17b781e3a68121bb7c4378f858ab5c4db5b3d012f138eba5fb8",
-"T3B1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "3f72196a8d043bf1f758e8662b99605dedcfdfb9b07b51b84e6ae553325840c6",
-"T3B1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "8a2baa49e150876b8b898d09f8a35f07463ba6b5042b08b3c25822f776ff62b6",
-"T3B1_es_solana-test_sign_message.py::test_sign_verify[long]": "852804c0500a3ff01cfacd5fe96e19fe41dac7eb2d44bf7c602bfbc4fe459717",
-"T3B1_es_solana-test_sign_message.py::test_sign_verify[multi]": "4ca603541f9ae0b222acb0602f4a8aac4e6471a33b7d43fe2d5c06d22c3c4667",
-"T3B1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "fc856a46db982ad2e5daa2d497171e0be7f87f6a6de6da3506a3c1a17fb2db93",
+"T3B1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "1c5108aa21b37119e9ed816d2f069e1e074d2d8a7a943d7d1ae8fe55da0102bc",
+"T3B1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "3e808687046e414b6a352c2f80cc00662d9d204b56531b61d03c798b3a3784ab",
+"T3B1_es_solana-test_sign_message.py::test_sign_verify[long]": "e2441e823d19d7f2bc0dd3b5aed24b25ba9570c685d3205db42752b7ce0cfb41",
+"T3B1_es_solana-test_sign_message.py::test_sign_verify[multi]": "23fee0f0522fc3cad539fe80de063b8fd8a5cc5065057c79a0a02ebce68805a8",
+"T3B1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "43c2e0393e7932e28f59c294af7a5841b7eb874de75225c87a12134b84d3a979",
"T3B1_es_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "e9412e8d0d7d2be96b734be953dca6a9ad5452684f1520251ed5315d2772621d",
"T3B1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "da3eb78d8b990314fd856187e5737d5bbacdb77c2968fd88ff4fd356b658c94e",
"T3B1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "64e93a6bce2f7c1b0dd510b82a4fb1434a8c925d938c96bfb746d381b3e9f2d4",
@@ -20606,16 +20606,16 @@
"T3B1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "1f55f6e2870bf5c60d8bd456ed6ff6a670abb017c105a6a0f4463f94031c1c40",
"T3B1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "8c6c525582dae58161db551cad56a7d79d997da8f977078c5e30a06b9e7871a0",
"T3B1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "e94756efc368c275542ff63750392e398d207d2dfb8ea969489ec540b26a75ae",
-"T3B1_fr_solana-test_sign_message.py::test_invalid_envelope[extra]": "e7fb92407703ede56882fc56153175ef4470c314f80e92685c25a7ffe8751620",
-"T3B1_fr_solana-test_sign_message.py::test_invalid_envelope[invalid]": "e7fb92407703ede56882fc56153175ef4470c314f80e92685c25a7ffe8751620",
-"T3B1_fr_solana-test_sign_message.py::test_invalid_envelope[malformed]": "e7fb92407703ede56882fc56153175ef4470c314f80e92685c25a7ffe8751620",
-"T3B1_fr_solana-test_sign_message.py::test_invalid_envelope[missing]": "e7fb92407703ede56882fc56153175ef4470c314f80e92685c25a7ffe8751620",
+"T3B1_fr_solana-test_sign_message.py::test_invalid_signed[extra]": "db8b417f60d2b77d066f757193251bde24533c844b6d041dd316c3883cd4675c",
+"T3B1_fr_solana-test_sign_message.py::test_invalid_signed[invalid]": "db8b417f60d2b77d066f757193251bde24533c844b6d041dd316c3883cd4675c",
+"T3B1_fr_solana-test_sign_message.py::test_invalid_signed[malformed]": "db8b417f60d2b77d066f757193251bde24533c844b6d041dd316c3883cd4675c",
+"T3B1_fr_solana-test_sign_message.py::test_invalid_signed[missing]": "db8b417f60d2b77d066f757193251bde24533c844b6d041dd316c3883cd4675c",
"T3B1_fr_solana-test_sign_message.py::test_missing_signer": "979886e5de665a0a5bd752457a29ad2bd0aad9d94702754cb351dc7d31979b42",
-"T3B1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "a654f4183c583bfbe53df058a7a181147fbdc2f872013f31c16fc692ff71f4f3",
-"T3B1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "5367444ae8a257b192f68eaac37ca4af0ba9bf8a59aa9b7b0f0fc5e0c054475b",
-"T3B1_fr_solana-test_sign_message.py::test_sign_verify[long]": "b07e502821413961aecd1c9491b45d94d2297280ccd7b51f3062977ed8ff38ce",
-"T3B1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "e519affd0b18a50cda3b4f5a97909f797b02b83b1083eb21a143ec6019cca89d",
-"T3B1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "9c69b80e240794dd9768cd2050fc1acece44cd6792c30639494c806ec4f1a5fb",
+"T3B1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "8fc3e66fc38473d63a7e59534f7b78661a84f76603502c99dd4491cbe24469d4",
+"T3B1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "b4fc563810996eacbdc54b5d704b7a7da55500a252f1736adfa8b0446f9e6939",
+"T3B1_fr_solana-test_sign_message.py::test_sign_verify[long]": "e7ca62dcedc23b8b9dc2a8b7f54befff0ff9b486893ef13507a4288897cb2645",
+"T3B1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "b34f55a7936bdfa5adf79b0a98e89247a0a72818a1f031421cb994fc07ade1c4",
+"T3B1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "f18e5f5eaa8c873a63c9d72b664ca40f2f8c36e8cbbc56684c8ee64ff3f8939b",
"T3B1_fr_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "024f1fd0cfe588c80dc9159e42a95e5384a36347375c1c296deacba3b7e6c3a2",
"T3B1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "b780b42c22576d20af856b76d20f20f06d7949546dc357b537e7d4b4d0cb5b34",
"T3B1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "0c68b9766e735f1e4b3393ab781eb834a675a509854b712b2fba48199f1d429e",
@@ -22350,16 +22350,16 @@
"T3B1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "32c59ef9c968bfa6e1c0039ca6bc5b6fa652bf0d43408c8863491198f9cfffd8",
"T3B1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "0c541c068d4b7d64f3f05f035d4d1846fcf1622035cb02bf277763e61376522a",
"T3B1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "8d3a7cf13a8606dd6fc17dc30ccdd80887995d62f49f1b3f804f843792ab1bdb",
-"T3B1_pt_solana-test_sign_message.py::test_invalid_envelope[extra]": "841fe022ae08583005a0bbaa568d8630438fa3e1d4d96a68859edaeb39870ac5",
-"T3B1_pt_solana-test_sign_message.py::test_invalid_envelope[invalid]": "841fe022ae08583005a0bbaa568d8630438fa3e1d4d96a68859edaeb39870ac5",
-"T3B1_pt_solana-test_sign_message.py::test_invalid_envelope[malformed]": "841fe022ae08583005a0bbaa568d8630438fa3e1d4d96a68859edaeb39870ac5",
-"T3B1_pt_solana-test_sign_message.py::test_invalid_envelope[missing]": "841fe022ae08583005a0bbaa568d8630438fa3e1d4d96a68859edaeb39870ac5",
+"T3B1_pt_solana-test_sign_message.py::test_invalid_signed[extra]": "6ff570597f8365127412742df2f534b7131b2eb61f887a479960236fe9809e2e",
+"T3B1_pt_solana-test_sign_message.py::test_invalid_signed[invalid]": "6ff570597f8365127412742df2f534b7131b2eb61f887a479960236fe9809e2e",
+"T3B1_pt_solana-test_sign_message.py::test_invalid_signed[malformed]": "6ff570597f8365127412742df2f534b7131b2eb61f887a479960236fe9809e2e",
+"T3B1_pt_solana-test_sign_message.py::test_invalid_signed[missing]": "6ff570597f8365127412742df2f534b7131b2eb61f887a479960236fe9809e2e",
"T3B1_pt_solana-test_sign_message.py::test_missing_signer": "bbd866375fe164eb4caaddceb8a49d710b09ad01ca2cf67a0006d3a0d3ecb121",
-"T3B1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "80277d96c132d4dae329ab259932a08dda306d4f3bd8347b48f450ba00945378",
-"T3B1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "d4242685e5a166d9bb3a294c58786d8804b02674c6b148794c7261e8fd855c06",
-"T3B1_pt_solana-test_sign_message.py::test_sign_verify[long]": "8ce1cc4b64cd43ae516ab54eb401edd888d302ef7d3b8fc3ca6862547d5d9d1b",
-"T3B1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "2c6415b48d57cd79058e031936b68844ac2b23d328cd416b5e40ca1d5946c8b1",
-"T3B1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "1f64c32e777fa3e75ea822688933a5137a8135d16dd1fe76e9fc433b320e568a",
+"T3B1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "0913fd256f6f8ea481e4cf78e5fa96b236bb2d235bfc4b2c8f003fa0dac07d0e",
+"T3B1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "a2fb57bb0ded3cdd31567918ea4fe11e76af15a26fb9803f6098a2887769297c",
+"T3B1_pt_solana-test_sign_message.py::test_sign_verify[long]": "a594bd7195194421dbe146846c77d5cd4a31ee15af749c2b94e9d598792e0364",
+"T3B1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "450471cb7e0ba402d5021e4e29e9087f262057661d5bcd7599bb828bce4b1e97",
+"T3B1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "f37f5d1d0101478bc0095921683cb6807b1331b7b80b52131b19611574ee200f",
"T3B1_pt_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "c209cfa7078f580bb15eadca1b0a602cdb1aa3e8376ac6cacad23cbc32157504",
"T3B1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "44eb13847d2f8b8fc3d49a477f4b6a4097e7c082d03fb58b94a1206b3c829752",
"T3B1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "6a88b1b91d8e89112fc4a3349ebedaf7689e1cbcd6ed6ba8a37caaf561810852",
@@ -24491,16 +24491,16 @@
"T3T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "39a8d65e3415dffd36d4e734fa4db1027d56ffd64940b90b630c67e594ed88be",
"T3T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "4f73761c8a1e6a9ff96ab53d50a341d03d23ccea5c24dfda377907ffdfea2654",
"T3T1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "88c5324858437fec3d08c3a3940afd59a245c88e78fbb3c8b6f93ba46d7ad059",
-"T3T1_cs_solana-test_sign_message.py::test_invalid_envelope[extra]": "aa47c0d0ea1f0deb018aeed7672a234dbc8389f8b288adddc2284ab7a12afa2a",
-"T3T1_cs_solana-test_sign_message.py::test_invalid_envelope[invalid]": "aa47c0d0ea1f0deb018aeed7672a234dbc8389f8b288adddc2284ab7a12afa2a",
-"T3T1_cs_solana-test_sign_message.py::test_invalid_envelope[malformed]": "aa47c0d0ea1f0deb018aeed7672a234dbc8389f8b288adddc2284ab7a12afa2a",
-"T3T1_cs_solana-test_sign_message.py::test_invalid_envelope[missing]": "aa47c0d0ea1f0deb018aeed7672a234dbc8389f8b288adddc2284ab7a12afa2a",
+"T3T1_cs_solana-test_sign_message.py::test_invalid_signed[extra]": "2c97549f7ca3eef99cfc9513b6699a8e5f51e1c5876c35cfba21a4cafa3b36fb",
+"T3T1_cs_solana-test_sign_message.py::test_invalid_signed[invalid]": "2c97549f7ca3eef99cfc9513b6699a8e5f51e1c5876c35cfba21a4cafa3b36fb",
+"T3T1_cs_solana-test_sign_message.py::test_invalid_signed[malformed]": "2c97549f7ca3eef99cfc9513b6699a8e5f51e1c5876c35cfba21a4cafa3b36fb",
+"T3T1_cs_solana-test_sign_message.py::test_invalid_signed[missing]": "2c97549f7ca3eef99cfc9513b6699a8e5f51e1c5876c35cfba21a4cafa3b36fb",
"T3T1_cs_solana-test_sign_message.py::test_missing_signer": "9c20243bc5dacf2442af5a8778b66a0ab7cb978e11c02fec371f109fbc9d55f6",
-"T3T1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "cbea16032c3440faa8a6cde9c62bf5a584340c0abd2821e37672c965102de873",
-"T3T1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "146b39028790892a9b7bda78e163e02c322fb9e6f640cdea78e8ad1374547c47",
-"T3T1_cs_solana-test_sign_message.py::test_sign_verify[long]": "6ab62afef0c64abf1924f9973de09d2c90b8f906f4835b562c8e1ddf05709929",
-"T3T1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "c00783373cd7005782c49f5fd9c9d646821ffecab384b4bb308fa2ff26df4124",
-"T3T1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "3032b120d087a59feab2dad93d903849aabf2a568a8807a8f772ffa5a337fdeb",
+"T3T1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "92247f45bd66f36867add24359a6c37e9958e7b1922d003dded25a41342a3866",
+"T3T1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "efc51002dee0c77b4c2bc40b91f7ef2bbdc5d3c18d7accaf4797a3f79847ebb2",
+"T3T1_cs_solana-test_sign_message.py::test_sign_verify[long]": "d1ab271335a8f35ae679e6b168b845f2381661af58413771a8337f00828dcfbc",
+"T3T1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "0ba826c1c4021c1989dd91d746f583ee55806b29f6357a10457f73fa440c2b5b",
+"T3T1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "d2f10e70376c0f08ae6ceeb3ac74f83eca6d06635390096a85fb7ab8a2f5dfec",
"T3T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "6d9ee93b99c655b94bf17d6c1a5ae399cf87b5aba1236204df3be47e7b3218f5",
"T3T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "fa3c3d543f42740dcbe901cded5dc4e4ad48337001db39c550bf9aa027f373bf",
"T3T1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "cad05f4a0534b4635ceb6b8a0b69c058c600aed68a5d968ca151ab5fe4bc5671",
@@ -26270,16 +26270,16 @@
"T3T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "f8a63f8ef2284c0cb78b06787dc2539c8a8a4d729583f919923aa24e7df708e6",
"T3T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "5abe9f0c369e66bfb900bb2c3bfcf2fde3231ce04df95578e03f4dfc0fc17bef",
"T3T1_de_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "c0eec0f00c5178fe8725a5ac3b85561448b1ba2d2ec98741b67c77a33235e7db",
-"T3T1_de_solana-test_sign_message.py::test_invalid_envelope[extra]": "60de055dda5e3736a4b33b5acd5fca3980f35fb901065af7772794cb5ed9605c",
-"T3T1_de_solana-test_sign_message.py::test_invalid_envelope[invalid]": "60de055dda5e3736a4b33b5acd5fca3980f35fb901065af7772794cb5ed9605c",
-"T3T1_de_solana-test_sign_message.py::test_invalid_envelope[malformed]": "60de055dda5e3736a4b33b5acd5fca3980f35fb901065af7772794cb5ed9605c",
-"T3T1_de_solana-test_sign_message.py::test_invalid_envelope[missing]": "60de055dda5e3736a4b33b5acd5fca3980f35fb901065af7772794cb5ed9605c",
+"T3T1_de_solana-test_sign_message.py::test_invalid_signed[extra]": "679d773053e9167cafa519ab47ca431e8d958b3513b2abc1854685cdcab03b58",
+"T3T1_de_solana-test_sign_message.py::test_invalid_signed[invalid]": "679d773053e9167cafa519ab47ca431e8d958b3513b2abc1854685cdcab03b58",
+"T3T1_de_solana-test_sign_message.py::test_invalid_signed[malformed]": "679d773053e9167cafa519ab47ca431e8d958b3513b2abc1854685cdcab03b58",
+"T3T1_de_solana-test_sign_message.py::test_invalid_signed[missing]": "679d773053e9167cafa519ab47ca431e8d958b3513b2abc1854685cdcab03b58",
"T3T1_de_solana-test_sign_message.py::test_missing_signer": "68c146f13417be0845fee20b1d8de4a05e0844608c2efb3cfae9f573be39f0c4",
-"T3T1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "a0a16b2c25b721a693778ff9d504d9603a58367dcb5433ff33d4a7344d784d35",
-"T3T1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "ab8fffe52a3a8172afab58434f809d5a0cb2059c09235f6409146177e50f5c5c",
-"T3T1_de_solana-test_sign_message.py::test_sign_verify[long]": "717c8f4e8e99c7832caa70140cf2eef04d5c4b1b0e6c46ddcd230c8937097b01",
-"T3T1_de_solana-test_sign_message.py::test_sign_verify[multi]": "54f9778848bad47315f0ee7abbb10e9a321314b877665717710572d2e9b0c61e",
-"T3T1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "d6b18453c57aae144142b75bec00508894f92d8f6d2fab21587cf69ced89f72c",
+"T3T1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "e35516ea9776eb9aebe7a6ed1a6ddc73b5a981ce8002a58eded756cd41ce99e5",
+"T3T1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "2e01b102d7b57f432eeac05505994c40b1031bcf748114b858960565813b909a",
+"T3T1_de_solana-test_sign_message.py::test_sign_verify[long]": "e71503666608d833422cf1ca9fd525b1fa280223ef7c8abc7c331120e6a99375",
+"T3T1_de_solana-test_sign_message.py::test_sign_verify[multi]": "622d68fd22a3f0014d25267a351b2d0da01a69a2420da980971fd3153e61f69f",
+"T3T1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "17bd98a5d665a6460082705d216c1b3fa555eb2a01e2743101435497cebd44e0",
"T3T1_de_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "04776bb3aa605428f9954db8d28582a2fff4aa240ce05273f3cbaf61719c4f53",
"T3T1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "bdc07cc2cc309434adec0e3d49b6302f54569c55478247b7aa51cc5c0df65970",
"T3T1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "39cb7b1d88ded0c927f3ec976f403f9f51822f5dbc77f68a61c1293add1667a5",
@@ -28049,16 +28049,16 @@
"T3T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "04dbbf5b101731795ad6a4988906f03da3b5b13abd50b6c05903895d1534487e",
"T3T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "bfaebe964a1b84c46f48c4028b4704640253607950c625f52a1b34dc97041a37",
"T3T1_en_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "b1fd569505e3fca630777dfcce4baca7160dd670a1598dfb257c1d6c58f41a3f",
-"T3T1_en_solana-test_sign_message.py::test_invalid_envelope[extra]": "7e5acf316b234df036809d0b86ffa98aa404ca467df15173ea6fbf156906e417",
-"T3T1_en_solana-test_sign_message.py::test_invalid_envelope[invalid]": "7e5acf316b234df036809d0b86ffa98aa404ca467df15173ea6fbf156906e417",
-"T3T1_en_solana-test_sign_message.py::test_invalid_envelope[malformed]": "7e5acf316b234df036809d0b86ffa98aa404ca467df15173ea6fbf156906e417",
-"T3T1_en_solana-test_sign_message.py::test_invalid_envelope[missing]": "7e5acf316b234df036809d0b86ffa98aa404ca467df15173ea6fbf156906e417",
+"T3T1_en_solana-test_sign_message.py::test_invalid_signed[extra]": "81b4bc5e27eeb50f1be36b84a57e2325c18a30fcbe6281e68fb492d3ef237d07",
+"T3T1_en_solana-test_sign_message.py::test_invalid_signed[invalid]": "81b4bc5e27eeb50f1be36b84a57e2325c18a30fcbe6281e68fb492d3ef237d07",
+"T3T1_en_solana-test_sign_message.py::test_invalid_signed[malformed]": "81b4bc5e27eeb50f1be36b84a57e2325c18a30fcbe6281e68fb492d3ef237d07",
+"T3T1_en_solana-test_sign_message.py::test_invalid_signed[missing]": "81b4bc5e27eeb50f1be36b84a57e2325c18a30fcbe6281e68fb492d3ef237d07",
"T3T1_en_solana-test_sign_message.py::test_missing_signer": "0064e8a52b9bff0c2a31432fa781b800afb21e8910d60f303671bdfc8d8425fc",
-"T3T1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "95be6901404b1bf872427403c2f7d84426e916f4b21a79821de187133e67c654",
-"T3T1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "047f35dcc92e3d0271278255bbc68319fedaa9051b5238f5c6977be3a1065ee1",
-"T3T1_en_solana-test_sign_message.py::test_sign_verify[long]": "c6cb4a3b8239ed56d5783c6a179d037284644a0301b47303179a99da2b635d31",
-"T3T1_en_solana-test_sign_message.py::test_sign_verify[multi]": "92d62026cc5b8af3571cfc9d8d0ed429961960c9a3d5a578a7fc349bb92f95ae",
-"T3T1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "156b0d947243a3a8e64499aa3f409db8f7089294135baf8bc6e57e0c791914d2",
+"T3T1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "5d0596d34e52098d8031bc57a82735eefebb3db1e914dbbfe1bab1967f4ab497",
+"T3T1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "c90a52b72dd23b451f651b143c2e84628c1a8ca523e78834a3e35669a95c5a20",
+"T3T1_en_solana-test_sign_message.py::test_sign_verify[long]": "e1190f615efd0a60ca8724d1da9d8abe0cd97a259d03f51e7f23ffa51ec0b8c4",
+"T3T1_en_solana-test_sign_message.py::test_sign_verify[multi]": "b10adac822f5c1865ec90bf1ef493b6d66831fdbaff95a0ef9070d5123356432",
+"T3T1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "c9b0bd03fa6d867f57db1fb00de651d1b3a9ef3b52e9a55e16f3a8f20764a31a",
"T3T1_en_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "f63b5e09233414bc5b6bf399bf67b5825d945640b2224788ea63c750db1d6c81",
"T3T1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "43327fdf54b1a77e364f15ec749f99475b46df0a879b8566f715911a12f402b3",
"T3T1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "7012cd2ec079083c2471ea551b672d7852877dbdc0b7c6f9323dc2ec8e58ff3f",
@@ -29828,16 +29828,16 @@
"T3T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "724e587481266f58c8db9a4906a65167f5162005566efa21ad33227d96c22c50",
"T3T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "dc0289c96e53066b0ec768234b75e19e2fe6c68bc70f8f9172814df117dc0909",
"T3T1_es_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "bd495005f8a94cae823ec5059285f8845543f32a354ff4f620fee706265a4e7f",
-"T3T1_es_solana-test_sign_message.py::test_invalid_envelope[extra]": "229087acebc2582cad7b5cc8cbcfc69ec760893a69f19d2db995d0379c8853a8",
-"T3T1_es_solana-test_sign_message.py::test_invalid_envelope[invalid]": "229087acebc2582cad7b5cc8cbcfc69ec760893a69f19d2db995d0379c8853a8",
-"T3T1_es_solana-test_sign_message.py::test_invalid_envelope[malformed]": "229087acebc2582cad7b5cc8cbcfc69ec760893a69f19d2db995d0379c8853a8",
-"T3T1_es_solana-test_sign_message.py::test_invalid_envelope[missing]": "229087acebc2582cad7b5cc8cbcfc69ec760893a69f19d2db995d0379c8853a8",
+"T3T1_es_solana-test_sign_message.py::test_invalid_signed[extra]": "adb0f10dcfe18ec4720c56bc5a8580e2657669c3ddbafbdfbb64c81b73cee4cb",
+"T3T1_es_solana-test_sign_message.py::test_invalid_signed[invalid]": "adb0f10dcfe18ec4720c56bc5a8580e2657669c3ddbafbdfbb64c81b73cee4cb",
+"T3T1_es_solana-test_sign_message.py::test_invalid_signed[malformed]": "adb0f10dcfe18ec4720c56bc5a8580e2657669c3ddbafbdfbb64c81b73cee4cb",
+"T3T1_es_solana-test_sign_message.py::test_invalid_signed[missing]": "adb0f10dcfe18ec4720c56bc5a8580e2657669c3ddbafbdfbb64c81b73cee4cb",
"T3T1_es_solana-test_sign_message.py::test_missing_signer": "41b9c9e85d64891dcfd03d675df77c533f035a2d191b161144d00afab69a589d",
-"T3T1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "ede502e50bf72a07c5c83f9f482778b1b4891e74fa7d0a0944daf3dbe7d2400e",
-"T3T1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "eb0ca0fe1ec6015bb26fc50d0d041354c6d57765932d8cc0d384e1dd9fee1fe8",
-"T3T1_es_solana-test_sign_message.py::test_sign_verify[long]": "1d5c8cec1e341d2ccd705e6316a8e4c8025af5b6e5d32001969350a88d840c94",
-"T3T1_es_solana-test_sign_message.py::test_sign_verify[multi]": "15b85fa75515539b5b2a831bbe200eff3f79d645e46f41ba6688562fda1ef811",
-"T3T1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "a70e5cb20795fd403199ffde9c0c1b01a0b67517277988fef1a5854b5eb76f5f",
+"T3T1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "749727a59282438f3a69505b5cf128c79c4e1f4498d77a544a3221acb5beba73",
+"T3T1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "b134ea2ac7059354065537a8728d4a42114cb03f29791f75844c3aaa7d17c35f",
+"T3T1_es_solana-test_sign_message.py::test_sign_verify[long]": "a97ae69e8a3202856cfae702041cc6100866406acc7a87ac00234c92a57b4f0e",
+"T3T1_es_solana-test_sign_message.py::test_sign_verify[multi]": "0af129fdc88be4a00e29070e29f893b0eb4c5ad7ed337197f3cf38b1ae57bb0d",
+"T3T1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "faf25f5eba2b02f97d6ae49530cf5f7fbbbd5fbb9c7788b67e3c75ab829e7c38",
"T3T1_es_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "7469329929dc737ac3cc5deb3b130a2c0a0644dc9c9947cd70a3fcddaa8f10e8",
"T3T1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "513f527c54bfbdff93f88a3515071d1e5a1a120ce91110474079bf31e689e41a",
"T3T1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "01b29e58df6e0f68ca4056bbaf18b7b720d74655102433a4b277f69664b70d0e",
@@ -31607,16 +31607,16 @@
"T3T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "a069ed19138d4af0b8781152e0a89f8b5947f19f035e4f265ee0caa7fcb7f0ec",
"T3T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "1ce7f09897b18d953c5992f6f92d39831e535fdf7923d9b8238f6f4f77a7c0a0",
"T3T1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "992f48601f2a2895255c5fba4ee7c3ef67738cb5125f175f047b35874327e488",
-"T3T1_fr_solana-test_sign_message.py::test_invalid_envelope[extra]": "e51af5e919c712fcbfeb35cef98222c7f7b76b9ea800213276a88becc83d00e7",
-"T3T1_fr_solana-test_sign_message.py::test_invalid_envelope[invalid]": "e51af5e919c712fcbfeb35cef98222c7f7b76b9ea800213276a88becc83d00e7",
-"T3T1_fr_solana-test_sign_message.py::test_invalid_envelope[malformed]": "e51af5e919c712fcbfeb35cef98222c7f7b76b9ea800213276a88becc83d00e7",
-"T3T1_fr_solana-test_sign_message.py::test_invalid_envelope[missing]": "e51af5e919c712fcbfeb35cef98222c7f7b76b9ea800213276a88becc83d00e7",
+"T3T1_fr_solana-test_sign_message.py::test_invalid_signed[extra]": "79c8515781993ab81b2431c93dd0ca3a5e28b8d700110eeef39912294a10bac9",
+"T3T1_fr_solana-test_sign_message.py::test_invalid_signed[invalid]": "79c8515781993ab81b2431c93dd0ca3a5e28b8d700110eeef39912294a10bac9",
+"T3T1_fr_solana-test_sign_message.py::test_invalid_signed[malformed]": "79c8515781993ab81b2431c93dd0ca3a5e28b8d700110eeef39912294a10bac9",
+"T3T1_fr_solana-test_sign_message.py::test_invalid_signed[missing]": "79c8515781993ab81b2431c93dd0ca3a5e28b8d700110eeef39912294a10bac9",
"T3T1_fr_solana-test_sign_message.py::test_missing_signer": "116c64aa168d12181b7a5317677ddf135d739fdac22d38ff08571dc3301c2f47",
-"T3T1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "b574cb76fa2abd463a6bfed851915439f7cf02956862eea855f9f900a9551996",
-"T3T1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "e4be15857cbedb27e199ad803cc475be255603a2fea7973860bf8aabc89128dc",
-"T3T1_fr_solana-test_sign_message.py::test_sign_verify[long]": "4ed21c2fcfc2ef288de28ac49107c303a8c9a259a042f0b7272fbb7b846139dc",
-"T3T1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "b34a191e787d605f4060f3a62b22faf0320048049f5befe1d8b69c34c39a3b73",
-"T3T1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "b7b0cbdbd747a0003e273060104260b95efa31698497f53c482f5f039c36c55a",
+"T3T1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "065bd0bd87b81b70aaa118916195a5a35ac32245fd1cdf69947cc97d7f120948",
+"T3T1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "538943bdeb841cd1f10d8fef88801d781a3657878956e25266939c32947b3081",
+"T3T1_fr_solana-test_sign_message.py::test_sign_verify[long]": "4db73ec03f534b38ca0e561413108f1e6b6f9215b424d8892a2661fc6f91af50",
+"T3T1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "1648f22093479f9cc051b54a930f57d6ffc89f12b8c9f2cb70d080c0fc1caf3b",
+"T3T1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "3d82d5f2dde7b343c1d687d6a2b2eb2b9ed2b350d1faf4e29d56e1ef3e7def54",
"T3T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "42ad13488b211a8c4d68b432e02ad4ae2e8301a272b2cc4439f9e00fecdcb264",
"T3T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "9ee77f1d2e23260e7a2c682c6d1aa4a3c887de3626d6da6b8ce9918cd57de75d",
"T3T1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "464e865d96515f26cd5e828ad1272f9c98c15683f713a6400e4614de38ca6c4a",
@@ -33386,16 +33386,16 @@
"T3T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "2c1e40e0ef216e107957a5672fcbbd96116ee14eda58ba90bb9bb96261330680",
"T3T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "390d9ccb251df4b1d83bd14a79197b3c107d7c35a6e05b6e434e51929484e7cf",
"T3T1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "48d076e547f1c6c3651244b09f0231b438db65442513c13cb1f66cc400dd24c7",
-"T3T1_pt_solana-test_sign_message.py::test_invalid_envelope[extra]": "61cd3839fabed4a215648341c743f8efebb8bd1ec612577299e1d9dcfdc9bafb",
-"T3T1_pt_solana-test_sign_message.py::test_invalid_envelope[invalid]": "61cd3839fabed4a215648341c743f8efebb8bd1ec612577299e1d9dcfdc9bafb",
-"T3T1_pt_solana-test_sign_message.py::test_invalid_envelope[malformed]": "61cd3839fabed4a215648341c743f8efebb8bd1ec612577299e1d9dcfdc9bafb",
-"T3T1_pt_solana-test_sign_message.py::test_invalid_envelope[missing]": "61cd3839fabed4a215648341c743f8efebb8bd1ec612577299e1d9dcfdc9bafb",
+"T3T1_pt_solana-test_sign_message.py::test_invalid_signed[extra]": "e2e83c1c49d6d0f0047b1f50962ec8004ce0eadab60e167347b6191b033702cb",
+"T3T1_pt_solana-test_sign_message.py::test_invalid_signed[invalid]": "e2e83c1c49d6d0f0047b1f50962ec8004ce0eadab60e167347b6191b033702cb",
+"T3T1_pt_solana-test_sign_message.py::test_invalid_signed[malformed]": "e2e83c1c49d6d0f0047b1f50962ec8004ce0eadab60e167347b6191b033702cb",
+"T3T1_pt_solana-test_sign_message.py::test_invalid_signed[missing]": "e2e83c1c49d6d0f0047b1f50962ec8004ce0eadab60e167347b6191b033702cb",
"T3T1_pt_solana-test_sign_message.py::test_missing_signer": "14256cd1b801d1b67a37de1198d61a80d342f39e5c5d6fa991ec7fb526d683be",
-"T3T1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "fb775abd06d217707a6d0caee6f874db21d210d538f9c063918943c8b03c72b8",
-"T3T1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "43bb8e949b27fc6052ffccb6f59d7838836048d9ec2d13c884a2a3c724931c62",
-"T3T1_pt_solana-test_sign_message.py::test_sign_verify[long]": "3b427d0db9c12db5dde7d533f7b62a46160ece0f786253bf3ee75272cbfa5a94",
-"T3T1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "c5aa4fb6904889c9eeb17ccbeb67c3bcfa081aa0f25a2501f7d746dde341c1cd",
-"T3T1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "cf616ace285caa56c60c6eed1448471c92627c92ff32336138d6280d8185e941",
+"T3T1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "bc9047eff0675564a6950d2beda5f412521f7b111e3d0cf142da6ad7f25f9ff5",
+"T3T1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "9ced87035752bc447d13a3e451fed897f861eb364fab78ef05dc389da2fba533",
+"T3T1_pt_solana-test_sign_message.py::test_sign_verify[long]": "9a854f184749529bbacf47e4ff64a26c35522f6a91d991ca1e49284800c7a996",
+"T3T1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "a4a8060a9e05ddf45c92bd1e7ed807ff206702a7bcc4b8df255c7676c1345403",
+"T3T1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "bea9eab6bcf41250c67e25ff56b9241561a04013443e24d2b9664a306918f7d0",
"T3T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "4bdf0b84902bcbbf8be1a1eebabba45b57ae83e4bc003471380ad075f2436f57",
"T3T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "4f4c660ddc0fe0d3db11460be14caebe066692aed7b53430cda351df0cba7e7b",
"T3T1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "7a27bd5593f5338c453f40d36db111510a91475b69c96ebe92ea75beb70fd1ea",
@@ -35820,16 +35820,16 @@
"T3W1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "191a7cd4398595e3cf9f2ad5d3ca74d7ea801a6b0b9e216957b820391e8314e2",
"T3W1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "37ba7f654044061581c0aa9a7166296ea29bd3a63310d4221b619a8f086fb493",
"T3W1_cs_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "e4426f7dc553465512e109beab5fce61c2210269f8937a25c431c44bc8c5a179",
-"T3W1_cs_solana-test_sign_message.py::test_invalid_envelope[extra]": "972cc88b09a581e231a3b785039ce4a0b434310065ed0d42edaec956c0bbb026",
-"T3W1_cs_solana-test_sign_message.py::test_invalid_envelope[invalid]": "972cc88b09a581e231a3b785039ce4a0b434310065ed0d42edaec956c0bbb026",
-"T3W1_cs_solana-test_sign_message.py::test_invalid_envelope[malformed]": "972cc88b09a581e231a3b785039ce4a0b434310065ed0d42edaec956c0bbb026",
-"T3W1_cs_solana-test_sign_message.py::test_invalid_envelope[missing]": "972cc88b09a581e231a3b785039ce4a0b434310065ed0d42edaec956c0bbb026",
+"T3W1_cs_solana-test_sign_message.py::test_invalid_signed[extra]": "aacaad6d09c10326069d93c1e73d7fa189ef1bc7dbb6d07a6b5e19152d08a33e",
+"T3W1_cs_solana-test_sign_message.py::test_invalid_signed[invalid]": "aacaad6d09c10326069d93c1e73d7fa189ef1bc7dbb6d07a6b5e19152d08a33e",
+"T3W1_cs_solana-test_sign_message.py::test_invalid_signed[malformed]": "aacaad6d09c10326069d93c1e73d7fa189ef1bc7dbb6d07a6b5e19152d08a33e",
+"T3W1_cs_solana-test_sign_message.py::test_invalid_signed[missing]": "aacaad6d09c10326069d93c1e73d7fa189ef1bc7dbb6d07a6b5e19152d08a33e",
"T3W1_cs_solana-test_sign_message.py::test_missing_signer": "2b06a6c36a96faaad9d1237b47e37374c5452331ad8fa3738accbd2e09ec1500",
-"T3W1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "7924d9d5ec4c5a78cf1be8e0e1c8648b2221e35aab6427fc95ae72262831791f",
-"T3W1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "a1b21800d933669d778c8d397a11e22ec28b3810f6a2e8d9f18ca44e619227fe",
-"T3W1_cs_solana-test_sign_message.py::test_sign_verify[long]": "596b51909c3566896d484252385342820429fd04670e34f6a1932270517349e6",
-"T3W1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "c52110357b620f09c541ef9bb67c76affa4266c8978f2dfaf743a56bd802aab1",
-"T3W1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "5d7d391558ee4b9d86fb261b9a14e73baa235a02c415502fd97bce9a68377f96",
+"T3W1_cs_solana-test_sign_message.py::test_sign_verify[ascii]": "0112b9d43838cd15902b49cb876b65b70dcf6bb15bd532880b6b67d4db1c5478",
+"T3W1_cs_solana-test_sign_message.py::test_sign_verify[large-multi]": "67be8393ddd738a4619f6d82dde3ade3d2de31ed9d31dc27b7d2d5612e9a088f",
+"T3W1_cs_solana-test_sign_message.py::test_sign_verify[long]": "3e2ad0d1d099249fc7cd0f45f31b0bb6dca7d1ffbfccee7fa926a33c6fa80222",
+"T3W1_cs_solana-test_sign_message.py::test_sign_verify[multi]": "eb64001c018047be7ad943bbb274b31643d83bfb484b91c8279669a8b4d8b1d2",
+"T3W1_cs_solana-test_sign_message.py::test_sign_verify[utf-8]": "b68783fddddbc7ff8af329be27250b330bf5b444259b24cffee9723f17b47275",
"T3W1_cs_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "a16d51bfde73c4ba501e957a047fb70e1070d3e8e0c4a50481166d94ab167a2c",
"T3W1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "669c028cbc44fcb933b61511bab07d6c43103f8b0660d8bff37e34ed7b5e8833",
"T3W1_cs_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "98c9bb2bdc368e25ae5679624ac4cf84606032cf8800fc39ba512c6bfbe6dcff",
@@ -37634,16 +37634,16 @@
"T3W1_de_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "1fa5edbbb3203e597e0b3bf9f3b639386d2ef64d15989638ffbfaa13a04f3415",
"T3W1_de_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "89ad571d78bb9d958411dedd18918928af42a0f13a733baefb9eae2487d3b688",
"T3W1_de_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "869670dcef8b3952917ff048807487718410bbee6eb387a3b45c2d9ce92aa4c0",
-"T3W1_de_solana-test_sign_message.py::test_invalid_envelope[extra]": "d1ec42a2b75608fd4f525a4316f7d2058ed0c1fd77c1fe4330cd4a6105001d89",
-"T3W1_de_solana-test_sign_message.py::test_invalid_envelope[invalid]": "d1ec42a2b75608fd4f525a4316f7d2058ed0c1fd77c1fe4330cd4a6105001d89",
-"T3W1_de_solana-test_sign_message.py::test_invalid_envelope[malformed]": "d1ec42a2b75608fd4f525a4316f7d2058ed0c1fd77c1fe4330cd4a6105001d89",
-"T3W1_de_solana-test_sign_message.py::test_invalid_envelope[missing]": "d1ec42a2b75608fd4f525a4316f7d2058ed0c1fd77c1fe4330cd4a6105001d89",
+"T3W1_de_solana-test_sign_message.py::test_invalid_signed[extra]": "9327df696298d07ec222881588074743033d0dc4bd9fa357d2e7770f0894ba3d",
+"T3W1_de_solana-test_sign_message.py::test_invalid_signed[invalid]": "9327df696298d07ec222881588074743033d0dc4bd9fa357d2e7770f0894ba3d",
+"T3W1_de_solana-test_sign_message.py::test_invalid_signed[malformed]": "9327df696298d07ec222881588074743033d0dc4bd9fa357d2e7770f0894ba3d",
+"T3W1_de_solana-test_sign_message.py::test_invalid_signed[missing]": "9327df696298d07ec222881588074743033d0dc4bd9fa357d2e7770f0894ba3d",
"T3W1_de_solana-test_sign_message.py::test_missing_signer": "32c06c9f4ef6d91d183e5480b273a0aec9bd56572528ddbfb70b7cd609cbef50",
-"T3W1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "eef7d3af69e59e376056ce7a405c6d16f8f8ac4e497c4107232553997a696208",
-"T3W1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "19030a435b3ee951126b4a4fc4e8c57ee9e286cb14631887bb422c731476ccdf",
-"T3W1_de_solana-test_sign_message.py::test_sign_verify[long]": "76b69ed9a803dad706f4d9139b3877bcdd0e1e8dd4373b42f4621f74b39c3389",
-"T3W1_de_solana-test_sign_message.py::test_sign_verify[multi]": "d24f0be891d7ac271694d6c445658139c6ae87099b90e874db56dbdfe175aeae",
-"T3W1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "64df61708adbce22942d9eff21555c1a4f81f5705f4f14e642b48167b47f81e6",
+"T3W1_de_solana-test_sign_message.py::test_sign_verify[ascii]": "a634e1b9c7aa477adac71921f70b5dedd438fbdda3d9ab454a2ea8e164ba8f40",
+"T3W1_de_solana-test_sign_message.py::test_sign_verify[large-multi]": "0f0a8e5a7eb5ed217945d1a88f9d0318018a5fc205ea0e81423e3abc8988a03a",
+"T3W1_de_solana-test_sign_message.py::test_sign_verify[long]": "5d555f56577266ceeef8fb3c36e03c88690b564b330c5bcea29d0cfbc76f4667",
+"T3W1_de_solana-test_sign_message.py::test_sign_verify[multi]": "d9513c24aab1a4b26af2f171a31cb0357f71e129f1e3422fd0860553f39d2e02",
+"T3W1_de_solana-test_sign_message.py::test_sign_verify[utf-8]": "b897906594b449b8f4296fd8dea49c93763413bb88ed033afbe0305ebe1e3bea",
"T3W1_de_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "a1a08cd71c333ef31d1b7d8f98d9b09c7636be39f9ee834247250ddba08dc0db",
"T3W1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "a364be56c98c21a5c0c8f750bd239070c660ee480fba1c4af96fea8bcc47ff76",
"T3W1_de_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "31ea68b6d274f43031b21d770f67e57564743ad28a6b2d019f6cc26776d7bc18",
@@ -39448,16 +39448,16 @@
"T3W1_en_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "fba1f00b3220da5ca61d7318621969f40920be23320b08c0e2f04d885613b565",
"T3W1_en_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "240ec3c624ffddcb29ac83b82182623b48c83cd0729d05e74700f43a5b22a94b",
"T3W1_en_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "f4e88e551de600e5ccb456859876652b6a1b6f6827de78b50fed032790197935",
-"T3W1_en_solana-test_sign_message.py::test_invalid_envelope[extra]": "f3c75bbd2ba9e9d201f1c5d1196f83b344b81e3c59d0dd42fe793c15d5113b67",
-"T3W1_en_solana-test_sign_message.py::test_invalid_envelope[invalid]": "f3c75bbd2ba9e9d201f1c5d1196f83b344b81e3c59d0dd42fe793c15d5113b67",
-"T3W1_en_solana-test_sign_message.py::test_invalid_envelope[malformed]": "f3c75bbd2ba9e9d201f1c5d1196f83b344b81e3c59d0dd42fe793c15d5113b67",
-"T3W1_en_solana-test_sign_message.py::test_invalid_envelope[missing]": "f3c75bbd2ba9e9d201f1c5d1196f83b344b81e3c59d0dd42fe793c15d5113b67",
+"T3W1_en_solana-test_sign_message.py::test_invalid_signed[extra]": "b40d86fe1fa4a04b0d1843429bb7a067ff933e17173b205a49b72de604fa3b59",
+"T3W1_en_solana-test_sign_message.py::test_invalid_signed[invalid]": "b40d86fe1fa4a04b0d1843429bb7a067ff933e17173b205a49b72de604fa3b59",
+"T3W1_en_solana-test_sign_message.py::test_invalid_signed[malformed]": "b40d86fe1fa4a04b0d1843429bb7a067ff933e17173b205a49b72de604fa3b59",
+"T3W1_en_solana-test_sign_message.py::test_invalid_signed[missing]": "b40d86fe1fa4a04b0d1843429bb7a067ff933e17173b205a49b72de604fa3b59",
"T3W1_en_solana-test_sign_message.py::test_missing_signer": "90812f196e8c35dc7f35cb5a9a0e553c8fc6a610812d85b9f166e90b3f1c8b59",
-"T3W1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "a27ea3ba64f67f25217c1a9d9ef166eccc5739ad0fe931bf2d3ffbe8b2be5916",
-"T3W1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "8f31b4b7b77797be75350ce2bc4003e75f1393f1c3a24d713cdd0a6340ef8072",
-"T3W1_en_solana-test_sign_message.py::test_sign_verify[long]": "307fd098dedf56a6276a772e901c578de9e1baeb58568441bb8c34ec2b0a197a",
-"T3W1_en_solana-test_sign_message.py::test_sign_verify[multi]": "dadacb50e354e7e33c3d312cdf7cf7244012455587a3fd0b7c70d5794c5579db",
-"T3W1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "af8e9c1cb6bff57542bc0bac4b965403c13753c09233751240a0d0fbdf9ab533",
+"T3W1_en_solana-test_sign_message.py::test_sign_verify[ascii]": "105383b9cba8a18338c43c68e29f757e3636471dd4fda411d25fa43cf998a0de",
+"T3W1_en_solana-test_sign_message.py::test_sign_verify[large-multi]": "ac45be6c876cd8a690f04789d72ec72dd04faec2135741738d6194694cf672aa",
+"T3W1_en_solana-test_sign_message.py::test_sign_verify[long]": "b49f4dda3bc44fc5f4a6f989b160e7d498504a9417f4f8fb036eaab842dfa9a0",
+"T3W1_en_solana-test_sign_message.py::test_sign_verify[multi]": "a88cb6fe4411e156165c2e481cf5b056ba0cd1f5f25e64c3a81f9b0ad7f8a9a9",
+"T3W1_en_solana-test_sign_message.py::test_sign_verify[utf-8]": "c314304f27745d85f4c33fe435f9c0cbaa06715e7af03a81a1ff4c3e544736aa",
"T3W1_en_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "0925de01e27012f303551a05f2f050ebb9bae58fab11e2fc5557e6d1f646de6f",
"T3W1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "b9d883f280aacc81f5048e41d090823730827db6680c962e33ea2259c2c6f60e",
"T3W1_en_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "dc664d20575cb66428de89831e51f52c99a608a94af4d21933f8e15b9213c735",
@@ -41262,16 +41262,16 @@
"T3W1_es_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "99f2055c2601a82954dbfdf3bac72a00ab16a0b1588231cb69693588221474c4",
"T3W1_es_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "aa756bfe3bb59b76564b51eb0c60b786a6a70641763c62d0994398d569a27da5",
"T3W1_es_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "1aed3aa54aad7e5a8ea1bc41390906ba719f2418bd41aaeaa305cad09d8f1ea2",
-"T3W1_es_solana-test_sign_message.py::test_invalid_envelope[extra]": "13b4614b945a5e9f8948d72d42c7dd0c0e7fb514c24b6979b360a12004bcca9f",
-"T3W1_es_solana-test_sign_message.py::test_invalid_envelope[invalid]": "13b4614b945a5e9f8948d72d42c7dd0c0e7fb514c24b6979b360a12004bcca9f",
-"T3W1_es_solana-test_sign_message.py::test_invalid_envelope[malformed]": "13b4614b945a5e9f8948d72d42c7dd0c0e7fb514c24b6979b360a12004bcca9f",
-"T3W1_es_solana-test_sign_message.py::test_invalid_envelope[missing]": "13b4614b945a5e9f8948d72d42c7dd0c0e7fb514c24b6979b360a12004bcca9f",
+"T3W1_es_solana-test_sign_message.py::test_invalid_signed[extra]": "9d4a4216b6f98818a1992d942bd77c42e233b7ed98ce49cbdbd549f4d3f06809",
+"T3W1_es_solana-test_sign_message.py::test_invalid_signed[invalid]": "9d4a4216b6f98818a1992d942bd77c42e233b7ed98ce49cbdbd549f4d3f06809",
+"T3W1_es_solana-test_sign_message.py::test_invalid_signed[malformed]": "9d4a4216b6f98818a1992d942bd77c42e233b7ed98ce49cbdbd549f4d3f06809",
+"T3W1_es_solana-test_sign_message.py::test_invalid_signed[missing]": "9d4a4216b6f98818a1992d942bd77c42e233b7ed98ce49cbdbd549f4d3f06809",
"T3W1_es_solana-test_sign_message.py::test_missing_signer": "ddbd1412a9f69aea1c41c375a2ec0647411a0e487ec5c1ee55e24505dfc34e29",
-"T3W1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "c13e062dd1bad9dbb5be19fb2e8e8d50965ad802ed8717868ea12297bc9ff3c7",
-"T3W1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "5f88887d852621ab137a8354046ae780a041b2cdef20819f105c61aa8a244b7b",
-"T3W1_es_solana-test_sign_message.py::test_sign_verify[long]": "8a51738d593da07d3b5fabeb433f73914cc747079ec497b3d6df43afebd63fe7",
-"T3W1_es_solana-test_sign_message.py::test_sign_verify[multi]": "8c1ac0c44f72cc895edac7085cd0b266c6168c221d2950e5a009f9f7f93ea276",
-"T3W1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "566d7c49c4c20074400e7def498c57e5363f9e86e69572a7e90b7b5a6188d4e1",
+"T3W1_es_solana-test_sign_message.py::test_sign_verify[ascii]": "28e1e2248a0d2a27a6f393a1425053f93986f3e32046f6696050bf36a8faed3f",
+"T3W1_es_solana-test_sign_message.py::test_sign_verify[large-multi]": "fc09f04f4802f8a02c3aff50d420399cdc86c701b4035b1a9b7d1e5a06acd746",
+"T3W1_es_solana-test_sign_message.py::test_sign_verify[long]": "71a062b4e7fbd37fcca5e3f70e9469d6a4e97beb3f32f2dca4fcbe161dccf91a",
+"T3W1_es_solana-test_sign_message.py::test_sign_verify[multi]": "e19b04fb63930fba2cc6f32df6fffd5112e9e9711ed0aa0fb6bd3878bb91c1da",
+"T3W1_es_solana-test_sign_message.py::test_sign_verify[utf-8]": "62fdd09fefd44c30fed0393064713eba0c64455462bc128edda95919b4ccb52d",
"T3W1_es_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "8d4aad20736b0d2aae0003242151eb39a737647dddb65a7e55ac844c5efd09aa",
"T3W1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "00083107887b9cbdb149a70e5615ab2ebbdec9d4c809a510d48e5c36bb3fbadb",
"T3W1_es_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "3757d42ce3ea7d0b9e9ef371a4cd068d9637590d3f5fd5ee43f29916ae934622",
@@ -43076,16 +43076,16 @@
"T3W1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "4421abcda525a0f8fdc569db3e2f13e11707c6b74ae36048931db79fd5079cec",
"T3W1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "ada63fe4f19f8429c927fac215dce7f5df7ac6aebf2b2f9df1f6054822d22ee2",
"T3W1_fr_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "9f0fe4396404ef5abb0ef1b94acdf63349a145fc8d1c70a83ab66fd39c608559",
-"T3W1_fr_solana-test_sign_message.py::test_invalid_envelope[extra]": "212b8736c020beb9125e7a3eddac8b0549786c6557cbd2c9691008831393c961",
-"T3W1_fr_solana-test_sign_message.py::test_invalid_envelope[invalid]": "212b8736c020beb9125e7a3eddac8b0549786c6557cbd2c9691008831393c961",
-"T3W1_fr_solana-test_sign_message.py::test_invalid_envelope[malformed]": "212b8736c020beb9125e7a3eddac8b0549786c6557cbd2c9691008831393c961",
-"T3W1_fr_solana-test_sign_message.py::test_invalid_envelope[missing]": "212b8736c020beb9125e7a3eddac8b0549786c6557cbd2c9691008831393c961",
+"T3W1_fr_solana-test_sign_message.py::test_invalid_signed[extra]": "b5be23ea6c845fe8f30faced2648914f4c6ef58aea18dc1a2e034498368acfef",
+"T3W1_fr_solana-test_sign_message.py::test_invalid_signed[invalid]": "b5be23ea6c845fe8f30faced2648914f4c6ef58aea18dc1a2e034498368acfef",
+"T3W1_fr_solana-test_sign_message.py::test_invalid_signed[malformed]": "b5be23ea6c845fe8f30faced2648914f4c6ef58aea18dc1a2e034498368acfef",
+"T3W1_fr_solana-test_sign_message.py::test_invalid_signed[missing]": "b5be23ea6c845fe8f30faced2648914f4c6ef58aea18dc1a2e034498368acfef",
"T3W1_fr_solana-test_sign_message.py::test_missing_signer": "a392ca1dea666647fb2d6edfcd90e4e3cad6ab0e294ca85cda7db478214a6a81",
-"T3W1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "bf72c9df41d4886ff9bbd390c19864eb3cb051480935e8aff67f67771852168c",
-"T3W1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "27fe66265e055bfd31cc545ce614600c0bab5d67aac3112caefa253c03e50df5",
-"T3W1_fr_solana-test_sign_message.py::test_sign_verify[long]": "9d4eded3145b556c14e9afc02a9b315439b6f78448e82e6d6a0470d4162b9bba",
-"T3W1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "8fa79a95a8117732108f9abba4b11fad22af5230ed75c1883301e898f09c5ff6",
-"T3W1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "0e99e4260b791e377d3df725b6d6748dc2ae707cd2a05f185a1c2b28a1565989",
+"T3W1_fr_solana-test_sign_message.py::test_sign_verify[ascii]": "b46cdac533f6d0e7ec960d2e5ea6342f1fe0396a057b4ed40d9552cb69059d8c",
+"T3W1_fr_solana-test_sign_message.py::test_sign_verify[large-multi]": "ff2f4752ff78df55544d0de04cdf250d0399a970a9690b20ac35a2cf15232b57",
+"T3W1_fr_solana-test_sign_message.py::test_sign_verify[long]": "c425a9a36b9a304cc8930fff1c67bb2d253d3296c1837a3dd7b2ecc7a017aa8a",
+"T3W1_fr_solana-test_sign_message.py::test_sign_verify[multi]": "c1fa9d0e172d2aa64d20f4766f7a24447899d1942e388b47f457c6864d67cc71",
+"T3W1_fr_solana-test_sign_message.py::test_sign_verify[utf-8]": "685cbb39b2b3d961de5111a58a6952fbbcd3f8246c45f9f252a16d05a09f3716",
"T3W1_fr_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "9d8c5e7b600491e2cd920f8ac9706ed6966bd216532e682c935e100ebda2a6d5",
"T3W1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "ed725d85881798559114dd27a1d4f97cab7c5fd1408fd42b9f0b66fd8e316d2d",
"T3W1_fr_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "b03131d7d43ed816305e1fe995aee770ccda51d8aa2fb068685e30f05a3326ed",
@@ -44895,16 +44895,16 @@
"T3W1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters0-result0]": "3031f2a3a2bbaa5fa1eb49c1de93b9b7f2b4e5630eadf0175085aa0ff90d7da0",
"T3W1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters1-result1]": "55e936978a858d8a6c09e847bbfdc58274bc92427df75f7b9e151a5f4849b8e0",
"T3W1_pt_solana-test_public_key.py::test_solana_get_public_key[parameters2-result2]": "68d1318a3099e997b26b5affd961df2acc66a9363e12c89401be038791bed6c7",
-"T3W1_pt_solana-test_sign_message.py::test_invalid_envelope[extra]": "a8ba754823942a5a86a2262ee9f63b10856caee4d89b68f76fa629efbbf04ae2",
-"T3W1_pt_solana-test_sign_message.py::test_invalid_envelope[invalid]": "a8ba754823942a5a86a2262ee9f63b10856caee4d89b68f76fa629efbbf04ae2",
-"T3W1_pt_solana-test_sign_message.py::test_invalid_envelope[malformed]": "a8ba754823942a5a86a2262ee9f63b10856caee4d89b68f76fa629efbbf04ae2",
-"T3W1_pt_solana-test_sign_message.py::test_invalid_envelope[missing]": "a8ba754823942a5a86a2262ee9f63b10856caee4d89b68f76fa629efbbf04ae2",
+"T3W1_pt_solana-test_sign_message.py::test_invalid_signed[extra]": "2eb04034280fe38f039dc1a4eb3581c17b23dc7bdb8885916c09762bc1f3a312",
+"T3W1_pt_solana-test_sign_message.py::test_invalid_signed[invalid]": "2eb04034280fe38f039dc1a4eb3581c17b23dc7bdb8885916c09762bc1f3a312",
+"T3W1_pt_solana-test_sign_message.py::test_invalid_signed[malformed]": "2eb04034280fe38f039dc1a4eb3581c17b23dc7bdb8885916c09762bc1f3a312",
+"T3W1_pt_solana-test_sign_message.py::test_invalid_signed[missing]": "2eb04034280fe38f039dc1a4eb3581c17b23dc7bdb8885916c09762bc1f3a312",
"T3W1_pt_solana-test_sign_message.py::test_missing_signer": "6fb22dca4b252028ed3f91db1fb746e30d12aece0a74e1bcc4abef605a3a9026",
-"T3W1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "6530a3c5591983bcc9081540bb7ee5aba5abae8a018d349aa6f4a39357bf4945",
-"T3W1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "57cbbfb2476db522b7d98cbc6ffc9f159afb44a1c2291ce5d1602b77de088269",
-"T3W1_pt_solana-test_sign_message.py::test_sign_verify[long]": "f8db097f652aa9174618661c7c85a1f465cb45e8d41168040d3fb6d9e0f8d11f",
-"T3W1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "9adb43d24b6603ea4068be808248d2c0ed66e4d0b07b1e4a34e1c90322910b2c",
-"T3W1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "49575a2bf2873c6bfcbfd671582a0b145a6918b70e6b99a156974543707675b1",
+"T3W1_pt_solana-test_sign_message.py::test_sign_verify[ascii]": "d94b8ae25dc249853d4475d89bbeedd73d9ea681669f2db459147a8513837c22",
+"T3W1_pt_solana-test_sign_message.py::test_sign_verify[large-multi]": "1a8a194cda1762ad9bd017e3d70096a1c8d4761f61f66a9732953e4fc5f875dc",
+"T3W1_pt_solana-test_sign_message.py::test_sign_verify[long]": "8ae6a67520c5f0c05f1388a64f8903370a37a090b0a690084123a5e0cc104be0",
+"T3W1_pt_solana-test_sign_message.py::test_sign_verify[multi]": "d8f5e079fc72f5d2733f473f629b133c54dcfb3d815c2f24551e864379198382",
+"T3W1_pt_solana-test_sign_message.py::test_sign_verify[utf-8]": "0b91ff1eb5eac8bfa63b78f0b0fb9b000bfe6537b5147622ae32dfab3e068630",
"T3W1_pt_solana-test_sign_tx.py::test_solana_sign_tx[advance_nonce_account]": "f91c2dec6173fd9b76164aee32799d0caab4fa646803ac9be607be120e72f812",
"T3W1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate]": "fe1d774e41da1a81ecba440aacb2bc57cd49b21f931683d58c0b3258d207c36a",
"T3W1_pt_solana-test_sign_tx.py::test_solana_sign_tx[allocate_with_seed]": "a1b188bc57a71169a225eec70979d4ca6006ac79802190b72cf44a00fb71003e",
Why this scored 39/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.