mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-17 21:22:10 +00:00
feat(solana): add get_address
This commit is contained in:
parent
ec4a607dbe
commit
44dc417c0e
@ -22,3 +22,23 @@ message SolanaPublicKey {
|
||||
required bytes public_key = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Ask device for Solana address
|
||||
* @start
|
||||
* @next SolanaAddress
|
||||
* @next Failure
|
||||
*/
|
||||
message SolanaGetAddress {
|
||||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
|
||||
optional bool show_display = 2; // optionally show on display before sending the result
|
||||
optional bool chunkify = 3; // display the address in chunks of 4 characters
|
||||
}
|
||||
|
||||
/**
|
||||
* Response: Contains a Solana address derived from device private seed
|
||||
* @end
|
||||
*/
|
||||
message SolanaAddress {
|
||||
required string address = 1; // Solana address as Base58 encoded string
|
||||
}
|
||||
|
||||
|
@ -366,4 +366,6 @@ enum MessageType {
|
||||
// Solana
|
||||
MessageType_SolanaGetPublicKey = 900 [(wire_in) = true];
|
||||
MessageType_SolanaPublicKey = 901 [(wire_out) = true];
|
||||
MessageType_SolanaGetAddress = 902 [(wire_in) = true];
|
||||
MessageType_SolanaAddress = 903 [(wire_out) = true];
|
||||
}
|
||||
|
32
common/tests/fixtures/solana/get_address.json
vendored
Normal file
32
common/tests/fixtures/solana/get_address.json
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"setup": {
|
||||
"mnemonic": "all all all all all all all all all all all all",
|
||||
"passphrase": ""
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/44'/501'"
|
||||
},
|
||||
"result": {
|
||||
"expected_address": "zZqNUDNijfbMXFy2wVCdJSm9MeMfxBMdxBqseSuiSW6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/44'/501'/0'"
|
||||
},
|
||||
"result": {
|
||||
"expected_address": "4UR47Kp4FxGJiJZZGSPAzXqRgMmZ27oVfGhHoLmcHakE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"parameters": {
|
||||
"path": "m/44'/501'/0'/0'"
|
||||
},
|
||||
"result": {
|
||||
"expected_address": "14CCvQzQzHCVgZM3j9soPnXuJXh1RmCfwLVUcdfbZVBS"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -683,6 +683,8 @@ if not utils.BITCOIN_ONLY:
|
||||
import apps.ripple.sign_tx
|
||||
apps.solana
|
||||
import apps.solana
|
||||
apps.solana.get_address
|
||||
import apps.solana.get_address
|
||||
apps.solana.get_public_key
|
||||
import apps.solana.get_public_key
|
||||
apps.stellar
|
||||
|
37
core/src/apps/solana/get_address.py
Normal file
37
core/src/apps/solana/get_address.py
Normal file
@ -0,0 +1,37 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor.crypto import base58
|
||||
|
||||
from apps.common.keychain import with_slip44_keychain
|
||||
|
||||
from . import CURVE, PATTERNS, SLIP44_ID
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from trezor.messages import SolanaAddress, SolanaGetAddress
|
||||
|
||||
from apps.common.keychain import Keychain
|
||||
|
||||
|
||||
@with_slip44_keychain(*PATTERNS, slip44_id=SLIP44_ID, curve=CURVE)
|
||||
async def get_address(
|
||||
msg: SolanaGetAddress,
|
||||
keychain: Keychain,
|
||||
) -> SolanaAddress:
|
||||
from trezor.messages import SolanaAddress
|
||||
from trezor.ui.layouts import show_address
|
||||
|
||||
from apps.common import paths
|
||||
|
||||
from .get_public_key import derive_public_key
|
||||
|
||||
public_key = derive_public_key(keychain, msg.address_n)
|
||||
address = base58.encode(public_key)
|
||||
|
||||
if msg.show_display:
|
||||
await show_address(
|
||||
address,
|
||||
path=paths.address_n_to_str(msg.address_n),
|
||||
chunkify=bool(msg.chunkify),
|
||||
)
|
||||
|
||||
return SolanaAddress(address=address)
|
@ -193,6 +193,8 @@ def _find_message_handler_module(msg_type: int) -> str:
|
||||
# solana
|
||||
if msg_type == MessageType.SolanaGetPublicKey:
|
||||
return "apps.solana.get_public_key"
|
||||
if msg_type == MessageType.SolanaGetAddress:
|
||||
return "apps.solana.get_address"
|
||||
|
||||
raise ValueError
|
||||
|
||||
|
@ -238,3 +238,5 @@ if not utils.BITCOIN_ONLY:
|
||||
WebAuthnRemoveResidentCredential = 803
|
||||
SolanaGetPublicKey = 900
|
||||
SolanaPublicKey = 901
|
||||
SolanaGetAddress = 902
|
||||
SolanaAddress = 903
|
||||
|
@ -256,6 +256,8 @@ if TYPE_CHECKING:
|
||||
WebAuthnRemoveResidentCredential = 803
|
||||
SolanaGetPublicKey = 900
|
||||
SolanaPublicKey = 901
|
||||
SolanaGetAddress = 902
|
||||
SolanaAddress = 903
|
||||
|
||||
class FailureType(IntEnum):
|
||||
UnexpectedMessage = 1
|
||||
|
@ -5225,6 +5225,38 @@ if TYPE_CHECKING:
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["SolanaPublicKey"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class SolanaGetAddress(protobuf.MessageType):
|
||||
address_n: "list[int]"
|
||||
show_display: "bool | None"
|
||||
chunkify: "bool | None"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
address_n: "list[int] | None" = None,
|
||||
show_display: "bool | None" = None,
|
||||
chunkify: "bool | None" = None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["SolanaGetAddress"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class SolanaAddress(protobuf.MessageType):
|
||||
address: "str"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
address: "str",
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, msg: Any) -> TypeGuard["SolanaAddress"]:
|
||||
return isinstance(msg, cls)
|
||||
|
||||
class StellarAsset(protobuf.MessageType):
|
||||
type: "StellarAssetType"
|
||||
code: "str | None"
|
||||
|
@ -29,3 +29,19 @@ def get_public_key(
|
||||
"""Get Solana public key."""
|
||||
address_n = tools.parse_path(address)
|
||||
return solana.get_public_key(client, address_n, show_display)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("-n", "--address", default=DEFAULT_PATH, help=PATH_HELP)
|
||||
@click.option("-d", "--show-display", is_flag=True)
|
||||
@click.option("-C", "--chunkify", is_flag=True)
|
||||
@with_client
|
||||
def get_address(
|
||||
client: "TrezorClient",
|
||||
address: str,
|
||||
show_display: bool,
|
||||
chunkify: bool,
|
||||
) -> messages.SolanaAddress:
|
||||
"""Get Solana address."""
|
||||
address_n = tools.parse_path(address)
|
||||
return solana.get_address(client, address_n, show_display, chunkify)
|
||||
|
@ -264,6 +264,8 @@ class MessageType(IntEnum):
|
||||
WebAuthnRemoveResidentCredential = 803
|
||||
SolanaGetPublicKey = 900
|
||||
SolanaPublicKey = 901
|
||||
SolanaGetAddress = 902
|
||||
SolanaAddress = 903
|
||||
|
||||
|
||||
class FailureType(IntEnum):
|
||||
@ -6678,6 +6680,40 @@ class SolanaPublicKey(protobuf.MessageType):
|
||||
self.public_key = public_key
|
||||
|
||||
|
||||
class SolanaGetAddress(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 902
|
||||
FIELDS = {
|
||||
1: protobuf.Field("address_n", "uint32", repeated=True, required=False, default=None),
|
||||
2: protobuf.Field("show_display", "bool", repeated=False, required=False, default=None),
|
||||
3: protobuf.Field("chunkify", "bool", repeated=False, required=False, default=None),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
address_n: Optional[Sequence["int"]] = None,
|
||||
show_display: Optional["bool"] = None,
|
||||
chunkify: Optional["bool"] = None,
|
||||
) -> None:
|
||||
self.address_n: Sequence["int"] = address_n if address_n is not None else []
|
||||
self.show_display = show_display
|
||||
self.chunkify = chunkify
|
||||
|
||||
|
||||
class SolanaAddress(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = 903
|
||||
FIELDS = {
|
||||
1: protobuf.Field("address", "string", repeated=False, required=True),
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
address: "str",
|
||||
) -> None:
|
||||
self.address = address
|
||||
|
||||
|
||||
class StellarAsset(protobuf.MessageType):
|
||||
MESSAGE_WIRE_TYPE = None
|
||||
FIELDS = {
|
||||
|
@ -17,3 +17,19 @@ def get_public_key(
|
||||
return client.call(
|
||||
messages.SolanaGetPublicKey(address_n=address_n, show_display=show_display)
|
||||
)
|
||||
|
||||
|
||||
@expect(messages.SolanaAddress)
|
||||
def get_address(
|
||||
client: "TrezorClient",
|
||||
address_n: List[int],
|
||||
show_display: bool,
|
||||
chunkify: bool = False,
|
||||
) -> "MessageType":
|
||||
return client.call(
|
||||
messages.SolanaGetAddress(
|
||||
address_n=address_n,
|
||||
show_display=show_display,
|
||||
chunkify=chunkify,
|
||||
)
|
||||
)
|
||||
|
2
rust/trezor-client/src/messages/generated.rs
generated
2
rust/trezor-client/src/messages/generated.rs
generated
@ -81,6 +81,8 @@ trezor_message_impl! {
|
||||
DebugLinkResetDebugEvents => MessageType_DebugLinkResetDebugEvents,
|
||||
SolanaGetPublicKey => MessageType_SolanaGetPublicKey,
|
||||
SolanaPublicKey => MessageType_SolanaPublicKey,
|
||||
SolanaGetAddress => MessageType_SolanaGetAddress,
|
||||
SolanaAddress => MessageType_SolanaAddress,
|
||||
}
|
||||
|
||||
#[cfg(feature = "binance")]
|
||||
|
62
rust/trezor-client/src/protos/generated/messages.rs
generated
62
rust/trezor-client/src/protos/generated/messages.rs
generated
@ -498,6 +498,10 @@ pub enum MessageType {
|
||||
MessageType_SolanaGetPublicKey = 900,
|
||||
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaPublicKey)
|
||||
MessageType_SolanaPublicKey = 901,
|
||||
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaGetAddress)
|
||||
MessageType_SolanaGetAddress = 902,
|
||||
// @@protoc_insertion_point(enum_value:hw.trezor.messages.MessageType.MessageType_SolanaAddress)
|
||||
MessageType_SolanaAddress = 903,
|
||||
}
|
||||
|
||||
impl ::protobuf::Enum for MessageType {
|
||||
@ -744,6 +748,8 @@ impl ::protobuf::Enum for MessageType {
|
||||
803 => ::std::option::Option::Some(MessageType::MessageType_WebAuthnRemoveResidentCredential),
|
||||
900 => ::std::option::Option::Some(MessageType::MessageType_SolanaGetPublicKey),
|
||||
901 => ::std::option::Option::Some(MessageType::MessageType_SolanaPublicKey),
|
||||
902 => ::std::option::Option::Some(MessageType::MessageType_SolanaGetAddress),
|
||||
903 => ::std::option::Option::Some(MessageType::MessageType_SolanaAddress),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -985,6 +991,8 @@ impl ::protobuf::Enum for MessageType {
|
||||
"MessageType_WebAuthnRemoveResidentCredential" => ::std::option::Option::Some(MessageType::MessageType_WebAuthnRemoveResidentCredential),
|
||||
"MessageType_SolanaGetPublicKey" => ::std::option::Option::Some(MessageType::MessageType_SolanaGetPublicKey),
|
||||
"MessageType_SolanaPublicKey" => ::std::option::Option::Some(MessageType::MessageType_SolanaPublicKey),
|
||||
"MessageType_SolanaGetAddress" => ::std::option::Option::Some(MessageType::MessageType_SolanaGetAddress),
|
||||
"MessageType_SolanaAddress" => ::std::option::Option::Some(MessageType::MessageType_SolanaAddress),
|
||||
_ => ::std::option::Option::None
|
||||
}
|
||||
}
|
||||
@ -1225,6 +1233,8 @@ impl ::protobuf::Enum for MessageType {
|
||||
MessageType::MessageType_WebAuthnRemoveResidentCredential,
|
||||
MessageType::MessageType_SolanaGetPublicKey,
|
||||
MessageType::MessageType_SolanaPublicKey,
|
||||
MessageType::MessageType_SolanaGetAddress,
|
||||
MessageType::MessageType_SolanaAddress,
|
||||
];
|
||||
}
|
||||
|
||||
@ -1471,6 +1481,8 @@ impl ::protobuf::EnumFull for MessageType {
|
||||
MessageType::MessageType_WebAuthnRemoveResidentCredential => 232,
|
||||
MessageType::MessageType_SolanaGetPublicKey => 233,
|
||||
MessageType::MessageType_SolanaPublicKey => 234,
|
||||
MessageType::MessageType_SolanaGetAddress => 235,
|
||||
MessageType::MessageType_SolanaAddress => 236,
|
||||
};
|
||||
Self::enum_descriptor().value_by_index(index)
|
||||
}
|
||||
@ -1520,7 +1532,7 @@ pub mod exts {
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x0emessages.proto\x12\x12hw.trezor.messages\x1a\x20google/protobuf/de\
|
||||
scriptor.proto*\xa6Q\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
|
||||
scriptor.proto*\xf5Q\n\x0bMessageType\x12(\n\x16MessageType_Initialize\
|
||||
\x10\0\x1a\x0c\x80\xa6\x1d\x01\xb0\xb5\x18\x01\x90\xb5\x18\x01\x12\x1e\n\
|
||||
\x10MessageType_Ping\x10\x01\x1a\x08\x80\xa6\x1d\x01\x90\xb5\x18\x01\x12\
|
||||
%\n\x13MessageType_Success\x10\x02\x1a\x0c\x80\xa6\x1d\x01\xa8\xb5\x18\
|
||||
@ -1785,29 +1797,31 @@ static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
ntial\x10\xa2\x06\x1a\x04\x90\xb5\x18\x01\x127\n,MessageType_WebAuthnRem\
|
||||
oveResidentCredential\x10\xa3\x06\x1a\x04\x90\xb5\x18\x01\x12)\n\x1eMess\
|
||||
ageType_SolanaGetPublicKey\x10\x84\x07\x1a\x04\x90\xb5\x18\x01\x12&\n\
|
||||
\x1bMessageType_SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x1a\
|
||||
\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\xac\x02\
|
||||
\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\x07wire_in\x18\xd2\x86\
|
||||
\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x06wireIn:>\n\
|
||||
\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValue\
|
||||
OptionsR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\x03\x20\x01(\x08\x12!\
|
||||
.google.protobuf.EnumValueOptionsR\x0bwireDebugIn:I\n\x0ewire_debug_out\
|
||||
\x18\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0c\
|
||||
wireDebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01(\x08\x12!.google.pro\
|
||||
tobuf.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_bootloader\x18\xd7\x86\
|
||||
\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0ewireBootload\
|
||||
er:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\x12!.google.protobuf.\
|
||||
EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\x18\xe0\xd4\x03\x20\x01\
|
||||
(\x08\x12!.google.protobuf.EnumValueOptionsR\x0bbitcoinOnly:U\n\x17has_b\
|
||||
itcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\x12\x1c.google.protobuf.\
|
||||
EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14experimental_message\x18\xa1\
|
||||
\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x13experim\
|
||||
entalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\x01(\r\x12\x1f.google.pr\
|
||||
otobuf.MessageOptionsR\x08wireType:N\n\x12experimental_field\x18\x89\x9e\
|
||||
\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x11experimentalF\
|
||||
ield:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\x01(\x08\x12\x1c\
|
||||
.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\n#com.satoshilab\
|
||||
s.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\
|
||||
\x1bMessageType_SolanaPublicKey\x10\x85\x07\x1a\x04\x98\xb5\x18\x01\x12'\
|
||||
\n\x1cMessageType_SolanaGetAddress\x10\x86\x07\x1a\x04\x90\xb5\x18\x01\
|
||||
\x12$\n\x19MessageType_SolanaAddress\x10\x87\x07\x1a\x04\x98\xb5\x18\x01\
|
||||
\x1a\x04\xc8\xf3\x18\x01\"\x04\x08Z\x10\\\"\x04\x08r\x10z\"\x06\x08\xac\
|
||||
\x02\x10\xb0\x02\"\x06\x08\xb5\x02\x10\xb8\x02:<\n\x07wire_in\x18\xd2\
|
||||
\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x06wireIn:>\
|
||||
\n\x08wire_out\x18\xd3\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumVal\
|
||||
ueOptionsR\x07wireOut:G\n\rwire_debug_in\x18\xd4\x86\x03\x20\x01(\x08\
|
||||
\x12!.google.protobuf.EnumValueOptionsR\x0bwireDebugIn:I\n\x0ewire_debug\
|
||||
_out\x18\xd5\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\
|
||||
\x0cwireDebugOut:@\n\twire_tiny\x18\xd6\x86\x03\x20\x01(\x08\x12!.google\
|
||||
.protobuf.EnumValueOptionsR\x08wireTiny:L\n\x0fwire_bootloader\x18\xd7\
|
||||
\x86\x03\x20\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0ewireBoot\
|
||||
loader:C\n\x0bwire_no_fsm\x18\xd8\x86\x03\x20\x01(\x08\x12!.google.proto\
|
||||
buf.EnumValueOptionsR\twireNoFsm:F\n\x0cbitcoin_only\x18\xe0\xd4\x03\x20\
|
||||
\x01(\x08\x12!.google.protobuf.EnumValueOptionsR\x0bbitcoinOnly:U\n\x17h\
|
||||
as_bitcoin_only_values\x18\xb9\x8e\x03\x20\x01(\x08\x12\x1c.google.proto\
|
||||
buf.EnumOptionsR\x14hasBitcoinOnlyValues:T\n\x14experimental_message\x18\
|
||||
\xa1\x96\x03\x20\x01(\x08\x12\x1f.google.protobuf.MessageOptionsR\x13exp\
|
||||
erimentalMessage:>\n\twire_type\x18\xa2\x96\x03\x20\x01(\r\x12\x1f.googl\
|
||||
e.protobuf.MessageOptionsR\x08wireType:N\n\x12experimental_field\x18\x89\
|
||||
\x9e\x03\x20\x01(\x08\x12\x1d.google.protobuf.FieldOptionsR\x11experimen\
|
||||
talField:U\n\x17include_in_bitcoin_only\x18\xe0\xd4\x03\x20\x01(\x08\x12\
|
||||
\x1c.google.protobuf.FileOptionsR\x14includeInBitcoinOnlyB8\n#com.satosh\
|
||||
ilabs.trezor.lib.protobufB\rTrezorMessage\x80\xa6\x1d\x01\
|
||||
";
|
||||
|
||||
/// `FileDescriptorProto` object which was a source for this generated file
|
||||
|
@ -348,12 +348,376 @@ impl ::protobuf::reflect::ProtobufValue for SolanaPublicKey {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaGetAddress)
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
pub struct SolanaGetAddress {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaGetAddress.address_n)
|
||||
pub address_n: ::std::vec::Vec<u32>,
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaGetAddress.show_display)
|
||||
pub show_display: ::std::option::Option<bool>,
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaGetAddress.chunkify)
|
||||
pub chunkify: ::std::option::Option<bool>,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaGetAddress.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a SolanaGetAddress {
|
||||
fn default() -> &'a SolanaGetAddress {
|
||||
<SolanaGetAddress as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl SolanaGetAddress {
|
||||
pub fn new() -> SolanaGetAddress {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// optional bool show_display = 2;
|
||||
|
||||
pub fn show_display(&self) -> bool {
|
||||
self.show_display.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn clear_show_display(&mut self) {
|
||||
self.show_display = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_show_display(&self) -> bool {
|
||||
self.show_display.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_show_display(&mut self, v: bool) {
|
||||
self.show_display = ::std::option::Option::Some(v);
|
||||
}
|
||||
|
||||
// optional bool chunkify = 3;
|
||||
|
||||
pub fn chunkify(&self) -> bool {
|
||||
self.chunkify.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn clear_chunkify(&mut self) {
|
||||
self.chunkify = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_chunkify(&self) -> bool {
|
||||
self.chunkify.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_chunkify(&mut self, v: bool) {
|
||||
self.chunkify = ::std::option::Option::Some(v);
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
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_vec_simpler_accessor::<_, _>(
|
||||
"address_n",
|
||||
|m: &SolanaGetAddress| { &m.address_n },
|
||||
|m: &mut SolanaGetAddress| { &mut m.address_n },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||
"show_display",
|
||||
|m: &SolanaGetAddress| { &m.show_display },
|
||||
|m: &mut SolanaGetAddress| { &mut m.show_display },
|
||||
));
|
||||
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||
"chunkify",
|
||||
|m: &SolanaGetAddress| { &m.chunkify },
|
||||
|m: &mut SolanaGetAddress| { &mut m.chunkify },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaGetAddress>(
|
||||
"SolanaGetAddress",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for SolanaGetAddress {
|
||||
const NAME: &'static str = "SolanaGetAddress";
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
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 => {
|
||||
is.read_repeated_packed_uint32_into(&mut self.address_n)?;
|
||||
},
|
||||
8 => {
|
||||
self.address_n.push(is.read_uint32()?);
|
||||
},
|
||||
16 => {
|
||||
self.show_display = ::std::option::Option::Some(is.read_bool()?);
|
||||
},
|
||||
24 => {
|
||||
self.chunkify = ::std::option::Option::Some(is.read_bool()?);
|
||||
},
|
||||
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;
|
||||
for value in &self.address_n {
|
||||
my_size += ::protobuf::rt::uint32_size(1, *value);
|
||||
};
|
||||
if let Some(v) = self.show_display {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
if let Some(v) = self.chunkify {
|
||||
my_size += 1 + 1;
|
||||
}
|
||||
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<()> {
|
||||
for v in &self.address_n {
|
||||
os.write_uint32(1, *v)?;
|
||||
};
|
||||
if let Some(v) = self.show_display {
|
||||
os.write_bool(2, v)?;
|
||||
}
|
||||
if let Some(v) = self.chunkify {
|
||||
os.write_bool(3, 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() -> SolanaGetAddress {
|
||||
SolanaGetAddress::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.address_n.clear();
|
||||
self.show_display = ::std::option::Option::None;
|
||||
self.chunkify = ::std::option::Option::None;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static SolanaGetAddress {
|
||||
static instance: SolanaGetAddress = SolanaGetAddress {
|
||||
address_n: ::std::vec::Vec::new(),
|
||||
show_display: ::std::option::Option::None,
|
||||
chunkify: ::std::option::Option::None,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for SolanaGetAddress {
|
||||
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("SolanaGetAddress").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for SolanaGetAddress {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for SolanaGetAddress {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(message:hw.trezor.messages.solana.SolanaAddress)
|
||||
#[derive(PartialEq,Clone,Default,Debug)]
|
||||
pub struct SolanaAddress {
|
||||
// message fields
|
||||
// @@protoc_insertion_point(field:hw.trezor.messages.solana.SolanaAddress.address)
|
||||
pub address: ::std::option::Option<::std::string::String>,
|
||||
// special fields
|
||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.solana.SolanaAddress.special_fields)
|
||||
pub special_fields: ::protobuf::SpecialFields,
|
||||
}
|
||||
|
||||
impl<'a> ::std::default::Default for &'a SolanaAddress {
|
||||
fn default() -> &'a SolanaAddress {
|
||||
<SolanaAddress as ::protobuf::Message>::default_instance()
|
||||
}
|
||||
}
|
||||
|
||||
impl SolanaAddress {
|
||||
pub fn new() -> SolanaAddress {
|
||||
::std::default::Default::default()
|
||||
}
|
||||
|
||||
// required string address = 1;
|
||||
|
||||
pub fn address(&self) -> &str {
|
||||
match self.address.as_ref() {
|
||||
Some(v) => v,
|
||||
None => "",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_address(&mut self) {
|
||||
self.address = ::std::option::Option::None;
|
||||
}
|
||||
|
||||
pub fn has_address(&self) -> bool {
|
||||
self.address.is_some()
|
||||
}
|
||||
|
||||
// Param is passed by value, moved
|
||||
pub fn set_address(&mut self, v: ::std::string::String) {
|
||||
self.address = ::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_address(&mut self) -> &mut ::std::string::String {
|
||||
if self.address.is_none() {
|
||||
self.address = ::std::option::Option::Some(::std::string::String::new());
|
||||
}
|
||||
self.address.as_mut().unwrap()
|
||||
}
|
||||
|
||||
// Take field
|
||||
pub fn take_address(&mut self) -> ::std::string::String {
|
||||
self.address.take().unwrap_or_else(|| ::std::string::String::new())
|
||||
}
|
||||
|
||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||
let mut fields = ::std::vec::Vec::with_capacity(1);
|
||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||
"address",
|
||||
|m: &SolanaAddress| { &m.address },
|
||||
|m: &mut SolanaAddress| { &mut m.address },
|
||||
));
|
||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<SolanaAddress>(
|
||||
"SolanaAddress",
|
||||
fields,
|
||||
oneofs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::Message for SolanaAddress {
|
||||
const NAME: &'static str = "SolanaAddress";
|
||||
|
||||
fn is_initialized(&self) -> bool {
|
||||
if self.address.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.address = ::std::option::Option::Some(is.read_string()?);
|
||||
},
|
||||
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.address.as_ref() {
|
||||
my_size += ::protobuf::rt::string_size(1, &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
|
||||
}
|
||||
|
||||
fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> {
|
||||
if let Some(v) = self.address.as_ref() {
|
||||
os.write_string(1, 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() -> SolanaAddress {
|
||||
SolanaAddress::new()
|
||||
}
|
||||
|
||||
fn clear(&mut self) {
|
||||
self.address = ::std::option::Option::None;
|
||||
self.special_fields.clear();
|
||||
}
|
||||
|
||||
fn default_instance() -> &'static SolanaAddress {
|
||||
static instance: SolanaAddress = SolanaAddress {
|
||||
address: ::std::option::Option::None,
|
||||
special_fields: ::protobuf::SpecialFields::new(),
|
||||
};
|
||||
&instance
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::MessageFull for SolanaAddress {
|
||||
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("SolanaAddress").unwrap()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for SolanaAddress {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
::protobuf::text_format::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::protobuf::reflect::ProtobufValue for SolanaAddress {
|
||||
type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage<Self>;
|
||||
}
|
||||
|
||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||
\n\x15messages-solana.proto\x12\x19hw.trezor.messages.solana\x1a\x15mess\
|
||||
ages-common.proto\"T\n\x12SolanaGetPublicKey\x12\x1b\n\taddress_n\x18\
|
||||
\x01\x20\x03(\rR\x08addressN\x12!\n\x0cshow_display\x18\x02\x20\x01(\x08\
|
||||
R\x0bshowDisplay\"0\n\x0fSolanaPublicKey\x12\x1d\n\npublic_key\x18\x01\
|
||||
\x20\x02(\x0cR\tpublicKey\
|
||||
\x20\x02(\x0cR\tpublicKey\"n\n\x10SolanaGetAddress\x12\x1b\n\taddress_n\
|
||||
\x18\x01\x20\x03(\rR\x08addressN\x12!\n\x0cshow_display\x18\x02\x20\x01(\
|
||||
\x08R\x0bshowDisplay\x12\x1a\n\x08chunkify\x18\x03\x20\x01(\x08R\x08chun\
|
||||
kify\")\n\rSolanaAddress\x12\x18\n\x07address\x18\x01\x20\x02(\tR\x07add\
|
||||
ress\
|
||||
";
|
||||
|
||||
/// `FileDescriptorProto` object which was a source for this generated file
|
||||
@ -372,9 +736,11 @@ 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(2);
|
||||
let mut messages = ::std::vec::Vec::with_capacity(4);
|
||||
messages.push(SolanaGetPublicKey::generated_message_descriptor_data());
|
||||
messages.push(SolanaPublicKey::generated_message_descriptor_data());
|
||||
messages.push(SolanaGetAddress::generated_message_descriptor_data());
|
||||
messages.push(SolanaAddress::generated_message_descriptor_data());
|
||||
let mut enums = ::std::vec::Vec::with_capacity(0);
|
||||
::protobuf::reflect::GeneratedFileDescriptor::new_generated(
|
||||
file_descriptor_proto(),
|
||||
|
40
tests/device_tests/solana/test_address.py
Normal file
40
tests/device_tests/solana/test_address.py
Normal file
@ -0,0 +1,40 @@
|
||||
# This file is part of the Trezor project.
|
||||
#
|
||||
# Copyright (C) 2012-2023 SatoshiLabs and contributors
|
||||
#
|
||||
# This library is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License version 3
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# 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>.
|
||||
|
||||
import pytest
|
||||
|
||||
from trezorlib.debuglink import TrezorClientDebugLink as Client
|
||||
from trezorlib.solana import get_address
|
||||
from trezorlib.tools import parse_path
|
||||
|
||||
from ...common import parametrize_using_common_fixtures
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.altcoin,
|
||||
pytest.mark.solana,
|
||||
pytest.mark.skip_t1,
|
||||
]
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures(
|
||||
"solana/get_address.json",
|
||||
)
|
||||
def test_solana_get_address(client: Client, parameters, result):
|
||||
actual_result = get_address(
|
||||
client, address_n=parse_path(parameters["path"]), show_display=True
|
||||
)
|
||||
|
||||
assert actual_result.address == result["expected_address"]
|
Loading…
Reference in New Issue
Block a user