Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions messages-solana.options
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ SolanaSignMessage.coin_name max_size:21
SolanaSignMessage.message max_size:1024
SolanaMessageSignature.public_key max_size:32
SolanaMessageSignature.signature max_size:64
SolanaSignOffchainMessage.address_n max_count:8
SolanaSignOffchainMessage.coin_name max_size:21
SolanaSignOffchainMessage.message max_size:1212
SolanaOffchainMessageSignature.public_key max_size:32
SolanaOffchainMessageSignature.signature max_size:64
37 changes: 37 additions & 0 deletions messages-solana.proto
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,40 @@ message SolanaMessageSignature {
optional bytes public_key = 1; // 32-byte Ed25519 public key
optional bytes signature = 2; // 64-byte Ed25519 signature
}

/**
* Request: Ask device to sign a Solana off-chain message with domain separation
*
* Per the Solana off-chain message spec, the device signs over the envelope:
* "\xff" || "solana offchain" || <version:u8> || <format:u8>
* || <message_length:u16 LE> || <message bytes>
*
* The "\xff" lead byte is invalid as a Solana transaction prefix, providing
* domain separation that plain SolanaSignMessage lacks. Firmware constructs
* the envelope from the components below; host supplies version/format/message.
*
* Format values:
* 0 = Restricted ASCII (printable, max 1212 bytes) — renderable on display
* 1 = UTF-8 (max 1212 bytes) — renderable, may need policy gate
* 2 = UTF-8 (max 65515 bytes) — Ledger-only mode, blind-sign
*
* @next SolanaOffchainMessageSignature
* @next Failure
*/
message SolanaSignOffchainMessage {
repeated uint32 address_n = 1; // BIP-32/BIP-44 path to signing key
optional string coin_name = 2 [default = "Solana"];
optional uint32 version = 3 [default = 0]; // Off-chain message spec version (0 = current)
optional uint32 message_format = 4; // 0=ASCII, 1=UTF8 limited, 2=UTF8 extended
optional bytes message = 5; // Raw message payload (firmware wraps with envelope)
optional bool show_display = 6; // Show message on device display
}

