fix: improve Solana message handling
What changed, and why it matters
This commit hardens how Keystone 3 handles Solana signing requests. Previously, the device partly trusted an external 'sign type' flag from the wallet app to decide whether a QR code contained a transaction or a plain message. The patch now inspects the actual bytes: if they look like a complete transaction it is treated as a transaction; if they start like a transaction but have extra hidden bytes it is rejected; otherwise it is treated as a message. It also adds a warning banner when a Solana message cannot be fully parsed, so the user knows they are 'blind signing'. A small UI fix also makes the camera scanner resume correctly after an error instead of getting stuck.
Treat this as a security-hardening fix and ensure it is included in the next firmware release. Review the classify_payload() logic for completeness, especially edge cases around off-chain message v0 and versioned transactions, and verify the UI warning is shown consistently for all raw message paths.
Security signals we found
Replaces trust in external sign-type metadata with byte-level payload classification
Rejects malformed transactions that contain a valid transaction prefix followed by hidden trailing data
Prevents a transaction from being displayed and signed as a plain message
Adds a blind-sign warning for unparsed Solana messages
Fixes scanner UI not resuming after an error
Evidence from the diff
The change introduces classify_payload() in rust/apps/solana/src/lib.rs, which categorizes Solana sign-data as Transaction, Message, or MalformedTransaction by parsing the bytes rather than relying on SolSignRequest.get_sign_type(). rust/rust_c/src/common/ur_ext.rs now maps Transaction and MalformedTransaction to ViewType::SolanaTx and Message to ViewType::SolanaMessage. rust/rust_c/src/solana/mod.rs rejects signing when the payload is MalformedTransaction (‘transaction contains hidden trailing data’) and refuses to parse a message that is actually a transaction. src/ui/gui_chain/multi/web3/gui_sol.c adds an orange ‘Blind Sign’ warning for raw/unparsed Solana messages. src/ui/gui_widgets/gui_scan_widgets.c changes error callbacks from GuiScanStart to a new GuiScanResumeAfterError so the camera resumes after an error. i18n strings are added for the new warning.
Changed components
rust/apps/solana/src/lib.rsrust/rust_c/src/common/ur_ext.rsrust/rust_c/src/solana/mod.rssrc/ui/gui_chain/multi/web3/gui_sol.csrc/ui/gui_widgets/gui_scan_widgets.csrc/ui/lv_i18n/data.csvsrc/ui/lv_i18n/lv_i18n.cInspect captured patch +151 / −38
diff --git a/rust/apps/solana/src/lib.rs b/rust/apps/solana/src/lib.rs
index 89ad9cf..38e72be 100644
--- a/rust/apps/solana/src/lib.rs
+++ b/rust/apps/solana/src/lib.rs
@@ -36,6 +36,33 @@ pub mod utils;
const OFFCHAIN_MESSAGE_DOMAIN: &[u8; 16] = b"\xffsolana offchain";
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum SolanaPayloadType {
+ Transaction,
+ Message,
+ MalformedTransaction,
+}
+
+pub fn classify_payload(data: &[u8]) -> SolanaPayloadType {
+ let is_complete_transaction = {
+ let mut candidate = data.to_vec();
+ message::Message::read_exact(&mut candidate).is_ok()
+ };
+ if is_complete_transaction {
+ return SolanaPayloadType::Transaction;
+ }
+
+ let has_transaction_prefix = {
+ let mut candidate = data.to_vec();
+ message::Message::has_valid_prefix(&mut candidate)
+ };
+ if has_transaction_prefix {
+ SolanaPayloadType::MalformedTransaction
+ } else {
+ SolanaPayloadType::Message
+ }
+}
+
fn parse_offchain_message_v0(data: &[u8]) -> Option<&str> {
const PREAMBLE_LEN: usize = 20;
const RESTRICTED_ASCII: u8 = 0;
@@ -185,6 +212,31 @@ mod tests {
assert_eq!(hex::encode(data), parsed.raw_message);
}
+ #[test]
+ fn classifies_payload_by_content_instead_of_external_sign_type() {
+ let transaction = hex::decode("010002041a93fffb26ce645adeae58f0f414c320bcec30ce12a66bd263a91ec9b3958ff46f345144d352e4190c2dec43e1d3e0296a49bdfc2594eed9d8a5902e22d0af8b00000000000000000000000000000000000000000000000000000000000000000306466fe5211732ffecadba72c39be7bc8ce5bbc5f7126b2c439b3a40000000f70a9d4448ef435c5beab6cbc4211e00ddb4b9ad84886385f8b7ccfb9d9e7ca40303000903d8d600000000000003000502400d0300020200010c020000008096980000000000").unwrap();
+ assert_eq!(
+ SolanaPayloadType::Transaction,
+ classify_payload(&transaction)
+ );
+
+ let mut transaction_with_suffix = transaction;
+ transaction_with_suffix.push(0xaa);
+ assert_eq!(
+ SolanaPayloadType::MalformedTransaction,
+ classify_payload(&transaction_with_suffix)
+ );
+
+ assert_eq!(
+ SolanaPayloadType::Message,
+ classify_payload(b"Sign in to this application")
+ );
+ assert_eq!(
+ SolanaPayloadType::Message,
+ classify_payload(b"\xffsolana offchain\x00\x01\x04\x00test")
+ );
+ }
+
#[test]
fn test_solana_version_message() {
let mut buffer = hex::decode("8001000308ad7dba70a9559a85961a00a0d00e7caf6967ff28c5861360cd8e22abcbb9b3eb080a39da2d35d3c666ff3d5195bb9065ed97a2208b4245bc70e69ff4b1d2b73fff21b6871e314c96e0848ba15117ec8cef8433b5a594ff2b88798b7e6d37b84e0a0cc6b26d4216a826e48cbb719136037e76cc273efb63ec73a6f2cb56cfa6015f376f7759fe1a4270a9b568d86110869cb073c8580adc986a178c876c18ee3d0306466fe5211732ffecadba72c39be7bc8ce5bbc5f7126b2c439b3a4000000004b2acb11258cce3682c418ba872ff3df91102712f15af12b6be69b3435b0008eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a5b6bfd38a1d64b54c65490c10b1be53496be5ede8d18086335aade667915e9e90705000502400d03000500090310010a00000000000606080d0706060e0802da8aeb4fc9196606030d010808218493e497c04859060b0001090802030d0f101112098c90fd150a4af80300060c00010d09080a0b0c04061113104b5d5ddc2296dac4ffffffffffffffff060b0001090802030d0f101112098c90fd150a4af803000110aaf654f15c22d8c9aa80622becb4872b0f5a52cc8f467d8a0da58b19197d690540024544420701757403060704").unwrap();
diff --git a/rust/rust_c/src/common/ur_ext.rs b/rust/rust_c/src/common/ur_ext.rs
index c394f1b..07cb1d0 100644
--- a/rust/rust_c/src/common/ur_ext.rs
+++ b/rust/rust_c/src/common/ur_ext.rs
@@ -54,7 +54,7 @@ use ur_registry::pb::protobuf_parser::{parse_protobuf, unzip};
use ur_registry::pb::protoc;
use ur_registry::pb::protoc::Base;
#[cfg(feature = "solana")]
-use ur_registry::solana::sol_sign_request::{SignType as SolanaSignType, SolSignRequest};
+use ur_registry::solana::sol_sign_request::SolSignRequest;
#[cfg(feature = "stellar")]
use ur_registry::stellar::stellar_sign_request::{SignType as StellarSignType, StellarSignRequest};
#[cfg(feature = "sui")]
@@ -378,17 +378,10 @@ impl InferViewType for BtcSignRequest {
#[cfg(feature = "solana")]
impl InferViewType for SolSignRequest {
fn infer(&self) -> Result<ViewType, URError> {
- match self.get_sign_type() {
- SolanaSignType::Transaction => Ok(ViewType::SolanaTx),
- SolanaSignType::Message => {
- let sign_data = self.get_sign_data();
- if app_solana::validate_tx(&mut sign_data.clone())
- || app_solana::has_tx_prefix(&mut sign_data.clone())
- {
- return Ok(ViewType::SolanaTx);
- }
- Ok(ViewType::SolanaMessage)
- }
+ match app_solana::classify_payload(&self.get_sign_data()) {
+ app_solana::SolanaPayloadType::Transaction
+ | app_solana::SolanaPayloadType::MalformedTransaction => Ok(ViewType::SolanaTx),
+ app_solana::SolanaPayloadType::Message => Ok(ViewType::SolanaMessage),
}
}
}
diff --git a/rust/rust_c/src/solana/mod.rs b/rust/rust_c/src/solana/mod.rs
index c37ee34..4ddfad3 100644
--- a/rust/rust_c/src/solana/mod.rs
+++ b/rust/rust_c/src/solana/mod.rs
@@ -10,7 +10,7 @@ use app_solana::errors::SolanaError;
use app_solana::parse_message;
use cty::c_char;
use structs::{DisplaySolanaMessage, DisplaySolanaTx};
-use ur_registry::solana::sol_sign_request::{SignType, SolSignRequest};
+use ur_registry::solana::sol_sign_request::SolSignRequest;
use ur_registry::solana::sol_signature::SolSignature;
use ur_registry::traits::RegistryItem;
@@ -19,19 +19,13 @@ pub mod structs;
unsafe fn build_sign_result(ptr: PtrUR, seed: &[u8]) -> Result<SolSignature, SolanaError> {
let sign_request = extract_ptr_with_type!(ptr, SolSignRequest);
let sign_data = sign_request.get_sign_data();
- let sign_type = sign_request.get_sign_type();
- let is_complete_transaction = match sign_type {
- // Exact parsing is performed together with the required-signer check below,
- // avoiding a second full transaction parse on the normal signing path.
- SignType::Transaction => true,
- SignType::Message => {
- let is_complete_transaction = app_solana::validate_tx(&mut sign_data.clone());
- if !is_complete_transaction && app_solana::has_tx_prefix(&mut sign_data.clone()) {
- return Err(SolanaError::InvalidData(
- "message contains a transaction prefix with hidden trailing data".to_string(),
- ));
- }
- is_complete_transaction
+ let is_complete_transaction = match app_solana::classify_payload(&sign_data) {
+ app_solana::SolanaPayloadType::Transaction => true,
+ app_solana::SolanaPayloadType::Message => false,
+ app_solana::SolanaPayloadType::MalformedTransaction => {
+ return Err(SolanaError::InvalidData(
+ "transaction contains hidden trailing data".to_string(),
+ ));
}
};
let mut path =
@@ -164,12 +158,20 @@ pub unsafe extern "C" fn solana_parse_message(
) -> PtrT<TransactionParseResult<DisplaySolanaMessage>> {
let sol_sign_request = extract_ptr_with_type!(ptr, SolSignRequest);
let pubkey = recover_c_char(pubkey);
- // verify whether the UR is message to prevent using the tx as message
- if app_solana::has_tx_prefix(&mut sol_sign_request.get_sign_data()) {
- return TransactionParseResult::from(RustCError::UnsupportedTransaction(
- "Transaction".to_string(),
- ))
- .c_ptr();
+ match app_solana::classify_payload(&sol_sign_request.get_sign_data()) {
+ app_solana::SolanaPayloadType::Message => {}
+ app_solana::SolanaPayloadType::Transaction => {
+ return TransactionParseResult::from(RustCError::UnsupportedTransaction(
+ "Transaction".to_string(),
+ ))
+ .c_ptr();
+ }
+ app_solana::SolanaPayloadType::MalformedTransaction => {
+ return TransactionParseResult::from(SolanaError::InvalidData(
+ "transaction contains hidden trailing data".to_string(),
+ ))
+ .c_ptr();
+ }
}
match parse_message(sol_sign_request.get_sign_data(), &pubkey.to_string()) {
Ok(t) => TransactionParseResult::success(DisplaySolanaMessage::from(t).c_ptr()).c_ptr(),
diff --git a/src/ui/gui_chain/multi/web3/gui_sol.c b/src/ui/gui_chain/multi/web3/gui_sol.c
index 827a8ab..9826aa8 100644
--- a/src/ui/gui_chain/multi/web3/gui_sol.c
+++ b/src/ui/gui_chain/multi/web3/gui_sol.c
@@ -28,6 +28,7 @@ typedef struct {
size_t page_count;
bool utf8;
lv_obj_t *viewport;
+ lv_obj_t *warning;
lv_obj_t *label;
lv_obj_t *page_label;
lv_obj_t *prev;
@@ -270,6 +271,17 @@ static void SolMessagePagerRefresh(SolMessagePager_t *pager)
}
page_text[length] = '\0';
+ lv_coord_t label_y = 0;
+ if (pager->warning != NULL) {
+ if (pager->page == 0) {
+ lv_obj_clear_flag(pager->warning, LV_OBJ_FLAG_HIDDEN);
+ lv_obj_update_layout(pager->warning);
+ label_y = lv_obj_get_height(pager->warning) + 16;
+ } else {
+ lv_obj_add_flag(pager->warning, LV_OBJ_FLAG_HIDDEN);
+ }
+ }
+ lv_obj_set_y(pager->label, label_y);
lv_label_set_text(pager->label, page_text);
lv_obj_set_height(pager->label, LV_SIZE_CONTENT);
lv_obj_update_layout(pager->viewport);
@@ -325,10 +337,33 @@ static lv_obj_t *SolMessagePagerButton(lv_obj_t *parent, const char *text)
return button;
}
+static lv_obj_t *SolMessageRiskWarning(lv_obj_t *parent)
+{
+ lv_obj_t *warning = lv_obj_create(parent);
+ lv_obj_set_width(warning, 360);
+ lv_obj_set_height(warning, LV_SIZE_CONTENT);
+ lv_obj_set_style_pad_all(warning, 16, LV_PART_MAIN);
+ lv_obj_set_style_pad_row(warning, 8, LV_PART_MAIN);
+ lv_obj_set_style_border_width(warning, 0, LV_PART_MAIN);
+ lv_obj_set_style_radius(warning, 8, LV_PART_MAIN);
+ lv_obj_set_style_bg_color(warning, lv_color_hex(0xF55831), LV_PART_MAIN);
+ lv_obj_set_style_bg_opa(warning, 48, LV_PART_MAIN);
+ lv_obj_set_flex_flow(warning, LV_FLEX_FLOW_COLUMN);
+
+ lv_obj_t *title = GuiCreateTextLabel(warning, _("solana_blind_sign_title"));
+ lv_obj_set_width(title, 328);
+ lv_obj_set_style_text_color(title, lv_color_hex(0xF55831), LV_PART_MAIN);
+
+ lv_obj_t *content = GuiCreateIllustrateLabel(
+ warning, _("solana_unparsed_message_warning"));
+ lv_obj_set_width(content, 328);
+ lv_label_set_long_mode(content, LV_LABEL_LONG_WRAP);
+ lv_obj_set_style_text_color(content, WHITE_COLOR, LV_PART_MAIN);
+ return warning;
+}
+
void GuiShowSolMessagePaged(lv_obj_t *parent, void *param, bool raw)
{
- static const char raw_notice[] =
- "\n\nUnparsed data. Verify it in the software wallet.";
DisplaySolanaMessage *message = (DisplaySolanaMessage *)param;
const char *text = raw ? message->raw_message : message->utf8_message;
if (text == NULL) {
@@ -338,7 +373,7 @@ void GuiShowSolMessagePaged(lv_obj_t *parent, void *param, bool raw)
SolMessagePager_t *pager = SRAM_MALLOC(sizeof(SolMessagePager_t));
memset(pager, 0, sizeof(SolMessagePager_t));
pager->text = text;
- pager->suffix = raw ? raw_notice : "";
+ pager->suffix = "";
pager->text_len = strlen(pager->text);
pager->suffix_len = strlen(pager->suffix);
pager->utf8 = !raw;
@@ -362,6 +397,11 @@ void GuiShowSolMessagePaged(lv_obj_t *parent, void *param, bool raw)
lv_obj_set_scroll_dir(pager->viewport, LV_DIR_VER);
lv_obj_add_flag(pager->viewport, LV_OBJ_FLAG_SCROLLABLE);
+ if (raw) {
+ pager->warning = SolMessageRiskWarning(pager->viewport);
+ lv_obj_set_pos(pager->warning, 0, 0);
+ }
+
pager->label = lv_label_create(pager->viewport);
lv_obj_set_pos(pager->label, 0, 0);
lv_obj_set_width(pager->label, 360);
diff --git a/src/ui/gui_widgets/gui_scan_widgets.c b/src/ui/gui_widgets/gui_scan_widgets.c
index 6fcd731..ec3de1f 100644
--- a/src/ui/gui_widgets/gui_scan_widgets.c
+++ b/src/ui/gui_widgets/gui_scan_widgets.c
@@ -34,6 +34,7 @@ static void GuiScanNavBarInit();
static void GuiSetScanCorner(void);
static void ThrowError(int32_t errorCode);
static void GuiScanStart();
+static void GuiScanResumeAfterError();
#ifdef BTC_ONLY
static lv_obj_t *g_noticeWindow;
@@ -106,7 +107,7 @@ void GuiScanResult(bool result, void *param)
#ifdef BTC_ONLY
if (g_viewTypeFilter[0] != 0xFF) {
if (!IsViewTypeSupported(g_qrcodeViewType, g_viewTypeFilter, NUMBER_OF_ARRAYS(g_viewTypeFilter))) {
- g_scanErrorHintBox = GuiCreateErrorCodeWindow(ERR_MULTISIG_WALLET_CONFIG_INVALID, &g_scanErrorHintBox, GuiScanStart);
+ g_scanErrorHintBox = GuiCreateErrorCodeWindow(ERR_MULTISIG_WALLET_CONFIG_INVALID, &g_scanErrorHintBox, GuiScanResumeAfterError);
return;
}
}
@@ -222,7 +223,7 @@ void GuiTransactionCheckFailed(PtrT_TransactionCheckResult result)
case BitcoinWalletTypeError:
case MasterFingerprintMismatch:
case UnsupportedTransaction:
- GuiCreateRustErrorWindow(result->error_code, result->error_message, NULL, GuiScanStart);
+ GuiCreateRustErrorWindow(result->error_code, result->error_message, NULL, GuiScanResumeAfterError);
break;
default:
ThrowError(ERR_INVALID_QRCODE);
@@ -289,7 +290,7 @@ static void GuiSetScanCorner(void)
static void ThrowError(int32_t errorCode)
{
GuiSetScanCorner();
- g_scanErrorHintBox = GuiCreateErrorCodeWindow(errorCode, &g_scanErrorHintBox, GuiScanStart);
+ g_scanErrorHintBox = GuiCreateErrorCodeWindow(errorCode, &g_scanErrorHintBox, GuiScanResumeAfterError);
}
static void GuiScanStart()
@@ -297,3 +298,10 @@ static void GuiScanStart()
GuiSetScanCorner();
GuiModeControlQrDecode(true);
}
+
+static void GuiScanResumeAfterError()
+{
+#ifndef COMPILE_SIMULATOR
+ GuiScanStart();
+#endif
+}
diff --git a/src/ui/lv_i18n/data.csv b/src/ui/lv_i18n/data.csv
index 036ba42..7529c4d 100644
--- a/src/ui/lv_i18n/data.csv
+++ b/src/ui/lv_i18n/data.csv
@@ -1073,3 +1073,5 @@ Wallet Profile,24,wallet_profile_mid_btn,Wallet Profile,Профиль коше
,20,btc_sighash_single_warning,"Only the corresponding output is locked. Other outputs may be changed after signing.","Зафиксирован только соответствующий выход. Другие выходы могут быть изменены после подписания.","해당 출력만 고정됩니다. 서명 후 다른 출력은 변경될 수 있습니다.","只有对应的输出被锁定。签名后其他输出仍可能被更改。","Solo la salida correspondiente está bloqueada. Las otras salidas pueden cambiarse después de firmar.","Nur der entsprechende Output ist festgelegt. Andere Outputs können nach dem Signieren geändert werden.","対応する出力のみが固定されます。署名後に他の出力が変更される可能性があります。"
,20,btc_sighash_none_warning,"Outputs are not locked and this signature may be reused with different outputs.","Выходы не зафиксированы и эта подпись может быть повторно использована с другими выходами.","출력이 고정되지 않으며 이 서명은 다른 출력과 함께 재사용될 수 있습니다.","输出未被锁定,此签名可能被复用于不同的输出。","Las salidas no están bloqueadas y esta firma puede reutilizarse con salidas diferentes.","Outputs sind nicht festgelegt und diese Signatur kann mit anderen Outputs wiederverwendet werden.","出力は固定されておらず、この署名は別の出力で再利用される可能性があります。"
,20,btc_large_fee_warning,"The transaction fee is unusually high. Verify it before signing.","Комиссия транзакции необычно высока. Проверьте её перед подписанием.","거래 수수료가 비정상적으로 높습니다. 서명하기 전에 확인하세요.","交易手续费异常高,请在签名前仔细核对。","La comisión de la transacción es inusualmente alta. Verifíquela antes de firmar.","Die Transaktionsgebühr ist ungewöhnlich hoch. Prüfen Sie sie vor dem Signieren.","取引手数料が異常に高額です。署名前に確認してください。"
+,24,solana_blind_sign_title,"Blind Sign","Слепая подпись","블라인드 서명","盲签","Firma ciega","Blindes Signieren","ブラインド署名"
+,20,solana_unparsed_message_warning,"This message could not be parsed. Its effect cannot be verified. Review all data before signing.","Это сообщение не удалось разобрать. Его действие невозможно проверить. Проверьте все данные перед подписанием.","이 메시지를 해석할 수 없어 영향을 확인할 수 없습니다. 서명하기 전에 모든 데이터를 검토하세요.","此消息无法解析,设备无法验证其影响。请在签名前核对全部数据。","Este mensaje no se pudo analizar y no se puede verificar su efecto. Revise todos los datos antes de firmar.","Diese Nachricht konnte nicht analysiert werden. Ihre Wirkung lässt sich nicht prüfen. Kontrollieren Sie vor dem Signieren alle Daten.","このメッセージは解析できず、その影響を確認できません。署名前にすべてのデータを確認してください。"
diff --git a/src/ui/lv_i18n/lv_i18n.c b/src/ui/lv_i18n/lv_i18n.c
index 4530b9e..d47b7cf 100644
--- a/src/ui/lv_i18n/lv_i18n.c
+++ b/src/ui/lv_i18n/lv_i18n.c
@@ -797,12 +797,14 @@ const static lv_i18n_phrase_t en_singulars[] = {
{"solana_alt_notice", "The Address Lookup Table URL provides a reference to view detailed account information related to this transaction. Please note that the URL may expire or change over time"},
{"solana_ata_desc", "The account receiving funds. An Associated Token Account (ATA) on Solana. Each user has one ATA per token type, and tokens are sent to the destination ATA."},
{"solana_auth_account", "The account with transaction authority."},
+ {"solana_blind_sign_title", "Blind Sign"},
{"solana_parse_tx_notice", "The accounts in Instructions will be affected by this transaction. Please review carefully."},
{"solana_source_ata", "The account sending funds."},
{"solana_squads_amount_brief", "The amount consists of three parts, you can see it in \"Details\""},
{"solana_squads_amount_desc", "This amount is the deploy fee, consisting of three parts. For details, please refer to the Squads Official Website."},
{"solana_squads_amount_lm", "The amount consists of three parts, you can see it in \"Leran More\""},
{"solana_squads_amount_title", "Amount Details"},
+ {"solana_unparsed_message_warning", "This message could not be parsed. Its effect cannot be verified. Review all data before signing."},
{"solana_warning", "This transaction may be risky, please check the details carefully before signing."},
{"spl_notice", "Unknown SPL Token account. Please verify to prevent asset loss."},
{"support_link", "support@keyst.one"},
@@ -1757,12 +1759,14 @@ const static lv_i18n_phrase_t de_singulars[] = {
{"solana_alt_notice", "Die URL der Adresstabelle bietet eine Referenz, um detaillierte Kontoinformationen zu dieser Transaktion einzusehen. Bitte beachten Sie, dass die URL ablaufen oder sich ändern kann."},
{"solana_ata_desc", "Das Konto, das Geld empfängt. Ein zugeordnetes Token-Konto (ATA) auf Solana. Jeder Benutzer hat ein ATA pro Token-Typ, und Tokens werden an das Ziel-ATA gesendet."},
{"solana_auth_account", "Das Konto mit Transaktionsberechtigung wird in der Solana-Blockchain als Autorisierungskonto (Auth Account) bezeichnet."},
+ {"solana_blind_sign_title", "Blindes Signieren"},
{"solana_parse_tx_notice", "Laut Anweisung betroffene Konten werden von dieser Transaktion beeinflusst. Bitte sorgfältig prüfen."},
{"solana_source_ata", "Das Konto, das Geld sendet, wird in der Solana-Blockchain als Quellkonto (Source Account) bezeichnet."},
{"solana_squads_amount_brief", "Der Betrag besteht aus drei Teilen, die Sie unter \"Details\" einsehen können."},
{"solana_squads_amount_desc", "Dieser Betrag ist die Bereitstellungsgebühr und besteht aus drei Teilen. Für weitere Details besuchen Sie bitte die offizielle Website von Squads."},
{"solana_squads_amount_lm", "Der Betrag besteht aus drei Teilen, die Sie unter \"Mehr erfahren\" einsehen können."},
{"solana_squads_amount_title", "Betragsdetails"},
+ {"solana_unparsed_message_warning", "Diese Nachricht konnte nicht analysiert werden. Ihre Wirkung lässt sich nicht prüfen. Kontrollieren Sie vor dem Signieren alle Daten."},
{"solana_warning", "Diese Transaktion könnte riskant sein. Bitte überprüfen Sie die Details sorgfältig, bevor Sie unterschreiben."},
{"spl_notice", "Unbekanntes SPL-Token-Konto. Bitte überprüfen Sie es, um Vermögensverluste zu vermeiden."},
{"support_link", "support@keyst.one"},
@@ -2717,12 +2721,14 @@ const static lv_i18n_phrase_t es_singulars[] = {
{"solana_alt_notice", "La URL de la Tabla de Consulta de Direcciones proporciona una referencia para ver la información detallada de las cuentas relacionadas con esta transacción. Tenga en cuenta que la URL puede expirar o cambiar con el tiempo."},
{"solana_ata_desc", "La cuenta que recibe los fondos. Una Cuenta de Token Asociada (ATA) en Solana. Cada usuario tiene una ATA por tipo de token, y los tokens se envían a la ATA de destino."},
{"solana_auth_account", "La cuenta con autoridad de transacción se conoce como cuenta de autorización (auth account) en la blockchain de Solana."},
+ {"solana_blind_sign_title", "Firma ciega"},
{"solana_parse_tx_notice", "Las cuentas indicadas en las Instrucciones se verán afectadas por esta transacción. Por favor, revíselas detenidamente."},
{"solana_source_ata", "La cuenta que envía los fondos se conoce como cuenta de origen (source account) en la blockchain de Solana."},
{"solana_squads_amount_brief", "El monto consta de tres partes, puedes verlo en \"Detalles\"."},
{"solana_squads_amount_desc", "Este monto es la tarifa de despliegue, que consta de tres partes. Para más detalles, por favor consulte el sitio web oficial de Squads."},
{"solana_squads_amount_lm", "El monto consta de tres partes, puedes verlo en \"Más información\"."},
{"solana_squads_amount_title", "Detalles del monto"},
+ {"solana_unparsed_message_warning", "Este mensaje no se pudo analizar y no se puede verificar su efecto. Revise todos los datos antes de firmar."},
{"solana_warning", "Esta transacción puede ser riesgosa, por favor revise cuidadosamente los detalles antes de firmar."},
{"spl_notice", "Cuenta de token SPL desconocida. Por favor, verifica para evitar la pérdida de activos."},
{"support_link", "support@keyst.one"},
@@ -3674,12 +3680,14 @@ const static lv_i18n_phrase_t ja_singulars[] = {
{"solana_alt_notice", "アドレス参照表のURLでは、この取引に関連する詳細な口座情報を確認できます。URLは期限切れや変更の可能性があることにご留意ください。"},
{"solana_ata_desc", "資金を受け取るアカウント。Solanaのアソシエイテッド・トークン・アカウント(ATA)。ユーザーはトークンタイプごとに1つのATAを持ち、トークンは宛先のATAに送信されます。"},
{"solana_auth_account", "トランザクションの権限を持つアカウントは、Solanaブロックチェーンでは認証アカウント(auth account)と呼ばれています。"},
+ {"solana_blind_sign_title", "ブラインド署名"},
{"solana_parse_tx_notice", "指示書の口座がこの取引の影響を受けます。慎重に確認してください。"},
{"solana_source_ata", "資金を送信するアカウントは、Solanaブロックチェーンではソースアカウント(source account)と呼ばれています。"},
{"solana_squads_amount_brief", "金額は3つの部分で構成されており、\"詳細\"でご確認いただけます。"},
{"solana_squads_amount_desc", "この金額はデプロイ料金であり、3つの部分で構成されています。詳細については、Squads公式ウェブサイトを参照してください。"},
{"solana_squads_amount_lm", "金額は3つの部分で構成されており、\"詳しく見る\"でご確認いただけます。"},
{"solana_squads_amount_title", "金額の詳細"},
+ {"solana_unparsed_message_warning", "このメッセージは解析できず、その影響を確認できません。署名前にすべてのデータを確認してください。"},
{"solana_warning", "この取引はリスクを伴う可能性があります。署名する前に詳細を注意深く確認してください。"},
{"spl_notice", "不明なSPLトークンアカウントです。資産の損失を防ぐために確認してください。"},
{"support_link", "support@keyst.one"},
@@ -4629,12 +4637,14 @@ const static lv_i18n_phrase_t ko_singulars[] = {
{"solana_alt_notice", "주소록 테이블 URL은 이 거래와 관련된 계좌 정보를 제공합니다. 단, URL이 만료되거나 변경될 수 있음을 유의하시기 바랍니다."},
{"solana_ata_desc", "자금을 받는 계정. Solana의 연계 토큰 계정(ATA). 각 사용자는 토큰 유형당 하나의 ATA를 가지며, 토큰은 대상 ATA로 전송됩니다."},
{"solana_auth_account", "트랜잭션 권한을 가진 계정을 Solana 블록체인에서는 인증 계정(auth account)이라고 합니다."},
+ {"solana_blind_sign_title", "블라인드 서명"},
{"solana_parse_tx_notice", "지침서에 명시된 계좌들은 이 거래의 영향을 받게 됩니다. 주의 깊게 검토해 주시기 바랍니다."},
{"solana_source_ata", "자금을 보내는 계정을 Solana 블록체인에서는 소스 계정(source account)이라고 합니다."},
{"solana_squads_amount_brief", "금액은 세 부분으로 구성되며, \"상세 정보\"에서 확인하실 수 있습니다."},
{"solana_squads_amount_desc", "이 금액은 배포 수수료로 세 부분으로 구성되어 있습니다. 자세한 내용은 Squads 공식 웹사이트를 참조하십시오."},
{"solana_squads_amount_lm", "금액은 세 부분으로 구성되며, \"자세히 알아보기\"에서 확인하실 수 있습니다."},
{"solana_squads_amount_title", "금액 세부 정보"},
+ {"solana_unparsed_message_warning", "이 메시지를 해석할 수 없어 영향을 확인할 수 없습니다. 서명하기 전에 모든 데이터를 검토하세요."},
{"solana_warning", "이 거래는 위험할 수 있으므로, 서명하기 전에 세부 사항을 주의 깊게 확인하시기 바랍니다."},
{"spl_notice", "알 수 없는 SPL 토큰 계정입니다. 자산 손실을 방지하기 위해 확인해 주세요."},
{"support_link", "support@keyst.one"},
@@ -5578,12 +5588,14 @@ const static lv_i18n_phrase_t pl_singulars[] = {
{"solana_alt_notice", "Adres URL tabeli wyszukiwania adresów zawiera odnośnik umożliwiający wyświetlenie szczegółowych informacji o koncie związanych z tą transakcją. Należy pamiętać, że adres URL może z czasem wygasnąć lub ulec zmianie"},
{"solana_ata_desc", "Konto otrzymujące środki. Powiązane konto tokenowe (ATA) w Solana. Każdy użytkownik ma jedną usługę ATA na każdy typ tokenu, a tokeny są wysyłane do docelowej usługi ATA."},
{"solana_auth_account", "Konto z uprawnieniami do transakcji."},
+ {"solana_blind_sign_title", "Blind Sign"},
{"solana_parse_tx_notice", "Transakcja ta będzie miała wpływ na konta w Instrukcjach. Proszę dokładnie zapoznać się z treścią."},
{"solana_source_ata", "Konto wysyłające środki."},
{"solana_squads_amount_brief", "Kwota składa się z trzech części, możesz ją zobaczyć w \"Szczegóły\""},
{"solana_squads_amount_desc", "Kwota ta stanowi opłatę za wdrożenie, składającą się z trzech części. Więcej szczegółów można znaleźć na oficjalnej stronie Squads."},
{"solana_squads_amount_lm", "Kwota składa się z trzech części, można ją zobaczyć w „Leran More”"},
{"solana_squads_amount_title", "Szczegóły kwoty"},
+ {"solana_unparsed_message_warning", "This message could not be parsed. Its effect cannot be verified. Review all data before signing."},
{"solana_warning", "Ta transakcja może być ryzykowna, proszę dokładnie sprawdzić szczegóły przed podpisaniem."},
{"spl_notice", "Nieznane konto tokenu SPL. Zweryfikuj, aby zapobiec utracie zasobów."},
{"support_link", "support@keyst.one"},
@@ -6546,12 +6558,14 @@ const static lv_i18n_phrase_t ru_singulars[] = {
{"solana_alt_notice", "Ссылка на таблицу адресов предоставляет информацию по счетам, связанным с этой операцией. Имейте в виду, что ссылка может измениться или устареть со временем."},
{"solana_ata_desc", "Счет, получающий средства. Ассоциированный токеновый счет (ATA) на Solana. Каждый пользователь имеет один ATA на каждый тип токена, и токены отправляются на целевой ATA."},
{"solana_auth_account", "Аккаунт, обладающий полномочиями на проведение транзакций, называется аутентифицирующим аккаунтом (auth account) в блокчейне Solana."},
+ {"solana_blind_sign_title", "Слепая подпись"},
{"solana_parse_tx_notice", "Счета, указанные в Инструкциях, будут затронуты этой операцией. Пожалуйста, внимательно проверьте."},
{"solana_source_ata", "Счет, отправляющий средства, называется исходным счетом (source account) в блокчейне Solana."},
{"solana_squads_amount_brief", "Сумма состоит из трех частей, которые вы можете увидеть в разделе \"Детали\"."},
{"solana_squads_amount_desc", "Эта сумма является комиссией за развертывание и состоит из трех частей. Для получения подробной информации, пожалуйста, обратитесь к официальному сайту Squads."},
{"solana_squads_amount_lm", "Сумма состоит из трех частей, вы можете увидеть это в разделе \"Подробнее\"."},
{"solana_squads_amount_title", "Детали суммы"},
+ {"solana_unparsed_message_warning", "Это сообщение не удалось разобрать. Его действие невозможно проверить. Проверьте все данные перед подписанием."},
{"solana_warning", "Эта транзакция может быть рискованной, пожалуйста, внимательно проверьте детали перед подписанием."},
{"spl_notice", "Неизвестный аккаунт SPL токена. Пожалуйста, проверьте, чтобы предотвратить потерю активов."},
{"support_link", "support@keyst.one"},
@@ -7509,12 +7523,14 @@ const static lv_i18n_phrase_t zh_cn_singulars[] = {
{"solana_alt_notice", "地址查找表的网址提供了与此交易相关账户信息的参考。请注意该网址可能会过期。"},
{"solana_ata_desc", "Solana上的关联代币帐户(ATA)。每个用户对每种代币类型都有一个ATA,代币被发送到目标ATA。"},
{"solana_auth_account", "拥有交易权限的账户在 Solana 区块链中被称为授权账户(auth account)。"},
+ {"solana_blind_sign_title", "盲签"},
{"solana_parse_tx_notice", "说明中的账户将受到此交易的影响。请仔细检查。"},
{"solana_source_ata", "发送资金的账户在 Solana 区块链中被称为源账户(source account)。"},
{"solana_squads_amount_brief", "该金额由三部分组成,您可以在\"详情\"中查看。"},
{"solana_squads_amount_desc", "该金额是部署费用,由三部分组成。详情请参考 Squads 官方网站。"},
{"solana_squads_amount_lm", "该金额由三部分组成,您可以在\"了解更多\"中查看。"},
{"solana_squads_amount_title", "金额详情"},
+ {"solana_unparsed_message_warning", "此消息无法解析,设备无法验证其影响。请在签名前核对全部数据。"},
{"solana_warning", "此交易可能存在风险,请在签署前仔细检查详情。"},
{"spl_notice", "未知的 SPL 代币账户。请验证以防止资产损失。"},
{"support_link", "support@keyst.one"},
Why this scored 62/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.