mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 20:38:10 +00:00
chore(core): decrease binance size by 460 bytes
This commit is contained in:
parent
f8f3f1bc55
commit
47b924cbec
@ -1,31 +1,34 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from trezor.messages import BinanceAddress
|
from apps.common.keychain import auto_keychain
|
||||||
from trezor.ui.layouts import show_address
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import Keychain, auto_keychain
|
|
||||||
|
|
||||||
from .helpers import address_from_public_key
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import BinanceGetAddress
|
from trezor.messages import BinanceGetAddress, BinanceAddress
|
||||||
from trezor.wire import Context
|
from trezor.wire import Context
|
||||||
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_address(
|
async def get_address(
|
||||||
ctx: Context, msg: BinanceGetAddress, keychain: Keychain
|
ctx: Context, msg: BinanceGetAddress, keychain: Keychain
|
||||||
) -> BinanceAddress:
|
) -> BinanceAddress:
|
||||||
|
from trezor.messages import BinanceAddress
|
||||||
|
from trezor.ui.layouts import show_address
|
||||||
|
|
||||||
|
from apps.common import paths
|
||||||
|
|
||||||
|
from .helpers import address_from_public_key
|
||||||
|
|
||||||
HRP = "bnb"
|
HRP = "bnb"
|
||||||
|
address_n = msg.address_n # local_cache_attribute
|
||||||
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
await paths.validate_path(ctx, keychain, address_n)
|
||||||
|
|
||||||
node = keychain.derive(msg.address_n)
|
node = keychain.derive(address_n)
|
||||||
pubkey = node.public_key()
|
pubkey = node.public_key()
|
||||||
address = address_from_public_key(pubkey, HRP)
|
address = address_from_public_key(pubkey, HRP)
|
||||||
if msg.show_display:
|
if msg.show_display:
|
||||||
title = paths.address_n_to_str(msg.address_n)
|
title = paths.address_n_to_str(address_n)
|
||||||
await show_address(ctx, address=address, title=title)
|
await show_address(ctx, address, title=title)
|
||||||
|
|
||||||
return BinanceAddress(address=address)
|
return BinanceAddress(address=address)
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from ubinascii import hexlify
|
|
||||||
|
|
||||||
from trezor.messages import BinancePublicKey
|
from apps.common.keychain import auto_keychain
|
||||||
from trezor.ui.layouts import show_pubkey
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import Keychain, auto_keychain
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import BinanceGetPublicKey
|
from trezor.messages import BinanceGetPublicKey, BinancePublicKey
|
||||||
from trezor.wire import Context
|
from trezor.wire import Context
|
||||||
|
from apps.common.keychain import Keychain
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def get_public_key(
|
async def get_public_key(
|
||||||
ctx: Context, msg: BinanceGetPublicKey, keychain: Keychain
|
ctx: Context, msg: BinanceGetPublicKey, keychain: Keychain
|
||||||
) -> BinancePublicKey:
|
) -> BinancePublicKey:
|
||||||
|
from ubinascii import hexlify
|
||||||
|
|
||||||
|
from trezor.messages import BinancePublicKey
|
||||||
|
from trezor.ui.layouts import show_pubkey
|
||||||
|
|
||||||
|
from apps.common import paths
|
||||||
|
|
||||||
await paths.validate_path(ctx, keychain, msg.address_n)
|
await paths.validate_path(ctx, keychain, msg.address_n)
|
||||||
node = keychain.derive(msg.address_n)
|
node = keychain.derive(msg.address_n)
|
||||||
pubkey = node.public_key()
|
pubkey = node.public_key()
|
||||||
|
@ -1,33 +1,52 @@
|
|||||||
from micropython import const
|
from micropython import const
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from trezor import wire
|
|
||||||
from trezor.crypto import bech32
|
|
||||||
from trezor.crypto.scripts import sha256_ripemd160
|
|
||||||
from trezor.messages import BinanceCancelMsg, BinanceOrderMsg, BinanceTransferMsg
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import BinanceInputOutput, BinanceSignTx
|
from trezor.messages import BinanceInputOutput, BinanceSignTx
|
||||||
from trezor.protobuf import MessageType
|
from trezor.protobuf import MessageType
|
||||||
|
|
||||||
ENVELOPE_BLUEPRINT = '{{"account_number":"{account_number}","chain_id":"{chain_id}","data":null,"memo":"{memo}","msgs":[{msgs}],"sequence":"{sequence}","source":"{source}"}}'
|
|
||||||
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{inputs}],"outputs":[{outputs}]}}'
|
|
||||||
MSG_NEWORDER_BLUEPRINT = '{{"id":"{id}","ordertype":{ordertype},"price":{price},"quantity":{quantity},"sender":"{sender}","side":{side},"symbol":"{symbol}","timeinforce":{timeinforce}}}'
|
|
||||||
MSG_CANCEL_BLUEPRINT = '{{"refid":"{refid}","sender":"{sender}","symbol":"{symbol}"}}'
|
|
||||||
INPUT_OUTPUT_BLUEPRINT = '{{"address":"{address}","coins":[{coins}]}}'
|
|
||||||
COIN_BLUEPRINT = '{{"amount":{amount},"denom":"{denom}"}}'
|
|
||||||
|
|
||||||
# 1*10^8 Jagers equal 1 BNB https://www.binance.vision/glossary/jager
|
# 1*10^8 Jagers equal 1 BNB https://www.binance.vision/glossary/jager
|
||||||
DECIMALS = const(8)
|
DECIMALS = const(8)
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: it is 11 bytes smaller to define it on top level than inside a function
|
||||||
|
def _make_input_output(input_output: BinanceInputOutput) -> str:
|
||||||
|
COIN_BLUEPRINT = '{{"amount":{},"denom":"{}"}}'
|
||||||
|
INPUT_OUTPUT_BLUEPRINT = '{{"address":"{}","coins":[{}]}}'
|
||||||
|
|
||||||
|
coins = ",".join(
|
||||||
|
COIN_BLUEPRINT.format(c.amount, c.denom) for c in input_output.coins
|
||||||
|
)
|
||||||
|
return INPUT_OUTPUT_BLUEPRINT.format(input_output.address, coins)
|
||||||
|
|
||||||
|
|
||||||
def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
|
def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
|
||||||
|
from trezor.messages import BinanceCancelMsg, BinanceOrderMsg, BinanceTransferMsg
|
||||||
|
from trezor import wire
|
||||||
|
|
||||||
|
# NOTE: not defining kwargs in format string saves 7 bytes per each argument
|
||||||
|
ENVELOPE_BLUEPRINT = '{{"account_number":"{}","chain_id":"{}","data":null,"memo":"{}","msgs":[{}],"sequence":"{}","source":"{}"}}'
|
||||||
|
MSG_TRANSFER_BLUEPRINT = '{{"inputs":[{}],"outputs":[{}]}}'
|
||||||
|
MSG_NEWORDER_BLUEPRINT = '{{"id":"{}","ordertype":{},"price":{},"quantity":{},"sender":"{}","side":{},"symbol":"{}","timeinforce":{}}}'
|
||||||
|
MSG_CANCEL_BLUEPRINT = '{{"refid":"{}","sender":"{}","symbol":"{}"}}'
|
||||||
|
|
||||||
if BinanceTransferMsg.is_type_of(msg):
|
if BinanceTransferMsg.is_type_of(msg):
|
||||||
json_msg = produce_transfer_json(msg)
|
inputs = ",".join(_make_input_output(i) for i in msg.inputs)
|
||||||
|
outputs = ",".join(_make_input_output(o) for o in msg.outputs)
|
||||||
|
json_msg = MSG_TRANSFER_BLUEPRINT.format(inputs, outputs)
|
||||||
elif BinanceOrderMsg.is_type_of(msg):
|
elif BinanceOrderMsg.is_type_of(msg):
|
||||||
json_msg = produce_neworder_json(msg)
|
json_msg = MSG_NEWORDER_BLUEPRINT.format(
|
||||||
|
msg.id,
|
||||||
|
msg.ordertype,
|
||||||
|
msg.price,
|
||||||
|
msg.quantity,
|
||||||
|
msg.sender,
|
||||||
|
msg.side,
|
||||||
|
msg.symbol,
|
||||||
|
msg.timeinforce,
|
||||||
|
)
|
||||||
elif BinanceCancelMsg.is_type_of(msg):
|
elif BinanceCancelMsg.is_type_of(msg):
|
||||||
json_msg = produce_cancel_json(msg)
|
json_msg = MSG_CANCEL_BLUEPRINT.format(msg.refid, msg.sender, msg.symbol)
|
||||||
else:
|
else:
|
||||||
raise wire.ProcessError("input message unrecognized")
|
raise wire.ProcessError("input message unrecognized")
|
||||||
|
|
||||||
@ -35,45 +54,12 @@ def produce_json_for_signing(envelope: BinanceSignTx, msg: MessageType) -> str:
|
|||||||
raise wire.DataError("Source is invalid")
|
raise wire.DataError("Source is invalid")
|
||||||
|
|
||||||
return ENVELOPE_BLUEPRINT.format(
|
return ENVELOPE_BLUEPRINT.format(
|
||||||
account_number=envelope.account_number,
|
envelope.account_number,
|
||||||
chain_id=envelope.chain_id,
|
envelope.chain_id,
|
||||||
memo=envelope.memo,
|
envelope.memo,
|
||||||
msgs=json_msg,
|
json_msg,
|
||||||
sequence=envelope.sequence,
|
envelope.sequence,
|
||||||
source=envelope.source,
|
envelope.source,
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def produce_transfer_json(msg: BinanceTransferMsg) -> str:
|
|
||||||
def make_input_output(input_output: BinanceInputOutput) -> str:
|
|
||||||
coins = ",".join(
|
|
||||||
COIN_BLUEPRINT.format(amount=c.amount, denom=c.denom)
|
|
||||||
for c in input_output.coins
|
|
||||||
)
|
|
||||||
return INPUT_OUTPUT_BLUEPRINT.format(address=input_output.address, coins=coins)
|
|
||||||
|
|
||||||
inputs = ",".join(make_input_output(i) for i in msg.inputs)
|
|
||||||
outputs = ",".join(make_input_output(o) for o in msg.outputs)
|
|
||||||
|
|
||||||
return MSG_TRANSFER_BLUEPRINT.format(inputs=inputs, outputs=outputs)
|
|
||||||
|
|
||||||
|
|
||||||
def produce_neworder_json(msg: BinanceOrderMsg) -> str:
|
|
||||||
return MSG_NEWORDER_BLUEPRINT.format(
|
|
||||||
id=msg.id,
|
|
||||||
ordertype=msg.ordertype,
|
|
||||||
price=msg.price,
|
|
||||||
quantity=msg.quantity,
|
|
||||||
sender=msg.sender,
|
|
||||||
side=msg.side,
|
|
||||||
symbol=msg.symbol,
|
|
||||||
timeinforce=msg.timeinforce,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def produce_cancel_json(msg: BinanceCancelMsg) -> str:
|
|
||||||
return MSG_CANCEL_BLUEPRINT.format(
|
|
||||||
refid=msg.refid, sender=msg.sender, symbol=msg.symbol
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +69,8 @@ def address_from_public_key(pubkey: bytes, hrp: str) -> str:
|
|||||||
Address_Bech32 = HRP + '1' + bech32.encode(convert8BitsTo5Bits(RIPEMD160(SHA256(compressed public key))))
|
Address_Bech32 = HRP + '1' + bech32.encode(convert8BitsTo5Bits(RIPEMD160(SHA256(compressed public key))))
|
||||||
HRP - bnb for productions, tbnb for tests
|
HRP - bnb for productions, tbnb for tests
|
||||||
"""
|
"""
|
||||||
|
from trezor.crypto import bech32
|
||||||
|
from trezor.crypto.scripts import sha256_ripemd160
|
||||||
|
|
||||||
h = sha256_ripemd160(pubkey).digest()
|
h = sha256_ripemd160(pubkey).digest()
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from trezor.enums import BinanceOrderSide, ButtonRequestType
|
from trezor.enums import ButtonRequestType
|
||||||
from trezor.strings import format_amount
|
from trezor.strings import format_amount
|
||||||
from trezor.ui.layouts import confirm_properties
|
from trezor.ui.layouts import confirm_properties
|
||||||
from trezor.ui.layouts.altcoin import confirm_transfer_binance
|
|
||||||
|
|
||||||
from . import helpers
|
from .helpers import DECIMALS
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import (
|
from trezor.messages import (
|
||||||
@ -18,14 +17,16 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
async def require_confirm_transfer(ctx: Context, msg: BinanceTransferMsg) -> None:
|
async def require_confirm_transfer(ctx: Context, msg: BinanceTransferMsg) -> None:
|
||||||
items = []
|
from trezor.ui.layouts.altcoin import confirm_transfer_binance
|
||||||
|
|
||||||
|
items: list[tuple[str, str, str]] = []
|
||||||
|
|
||||||
def make_input_output_pages(msg: BinanceInputOutput, direction: str) -> None:
|
def make_input_output_pages(msg: BinanceInputOutput, direction: str) -> None:
|
||||||
for coin in msg.coins:
|
for coin in msg.coins:
|
||||||
items.append(
|
items.append(
|
||||||
(
|
(
|
||||||
direction,
|
direction,
|
||||||
format_amount(coin.amount, helpers.DECIMALS) + " " + coin.denom,
|
format_amount(coin.amount, DECIMALS) + " " + coin.denom,
|
||||||
msg.address,
|
msg.address,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -43,18 +44,20 @@ async def require_confirm_cancel(ctx: Context, msg: BinanceCancelMsg) -> None:
|
|||||||
await confirm_properties(
|
await confirm_properties(
|
||||||
ctx,
|
ctx,
|
||||||
"confirm_cancel",
|
"confirm_cancel",
|
||||||
title="Confirm cancel",
|
"Confirm cancel",
|
||||||
props=[
|
(
|
||||||
("Sender address:", str(msg.sender)),
|
("Sender address:", str(msg.sender)),
|
||||||
("Pair:", str(msg.symbol)),
|
("Pair:", str(msg.symbol)),
|
||||||
("Order ID:", str(msg.refid)),
|
("Order ID:", str(msg.refid)),
|
||||||
],
|
),
|
||||||
hold=True,
|
hold=True,
|
||||||
br_code=ButtonRequestType.SignTx,
|
br_code=ButtonRequestType.SignTx,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
|
async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
|
||||||
|
from trezor.enums import BinanceOrderSide
|
||||||
|
|
||||||
if msg.side == BinanceOrderSide.BUY:
|
if msg.side == BinanceOrderSide.BUY:
|
||||||
side = "Buy"
|
side = "Buy"
|
||||||
elif msg.side == BinanceOrderSide.SELL:
|
elif msg.side == BinanceOrderSide.SELL:
|
||||||
@ -65,14 +68,14 @@ async def require_confirm_order(ctx: Context, msg: BinanceOrderMsg) -> None:
|
|||||||
await confirm_properties(
|
await confirm_properties(
|
||||||
ctx,
|
ctx,
|
||||||
"confirm_order",
|
"confirm_order",
|
||||||
title="Confirm order",
|
"Confirm order",
|
||||||
props=[
|
(
|
||||||
("Sender address:", str(msg.sender)),
|
("Sender address:", str(msg.sender)),
|
||||||
("Pair:", str(msg.symbol)),
|
("Pair:", str(msg.symbol)),
|
||||||
("Side:", side),
|
("Side:", side),
|
||||||
("Quantity:", format_amount(msg.quantity, helpers.DECIMALS)),
|
("Quantity:", format_amount(msg.quantity, DECIMALS)),
|
||||||
("Price:", format_amount(msg.price, helpers.DECIMALS)),
|
("Price:", format_amount(msg.price, DECIMALS)),
|
||||||
],
|
),
|
||||||
hold=True,
|
hold=True,
|
||||||
br_code=ButtonRequestType.SignTx,
|
br_code=ButtonRequestType.SignTx,
|
||||||
)
|
)
|
||||||
|
@ -1,30 +1,33 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from trezor import wire
|
from apps.common.keychain import auto_keychain
|
||||||
from trezor.crypto.curve import secp256k1
|
|
||||||
from trezor.crypto.hashlib import sha256
|
|
||||||
from trezor.enums import MessageType
|
|
||||||
from trezor.messages import (
|
|
||||||
BinanceCancelMsg,
|
|
||||||
BinanceOrderMsg,
|
|
||||||
BinanceSignedTx,
|
|
||||||
BinanceTransferMsg,
|
|
||||||
BinanceTxRequest,
|
|
||||||
)
|
|
||||||
|
|
||||||
from apps.common import paths
|
|
||||||
from apps.common.keychain import Keychain, auto_keychain
|
|
||||||
|
|
||||||
from . import helpers, layout
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from trezor.messages import BinanceSignTx
|
from trezor.messages import BinanceSignTx, BinanceSignedTx
|
||||||
|
from apps.common.keychain import Keychain
|
||||||
|
from trezor.wire import Context
|
||||||
|
|
||||||
|
|
||||||
@auto_keychain(__name__)
|
@auto_keychain(__name__)
|
||||||
async def sign_tx(
|
async def sign_tx(
|
||||||
ctx: wire.Context, envelope: BinanceSignTx, keychain: Keychain
|
ctx: Context, envelope: BinanceSignTx, keychain: Keychain
|
||||||
) -> BinanceSignedTx:
|
) -> BinanceSignedTx:
|
||||||
|
from trezor import wire
|
||||||
|
from trezor.crypto.curve import secp256k1
|
||||||
|
from trezor.crypto.hashlib import sha256
|
||||||
|
from trezor.enums import MessageType
|
||||||
|
from trezor.messages import (
|
||||||
|
BinanceCancelMsg,
|
||||||
|
BinanceOrderMsg,
|
||||||
|
BinanceSignedTx,
|
||||||
|
BinanceTransferMsg,
|
||||||
|
BinanceTxRequest,
|
||||||
|
)
|
||||||
|
|
||||||
|
from apps.common import paths
|
||||||
|
|
||||||
|
from . import helpers, layout
|
||||||
|
|
||||||
# create transaction message -> sign it -> create signature/pubkey message -> serialize all
|
# create transaction message -> sign it -> create signature/pubkey message -> serialize all
|
||||||
if envelope.msg_count > 1:
|
if envelope.msg_count > 1:
|
||||||
raise wire.DataError("Multiple messages not supported.")
|
raise wire.DataError("Multiple messages not supported.")
|
||||||
@ -55,11 +58,8 @@ async def sign_tx(
|
|||||||
else:
|
else:
|
||||||
raise wire.ProcessError("input message unrecognized")
|
raise wire.ProcessError("input message unrecognized")
|
||||||
|
|
||||||
signature_bytes = generate_content_signature(msg_json.encode(), node.private_key())
|
# generate_content_signature
|
||||||
|
msghash = sha256(msg_json.encode()).digest()
|
||||||
|
signature_bytes = secp256k1.sign(node.private_key(), msghash)[1:65]
|
||||||
|
|
||||||
return BinanceSignedTx(signature=signature_bytes, public_key=node.public_key())
|
return BinanceSignedTx(signature=signature_bytes, public_key=node.public_key())
|
||||||
|
|
||||||
|
|
||||||
def generate_content_signature(json: bytes, private_key: bytes) -> bytes:
|
|
||||||
msghash = sha256(json).digest()
|
|
||||||
return secp256k1.sign(private_key, msghash)[1:65]
|
|
||||||
|
@ -5,7 +5,6 @@ from trezor.crypto.hashlib import sha256
|
|||||||
|
|
||||||
if not utils.BITCOIN_ONLY:
|
if not utils.BITCOIN_ONLY:
|
||||||
from apps.binance.helpers import produce_json_for_signing
|
from apps.binance.helpers import produce_json_for_signing
|
||||||
from apps.binance.sign_tx import generate_content_signature, sign_tx
|
|
||||||
from trezor.messages import BinanceCancelMsg
|
from trezor.messages import BinanceCancelMsg
|
||||||
from trezor.messages import BinanceCoin
|
from trezor.messages import BinanceCoin
|
||||||
from trezor.messages import BinanceInputOutput
|
from trezor.messages import BinanceInputOutput
|
||||||
@ -14,6 +13,12 @@ if not utils.BITCOIN_ONLY:
|
|||||||
from trezor.messages import BinanceTransferMsg
|
from trezor.messages import BinanceTransferMsg
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: copy-pasted from apps.binance.sign_tx
|
||||||
|
def generate_content_signature(json: bytes, private_key: bytes) -> bytes:
|
||||||
|
msghash = sha256(json).digest()
|
||||||
|
return secp256k1.sign(private_key, msghash)[1:65]
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
||||||
class TestBinanceSign(unittest.TestCase):
|
class TestBinanceSign(unittest.TestCase):
|
||||||
def test_order_signature(self):
|
def test_order_signature(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user