1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-22 14:28:07 +00:00
trezor-firmware/core/src/apps/binance/helpers.py

80 lines
3.0 KiB
Python
Raw Normal View History

from micropython import const
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from trezor.messages import BinanceInputOutput, BinanceSignTx
from trezor.protobuf import MessageType
2019-09-03 07:12:04 +00:00
# 1*10^8 Jagers equal 1 BNB https://www.binance.vision/glossary/jager
2019-12-09 16:43:30 +00:00
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:
from trezor import wire
from trezor.messages import BinanceCancelMsg, BinanceOrderMsg, BinanceTransferMsg
# 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):
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):
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):
json_msg = MSG_CANCEL_BLUEPRINT.format(msg.refid, msg.sender, msg.symbol)
else:
raise wire.ProcessError("input message unrecognized")
if envelope.source < 0:
raise wire.DataError("Source is invalid")
return ENVELOPE_BLUEPRINT.format(
envelope.account_number,
envelope.chain_id,
envelope.memo,
json_msg,
envelope.sequence,
envelope.source,
)
def address_from_public_key(pubkey: bytes, hrp: str) -> str:
"""
Address = RIPEMD160(SHA256(compressed public key))
Address_Bech32 = HRP + '1' + bech32.encode(convert8BitsTo5Bits(RIPEMD160(SHA256(compressed public key))))
HRP - bnb for productions, tbnb for tests
"""
from trezor.crypto import bech32
from trezor.crypto.scripts import sha256_ripemd160
h = sha256_ripemd160(pubkey).digest()
assert (len(h) * 8) % 5 == 0 # no padding will be added by convertbits
convertedbits = bech32.convertbits(h, 8, 5)
return bech32.bech32_encode(hrp, convertedbits, bech32.Encoding.BECH32)