mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-16 19:38:09 +00:00
stellar: style and text api changes
This commit is contained in:
parent
b722fddc58
commit
b46ce034d6
@ -1,21 +1,26 @@
|
|||||||
from trezor.wire import register, protobuf_workflow
|
from trezor.messages.MessageType import (
|
||||||
from trezor.messages.wire_types import StellarGetAddress
|
StellarGetAddress,
|
||||||
from trezor.messages.wire_types import StellarGetPublicKey
|
StellarGetPublicKey,
|
||||||
from trezor.messages.wire_types import StellarSignTx
|
StellarSignTx,
|
||||||
|
)
|
||||||
|
from trezor.wire import protobuf_workflow, register
|
||||||
|
|
||||||
|
|
||||||
def dispatch_StellarGetAddress(*args, **kwargs):
|
def dispatch_StellarGetAddress(*args, **kwargs):
|
||||||
from .get_address import get_address
|
from .get_address import get_address
|
||||||
|
|
||||||
return get_address(*args, **kwargs)
|
return get_address(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def dispatch_StellarGetPublicKey(*args, **kwargs):
|
def dispatch_StellarGetPublicKey(*args, **kwargs):
|
||||||
from .get_public_key import get_public_key
|
from .get_public_key import get_public_key
|
||||||
|
|
||||||
return get_public_key(*args, **kwargs)
|
return get_public_key(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def dispatch_StellarSignTx(*args, **kwargs):
|
def dispatch_StellarSignTx(*args, **kwargs):
|
||||||
from .sign_tx import sign_tx
|
from .sign_tx import sign_tx
|
||||||
|
|
||||||
return sign_tx(*args, **kwargs)
|
return sign_tx(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,37 +1,38 @@
|
|||||||
from trezor.messages import wire_types
|
|
||||||
from micropython import const
|
from micropython import const
|
||||||
|
|
||||||
STELLAR_CURVE = 'ed25519'
|
from trezor.messages import MessageType
|
||||||
TX_TYPE = bytearray('\x00\x00\x00\x02')
|
|
||||||
|
STELLAR_CURVE = "ed25519"
|
||||||
|
TX_TYPE = bytearray("\x00\x00\x00\x02")
|
||||||
|
|
||||||
# source: https://github.com/stellar/go/blob/3d2c1defe73dbfed00146ebe0e8d7e07ce4bb1b6/xdr/Stellar-transaction.x#L16
|
# source: https://github.com/stellar/go/blob/3d2c1defe73dbfed00146ebe0e8d7e07ce4bb1b6/xdr/Stellar-transaction.x#L16
|
||||||
# Inflation not supported see https://github.com/trezor/trezor-core/issues/202#issuecomment-393342089
|
# Inflation not supported see https://github.com/trezor/trezor-core/issues/202#issuecomment-393342089
|
||||||
op_codes = {
|
op_codes = {
|
||||||
'StellarAccountMergeOp': const(8),
|
"StellarAccountMergeOp": const(8),
|
||||||
'StellarAllowTrustOp': const(7),
|
"StellarAllowTrustOp": const(7),
|
||||||
'StellarBumpSequenceOp': const(11),
|
"StellarBumpSequenceOp": const(11),
|
||||||
'StellarChangeTrustOp': const(6),
|
"StellarChangeTrustOp": const(6),
|
||||||
'StellarCreateAccountOp': const(0),
|
"StellarCreateAccountOp": const(0),
|
||||||
'StellarCreatePassiveOfferOp': const(4),
|
"StellarCreatePassiveOfferOp": const(4),
|
||||||
'StellarManageDataOp': const(10),
|
"StellarManageDataOp": const(10),
|
||||||
'StellarManageOfferOp': const(3),
|
"StellarManageOfferOp": const(3),
|
||||||
'StellarPathPaymentOp': const(2),
|
"StellarPathPaymentOp": const(2),
|
||||||
'StellarPaymentOp': const(1),
|
"StellarPaymentOp": const(1),
|
||||||
'StellarSetOptionsOp': const(5),
|
"StellarSetOptionsOp": const(5),
|
||||||
}
|
}
|
||||||
|
|
||||||
op_wire_types = [
|
op_wire_types = [
|
||||||
wire_types.StellarAccountMergeOp,
|
MessageType.StellarAccountMergeOp,
|
||||||
wire_types.StellarAllowTrustOp,
|
MessageType.StellarAllowTrustOp,
|
||||||
wire_types.StellarBumpSequenceOp,
|
MessageType.StellarBumpSequenceOp,
|
||||||
wire_types.StellarChangeTrustOp,
|
MessageType.StellarChangeTrustOp,
|
||||||
wire_types.StellarCreateAccountOp,
|
MessageType.StellarCreateAccountOp,
|
||||||
wire_types.StellarCreatePassiveOfferOp,
|
MessageType.StellarCreatePassiveOfferOp,
|
||||||
wire_types.StellarManageDataOp,
|
MessageType.StellarManageDataOp,
|
||||||
wire_types.StellarManageOfferOp,
|
MessageType.StellarManageOfferOp,
|
||||||
wire_types.StellarPathPaymentOp,
|
MessageType.StellarPathPaymentOp,
|
||||||
wire_types.StellarPaymentOp,
|
MessageType.StellarPaymentOp,
|
||||||
wire_types.StellarSetOptionsOp,
|
MessageType.StellarSetOptionsOp,
|
||||||
]
|
]
|
||||||
|
|
||||||
# https://github.com/stellar/go/blob/e0ffe19f58879d3c31e2976b97a5bf10e13a337b/xdr/xdr_generated.go#L584
|
# https://github.com/stellar/go/blob/e0ffe19f58879d3c31e2976b97a5bf10e13a337b/xdr/xdr_generated.go#L584
|
||||||
@ -44,8 +45,8 @@ ASSET_TYPE_ALPHANUM12 = const(2)
|
|||||||
AMOUNT_DIVISIBILITY = const(7)
|
AMOUNT_DIVISIBILITY = const(7)
|
||||||
|
|
||||||
# https://github.com/stellar/go/blob/master/network/main.go
|
# https://github.com/stellar/go/blob/master/network/main.go
|
||||||
NETWORK_PASSPHRASE_PUBLIC = 'Public Global Stellar Network ; September 2015'
|
NETWORK_PASSPHRASE_PUBLIC = "Public Global Stellar Network ; September 2015"
|
||||||
NETWORK_PASSPHRASE_TESTNET = 'Test SDF Network ; September 2015'
|
NETWORK_PASSPHRASE_TESTNET = "Test SDF Network ; September 2015"
|
||||||
|
|
||||||
# https://www.stellar.org/developers/guides/concepts/accounts.html#flags
|
# https://www.stellar.org/developers/guides/concepts/accounts.html#flags
|
||||||
FLAG_AUTH_REQUIRED = const(1)
|
FLAG_AUTH_REQUIRED = const(1)
|
||||||
@ -68,5 +69,5 @@ SIGN_TYPE_HASH = const(2)
|
|||||||
|
|
||||||
def get_op_code(msg) -> int:
|
def get_op_code(msg) -> int:
|
||||||
if msg.__qualname__ not in op_codes:
|
if msg.__qualname__ not in op_codes:
|
||||||
raise ValueError('Stellar: op code unknown')
|
raise ValueError("Stellar: op code unknown")
|
||||||
return op_codes[msg.__qualname__]
|
return op_codes[msg.__qualname__]
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
from trezor.messages.StellarAddress import StellarAddress
|
||||||
|
from trezor.messages.StellarGetAddress import StellarGetAddress
|
||||||
|
|
||||||
from apps.common import seed
|
from apps.common import seed
|
||||||
from apps.common.display_address import show_address, show_qr
|
from apps.common.display_address import show_address, show_qr
|
||||||
from apps.stellar import helpers
|
from apps.stellar import helpers
|
||||||
from trezor.messages.StellarAddress import StellarAddress
|
|
||||||
from trezor.messages.StellarGetAddress import StellarGetAddress
|
|
||||||
|
|
||||||
|
|
||||||
async def get_address(ctx, msg: StellarGetAddress):
|
async def get_address(ctx, msg: StellarGetAddress):
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
|
from ubinascii import hexlify
|
||||||
|
|
||||||
|
from trezor import ui
|
||||||
|
from trezor.messages import ButtonRequestType
|
||||||
|
from trezor.messages.StellarGetPublicKey import StellarGetPublicKey
|
||||||
|
from trezor.messages.StellarPublicKey import StellarPublicKey
|
||||||
|
from trezor.ui.text import Text
|
||||||
|
|
||||||
from apps.common import seed
|
from apps.common import seed
|
||||||
from apps.common.confirm import confirm
|
from apps.common.confirm import confirm
|
||||||
from apps.common.display_address import split_address
|
from apps.common.display_address import split_address
|
||||||
from apps.stellar import helpers
|
from apps.stellar import helpers
|
||||||
from trezor import ui
|
|
||||||
from trezor.messages.StellarPublicKey import StellarPublicKey
|
|
||||||
from trezor.messages.StellarGetPublicKey import StellarGetPublicKey
|
|
||||||
from trezor.messages import ButtonRequestType
|
|
||||||
from trezor.ui.text import Text
|
|
||||||
from ubinascii import hexlify
|
|
||||||
|
|
||||||
|
|
||||||
async def get_public_key(ctx, msg: StellarGetPublicKey):
|
async def get_public_key(ctx, msg: StellarGetPublicKey):
|
||||||
@ -24,13 +26,16 @@ async def get_public_key(ctx, msg: StellarGetPublicKey):
|
|||||||
|
|
||||||
async def _show(ctx, pubkey: bytes):
|
async def _show(ctx, pubkey: bytes):
|
||||||
lines = split_address(hexlify(pubkey))
|
lines = split_address(hexlify(pubkey))
|
||||||
content = Text('Export Stellar ID', ui.ICON_RECEIVE,
|
content = Text(
|
||||||
ui.NORMAL, 'Share public account ID?', # todo only two lines are displayed
|
"Export Stellar ID",
|
||||||
ui.MONO, *lines,
|
ui.ICON_RECEIVE,
|
||||||
icon_color=ui.GREEN)
|
ui.NORMAL,
|
||||||
|
"Share public account ID?", # todo only two lines are displayed
|
||||||
|
ui.MONO,
|
||||||
|
*lines,
|
||||||
|
icon_color=ui.GREEN
|
||||||
|
)
|
||||||
|
|
||||||
return await confirm(
|
return await confirm(
|
||||||
ctx,
|
ctx, content, code=ButtonRequestType.Address, cancel_style=ui.BTN_KEY
|
||||||
content,
|
)
|
||||||
code=ButtonRequestType.Address,
|
|
||||||
cancel_style=ui.BTN_KEY)
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
from trezor.crypto import base32
|
|
||||||
from trezor.wire import ProcessError
|
|
||||||
import ustruct
|
import ustruct
|
||||||
|
|
||||||
STELLAR_CURVE = 'ed25519'
|
from trezor.crypto import base32
|
||||||
|
from trezor.wire import ProcessError
|
||||||
|
|
||||||
|
STELLAR_CURVE = "ed25519"
|
||||||
|
|
||||||
|
|
||||||
def public_key_from_address(address: str) -> bytes:
|
def public_key_from_address(address: str) -> bytes:
|
||||||
@ -27,7 +28,7 @@ def address_from_public_key(pubkey: bytes):
|
|||||||
|
|
||||||
def _crc16_checksum_verify(data: bytes, checksum: bytes):
|
def _crc16_checksum_verify(data: bytes, checksum: bytes):
|
||||||
if _crc16_checksum(data) != checksum:
|
if _crc16_checksum(data) != checksum:
|
||||||
raise ProcessError('Invalid address checksum')
|
raise ProcessError("Invalid address checksum")
|
||||||
|
|
||||||
|
|
||||||
def _crc16_checksum(data: bytes) -> bytes:
|
def _crc16_checksum(data: bytes) -> bytes:
|
||||||
@ -42,8 +43,8 @@ def _crc16_checksum(data: bytes) -> bytes:
|
|||||||
|
|
||||||
for byte in data:
|
for byte in data:
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
bit = ((byte >> (7 - i) & 1) == 1)
|
bit = (byte >> (7 - i) & 1) == 1
|
||||||
c15 = ((crc >> 15 & 1) == 1)
|
c15 = (crc >> 15 & 1) == 1
|
||||||
crc <<= 1
|
crc <<= 1
|
||||||
if c15 ^ bit:
|
if c15 ^ bit:
|
||||||
crc ^= polynomial
|
crc ^= polynomial
|
||||||
|
@ -1,63 +1,59 @@
|
|||||||
from apps.common.confirm import require_confirm, require_hold_to_confirm
|
from trezor import ui, utils
|
||||||
from apps.stellar import consts
|
|
||||||
from trezor import ui
|
|
||||||
from trezor.messages import ButtonRequestType
|
from trezor.messages import ButtonRequestType
|
||||||
from trezor.ui.text import Text
|
from trezor.ui.text import Text
|
||||||
from trezor import utils
|
|
||||||
|
from apps.common.confirm import require_confirm, require_hold_to_confirm
|
||||||
|
from apps.stellar import consts
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_init(ctx, address: str, network_passphrase: str):
|
async def require_confirm_init(ctx, address: str, network_passphrase: str):
|
||||||
content = Text('Confirm Stellar', ui.ICON_SEND,
|
text = Text("Confirm Stellar", ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, 'Initialize singing with',
|
text.normal("Initialize singing with")
|
||||||
ui.MONO, *split(address),
|
text.mono(*split(address))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
network = get_network_warning(network_passphrase)
|
network = get_network_warning(network_passphrase)
|
||||||
if network:
|
if network:
|
||||||
content = Text('Confirm network', ui.ICON_CONFIRM,
|
text = Text("Confirm network", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, 'Transaction is on',
|
text.normal("Transaction is on")
|
||||||
ui.BOLD, network,
|
text.bold(network)
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_memo(ctx, memo_type: int, memo_text: str):
|
async def require_confirm_memo(ctx, memo_type: int, memo_text: str):
|
||||||
if memo_type == consts.MEMO_TYPE_TEXT:
|
if memo_type == consts.MEMO_TYPE_TEXT:
|
||||||
title = 'Memo (TEXT)'
|
title = "Memo (TEXT)"
|
||||||
elif memo_type == consts.MEMO_TYPE_ID:
|
elif memo_type == consts.MEMO_TYPE_ID:
|
||||||
title = 'Memo (ID)'
|
title = "Memo (ID)"
|
||||||
elif memo_type == consts.MEMO_TYPE_HASH:
|
elif memo_type == consts.MEMO_TYPE_HASH:
|
||||||
title = 'Memo (HASH)'
|
title = "Memo (HASH)"
|
||||||
elif memo_type == consts.MEMO_TYPE_RETURN:
|
elif memo_type == consts.MEMO_TYPE_RETURN:
|
||||||
title = 'Memo (RETURN)'
|
title = "Memo (RETURN)"
|
||||||
else: # MEMO_TYPE_NONE
|
else: # MEMO_TYPE_NONE
|
||||||
title = 'No memo set!' # todo format this as ui.NORMAL not MONO
|
title = "No memo set!" # todo format this as ui.NORMAL not MONO
|
||||||
memo_text = 'Important: Many exchanges require a memo when depositing'
|
memo_text = "Important: Many exchanges require a memo when depositing"
|
||||||
content = Text('Confirm memo', ui.ICON_CONFIRM,
|
text = Text("Confirm memo", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, title,
|
text.bold(title)
|
||||||
ui.MONO, *split(memo_text),
|
text.mono(*split(memo_text))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def require_confirm_final(ctx, fee: int, num_operations: int):
|
async def require_confirm_final(ctx, fee: int, num_operations: int):
|
||||||
op_str = str(num_operations) + ' operation'
|
op_str = str(num_operations) + " operation"
|
||||||
if num_operations > 1:
|
if num_operations > 1:
|
||||||
op_str += 's'
|
op_str += "s"
|
||||||
content = Text('Final confirm', ui.ICON_SEND,
|
text = Text("Final confirm", ui.ICON_SEND, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, 'Sign this transaction',
|
text.normal("Sign this transaction")
|
||||||
ui.NORMAL, 'made up of ' + op_str,
|
text.normal("made up of " + op_str)
|
||||||
ui.BOLD, 'and pay ' + format_amount(fee),
|
text.bold("and pay " + format_amount(fee))
|
||||||
ui.NORMAL, 'for fee?',
|
text.normal("for fee?")
|
||||||
icon_color=ui.GREEN)
|
|
||||||
# we use SignTx, not ConfirmOutput, for compatibility with T1
|
# we use SignTx, not ConfirmOutput, for compatibility with T1
|
||||||
await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx)
|
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||||
|
|
||||||
|
|
||||||
def format_amount(amount: int, ticker=True) -> str:
|
def format_amount(amount: int, ticker=True) -> str:
|
||||||
t = ''
|
t = ""
|
||||||
if ticker:
|
if ticker:
|
||||||
t = ' XLM'
|
t = " XLM"
|
||||||
return utils.format_amount(amount, consts.AMOUNT_DIVISIBILITY) + t
|
return utils.format_amount(amount, consts.AMOUNT_DIVISIBILITY) + t
|
||||||
|
|
||||||
|
|
||||||
@ -70,13 +66,13 @@ def split(text):
|
|||||||
def trim(payload: str, length: int, dots=True) -> str:
|
def trim(payload: str, length: int, dots=True) -> str:
|
||||||
if len(payload) > length:
|
if len(payload) > length:
|
||||||
if dots:
|
if dots:
|
||||||
return payload[:length - 2] + '..'
|
return payload[: length - 2] + ".."
|
||||||
return payload[:length - 2]
|
return payload[: length - 2]
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
# todo merge with nem
|
# todo merge with nem
|
||||||
def trim_to_rows(payload: str, rows: int=1) -> str:
|
def trim_to_rows(payload: str, rows: int = 1) -> str:
|
||||||
return trim(payload, rows * 17)
|
return trim(payload, rows * 17)
|
||||||
|
|
||||||
|
|
||||||
@ -84,5 +80,5 @@ def get_network_warning(network_passphrase: str):
|
|||||||
if network_passphrase == consts.NETWORK_PASSPHRASE_PUBLIC:
|
if network_passphrase == consts.NETWORK_PASSPHRASE_PUBLIC:
|
||||||
return None
|
return None
|
||||||
if network_passphrase == consts.NETWORK_PASSPHRASE_TESTNET:
|
if network_passphrase == consts.NETWORK_PASSPHRASE_TESTNET:
|
||||||
return 'testnet network'
|
return "testnet network"
|
||||||
return 'private network'
|
return "private network"
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
from apps.stellar.operations import serialize
|
from apps.stellar import consts, writers
|
||||||
from apps.stellar.operations import layout
|
from apps.stellar.operations import layout, serialize
|
||||||
from apps.stellar import consts
|
|
||||||
from apps.stellar import writers
|
|
||||||
|
|
||||||
|
|
||||||
async def operation(ctx, w, op):
|
async def operation(ctx, w, op):
|
||||||
@ -43,4 +41,4 @@ async def operation(ctx, w, op):
|
|||||||
await layout.confirm_set_options_op(ctx, op)
|
await layout.confirm_set_options_op(ctx, op)
|
||||||
serialize.serialize_set_options_op(w, op)
|
serialize.serialize_set_options_op(w, op)
|
||||||
else:
|
else:
|
||||||
raise ValueError('serialize.Stellar: unknown operation')
|
raise ValueError("serialize.Stellar: unknown operation")
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
from apps.stellar.layout import split, format_amount, ui, trim_to_rows, require_confirm
|
from ubinascii import hexlify
|
||||||
from apps.stellar import consts
|
|
||||||
from trezor.messages import ButtonRequestType
|
from trezor.messages import ButtonRequestType
|
||||||
from trezor.ui.text import Text
|
|
||||||
from trezor.messages.StellarAccountMergeOp import StellarAccountMergeOp
|
from trezor.messages.StellarAccountMergeOp import StellarAccountMergeOp
|
||||||
from trezor.messages.StellarAssetType import StellarAssetType
|
|
||||||
from trezor.messages.StellarAllowTrustOp import StellarAllowTrustOp
|
from trezor.messages.StellarAllowTrustOp import StellarAllowTrustOp
|
||||||
|
from trezor.messages.StellarAssetType import StellarAssetType
|
||||||
from trezor.messages.StellarBumpSequenceOp import StellarBumpSequenceOp
|
from trezor.messages.StellarBumpSequenceOp import StellarBumpSequenceOp
|
||||||
from trezor.messages.StellarChangeTrustOp import StellarChangeTrustOp
|
from trezor.messages.StellarChangeTrustOp import StellarChangeTrustOp
|
||||||
from trezor.messages.StellarCreateAccountOp import StellarCreateAccountOp
|
from trezor.messages.StellarCreateAccountOp import StellarCreateAccountOp
|
||||||
@ -14,252 +13,238 @@ from trezor.messages.StellarManageOfferOp import StellarManageOfferOp
|
|||||||
from trezor.messages.StellarPathPaymentOp import StellarPathPaymentOp
|
from trezor.messages.StellarPathPaymentOp import StellarPathPaymentOp
|
||||||
from trezor.messages.StellarPaymentOp import StellarPaymentOp
|
from trezor.messages.StellarPaymentOp import StellarPaymentOp
|
||||||
from trezor.messages.StellarSetOptionsOp import StellarSetOptionsOp
|
from trezor.messages.StellarSetOptionsOp import StellarSetOptionsOp
|
||||||
|
from trezor.ui.text import Text
|
||||||
from trezor.wire import ProcessError
|
from trezor.wire import ProcessError
|
||||||
from ubinascii import hexlify
|
|
||||||
|
from apps.stellar import consts
|
||||||
|
from apps.stellar.layout import format_amount, require_confirm, split, trim_to_rows, ui
|
||||||
|
|
||||||
|
|
||||||
async def confirm_source_account(ctx, source_account: bytes):
|
async def confirm_source_account(ctx, source_account: bytes):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Source account:',
|
text.bold("Source account:")
|
||||||
ui.MONO, *split(source_account),
|
text.mono(*split(source_account))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_allow_trust_op(ctx, op: StellarAllowTrustOp):
|
async def confirm_allow_trust_op(ctx, op: StellarAllowTrustOp):
|
||||||
if op.is_authorized:
|
if op.is_authorized:
|
||||||
text = 'Allow Trust'
|
text = "Allow Trust"
|
||||||
else:
|
else:
|
||||||
text = 'Revoke Trust'
|
text = "Revoke Trust"
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, text,
|
text.bold(text)
|
||||||
ui.NORMAL, 'of %s by:' % op.asset_code,
|
text.normal("of %s by:" % op.asset_code)
|
||||||
ui.MONO, *split(trim_to_rows(op.trusted_account, 3)),
|
text.mono(*split(trim_to_rows(op.trusted_account, 3)))
|
||||||
icon_color=ui.GREEN)
|
|
||||||
|
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_account_merge_op(ctx, op: StellarAccountMergeOp):
|
async def confirm_account_merge_op(ctx, op: StellarAccountMergeOp):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Account Merge',
|
text.bold("Account Merge")
|
||||||
ui.NORMAL, 'All XLM will be sent to:',
|
text.normal("All XLM will be sent to:")
|
||||||
ui.MONO, *split(trim_to_rows(op.destination_account, 3)),
|
text.mono(*split(trim_to_rows(op.destination_account, 3)))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_bump_sequence_op(ctx, op: StellarBumpSequenceOp):
|
async def confirm_bump_sequence_op(ctx, op: StellarBumpSequenceOp):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Bump Sequence',
|
text.bold("Bump Sequence")
|
||||||
ui.NORMAL, 'Set sequence to',
|
text.normal("Set sequence to")
|
||||||
ui.MONO, str(op.bump_to),
|
text.mono(str(op.bump_to))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_change_trust_op(ctx, op: StellarChangeTrustOp):
|
async def confirm_change_trust_op(ctx, op: StellarChangeTrustOp):
|
||||||
if op.limit == 0:
|
if op.limit == 0:
|
||||||
text = 'Delete Trust'
|
text = "Delete Trust"
|
||||||
else:
|
else:
|
||||||
text = 'Add Trust'
|
text = "Add Trust"
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, text,
|
text.bold(text)
|
||||||
ui.NORMAL, 'Asset: %s' % op.asset.code,
|
text.normal("Asset: %s" % op.asset.code)
|
||||||
ui.NORMAL, 'Amount: %s' % format_amount(op.limit, ticker=False),
|
text.normal("Amount: %s" % format_amount(op.limit, ticker=False))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
await confirm_asset_issuer(ctx, op.asset)
|
await confirm_asset_issuer(ctx, op.asset)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_create_account_op(ctx, op: StellarCreateAccountOp):
|
async def confirm_create_account_op(ctx, op: StellarCreateAccountOp):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Create Account',
|
text.bold("Create Account")
|
||||||
ui.NORMAL, 'with %s' % format_amount(op.starting_balance),
|
text.normal("with %s" % format_amount(op.starting_balance))
|
||||||
ui.MONO, *split(trim_to_rows(op.new_account, 3)),
|
text.mono(*split(trim_to_rows(op.new_account, 3)))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_create_passive_offer_op(ctx, op: StellarCreatePassiveOfferOp):
|
async def confirm_create_passive_offer_op(ctx, op: StellarCreatePassiveOfferOp):
|
||||||
if op.amount == 0:
|
if op.amount == 0:
|
||||||
text = 'Delete Passive Offer'
|
text = "Delete Passive Offer"
|
||||||
else:
|
else:
|
||||||
text = 'New Passive Offer'
|
text = "New Passive Offer"
|
||||||
await _confirm_offer(ctx, text, op)
|
await _confirm_offer(ctx, text, op)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_manage_offer_op(ctx, op: StellarManageOfferOp):
|
async def confirm_manage_offer_op(ctx, op: StellarManageOfferOp):
|
||||||
if op.offer_id == 0:
|
if op.offer_id == 0:
|
||||||
text = 'New Offer'
|
text = "New Offer"
|
||||||
else:
|
else:
|
||||||
if op.amount == 0:
|
if op.amount == 0:
|
||||||
text = 'Delete'
|
text = "Delete"
|
||||||
else:
|
else:
|
||||||
text = 'Update'
|
text = "Update"
|
||||||
text += ' #%d' % op.offer_id
|
text += " #%d" % op.offer_id
|
||||||
await _confirm_offer(ctx, text, op)
|
await _confirm_offer(ctx, text, op)
|
||||||
|
|
||||||
|
|
||||||
async def _confirm_offer(ctx, text, op):
|
async def _confirm_offer(ctx, text, op):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, text,
|
text.bold(text)
|
||||||
ui.NORMAL, 'Sell %s %s' % (format_amount(op.amount, ticker=False), op.selling_asset.code),
|
text.normal(
|
||||||
ui.NORMAL, 'For %f' % (op.price_n / op.price_d),
|
"Sell %s %s" % (format_amount(op.amount, ticker=False), op.selling_asset.code)
|
||||||
ui.NORMAL, 'Per %s' % format_asset_code(op.buying_asset),
|
)
|
||||||
icon_color=ui.GREEN)
|
text.normal("For %f" % (op.price_n / op.price_d))
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
text.normal("Per %s" % format_asset_code(op.buying_asset))
|
||||||
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await confirm_asset_issuer(ctx, op.selling_asset)
|
await confirm_asset_issuer(ctx, op.selling_asset)
|
||||||
await confirm_asset_issuer(ctx, op.buying_asset)
|
await confirm_asset_issuer(ctx, op.buying_asset)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_manage_data_op(ctx, op: StellarManageDataOp):
|
async def confirm_manage_data_op(ctx, op: StellarManageDataOp):
|
||||||
from trezor.crypto.hashlib import sha256
|
from trezor.crypto.hashlib import sha256
|
||||||
|
|
||||||
if op.value:
|
if op.value:
|
||||||
title = 'Set'
|
title = "Set"
|
||||||
else:
|
else:
|
||||||
title = 'Clear'
|
title = "Clear"
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, '%s data value key' % title,
|
text.bold("%s data value key" % title)
|
||||||
ui.MONO, *split(op.key),
|
text.mono(*split(op.key))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
if op.value:
|
if op.value:
|
||||||
digest = sha256(op.value).digest()
|
digest = sha256(op.value).digest()
|
||||||
digest_str = hexlify(digest).decode()
|
digest_str = hexlify(digest).decode()
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Value (SHA-256):',
|
text.bold("Value (SHA-256):")
|
||||||
ui.MONO, *split(digest_str),
|
text.mono(*split(digest_str))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
|
||||||
|
|
||||||
async def confirm_path_payment_op(ctx, op: StellarPathPaymentOp):
|
async def confirm_path_payment_op(ctx, op: StellarPathPaymentOp):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Path Pay %s' % format_amount(op.destination_amount, ticker=False),
|
text.bold("Path Pay %s" % format_amount(op.destination_amount, ticker=False))
|
||||||
ui.BOLD, '%s to:' % format_asset_code(op.destination_asset),
|
text.bold("%s to:" % format_asset_code(op.destination_asset))
|
||||||
ui.MONO, *split(trim_to_rows(op.destination_account, 3)),
|
text.mono(*split(trim_to_rows(op.destination_account, 3)))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
await confirm_asset_issuer(ctx, op.destination_asset)
|
await confirm_asset_issuer(ctx, op.destination_asset)
|
||||||
# confirm what the sender is using to pay
|
# confirm what the sender is using to pay
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.NORMAL, 'Pay using',
|
text.normal("Pay using")
|
||||||
ui.BOLD, format_amount(op.send_max, ticker=False),
|
text.bold(format_amount(op.send_max, ticker=False))
|
||||||
ui.BOLD, format_asset_code(op.send_asset),
|
text.bold(format_asset_code(op.send_asset))
|
||||||
ui.NORMAL, 'This amount is debited',
|
text.normal("This amount is debited")
|
||||||
ui.NORMAL, 'from your account.',
|
text.normal("from your account.")
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
await confirm_asset_issuer(ctx, op.send_asset)
|
await confirm_asset_issuer(ctx, op.send_asset)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_payment_op(ctx, op: StellarPaymentOp):
|
async def confirm_payment_op(ctx, op: StellarPaymentOp):
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Pay %s' % format_amount(op.amount, ticker=False),
|
text.bold("Pay %s" % format_amount(op.amount, ticker=False))
|
||||||
ui.BOLD, '%s to:' % format_asset_code(op.asset),
|
text.bold("%s to:" % format_asset_code(op.asset))
|
||||||
ui.MONO, *split(trim_to_rows(op.destination_account, 3)),
|
text.mono(*split(trim_to_rows(op.destination_account, 3)))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
await confirm_asset_issuer(ctx, op.asset)
|
await confirm_asset_issuer(ctx, op.asset)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_set_options_op(ctx, op: StellarSetOptionsOp):
|
async def confirm_set_options_op(ctx, op: StellarSetOptionsOp):
|
||||||
if op.inflation_destination_account:
|
if op.inflation_destination_account:
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Set Inflation Destination',
|
text.bold("Set Inflation Destination")
|
||||||
ui.MONO, *split(op.inflation_destination_account),
|
text.mono(*split(op.inflation_destination_account))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
if op.clear_flags:
|
if op.clear_flags:
|
||||||
text = _format_flags(op.clear_flags)
|
text = _format_flags(op.clear_flags)
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Clear Flags',
|
text.bold("Clear Flags")
|
||||||
ui.MONO, *text,
|
text.mono(*text)
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
if op.set_flags:
|
if op.set_flags:
|
||||||
text = _format_flags(op.set_flags)
|
text = _format_flags(op.set_flags)
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Set Flags',
|
text.bold("Set Flags")
|
||||||
ui.MONO, *text,
|
text.mono(*text)
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
thresholds = _format_thresholds(op)
|
thresholds = _format_thresholds(op)
|
||||||
if thresholds:
|
if thresholds:
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Account Thresholds',
|
text.bold("Account Thresholds")
|
||||||
ui.MONO, *thresholds,
|
text.mono(*thresholds)
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
if op.home_domain:
|
if op.home_domain:
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, 'Home Domain',
|
text.bold("Home Domain")
|
||||||
ui.MONO, *split(op.home_domain),
|
text.mono(*split(op.home_domain))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
if op.signer_type is not None:
|
if op.signer_type is not None:
|
||||||
if op.signer_weight > 0:
|
if op.signer_weight > 0:
|
||||||
text = 'Add Signer (%s)'
|
text = "Add Signer (%s)"
|
||||||
else:
|
else:
|
||||||
text = 'Remove Signer (%s)'
|
text = "Remove Signer (%s)"
|
||||||
if op.signer_type == consts.SIGN_TYPE_ACCOUNT:
|
if op.signer_type == consts.SIGN_TYPE_ACCOUNT:
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, text % 'acc',
|
text.bold(text % "acc")
|
||||||
ui.MONO, *split(op.signer_key),
|
text.mono(*split(op.signer_key))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
elif op.signer_type in (consts.SIGN_TYPE_PRE_AUTH, consts.SIGN_TYPE_HASH):
|
elif op.signer_type in (consts.SIGN_TYPE_PRE_AUTH, consts.SIGN_TYPE_HASH):
|
||||||
if op.signer_type == consts.SIGN_TYPE_PRE_AUTH:
|
if op.signer_type == consts.SIGN_TYPE_PRE_AUTH:
|
||||||
signer_type = 'auth'
|
signer_type = "auth"
|
||||||
else:
|
else:
|
||||||
signer_type = 'hash'
|
signer_type = "hash"
|
||||||
content = Text('Confirm operation', ui.ICON_CONFIRM,
|
text = Text("Confirm operation", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, text % signer_type,
|
text.bold(text % signer_type)
|
||||||
ui.MONO, *split(hexlify(op.signer_key).decode()),
|
text.mono(*split(hexlify(op.signer_key).decode()))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
else:
|
else:
|
||||||
raise ProcessError('Stellar: invalid signer type')
|
raise ProcessError("Stellar: invalid signer type")
|
||||||
|
|
||||||
|
|
||||||
def _format_thresholds(op: StellarSetOptionsOp) -> tuple:
|
def _format_thresholds(op: StellarSetOptionsOp) -> tuple:
|
||||||
text = ()
|
text = ()
|
||||||
if op.master_weight is not None:
|
if op.master_weight is not None:
|
||||||
text += ('Master Weight: %d' % op.master_weight, )
|
text += ("Master Weight: %d" % op.master_weight,)
|
||||||
if op.low_threshold is not None:
|
if op.low_threshold is not None:
|
||||||
text += ('Low: %d' % op.low_threshold, )
|
text += ("Low: %d" % op.low_threshold,)
|
||||||
if op.medium_threshold is not None:
|
if op.medium_threshold is not None:
|
||||||
text += ('Medium: %d' % op.medium_threshold, )
|
text += ("Medium: %d" % op.medium_threshold,)
|
||||||
if op.high_threshold is not None:
|
if op.high_threshold is not None:
|
||||||
text += ('High: %d' % op.high_threshold, )
|
text += ("High: %d" % op.high_threshold,)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def _format_flags(flags: int) -> tuple:
|
def _format_flags(flags: int) -> tuple:
|
||||||
if flags > consts.FLAGS_MAX_SIZE:
|
if flags > consts.FLAGS_MAX_SIZE:
|
||||||
raise ProcessError('Stellar: invalid flags')
|
raise ProcessError("Stellar: invalid flags")
|
||||||
text = ()
|
text = ()
|
||||||
if flags & consts.FLAG_AUTH_REQUIRED:
|
if flags & consts.FLAG_AUTH_REQUIRED:
|
||||||
text += ('AUTH_REQUIRED', )
|
text += ("AUTH_REQUIRED",)
|
||||||
if flags & consts.FLAG_AUTH_REVOCABLE:
|
if flags & consts.FLAG_AUTH_REVOCABLE:
|
||||||
text += ('AUTH_REVOCABLE', )
|
text += ("AUTH_REVOCABLE",)
|
||||||
if flags & consts.FLAG_AUTH_IMMUTABLE:
|
if flags & consts.FLAG_AUTH_IMMUTABLE:
|
||||||
text += ('AUTH_IMMUTABLE', )
|
text += ("AUTH_IMMUTABLE",)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def format_asset_code(asset: StellarAssetType) -> str:
|
def format_asset_code(asset: StellarAssetType) -> str:
|
||||||
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
|
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
|
||||||
return 'XLM (native)'
|
return "XLM (native)"
|
||||||
return asset.code
|
return asset.code
|
||||||
|
|
||||||
|
|
||||||
async def confirm_asset_issuer(ctx, asset: StellarAssetType):
|
async def confirm_asset_issuer(ctx, asset: StellarAssetType):
|
||||||
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
|
if asset is None or asset.type == consts.ASSET_TYPE_NATIVE:
|
||||||
return
|
return
|
||||||
content = Text('Confirm issuer', ui.ICON_CONFIRM,
|
text = Text("Confirm issuer", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
||||||
ui.BOLD, '%s issuer:' % asset.code,
|
text.bold("%s issuer:" % asset.code)
|
||||||
ui.MONO, *split(asset.issuer),
|
text.mono(*split(asset.issuer))
|
||||||
icon_color=ui.GREEN)
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||||
await require_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
from apps.stellar import writers
|
|
||||||
from apps.stellar import consts
|
|
||||||
from trezor.messages.StellarAccountMergeOp import StellarAccountMergeOp
|
from trezor.messages.StellarAccountMergeOp import StellarAccountMergeOp
|
||||||
from trezor.messages.StellarAssetType import StellarAssetType
|
|
||||||
from trezor.messages.StellarAllowTrustOp import StellarAllowTrustOp
|
from trezor.messages.StellarAllowTrustOp import StellarAllowTrustOp
|
||||||
|
from trezor.messages.StellarAssetType import StellarAssetType
|
||||||
from trezor.messages.StellarBumpSequenceOp import StellarBumpSequenceOp
|
from trezor.messages.StellarBumpSequenceOp import StellarBumpSequenceOp
|
||||||
from trezor.messages.StellarChangeTrustOp import StellarChangeTrustOp
|
from trezor.messages.StellarChangeTrustOp import StellarChangeTrustOp
|
||||||
from trezor.messages.StellarCreateAccountOp import StellarCreateAccountOp
|
from trezor.messages.StellarCreateAccountOp import StellarCreateAccountOp
|
||||||
@ -14,6 +12,8 @@ from trezor.messages.StellarPaymentOp import StellarPaymentOp
|
|||||||
from trezor.messages.StellarSetOptionsOp import StellarSetOptionsOp
|
from trezor.messages.StellarSetOptionsOp import StellarSetOptionsOp
|
||||||
from trezor.wire import ProcessError
|
from trezor.wire import ProcessError
|
||||||
|
|
||||||
|
from apps.stellar import consts, writers
|
||||||
|
|
||||||
|
|
||||||
def serialize_account_merge_op(w, msg: StellarAccountMergeOp):
|
def serialize_account_merge_op(w, msg: StellarAccountMergeOp):
|
||||||
writers.write_pubkey(w, msg.destination_account)
|
writers.write_pubkey(w, msg.destination_account)
|
||||||
@ -52,7 +52,7 @@ def serialize_create_passive_offer_op(w, msg: StellarCreatePassiveOfferOp):
|
|||||||
|
|
||||||
def serialize_manage_data_op(w, msg: StellarManageDataOp):
|
def serialize_manage_data_op(w, msg: StellarManageDataOp):
|
||||||
if len(msg.key) > 64:
|
if len(msg.key) > 64:
|
||||||
raise ProcessError('Stellar: max length of a key is 64 bytes')
|
raise ProcessError("Stellar: max length of a key is 64 bytes")
|
||||||
writers.write_string(w, msg.key)
|
writers.write_string(w, msg.key)
|
||||||
writers.write_bool(w, bool(msg.value))
|
writers.write_bool(w, bool(msg.value))
|
||||||
if msg.value:
|
if msg.value:
|
||||||
@ -124,7 +124,7 @@ def serialize_set_options_op(w, msg: StellarSetOptionsOp):
|
|||||||
writers.write_bool(w, bool(msg.home_domain))
|
writers.write_bool(w, bool(msg.home_domain))
|
||||||
if msg.home_domain:
|
if msg.home_domain:
|
||||||
if len(msg.home_domain) > 32:
|
if len(msg.home_domain) > 32:
|
||||||
raise ProcessError('Stellar: max length of a home domain is 32 bytes')
|
raise ProcessError("Stellar: max length of a home domain is 32 bytes")
|
||||||
writers.write_string(w, msg.home_domain)
|
writers.write_string(w, msg.home_domain)
|
||||||
|
|
||||||
# signer
|
# signer
|
||||||
@ -154,7 +154,7 @@ def _serialize_asset_code(w, asset_type: int, asset_code: str):
|
|||||||
# pad with zeros to 12 chars
|
# pad with zeros to 12 chars
|
||||||
writers.write_bytes(w, code + bytearray([0] * (12 - len(code))))
|
writers.write_bytes(w, code + bytearray([0] * (12 - len(code))))
|
||||||
else:
|
else:
|
||||||
raise ProcessError('Stellar: invalid asset type')
|
raise ProcessError("Stellar: invalid asset type")
|
||||||
|
|
||||||
|
|
||||||
def _serialize_asset(w, asset: StellarAssetType):
|
def _serialize_asset(w, asset: StellarAssetType):
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
from apps.common import seed
|
from ubinascii import hexlify
|
||||||
from apps.stellar import writers
|
|
||||||
from apps.stellar.operations import operation
|
|
||||||
from apps.stellar import helpers
|
|
||||||
from apps.stellar import layout
|
|
||||||
from apps.stellar import consts
|
|
||||||
from trezor.wire import ProcessError
|
|
||||||
from trezor.messages.StellarSignTx import StellarSignTx
|
|
||||||
from trezor.messages.StellarTxOpRequest import StellarTxOpRequest
|
|
||||||
from trezor.messages.StellarSignedTx import StellarSignedTx
|
|
||||||
from trezor.crypto.curve import ed25519
|
from trezor.crypto.curve import ed25519
|
||||||
from trezor.crypto.hashlib import sha256
|
from trezor.crypto.hashlib import sha256
|
||||||
from ubinascii import hexlify
|
from trezor.messages.StellarSignedTx import StellarSignedTx
|
||||||
|
from trezor.messages.StellarSignTx import StellarSignTx
|
||||||
|
from trezor.messages.StellarTxOpRequest import StellarTxOpRequest
|
||||||
|
from trezor.wire import ProcessError
|
||||||
|
|
||||||
|
from apps.common import seed
|
||||||
|
from apps.stellar import consts, helpers, layout, writers
|
||||||
|
from apps.stellar.operations import operation
|
||||||
|
|
||||||
|
|
||||||
async def sign_tx(ctx, msg: StellarSignTx):
|
async def sign_tx(ctx, msg: StellarSignTx):
|
||||||
if msg.num_operations == 0:
|
if msg.num_operations == 0:
|
||||||
raise ProcessError('Stellar: At least one operation is required')
|
raise ProcessError("Stellar: At least one operation is required")
|
||||||
|
|
||||||
node = await seed.derive_node(ctx, msg.address_n, consts.STELLAR_CURVE)
|
node = await seed.derive_node(ctx, msg.address_n, consts.STELLAR_CURVE)
|
||||||
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
pubkey = seed.remove_ed25519_prefix(node.public_key())
|
||||||
@ -50,7 +49,7 @@ async def _init(ctx, w: bytearray, pubkey: bytes, msg: StellarSignTx):
|
|||||||
address = helpers.address_from_public_key(pubkey)
|
address = helpers.address_from_public_key(pubkey)
|
||||||
writers.write_pubkey(w, address)
|
writers.write_pubkey(w, address)
|
||||||
if helpers.public_key_from_address(msg.source_account) != pubkey:
|
if helpers.public_key_from_address(msg.source_account) != pubkey:
|
||||||
raise ProcessError('Stellar: source account does not match address_n')
|
raise ProcessError("Stellar: source account does not match address_n")
|
||||||
writers.write_uint32(w, msg.fee)
|
writers.write_uint32(w, msg.fee)
|
||||||
writers.write_uint64(w, msg.sequence_number)
|
writers.write_uint64(w, msg.sequence_number)
|
||||||
|
|
||||||
@ -80,11 +79,11 @@ async def _memo(ctx, w: bytearray, msg: StellarSignTx):
|
|||||||
writers.write_uint32(w, msg.memo_type)
|
writers.write_uint32(w, msg.memo_type)
|
||||||
if msg.memo_type == consts.MEMO_TYPE_NONE:
|
if msg.memo_type == consts.MEMO_TYPE_NONE:
|
||||||
# nothing is serialized
|
# nothing is serialized
|
||||||
memo_confirm_text = ''
|
memo_confirm_text = ""
|
||||||
elif msg.memo_type == consts.MEMO_TYPE_TEXT:
|
elif msg.memo_type == consts.MEMO_TYPE_TEXT:
|
||||||
# Text: 4 bytes (size) + up to 28 bytes
|
# Text: 4 bytes (size) + up to 28 bytes
|
||||||
if len(msg.memo_text) > 28:
|
if len(msg.memo_text) > 28:
|
||||||
raise ProcessError('Stellar: max length of a memo text is 28 bytes')
|
raise ProcessError("Stellar: max length of a memo text is 28 bytes")
|
||||||
writers.write_string(w, msg.memo_text)
|
writers.write_string(w, msg.memo_text)
|
||||||
memo_confirm_text = msg.memo_text
|
memo_confirm_text = msg.memo_text
|
||||||
elif msg.memo_type == consts.MEMO_TYPE_ID:
|
elif msg.memo_type == consts.MEMO_TYPE_ID:
|
||||||
@ -96,7 +95,7 @@ async def _memo(ctx, w: bytearray, msg: StellarSignTx):
|
|||||||
writers.write_bytes(w, bytearray(msg.memo_hash))
|
writers.write_bytes(w, bytearray(msg.memo_hash))
|
||||||
memo_confirm_text = hexlify(msg.memo_hash).decode()
|
memo_confirm_text = hexlify(msg.memo_hash).decode()
|
||||||
else:
|
else:
|
||||||
raise ProcessError('Stellar invalid memo type')
|
raise ProcessError("Stellar invalid memo type")
|
||||||
await layout.require_confirm_memo(ctx, msg.memo_type, memo_confirm_text)
|
await layout.require_confirm_memo(ctx, msg.memo_type, memo_confirm_text)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import ustruct
|
import ustruct
|
||||||
|
|
||||||
from .helpers import public_key_from_address
|
from .helpers import public_key_from_address
|
||||||
|
|
||||||
|
|
||||||
def write_uint32(w, n: int):
|
def write_uint32(w, n: int):
|
||||||
write_bytes(w, ustruct.pack('>L', n))
|
write_bytes(w, ustruct.pack(">L", n))
|
||||||
|
|
||||||
|
|
||||||
def write_uint64(w, n: int):
|
def write_uint64(w, n: int):
|
||||||
write_bytes(w, ustruct.pack('>Q', n))
|
write_bytes(w, ustruct.pack(">Q", n))
|
||||||
|
|
||||||
|
|
||||||
def write_string(w, s: str):
|
def write_string(w, s: str):
|
||||||
|
Loading…
Reference in New Issue
Block a user