/**
* Response: Ed25519 signature over the off-chain message envelope
* @prev SolanaSignOffchainMessage
*/
message SolanaOffchainMessageSignature {
optional bytes public_key = 1; // 32-byte Ed25519 public key
optional bytes signature = 2; // 64-byte Ed25519 signature over the envelope
}
5 changes: 5 additions & 0 deletions messages-ton.options
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ TonSignTx.memo max_size:121
TonAddress.address max_size:50
TonAddress.raw_address max_size:70
TonSignedTx.signature max_size:64
TonSignMessage.address_n max_count:8
TonSignMessage.coin_name max_size:21
TonSignMessage.message max_size:1024
TonMessageSignature.public_key max_size:32
TonMessageSignature.signature max_size:64
28 changes: 28 additions & 0 deletions messages-ton.proto
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,31 @@ message TonSignTx {
message TonSignedTx {
optional bytes signature = 1; // Ed25519 signature (64 bytes)
}

//////////////////////////////////////
// TON: Message signing //
//////////////////////////////////////

/**
* Request: Ask device to sign an arbitrary message with Ed25519
* Note: lacks domain separation by default. Firmware policy may gate
* this behind AdvancedMode (matching the SolanaSignMessage pattern)
* until a TON Connect-style envelope (ton_proof) is implemented.
* @next TonMessageSignature
* @next Failure
*/
message TonSignMessage {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional string coin_name = 2 [default='Ton'];
optional bytes message = 3; // Message bytes to sign
optional bool show_display = 4; // Show message on device display
}

/**
* Response: Ed25519 signature and public key for the signed message
* @prev TonSignMessage
*/
message TonMessageSignature {
optional bytes public_key = 1; // 32-byte Ed25519 public key
optional bytes signature = 2; // 64-byte Ed25519 signature
}
14 changes: 14 additions & 0 deletions messages-tron.options
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ TronTriggerSmartContract.contract_address max_size:35
TronTriggerSmartContract.data max_size:512
TronSignTx.data max_size:256
TronSignedTx.serialized_tx max_size:1024
TronSignMessage.address_n max_count:8
TronSignMessage.coin_name max_size:21
TronSignMessage.message max_size:1024
TronMessageSignature.address max_size:35
TronMessageSignature.signature max_size:65
TronVerifyMessage.address max_size:35
TronVerifyMessage.signature max_size:65
TronVerifyMessage.message max_size:1024
TronSignTypedHash.address_n max_count:8
TronSignTypedHash.coin_name max_size:21
TronSignTypedHash.domain_separator_hash max_size:32
TronSignTypedHash.message_hash max_size:32
TronTypedDataSignature.address max_size:35
TronTypedDataSignature.signature max_size:65
65 changes: 65 additions & 0 deletions messages-tron.proto
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,68 @@ message TronSignedTx {
optional bytes signature = 1; // ECDSA signature (65 bytes: r + s + recovery_id)
optional bytes serialized_tx = 2; // Reconstructed raw_data bytes (for host verification)
}

//////////////////////////////////////
// TRON: Message signing (TIP-191) //
//////////////////////////////////////

/**
* Request: Ask device to sign a message using TIP-191 personal_sign
* Hash: keccak256("\x19TRON Signed Message:\n" + len(message) + message)
* @next TronMessageSignature
* @next Failure
*/
message TronSignMessage {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional string coin_name = 2 [default='Tron'];
optional bytes message = 3; // Message bytes to sign
optional bool show_display = 4; // Show message on device display
}

/**
* Response: Signed message
* @prev TronSignMessage
*/
message TronMessageSignature {
optional string address = 1; // Base58Check TRON address that signed
optional bytes signature = 2; // 65-byte signature (r + s + v)
}

/**
* Request: Ask device to verify a TIP-191 message signature
* @next Success
* @next Failure
*/
message TronVerifyMessage {
optional string address = 1; // Base58Check TRON address claimed to have signed
optional bytes signature = 2; // 65-byte signature to verify
optional bytes message = 3; // Message that was signed
}

//////////////////////////////////////
// TRON: Typed data signing (TIP-712)//
//////////////////////////////////////

/**
* Request: Ask device to sign hash of typed data (TIP-712 hash mode)
* Domain separation: keccak256("\x19\x01" + domain_separator_hash + message_hash)
* Host pre-computes the EIP-712-style domainSeparator and message hashes.
* @start
* @next TronTypedDataSignature
* @next Failure
*/
message TronSignTypedHash {
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
optional string coin_name = 2 [default='Tron'];
required bytes domain_separator_hash = 3; // 32-byte domainSeparator hash
optional bytes message_hash = 4; // 32-byte message hash (empty if domain-only)
}

/**
* Response: Signed typed data
* @prev TronSignTypedHash
*/
message TronTypedDataSignature {
required string address = 1; // Base58Check TRON address that signed
required bytes signature = 2; // 65-byte signature (r + s + v)
}
9 changes: 9 additions & 0 deletions messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ enum MessageType {
MessageType_SolanaSignedTx = 753 [ (wire_out) = true ];
MessageType_SolanaSignMessage = 754 [ (wire_in) = true ];
MessageType_SolanaMessageSignature = 755 [ (wire_out) = true ];
MessageType_SolanaSignOffchainMessage = 756 [ (wire_in) = true ];
MessageType_SolanaOffchainMessageSignature = 757 [ (wire_out) = true ];

// Binance
MessageType_BinanceGetAddress = 800 [ (wire_in) = true ];
Expand Down Expand Up @@ -224,12 +226,19 @@ enum MessageType {
MessageType_TronAddress = 1401 [ (wire_out) = true ];
MessageType_TronSignTx = 1402 [ (wire_in) = true ];
MessageType_TronSignedTx = 1403 [ (wire_out) = true ];
MessageType_TronSignMessage = 1404 [ (wire_in) = true ];
MessageType_TronMessageSignature = 1405 [ (wire_out) = true ];
MessageType_TronVerifyMessage = 1406 [ (wire_in) = true ];
MessageType_TronSignTypedHash = 1407 [ (wire_in) = true ];
MessageType_TronTypedDataSignature = 1408 [ (wire_out) = true ];

// TON
MessageType_TonGetAddress = 1500 [ (wire_in) = true ];
MessageType_TonAddress = 1501 [ (wire_out) = true ];
MessageType_TonSignTx = 1502 [ (wire_in) = true ];
MessageType_TonSignedTx = 1503 [ (wire_out) = true ];
MessageType_TonSignMessage = 1504 [ (wire_in) = true ];
MessageType_TonMessageSignature = 1505 [ (wire_out) = true ];
}

////////////////////
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@keepkey/device-protocol",
"version": "7.13.4",
"version": "7.14.1",
"publishConfig": {
"access": "public"
},
Expand Down