mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-11 16:00:57 +00:00
core/bitcoin: finalize bitcoin refactor
- core/bitcoin: move common files to the app's root - core/bitcoin: use require_confirm instead of confirm - core: move bitcoin unrelated functions from 'bitcoin' to a new 'misc' app - core/bitcoin: use relative imports inside the app - core: rename wallet app to bitcoin - core/wallet: replace SigningErrors and the other exception classes with wire.Errors
This commit is contained in:
parent
aa52fc3903
commit
445f56d387
@ -492,11 +492,13 @@ if FROZEN:
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*/*.py',
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py',
|
||||
exclude=[
|
||||
SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py',
|
||||
SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py',
|
||||
])
|
||||
)
|
||||
|
||||
@ -540,8 +542,9 @@ if FROZEN:
|
||||
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py'))
|
||||
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py'))
|
||||
|
||||
source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY)
|
||||
|
||||
|
@ -460,11 +460,13 @@ if FROZEN:
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/homescreen/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/management/*/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/*/*.py',
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/misc/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/*/*.py',
|
||||
exclude=[
|
||||
SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py',
|
||||
SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py',
|
||||
SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py',
|
||||
])
|
||||
)
|
||||
|
||||
@ -508,8 +510,9 @@ if FROZEN:
|
||||
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py'))
|
||||
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/decred.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/wallet/sign_tx/zcash.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py'))
|
||||
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash.py'))
|
||||
|
||||
source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY)
|
||||
|
||||
|
@ -5,10 +5,6 @@ from trezor.messages import MessageType
|
||||
def boot() -> None:
|
||||
wire.add(MessageType.GetPublicKey, __name__, "get_public_key")
|
||||
wire.add(MessageType.GetAddress, __name__, "get_address")
|
||||
wire.add(MessageType.GetEntropy, __name__, "get_entropy")
|
||||
wire.add(MessageType.SignTx, __name__, "sign_tx")
|
||||
wire.add(MessageType.SignMessage, __name__, "sign_message")
|
||||
wire.add(MessageType.VerifyMessage, __name__, "verify_message")
|
||||
wire.add(MessageType.SignIdentity, __name__, "sign_identity")
|
||||
wire.add(MessageType.GetECDHSessionKey, __name__, "get_ecdh_session_key")
|
||||
wire.add(MessageType.CipherKeyValue, __name__, "cipher_key_value")
|
@ -1,31 +1,21 @@
|
||||
from micropython import const
|
||||
|
||||
from trezor.crypto import base58, bech32, cashaddr
|
||||
from trezor import wire
|
||||
from trezor.crypto import base58, cashaddr
|
||||
from trezor.crypto.hashlib import sha256
|
||||
from trezor.messages import FailureType, InputScriptType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType
|
||||
from trezor.utils import ensure
|
||||
|
||||
from .common import ecdsa_hash_pubkey, encode_bech32_address
|
||||
from .multisig import multisig_get_pubkeys, multisig_pubkey_index
|
||||
from .scripts import output_script_multisig, output_script_native_p2wpkh_or_p2wsh
|
||||
|
||||
from apps.common import HARDENED, address_type, paths
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.wallet.sign_tx.multisig import multisig_get_pubkeys, multisig_pubkey_index
|
||||
from apps.wallet.sign_tx.scripts import (
|
||||
output_script_multisig,
|
||||
output_script_native_p2wpkh_or_p2wsh,
|
||||
)
|
||||
|
||||
if False:
|
||||
from typing import List
|
||||
from trezor.crypto import bip32
|
||||
from trezor.messages.TxInputType import EnumTypeInputScriptType
|
||||
|
||||
# supported witness version for bech32 addresses
|
||||
_BECH32_WITVER = const(0x00)
|
||||
|
||||
|
||||
class AddressError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_address(
|
||||
script_type: EnumTypeInputScriptType,
|
||||
@ -42,11 +32,9 @@ def get_address(
|
||||
pubkey = node.public_key()
|
||||
index = multisig_pubkey_index(multisig, pubkey)
|
||||
if index is None:
|
||||
raise AddressError(FailureType.ProcessError, "Public key not found")
|
||||
raise wire.ProcessError("Public key not found")
|
||||
if coin.address_type_p2sh is None:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Multisig not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Multisig not enabled on this coin")
|
||||
|
||||
pubkeys = multisig_get_pubkeys(multisig)
|
||||
address = address_multisig_p2sh(pubkeys, multisig.m, coin)
|
||||
@ -54,7 +42,7 @@ def get_address(
|
||||
address = address_to_cashaddr(address, coin)
|
||||
return address
|
||||
if script_type == InputScriptType.SPENDMULTISIG:
|
||||
raise AddressError(FailureType.ProcessError, "Multisig details required")
|
||||
raise wire.ProcessError("Multisig details required")
|
||||
|
||||
# p2pkh
|
||||
address = node.address(coin.address_type)
|
||||
@ -64,9 +52,7 @@ def get_address(
|
||||
|
||||
elif script_type == InputScriptType.SPENDWITNESS: # native p2wpkh or native p2wsh
|
||||
if not coin.segwit or not coin.bech32_prefix:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Segwit not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Segwit not enabled on this coin")
|
||||
# native p2wsh multisig
|
||||
if multisig is not None:
|
||||
pubkeys = multisig_get_pubkeys(multisig)
|
||||
@ -79,9 +65,7 @@ def get_address(
|
||||
script_type == InputScriptType.SPENDP2SHWITNESS
|
||||
): # p2wpkh or p2wsh nested in p2sh
|
||||
if not coin.segwit or coin.address_type_p2sh is None:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Segwit not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Segwit not enabled on this coin")
|
||||
# p2wsh multisig nested in p2sh
|
||||
if multisig is not None:
|
||||
pubkeys = multisig_get_pubkeys(multisig)
|
||||
@ -91,14 +75,12 @@ def get_address(
|
||||
return address_p2wpkh_in_p2sh(node.public_key(), coin)
|
||||
|
||||
else:
|
||||
raise AddressError(FailureType.ProcessError, "Invalid script type")
|
||||
raise wire.ProcessError("Invalid script type")
|
||||
|
||||
|
||||
def address_multisig_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str:
|
||||
if coin.address_type_p2sh is None:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Multisig not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Multisig not enabled on this coin")
|
||||
redeem_script = output_script_multisig(pubkeys, m)
|
||||
redeem_script_hash = coin.script_hash(redeem_script)
|
||||
return address_p2sh(redeem_script_hash, coin)
|
||||
@ -106,9 +88,7 @@ def address_multisig_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str:
|
||||
|
||||
def address_multisig_p2wsh_in_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo) -> str:
|
||||
if coin.address_type_p2sh is None:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Multisig not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Multisig not enabled on this coin")
|
||||
witness_script = output_script_multisig(pubkeys, m)
|
||||
witness_script_hash = sha256(witness_script).digest()
|
||||
return address_p2wsh_in_p2sh(witness_script_hash, coin)
|
||||
@ -116,9 +96,7 @@ def address_multisig_p2wsh_in_p2sh(pubkeys: List[bytes], m: int, coin: CoinInfo)
|
||||
|
||||
def address_multisig_p2wsh(pubkeys: List[bytes], m: int, hrp: str) -> str:
|
||||
if not hrp:
|
||||
raise AddressError(
|
||||
FailureType.ProcessError, "Multisig not enabled on this coin"
|
||||
)
|
||||
raise wire.ProcessError("Multisig not enabled on this coin")
|
||||
witness_script = output_script_multisig(pubkeys, m)
|
||||
witness_script_hash = sha256(witness_script).digest()
|
||||
return address_p2wsh(witness_script_hash, hrp)
|
||||
@ -149,24 +127,11 @@ def address_p2wsh_in_p2sh(witness_script_hash: bytes, coin: CoinInfo) -> str:
|
||||
|
||||
def address_p2wpkh(pubkey: bytes, coin: CoinInfo) -> str:
|
||||
pubkeyhash = ecdsa_hash_pubkey(pubkey, coin)
|
||||
address = bech32.encode(coin.bech32_prefix, _BECH32_WITVER, pubkeyhash)
|
||||
if address is None:
|
||||
raise AddressError(FailureType.ProcessError, "Invalid address")
|
||||
return address
|
||||
return encode_bech32_address(coin.bech32_prefix, pubkeyhash)
|
||||
|
||||
|
||||
def address_p2wsh(witness_script_hash: bytes, hrp: str) -> str:
|
||||
address = bech32.encode(hrp, _BECH32_WITVER, witness_script_hash)
|
||||
if address is None:
|
||||
raise AddressError(FailureType.ProcessError, "Invalid address")
|
||||
return address
|
||||
|
||||
|
||||
def decode_bech32_address(prefix: str, address: str) -> bytes:
|
||||
witver, raw = bech32.decode(prefix, address)
|
||||
if witver != _BECH32_WITVER:
|
||||
raise AddressError(FailureType.ProcessError, "Invalid address witness program")
|
||||
return bytes(raw)
|
||||
return encode_bech32_address(hrp, witness_script_hash)
|
||||
|
||||
|
||||
def address_to_cashaddr(address: str, coin: CoinInfo) -> str:
|
||||
@ -181,17 +146,6 @@ def address_to_cashaddr(address: str, coin: CoinInfo) -> str:
|
||||
return cashaddr.encode(coin.cashaddr_prefix, version, data)
|
||||
|
||||
|
||||
def ecdsa_hash_pubkey(pubkey: bytes, coin: CoinInfo) -> bytes:
|
||||
if pubkey[0] == 0x04:
|
||||
ensure(len(pubkey) == 65) # uncompressed format
|
||||
elif pubkey[0] == 0x00:
|
||||
ensure(len(pubkey) == 1) # point at infinity
|
||||
else:
|
||||
ensure(len(pubkey) == 33) # compresssed format
|
||||
|
||||
return coin.script_hash(pubkey)
|
||||
|
||||
|
||||
def address_short(coin: CoinInfo, address: str) -> str:
|
||||
if coin.cashaddr_prefix is not None and address.startswith(
|
||||
coin.cashaddr_prefix + ":"
|
42
core/src/apps/bitcoin/common.py
Normal file
42
core/src/apps/bitcoin/common.py
Normal file
@ -0,0 +1,42 @@
|
||||
from micropython import const
|
||||
|
||||
from trezor import wire
|
||||
from trezor.crypto import bech32, bip32, der
|
||||
from trezor.crypto.curve import secp256k1
|
||||
from trezor.utils import ensure
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
|
||||
# supported witness version for bech32 addresses
|
||||
_BECH32_WITVER = const(0x00)
|
||||
|
||||
|
||||
def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes:
|
||||
sig = secp256k1.sign(node.private_key(), digest)
|
||||
sigder = der.encode_seq((sig[1:33], sig[33:65]))
|
||||
return sigder
|
||||
|
||||
|
||||
def ecdsa_hash_pubkey(pubkey: bytes, coin: CoinInfo) -> bytes:
|
||||
if pubkey[0] == 0x04:
|
||||
ensure(len(pubkey) == 65) # uncompressed format
|
||||
elif pubkey[0] == 0x00:
|
||||
ensure(len(pubkey) == 1) # point at infinity
|
||||
else:
|
||||
ensure(len(pubkey) == 33) # compresssed format
|
||||
|
||||
return coin.script_hash(pubkey)
|
||||
|
||||
|
||||
def encode_bech32_address(prefix: str, script: bytes) -> bytes:
|
||||
address = bech32.encode(prefix, _BECH32_WITVER, script)
|
||||
if address is None:
|
||||
raise wire.ProcessError("Invalid address")
|
||||
return address
|
||||
|
||||
|
||||
def decode_bech32_address(prefix: str, address: str) -> bytes:
|
||||
witver, raw = bech32.decode(prefix, address)
|
||||
if witver != _BECH32_WITVER:
|
||||
raise wire.ProcessError("Invalid address witness program")
|
||||
return bytes(raw)
|
@ -2,9 +2,9 @@ from trezor.crypto import bip32
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages.Address import Address
|
||||
|
||||
from . import addresses
|
||||
from .keychain import with_keychain
|
||||
from .sign_tx import addresses
|
||||
from .sign_tx.multisig import multisig_pubkey_index
|
||||
from .multisig import multisig_pubkey_index
|
||||
|
||||
from apps.common.layout import address_n_to_str, show_address, show_qr, show_xpub
|
||||
from apps.common.paths import validate_path
|
@ -1,20 +1,16 @@
|
||||
from trezor import wire
|
||||
from trezor.crypto import bip32
|
||||
from trezor.crypto.hashlib import sha256
|
||||
from trezor.messages import FailureType
|
||||
from trezor.messages.HDNodeType import HDNodeType
|
||||
from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.wallet.sign_tx.writers import write_bytes_fixed, write_uint32
|
||||
from .writers import write_bytes_fixed, write_uint32
|
||||
|
||||
if False:
|
||||
from typing import List
|
||||
|
||||
|
||||
class MultisigError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def multisig_fingerprint(multisig: MultisigRedeemScriptType) -> bytes:
|
||||
if multisig.nodes:
|
||||
pubnodes = multisig.nodes
|
||||
@ -24,11 +20,11 @@ def multisig_fingerprint(multisig: MultisigRedeemScriptType) -> bytes:
|
||||
n = len(pubnodes)
|
||||
|
||||
if n < 1 or n > 15 or m < 1 or m > 15:
|
||||
raise MultisigError(FailureType.DataError, "Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
|
||||
for d in pubnodes:
|
||||
if len(d.public_key) != 33 or len(d.chain_code) != 32:
|
||||
raise MultisigError(FailureType.DataError, "Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
|
||||
# casting to bytes(), sorting on bytearray() is not supported in MicroPython
|
||||
pubnodes = sorted(pubnodes, key=lambda n: bytes(n.public_key))
|
||||
@ -55,7 +51,7 @@ def multisig_pubkey_index(multisig: MultisigRedeemScriptType, pubkey: bytes) ->
|
||||
for i, hd in enumerate(multisig.pubkeys):
|
||||
if multisig_get_pubkey(hd.node, hd.address_n) == pubkey:
|
||||
return i
|
||||
raise MultisigError(FailureType.DataError, "Pubkey not found in multisig script")
|
||||
raise wire.DataError("Pubkey not found in multisig script")
|
||||
|
||||
|
||||
def multisig_get_pubkey(n: HDNodeType, p: list) -> bytes:
|
@ -1,34 +1,30 @@
|
||||
from trezor import utils
|
||||
from trezor import utils, wire
|
||||
from trezor.crypto import base58, cashaddr
|
||||
from trezor.crypto.hashlib import sha256
|
||||
from trezor.messages import FailureType, InputScriptType, OutputScriptType
|
||||
from trezor.messages import InputScriptType, OutputScriptType
|
||||
from trezor.messages.MultisigRedeemScriptType import MultisigRedeemScriptType
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
from trezor.messages.TxOutputType import TxOutputType
|
||||
|
||||
from apps.common import address_type
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.writers import empty_bytearray
|
||||
from apps.wallet.sign_tx import addresses
|
||||
from apps.wallet.sign_tx.multisig import (
|
||||
from apps.common.writers import empty_bytearray, write_bitcoin_varint
|
||||
|
||||
from . import common
|
||||
from .multisig import (
|
||||
multisig_get_pubkey_count,
|
||||
multisig_get_pubkeys,
|
||||
multisig_pubkey_index,
|
||||
)
|
||||
from apps.wallet.sign_tx.writers import (
|
||||
from .writers import (
|
||||
write_bytes_fixed,
|
||||
write_bytes_unchecked,
|
||||
write_op_push,
|
||||
write_varint,
|
||||
)
|
||||
|
||||
if False:
|
||||
from typing import List, Optional
|
||||
from apps.wallet.sign_tx.writers import Writer
|
||||
|
||||
|
||||
class ScriptsError(ValueError):
|
||||
pass
|
||||
from .writers import Writer
|
||||
|
||||
|
||||
def input_derive_script(
|
||||
@ -54,7 +50,7 @@ def input_derive_script(
|
||||
return input_script_p2wsh_in_p2sh(witness_script_hash)
|
||||
|
||||
# p2wpkh in p2sh
|
||||
return input_script_p2wpkh_in_p2sh(addresses.ecdsa_hash_pubkey(pubkey, coin))
|
||||
return input_script_p2wpkh_in_p2sh(common.ecdsa_hash_pubkey(pubkey, coin))
|
||||
elif txi.script_type == InputScriptType.SPENDWITNESS:
|
||||
# native p2wpkh or p2wsh
|
||||
return input_script_native_p2wpkh_or_p2wsh()
|
||||
@ -65,7 +61,7 @@ def input_derive_script(
|
||||
txi.multisig, signature, signature_index, hash_type, coin
|
||||
)
|
||||
else:
|
||||
raise ScriptsError(FailureType.ProcessError, "Invalid script type")
|
||||
raise wire.ProcessError("Invalid script type")
|
||||
|
||||
|
||||
def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes:
|
||||
@ -74,7 +70,7 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes:
|
||||
|
||||
if coin.bech32_prefix and txo.address.startswith(coin.bech32_prefix):
|
||||
# p2wpkh or p2wsh
|
||||
witprog = addresses.decode_bech32_address(coin.bech32_prefix, txo.address)
|
||||
witprog = common.decode_bech32_address(coin.bech32_prefix, txo.address)
|
||||
return output_script_native_p2wpkh_or_p2wsh(witprog)
|
||||
|
||||
if (
|
||||
@ -89,13 +85,13 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes:
|
||||
elif version == cashaddr.ADDRESS_TYPE_P2SH:
|
||||
version = coin.address_type_p2sh
|
||||
else:
|
||||
raise ScriptsError("Unknown cashaddr address type")
|
||||
raise wire.DataError("Unknown cashaddr address type")
|
||||
raw_address = bytes([version]) + data
|
||||
else:
|
||||
try:
|
||||
raw_address = base58.decode_check(txo.address, coin.b58_hash)
|
||||
except ValueError:
|
||||
raise ScriptsError(FailureType.DataError, "Invalid address")
|
||||
raise wire.DataError("Invalid address")
|
||||
|
||||
if address_type.check(coin.address_type, raw_address):
|
||||
# p2pkh
|
||||
@ -108,7 +104,7 @@ def output_derive_script(txo: TxOutputType, coin: CoinInfo) -> bytes:
|
||||
script = output_script_p2sh(scripthash)
|
||||
return script
|
||||
|
||||
raise ScriptsError(FailureType.DataError, "Invalid address type")
|
||||
raise wire.DataError("Invalid address type")
|
||||
|
||||
|
||||
# see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification
|
||||
@ -131,9 +127,7 @@ def bip143_derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray:
|
||||
return output_script_p2pkh(pubkeyhash)
|
||||
|
||||
else:
|
||||
raise ScriptsError(
|
||||
FailureType.DataError, "Unknown input script type for bip143 script code",
|
||||
)
|
||||
raise wire.DataError("Unknown input script type for bip143 script code")
|
||||
|
||||
|
||||
# P2PKH, P2SH
|
||||
@ -238,7 +232,7 @@ def input_script_p2wsh_in_p2sh(script_hash: bytes) -> bytearray:
|
||||
# Signature is moved to the witness.
|
||||
|
||||
if len(script_hash) != 32:
|
||||
raise ScriptsError("Redeem script hash should be 32 bytes long")
|
||||
raise wire.DataError("Redeem script hash should be 32 bytes long")
|
||||
|
||||
w = empty_bytearray(3 + len(script_hash))
|
||||
w.append(0x22) # length of the data
|
||||
@ -272,7 +266,7 @@ def witness_p2wsh(
|
||||
)
|
||||
# fill in our signature
|
||||
if signatures[signature_index]:
|
||||
raise ScriptsError("Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
signatures[signature_index] = signature
|
||||
|
||||
# filter empty
|
||||
@ -324,7 +318,7 @@ def input_script_multisig(
|
||||
) -> bytearray:
|
||||
signatures = multisig.signatures # other signatures
|
||||
if len(signatures[signature_index]) > 0:
|
||||
raise ScriptsError("Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
signatures[signature_index] = signature # our signature
|
||||
|
||||
# length of the redeem script
|
||||
@ -367,10 +361,10 @@ def output_script_multisig(pubkeys: List[bytes], m: int) -> bytearray:
|
||||
def write_output_script_multisig(w: Writer, pubkeys: List[bytes], m: int) -> None:
|
||||
n = len(pubkeys)
|
||||
if n < 1 or n > 15 or m < 1 or m > 15 or m > n:
|
||||
raise ScriptsError("Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
for pubkey in pubkeys:
|
||||
if len(pubkey) != 33:
|
||||
raise ScriptsError("Invalid multisig parameters")
|
||||
raise wire.DataError("Invalid multisig parameters")
|
||||
|
||||
w.append(0x50 + m) # numbers 1 to 16 are pushed as 0x50 + value
|
||||
for p in pubkeys:
|
@ -3,8 +3,8 @@ from trezor.crypto.curve import secp256k1
|
||||
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
||||
from trezor.messages.MessageSignature import MessageSignature
|
||||
|
||||
from .addresses import get_address, validate_full_path
|
||||
from .keychain import with_keychain
|
||||
from .sign_tx.addresses import get_address, validate_full_path
|
||||
|
||||
from apps.common.paths import validate_path
|
||||
from apps.common.signverify import message_digest, require_confirm_sign_message
|
@ -5,12 +5,12 @@ from trezor.messages.TxAck import TxAck
|
||||
from trezor.messages.TxRequest import TxRequest
|
||||
|
||||
from ..keychain import with_keychain
|
||||
from . import addresses, bitcoin, common, helpers, layout, multisig, progress, scripts
|
||||
from . import bitcoin, helpers, layout, progress
|
||||
|
||||
from apps.common import coininfo, paths, seed
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
from apps.wallet.sign_tx import bitcoinlike, decred, zcash
|
||||
from . import bitcoinlike, decred, zcash
|
||||
|
||||
if False:
|
||||
from typing import Type, Union
|
||||
@ -36,22 +36,11 @@ async def sign_tx(
|
||||
else:
|
||||
signer_class = bitcoin.Bitcoin
|
||||
|
||||
try:
|
||||
signer = signer_class(msg, keychain, coin).signer()
|
||||
except common.SigningError as e:
|
||||
raise wire.Error(*e.args)
|
||||
signer = signer_class(msg, keychain, coin).signer()
|
||||
|
||||
res = None # type: Union[TxAck, bool, None]
|
||||
while True:
|
||||
try:
|
||||
req = signer.send(res)
|
||||
except (
|
||||
common.SigningError,
|
||||
multisig.MultisigError,
|
||||
addresses.AddressError,
|
||||
scripts.ScriptsError,
|
||||
) as e:
|
||||
raise wire.Error(*e.args)
|
||||
req = signer.send(res)
|
||||
if isinstance(req, TxRequest):
|
||||
if req.request_type == TXFINISHED:
|
||||
break
|
@ -1,8 +1,9 @@
|
||||
import gc
|
||||
from micropython import const
|
||||
|
||||
from trezor import wire
|
||||
from trezor.crypto.hashlib import sha256
|
||||
from trezor.messages import FailureType, InputScriptType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TransactionType import TransactionType
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
@ -14,17 +15,12 @@ from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
|
||||
from trezor.utils import HashWriter, ensure
|
||||
|
||||
from apps.common import coininfo, seed
|
||||
from apps.wallet.sign_tx import (
|
||||
addresses,
|
||||
helpers,
|
||||
multisig,
|
||||
progress,
|
||||
scripts,
|
||||
tx_weight,
|
||||
writers,
|
||||
)
|
||||
from apps.wallet.sign_tx.common import SigningError, ecdsa_sign
|
||||
from apps.wallet.sign_tx.matchcheck import MultisigFingerprintChecker, WalletPathChecker
|
||||
from apps.common.writers import write_bitcoin_varint
|
||||
|
||||
from .. import addresses, multisig, scripts, writers
|
||||
from ..common import ecdsa_hash_pubkey, ecdsa_sign
|
||||
from . import helpers, progress, tx_weight
|
||||
from .matchcheck import MultisigFingerprintChecker, WalletPathChecker
|
||||
|
||||
if False:
|
||||
from typing import Set, Tuple, Union
|
||||
@ -136,17 +132,10 @@ class Bitcoin:
|
||||
|
||||
# fee > (coin.maxfee per byte * tx size)
|
||||
if fee > (self.coin.maxfee_kb / 1000) * (self.weight.get_total() / 4):
|
||||
if not await helpers.confirm_feeoverthreshold(fee, self.coin):
|
||||
raise SigningError(FailureType.ActionCancelled, "Signing cancelled")
|
||||
|
||||
await helpers.confirm_feeoverthreshold(fee, self.coin)
|
||||
if self.tx.lock_time > 0:
|
||||
if not await helpers.confirm_nondefault_locktime(self.tx.lock_time):
|
||||
raise SigningError(FailureType.ActionCancelled, "Locktime cancelled")
|
||||
|
||||
if not await helpers.confirm_total(
|
||||
self.total_in - self.change_out, fee, self.coin
|
||||
):
|
||||
raise SigningError(FailureType.ActionCancelled, "Total cancelled")
|
||||
await helpers.confirm_nondefault_locktime(self.tx.lock_time)
|
||||
await helpers.confirm_total(self.total_in - self.change_out, fee, self.coin)
|
||||
|
||||
async def step4_serialize_inputs(self) -> None:
|
||||
self.write_tx_header(self.serialized_tx, self.tx, bool(self.segwit))
|
||||
@ -193,7 +182,7 @@ class Bitcoin:
|
||||
elif input_is_nonsegwit(txi):
|
||||
await self.process_nonsegwit_input(txi)
|
||||
else:
|
||||
raise SigningError(FailureType.DataError, "Wrong input script type")
|
||||
raise wire.DataError("Wrong input script type")
|
||||
|
||||
async def process_segwit_input(self, txi: TxInputType) -> None:
|
||||
await self.process_bip143_input(txi)
|
||||
@ -205,7 +194,7 @@ class Bitcoin:
|
||||
|
||||
async def process_bip143_input(self, txi: TxInputType) -> None:
|
||||
if not txi.amount:
|
||||
raise SigningError(FailureType.DataError, "Expected input with amount")
|
||||
raise wire.DataError("Expected input with amount")
|
||||
self.bip143_in += txi.amount
|
||||
self.total_in += txi.amount
|
||||
|
||||
@ -213,24 +202,22 @@ class Bitcoin:
|
||||
if self.change_out == 0 and self.output_is_change(txo):
|
||||
# output is change and does not need confirmation
|
||||
self.change_out = txo.amount
|
||||
elif not await helpers.confirm_output(txo, self.coin):
|
||||
raise SigningError(FailureType.ActionCancelled, "Output cancelled")
|
||||
else:
|
||||
await helpers.confirm_output(txo, self.coin)
|
||||
|
||||
self.write_tx_output(self.h_confirmed, txo, script_pubkey)
|
||||
self.hash143_add_output(txo, script_pubkey)
|
||||
self.total_out += txo.amount
|
||||
|
||||
def on_negative_fee(self) -> None:
|
||||
raise SigningError(FailureType.NotEnoughFunds, "Not enough funds")
|
||||
raise wire.NotEnoughFunds("Not enough funds")
|
||||
|
||||
async def serialize_segwit_input(self, i: int) -> None:
|
||||
# STAGE_REQUEST_SEGWIT_INPUT in legacy
|
||||
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
|
||||
|
||||
if not input_is_segwit(txi):
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
self.wallet_path.check_input(txi)
|
||||
# NOTE: No need to check the multisig fingerprint, because we won't be signing
|
||||
# the script here. Signatures are produced in STAGE_REQUEST_SEGWIT_WITNESS.
|
||||
@ -245,15 +232,13 @@ class Bitcoin:
|
||||
self.multisig_fingerprint.check_input(txi)
|
||||
|
||||
if txi.amount > self.bip143_in:
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
self.bip143_in -= txi.amount
|
||||
|
||||
node = self.keychain.derive(txi.address_n)
|
||||
public_key = node.public_key()
|
||||
hash143_hash = self.hash143_preimage_hash(
|
||||
txi, addresses.ecdsa_hash_pubkey(public_key, self.coin)
|
||||
txi, ecdsa_hash_pubkey(public_key, self.coin)
|
||||
)
|
||||
|
||||
signature = ecdsa_sign(node, hash143_hash)
|
||||
@ -265,9 +250,7 @@ class Bitcoin:
|
||||
txi = await helpers.request_tx_input(self.tx_req, i, self.coin)
|
||||
|
||||
if not input_is_segwit(txi):
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
|
||||
public_key, signature = self.sign_bip143_input(txi)
|
||||
|
||||
@ -318,9 +301,7 @@ class Bitcoin:
|
||||
addresses.ecdsa_hash_pubkey(key_sign_pub, self.coin)
|
||||
)
|
||||
else:
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Unknown transaction type"
|
||||
)
|
||||
raise wire.ProcessError("Unknown transaction type")
|
||||
txi_sign = txi
|
||||
else:
|
||||
script_pubkey = bytes()
|
||||
@ -340,9 +321,7 @@ class Bitcoin:
|
||||
|
||||
# check the control digests
|
||||
if self.h_confirmed.get_digest() != h_check.get_digest():
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
|
||||
# compute the signature from the tx digest
|
||||
signature = ecdsa_sign(
|
||||
@ -368,9 +347,7 @@ class Bitcoin:
|
||||
tx = await helpers.request_tx_meta(self.tx_req, self.coin, prev_hash)
|
||||
|
||||
if tx.outputs_cnt <= prev_index:
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Not enough outputs in previous transaction."
|
||||
)
|
||||
raise wire.ProcessError("Not enough outputs in previous transaction.")
|
||||
|
||||
txh = self.create_hash_writer()
|
||||
|
||||
@ -401,9 +378,7 @@ class Bitcoin:
|
||||
writers.get_tx_hash(txh, double=self.coin.sign_hash_double, reverse=True)
|
||||
!= prev_hash
|
||||
):
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Encountered invalid prev_hash"
|
||||
)
|
||||
raise wire.ProcessError("Encountered invalid prev_hash")
|
||||
|
||||
return amount_out
|
||||
|
||||
@ -469,7 +444,7 @@ class Bitcoin:
|
||||
txo.script_type
|
||||
]
|
||||
except KeyError:
|
||||
raise SigningError(FailureType.DataError, "Invalid script type")
|
||||
raise wire.DataError("Invalid script type")
|
||||
node = self.keychain.derive(txo.address_n)
|
||||
txo.address = addresses.get_address(
|
||||
input_script_type, self.coin, node, txo.multisig
|
@ -1,14 +1,16 @@
|
||||
import gc
|
||||
from micropython import const
|
||||
|
||||
from trezor.messages import FailureType
|
||||
from trezor import wire
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TransactionType import TransactionType
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
|
||||
from apps.wallet.sign_tx import helpers, multisig, writers
|
||||
from apps.wallet.sign_tx.bitcoin import Bitcoin, input_is_nonsegwit
|
||||
from apps.wallet.sign_tx.common import SigningError
|
||||
from .. import multisig, writers
|
||||
from . import helpers
|
||||
from .bitcoin import Bitcoin, input_is_nonsegwit
|
||||
|
||||
from apps.common.writers import write_bitcoin_varint
|
||||
|
||||
if False:
|
||||
from typing import Union
|
||||
@ -19,7 +21,7 @@ _SIGHASH_FORKID = const(0x40)
|
||||
class Bitcoinlike(Bitcoin):
|
||||
async def process_segwit_input(self, txi: TxInputType) -> None:
|
||||
if not self.coin.segwit:
|
||||
raise SigningError(FailureType.DataError, "Segwit not enabled on this coin")
|
||||
raise wire.DataError("Segwit not enabled on this coin")
|
||||
await super().process_segwit_input(txi)
|
||||
|
||||
async def process_nonsegwit_input(self, txi: TxInputType) -> None:
|
||||
@ -32,9 +34,7 @@ class Bitcoinlike(Bitcoin):
|
||||
txi = await helpers.request_tx_input(self.tx_req, i_sign, self.coin)
|
||||
|
||||
if not input_is_nonsegwit(txi):
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
public_key, signature = self.sign_bip143_input(txi)
|
||||
|
||||
# if multisig, do a sanity check to ensure we are signing with a key that is included in the multisig
|
@ -1,8 +1,9 @@
|
||||
import gc
|
||||
from micropython import const
|
||||
|
||||
from trezor import wire
|
||||
from trezor.crypto.hashlib import blake256
|
||||
from trezor.messages import FailureType, InputScriptType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TransactionType import TransactionType
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
@ -11,9 +12,11 @@ from trezor.messages.TxOutputType import TxOutputType
|
||||
from trezor.utils import HashWriter, ensure
|
||||
|
||||
from apps.common import coininfo, seed
|
||||
from apps.wallet.sign_tx import addresses, helpers, multisig, progress, scripts, writers
|
||||
from apps.wallet.sign_tx.bitcoin import Bitcoin
|
||||
from apps.wallet.sign_tx.common import SigningError, ecdsa_sign
|
||||
|
||||
from .. import multisig, scripts, writers
|
||||
from ..common import ecdsa_hash_pubkey, ecdsa_sign
|
||||
from . import helpers, progress
|
||||
from .bitcoin import Bitcoin
|
||||
|
||||
DECRED_SERIALIZE_FULL = const(0 << 16)
|
||||
DECRED_SERIALIZE_NO_WITNESS = const(1 << 16)
|
||||
@ -60,10 +63,7 @@ class Decred(Bitcoin):
|
||||
|
||||
async def confirm_output(self, txo: TxOutputType, script_pubkey: bytes) -> None:
|
||||
if txo.decred_script_version != 0:
|
||||
raise SigningError(
|
||||
FailureType.ActionCancelled,
|
||||
"Cannot send to output with script version != 0",
|
||||
)
|
||||
raise wire.ActionCancelled("Cannot send to output with script version != 0")
|
||||
await super().confirm_output(txo, script_pubkey)
|
||||
self.write_tx_output(self.serialized_tx, txo, script_pubkey)
|
||||
|
||||
@ -90,10 +90,10 @@ class Decred(Bitcoin):
|
||||
)
|
||||
elif txi_sign.script_type == InputScriptType.SPENDADDRESS:
|
||||
prev_pkscript = scripts.output_script_p2pkh(
|
||||
addresses.ecdsa_hash_pubkey(key_sign_pub, self.coin)
|
||||
ecdsa_hash_pubkey(key_sign_pub, self.coin)
|
||||
)
|
||||
else:
|
||||
raise SigningError("Unsupported input script type")
|
||||
raise wire.DataError("Unsupported input script type")
|
||||
|
||||
h_witness = self.create_hash_writer()
|
||||
writers.write_uint32(
|
||||
@ -138,10 +138,7 @@ class Decred(Bitcoin):
|
||||
|
||||
def check_prevtx_output(self, txo_bin: TxOutputBinType) -> None:
|
||||
if txo_bin.decred_script_version != 0:
|
||||
raise SigningError(
|
||||
FailureType.ProcessError,
|
||||
"Cannot use utxo that has script_version != 0",
|
||||
)
|
||||
raise wire.ProcessError("Cannot use utxo that has script_version != 0")
|
||||
|
||||
def hash143_add_input(self, txi: TxInputType) -> None:
|
||||
writers.write_tx_input_decred(self.h_prefix, txi)
|
@ -1,7 +1,7 @@
|
||||
import gc
|
||||
|
||||
from trezor import utils
|
||||
from trezor.messages import FailureType, InputScriptType, OutputScriptType
|
||||
from trezor import utils, wire
|
||||
from trezor.messages import InputScriptType, OutputScriptType
|
||||
from trezor.messages.RequestType import (
|
||||
TXEXTRADATA,
|
||||
TXFINISHED,
|
||||
@ -16,8 +16,7 @@ from trezor.messages.TxOutputBinType import TxOutputBinType
|
||||
from trezor.messages.TxOutputType import TxOutputType
|
||||
from trezor.messages.TxRequest import TxRequest
|
||||
|
||||
from .common import SigningError
|
||||
from .writers import TX_HASH_SIZE
|
||||
from ..writers import TX_HASH_SIZE
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
|
||||
@ -195,11 +194,11 @@ def sanitize_sign_tx(tx: SignTx, coin: CoinInfo) -> SignTx:
|
||||
if coin.decred or coin.overwintered:
|
||||
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
||||
elif tx.expiry:
|
||||
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
||||
raise wire.DataError("Expiry not enabled on this coin.")
|
||||
if coin.timestamp and not tx.timestamp:
|
||||
raise SigningError(FailureType.DataError, "Timestamp must be set.")
|
||||
raise wire.DataError("Timestamp must be set.")
|
||||
elif not coin.timestamp and tx.timestamp:
|
||||
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
||||
raise wire.DataError("Timestamp not enabled on this coin.")
|
||||
return tx
|
||||
|
||||
|
||||
@ -211,17 +210,15 @@ def sanitize_tx_meta(tx: TransactionType, coin: CoinInfo) -> TransactionType:
|
||||
if coin.extra_data:
|
||||
tx.extra_data_len = tx.extra_data_len if tx.extra_data_len is not None else 0
|
||||
elif tx.extra_data_len:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Extra data not enabled on this coin."
|
||||
)
|
||||
raise wire.DataError("Extra data not enabled on this coin.")
|
||||
if coin.decred or coin.overwintered:
|
||||
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
||||
elif tx.expiry:
|
||||
raise SigningError(FailureType.DataError, "Expiry not enabled on this coin.")
|
||||
raise wire.DataError("Expiry not enabled on this coin.")
|
||||
if coin.timestamp and not tx.timestamp:
|
||||
raise SigningError(FailureType.DataError, "Timestamp must be set.")
|
||||
raise wire.DataError("Timestamp must be set.")
|
||||
elif not coin.timestamp and tx.timestamp:
|
||||
raise SigningError(FailureType.DataError, "Timestamp not enabled on this coin.")
|
||||
raise wire.DataError("Timestamp not enabled on this coin.")
|
||||
return tx
|
||||
|
||||
|
||||
@ -232,29 +229,18 @@ def sanitize_tx_input(tx: TransactionType, coin: CoinInfo) -> TxInputType:
|
||||
if txi.sequence is None:
|
||||
txi.sequence = 0xFFFFFFFF
|
||||
if txi.prev_hash is None or len(txi.prev_hash) != TX_HASH_SIZE:
|
||||
raise SigningError(FailureType.DataError, "Provided prev_hash is invalid.")
|
||||
raise wire.DataError("Provided prev_hash is invalid.")
|
||||
if txi.multisig and txi.script_type not in MULTISIG_INPUT_SCRIPT_TYPES:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Multisig field provided but not expected.",
|
||||
)
|
||||
raise wire.DataError("Multisig field provided but not expected.")
|
||||
if txi.address_n and txi.script_type not in INTERNAL_INPUT_SCRIPT_TYPES:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Input's address_n provided but not expected.",
|
||||
)
|
||||
raise wire.DataError("Input's address_n provided but not expected.")
|
||||
if not coin.decred and txi.decred_tree is not None:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"Decred details provided but Decred coin not specified.",
|
||||
)
|
||||
raise wire.DataError("Decred details provided but Decred coin not specified.")
|
||||
if txi.script_type in SEGWIT_INPUT_SCRIPT_TYPES:
|
||||
if not coin.segwit:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Segwit not enabled on this coin",
|
||||
)
|
||||
raise wire.DataError("Segwit not enabled on this coin")
|
||||
if txi.amount is None:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Segwit input without amount",
|
||||
)
|
||||
raise wire.DataError("Segwit input without amount")
|
||||
|
||||
_sanitize_decred(txi, coin)
|
||||
return txi
|
||||
@ -263,35 +249,24 @@ def sanitize_tx_input(tx: TransactionType, coin: CoinInfo) -> TxInputType:
|
||||
def sanitize_tx_output(tx: TransactionType, coin: CoinInfo) -> TxOutputType:
|
||||
txo = tx.outputs[0]
|
||||
if txo.multisig and txo.script_type not in MULTISIG_OUTPUT_SCRIPT_TYPES:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Multisig field provided but not expected.",
|
||||
)
|
||||
raise wire.DataError("Multisig field provided but not expected.")
|
||||
if txo.address_n and txo.script_type not in CHANGE_OUTPUT_SCRIPT_TYPES:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Output's address_n provided but not expected.",
|
||||
)
|
||||
raise wire.DataError("Output's address_n provided but not expected.")
|
||||
if txo.script_type == OutputScriptType.PAYTOOPRETURN:
|
||||
# op_return output
|
||||
if txo.amount != 0:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "OP_RETURN output with non-zero amount"
|
||||
)
|
||||
raise wire.DataError("OP_RETURN output with non-zero amount")
|
||||
if txo.address or txo.address_n or txo.multisig:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "OP_RETURN output with address or multisig"
|
||||
)
|
||||
raise wire.DataError("OP_RETURN output with address or multisig")
|
||||
else:
|
||||
if txo.op_return_data:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"OP RETURN data provided but not OP RETURN script type.",
|
||||
raise wire.DataError(
|
||||
"OP RETURN data provided but not OP RETURN script type."
|
||||
)
|
||||
if txo.address_n and txo.address:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Both address and address_n provided."
|
||||
)
|
||||
raise wire.DataError("Both address and address_n provided.")
|
||||
if not txo.address_n and not txo.address:
|
||||
raise SigningError(FailureType.DataError, "Missing address")
|
||||
raise wire.DataError("Missing address")
|
||||
|
||||
_sanitize_decred(txo, coin)
|
||||
|
||||
@ -312,7 +287,6 @@ def _sanitize_decred(
|
||||
tx.decred_script_version = 0
|
||||
else:
|
||||
if tx.decred_script_version is not None:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"Decred details provided but Decred coin not specified.",
|
||||
raise wire.DataError(
|
||||
"Decred details provided but Decred coin not specified."
|
||||
)
|
@ -10,7 +10,7 @@ from trezor.utils import chunks
|
||||
from apps.common import coininfo
|
||||
|
||||
if False:
|
||||
from typing import Iterator, List
|
||||
from typing import Iterator
|
||||
from trezor import wire
|
||||
|
||||
_LOCKTIME_TIMESTAMP_MIN_VALUE = const(500000000)
|
||||
@ -30,10 +30,11 @@ def split_op_return(data: str) -> Iterator[str]:
|
||||
|
||||
async def confirm_output(
|
||||
ctx: wire.Context, output: TxOutputType, coin: coininfo.CoinInfo
|
||||
) -> bool:
|
||||
) -> None:
|
||||
from trezor.ui.text import Text
|
||||
from apps.common.confirm import confirm
|
||||
from apps.wallet.sign_tx import addresses, omni
|
||||
from apps.common.confirm import require_confirm
|
||||
from . import omni
|
||||
from .. import addresses
|
||||
|
||||
if output.script_type == OutputScriptType.PAYTOOPRETURN:
|
||||
data = output.op_return_data
|
||||
@ -54,50 +55,39 @@ async def confirm_output(
|
||||
text = Text("Confirm sending", ui.ICON_SEND, ui.GREEN)
|
||||
text.normal(format_coin_amount(output.amount, coin) + " to")
|
||||
text.mono(*split_address(address_short))
|
||||
return await confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
||||
|
||||
|
||||
async def confirm_total(
|
||||
ctx: wire.Context, spending: int, fee: int, coin: coininfo.CoinInfo
|
||||
) -> bool:
|
||||
) -> None:
|
||||
from trezor.ui.text import Text
|
||||
from apps.common.confirm import hold_to_confirm
|
||||
from apps.common.confirm import require_hold_to_confirm
|
||||
|
||||
text = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN)
|
||||
text.normal("Total amount:")
|
||||
text.bold(format_coin_amount(spending, coin))
|
||||
text.normal("including fee:")
|
||||
text.bold(format_coin_amount(fee, coin))
|
||||
return await hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||
await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx)
|
||||
|
||||
|
||||
async def confirm_feeoverthreshold(
|
||||
ctx: wire.Context, fee: int, coin: coininfo.CoinInfo
|
||||
) -> bool:
|
||||
) -> None:
|
||||
from trezor.ui.text import Text
|
||||
from apps.common.confirm import confirm
|
||||
from apps.common.confirm import require_confirm
|
||||
|
||||
text = Text("High fee", ui.ICON_SEND, ui.GREEN)
|
||||
text.normal("The fee of")
|
||||
text.bold(format_coin_amount(fee, coin))
|
||||
text.normal("is unexpectedly high.", "Continue?")
|
||||
return await confirm(ctx, text, ButtonRequestType.FeeOverThreshold)
|
||||
await require_confirm(ctx, text, ButtonRequestType.FeeOverThreshold)
|
||||
|
||||
|
||||
async def confirm_foreign_address(
|
||||
ctx: wire.Context, address_n: List[int], coin: coininfo.CoinInfo
|
||||
) -> bool:
|
||||
async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> None:
|
||||
from trezor.ui.text import Text
|
||||
from apps.common.confirm import confirm
|
||||
|
||||
text = Text("Confirm sending", ui.ICON_SEND, ui.RED)
|
||||
text.normal("Trying to spend", "coins from another chain.", "Continue?")
|
||||
return await confirm(ctx, text, ButtonRequestType.SignTx)
|
||||
|
||||
|
||||
async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> bool:
|
||||
from trezor.ui.text import Text
|
||||
from apps.common.confirm import confirm
|
||||
from apps.common.confirm import require_confirm
|
||||
|
||||
text = Text("Confirm locktime", ui.ICON_SEND, ui.GREEN)
|
||||
text.normal("Locktime for this transaction is set to")
|
||||
@ -107,4 +97,4 @@ async def confirm_nondefault_locktime(ctx: wire.Context, lock_time: int) -> bool
|
||||
text.normal("timestamp:")
|
||||
text.bold(str(lock_time))
|
||||
text.normal("Continue?")
|
||||
return await confirm(ctx, text, ButtonRequestType.SignTx)
|
||||
await require_confirm(ctx, text, ButtonRequestType.SignTx)
|
@ -1,12 +1,11 @@
|
||||
from micropython import const
|
||||
|
||||
from trezor.messages import FailureType
|
||||
from trezor import wire
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
from trezor.messages.TxOutputType import TxOutputType
|
||||
from trezor.utils import ensure
|
||||
|
||||
from apps.wallet.sign_tx import multisig
|
||||
from apps.wallet.sign_tx.common import SigningError
|
||||
from .. import multisig
|
||||
|
||||
if False:
|
||||
from typing import Any, Union
|
||||
@ -71,9 +70,7 @@ class MatchChecker:
|
||||
# All added inputs had a matching attribute, allowing a change-output.
|
||||
# Ensure that this input still has the same attribute.
|
||||
if self.attribute != self.attribute_from_tx(txi):
|
||||
raise SigningError(
|
||||
FailureType.ProcessError, "Transaction has changed during signing"
|
||||
)
|
||||
raise wire.ProcessError("Transaction has changed during signing")
|
||||
|
||||
def output_matches(self, txo: TxOutputType) -> bool:
|
||||
self.read_only = True
|
@ -1,8 +1,9 @@
|
||||
import ustruct as struct
|
||||
from micropython import const
|
||||
|
||||
from trezor import wire
|
||||
from trezor.crypto.hashlib import blake2b
|
||||
from trezor.messages import FailureType, InputScriptType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TransactionType import TransactionType
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
@ -10,12 +11,10 @@ from trezor.utils import HashWriter, ensure
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.sign_tx import helpers
|
||||
from apps.wallet.sign_tx.bitcoinlike import Bitcoinlike
|
||||
from apps.wallet.sign_tx.common import SigningError
|
||||
from apps.wallet.sign_tx.multisig import multisig_get_pubkeys
|
||||
from apps.wallet.sign_tx.scripts import output_script_multisig, output_script_p2pkh
|
||||
from apps.wallet.sign_tx.writers import (
|
||||
|
||||
from ..multisig import multisig_get_pubkeys
|
||||
from ..scripts import output_script_multisig, output_script_p2pkh
|
||||
from ..writers import (
|
||||
TX_HASH_SIZE,
|
||||
get_tx_hash,
|
||||
write_bytes_fixed,
|
||||
@ -25,10 +24,12 @@ from apps.wallet.sign_tx.writers import (
|
||||
write_uint64,
|
||||
write_varint,
|
||||
)
|
||||
from . import helpers
|
||||
from .bitcoinlike import Bitcoinlike
|
||||
|
||||
if False:
|
||||
from typing import Union
|
||||
from apps.wallet.sign_tx.writers import Writer
|
||||
from .writers import Writer
|
||||
|
||||
OVERWINTERED = const(0x80000000)
|
||||
|
||||
@ -45,10 +46,7 @@ class Overwintered(Bitcoinlike):
|
||||
if not self.tx.branch_id:
|
||||
self.tx.branch_id = 0x76B809BB # Sapling
|
||||
else:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"Unsupported version for overwintered transaction",
|
||||
)
|
||||
raise wire.DataError("Unsupported version for overwintered transaction")
|
||||
|
||||
async def step7_finish(self) -> None:
|
||||
self.write_tx_footer(self.serialized_tx, self.tx)
|
||||
@ -63,10 +61,7 @@ class Overwintered(Bitcoinlike):
|
||||
write_varint(self.serialized_tx, 0) # nShieldedOutput
|
||||
write_varint(self.serialized_tx, 0) # nJoinSplit
|
||||
else:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"Unsupported version for overwintered transaction",
|
||||
)
|
||||
raise wire.DataError("Unsupported version for overwintered transaction")
|
||||
|
||||
await helpers.request_tx_finish(self.tx_req)
|
||||
|
||||
@ -136,10 +131,7 @@ class Overwintered(Bitcoinlike):
|
||||
# 12. nHashType
|
||||
write_uint32(h_preimage, self.get_hash_type())
|
||||
else:
|
||||
raise SigningError(
|
||||
FailureType.DataError,
|
||||
"Unsupported version for overwintered transaction",
|
||||
)
|
||||
raise wire.DataError("Unsupported version for overwintered transaction")
|
||||
|
||||
# 10a /13a. outpoint
|
||||
write_bytes_reversed(h_preimage, txi.prev_hash, TX_HASH_SIZE)
|
||||
@ -170,6 +162,4 @@ def derive_script_code(txi: TxInputType, pubkeyhash: bytes) -> bytearray:
|
||||
return output_script_p2pkh(pubkeyhash)
|
||||
|
||||
else:
|
||||
raise SigningError(
|
||||
FailureType.DataError, "Unknown input script type for zip143 script code"
|
||||
)
|
||||
raise wire.DataError("Unknown input script type for zip143 script code")
|
@ -3,9 +3,7 @@ from trezor.crypto.curve import secp256k1
|
||||
from trezor.messages.InputScriptType import SPENDADDRESS, SPENDP2SHWITNESS, SPENDWITNESS
|
||||
from trezor.messages.Success import Success
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.signverify import message_digest, require_confirm_verify_message
|
||||
from apps.wallet.sign_tx.addresses import (
|
||||
from .addresses import (
|
||||
address_p2wpkh,
|
||||
address_p2wpkh_in_p2sh,
|
||||
address_pkh,
|
||||
@ -13,6 +11,9 @@ from apps.wallet.sign_tx.addresses import (
|
||||
address_to_cashaddr,
|
||||
)
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.signverify import message_digest, require_confirm_verify_message
|
||||
|
||||
|
||||
async def verify_message(ctx, msg):
|
||||
message = msg.message
|
@ -4,9 +4,9 @@ from trezor import utils, wire
|
||||
from trezor.crypto.hashlib import blake256, sha256
|
||||
from trezor.ui.text import Text
|
||||
|
||||
from apps.bitcoin.writers import write_varint
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.layout import split_address
|
||||
from apps.wallet.sign_tx.writers import write_varint
|
||||
|
||||
if False:
|
||||
from typing import List
|
||||
|
@ -3,12 +3,12 @@ from trezor.crypto.hashlib import sha256
|
||||
from trezor.messages.LiskMessageSignature import LiskMessageSignature
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.bitcoin.sign_tx.writers import write_varint
|
||||
from apps.common import paths
|
||||
from apps.common.seed import with_slip44_keychain
|
||||
from apps.common.signverify import require_confirm_sign_message
|
||||
from apps.lisk import CURVE, SLIP44_ID
|
||||
from apps.lisk.helpers import validate_full_path
|
||||
from apps.wallet.sign_tx.writers import write_varint
|
||||
|
||||
|
||||
def message_digest(message):
|
||||
|
9
core/src/apps/misc/__init__.py
Normal file
9
core/src/apps/misc/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
|
||||
def boot() -> None:
|
||||
wire.add(MessageType.GetEntropy, __name__, "get_entropy")
|
||||
wire.add(MessageType.SignIdentity, __name__, "sign_identity")
|
||||
wire.add(MessageType.GetECDHSessionKey, __name__, "get_ecdh_session_key")
|
||||
wire.add(MessageType.CipherKeyValue, __name__, "cipher_key_value")
|
@ -6,13 +6,11 @@ from trezor.messages.ECDHSessionKey import ECDHSessionKey
|
||||
from trezor.ui.text import Text
|
||||
from trezor.utils import chunks
|
||||
|
||||
from .sign_identity import serialize_identity, serialize_identity_without_proto
|
||||
|
||||
from apps.common import HARDENED
|
||||
from apps.common.confirm import require_confirm
|
||||
from apps.common.seed import get_keychain
|
||||
from apps.wallet.sign_identity import (
|
||||
serialize_identity,
|
||||
serialize_identity_without_proto,
|
||||
)
|
||||
|
||||
|
||||
async def get_ecdh_session_key(ctx, msg):
|
@ -1,12 +0,0 @@
|
||||
from trezor.crypto import bip32, der
|
||||
from trezor.crypto.curve import secp256k1
|
||||
|
||||
|
||||
class SigningError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
def ecdsa_sign(node: bip32.HDNode, digest: bytes) -> bytes:
|
||||
sig = secp256k1.sign(node.private_key(), digest)
|
||||
sigder = der.encode_seq((sig[1:33], sig[33:65]))
|
||||
return sigder
|
@ -17,7 +17,8 @@ def _boot_apps() -> None:
|
||||
# load applications
|
||||
import apps.homescreen
|
||||
import apps.management
|
||||
import apps.wallet
|
||||
import apps.bitcoin
|
||||
import apps.misc
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
import apps.ethereum
|
||||
@ -38,7 +39,8 @@ def _boot_apps() -> None:
|
||||
# boot applications
|
||||
apps.homescreen.boot()
|
||||
apps.management.boot()
|
||||
apps.wallet.boot()
|
||||
apps.bitcoin.boot()
|
||||
apps.misc.boot()
|
||||
if not utils.BITCOIN_ONLY:
|
||||
apps.ethereum.boot()
|
||||
apps.lisk.boot()
|
||||
|
@ -2,12 +2,12 @@ from common import *
|
||||
from trezor.crypto import bip32, bip39
|
||||
from trezor.utils import HashWriter
|
||||
|
||||
from apps.wallet.sign_tx.addresses import validate_full_path, validate_path_for_bitcoin_public_key
|
||||
from apps.bitcoin.addresses import validate_full_path, validate_path_for_bitcoin_public_key
|
||||
from apps.common.paths import HARDENED
|
||||
from apps.common import coins
|
||||
from apps.wallet.sign_tx import scripts
|
||||
from apps.wallet.sign_tx.addresses import *
|
||||
from apps.wallet.sign_tx.writers import *
|
||||
from apps.bitcoin import scripts
|
||||
from apps.bitcoin.addresses import *
|
||||
from apps.bitcoin.writers import *
|
||||
|
||||
|
||||
def node_derive(root, path):
|
||||
@ -111,7 +111,7 @@ class TestAddress(unittest.TestCase):
|
||||
self.assertEqual(address, '39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z')
|
||||
|
||||
for invalid_m in (-1, 0, len(pubkeys) + 1, 16):
|
||||
with self.assertRaises(scripts.ScriptsError):
|
||||
with self.assertRaises(wire.DataError):
|
||||
address_multisig_p2sh(pubkeys, invalid_m, coin)
|
||||
|
||||
def test_multisig_address_p2wsh_in_p2sh(self):
|
@ -1,7 +1,7 @@
|
||||
from common import *
|
||||
|
||||
from apps.wallet.sign_tx.common import *
|
||||
from apps.wallet.sign_tx.addresses import *
|
||||
from apps.bitcoin.common import *
|
||||
from apps.bitcoin.addresses import *
|
||||
from apps.common import coins
|
||||
from trezor.crypto import bip32, bip39
|
||||
|
@ -1,8 +1,8 @@
|
||||
from common import *
|
||||
|
||||
from apps.wallet.sign_tx.scripts import output_derive_script
|
||||
from apps.wallet.sign_tx.bitcoin import Bitcoin
|
||||
from apps.wallet.sign_tx.writers import get_tx_hash
|
||||
from apps.bitcoin.scripts import output_derive_script
|
||||
from apps.bitcoin.sign_tx.bitcoin import Bitcoin
|
||||
from apps.bitcoin.writers import get_tx_hash
|
||||
from apps.common import coins
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TxInputType import TxInputType
|
@ -1,8 +1,8 @@
|
||||
from common import *
|
||||
|
||||
from apps.wallet.sign_tx.scripts import output_derive_script
|
||||
from apps.wallet.sign_tx.bitcoin import Bitcoin
|
||||
from apps.wallet.sign_tx.writers import get_tx_hash
|
||||
from apps.bitcoin.scripts import output_derive_script
|
||||
from apps.bitcoin.sign_tx.bitcoin import Bitcoin
|
||||
from apps.bitcoin.writers import get_tx_hash
|
||||
from apps.common import coins
|
||||
from trezor.messages.SignTx import SignTx
|
||||
from trezor.messages.TxInputType import TxInputType
|
@ -13,12 +13,12 @@ from trezor.messages.TxRequestDetailsType import TxRequestDetailsType
|
||||
from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages import OutputScriptType
|
||||
from trezor import wire
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import helpers, bitcoin
|
||||
from apps.wallet.sign_tx.scripts import ScriptsError
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import helpers, bitcoin
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
||||
@ -272,7 +272,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
|
||||
signer = bitcoin.Bitcoin(tx, keychain, coin).signer()
|
||||
for request, response in chunks(messages, 2):
|
||||
if response is None:
|
||||
with self.assertRaises(ScriptsError):
|
||||
with self.assertRaises(wire.DataError):
|
||||
signer.send(request)
|
||||
else:
|
||||
self.assertEqual(signer.send(request), response)
|
@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import bitcoinlike, helpers
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import bitcoinlike, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
@ -13,11 +13,12 @@ from trezor.messages.TxRequestDetailsType import TxRequestDetailsType
|
||||
from trezor.messages.TxRequestSerializedType import TxRequestSerializedType
|
||||
from trezor.messages import InputScriptType
|
||||
from trezor.messages import OutputScriptType
|
||||
from trezor import wire
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import bitcoin, common, helpers
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import bitcoin, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
||||
@ -341,8 +342,8 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
|
||||
i = 0
|
||||
messages_count = int(len(messages) / 2)
|
||||
for request, response in chunks(messages, 2):
|
||||
if i == messages_count - 1: # last message should throw SigningError
|
||||
self.assertRaises(common.SigningError, signer.send, request)
|
||||
if i == messages_count - 1: # last message should throw wire.Error
|
||||
self.assertRaises(wire.ProcessError, signer.send, request)
|
||||
else:
|
||||
self.assertEqual(signer.send(request), response)
|
||||
i += 1
|
@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import bitcoinlike, helpers
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import bitcoinlike, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
@ -3,8 +3,7 @@ from common import *
|
||||
from trezor.messages.TxInputType import TxInputType
|
||||
from trezor.messages import InputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.wallet.sign_tx import writers
|
||||
from apps.bitcoin import writers
|
||||
|
||||
|
||||
class TestWriters(unittest.TestCase):
|
@ -16,7 +16,7 @@ from trezor.messages import OutputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.sign_tx import bitcoin, helpers
|
||||
from apps.bitcoin.sign_tx import bitcoin, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
@ -1,6 +1,6 @@
|
||||
from common import *
|
||||
|
||||
from apps.wallet.sign_tx.omni import is_valid, parse
|
||||
from apps.bitcoin.sign_tx.omni import is_valid, parse
|
||||
|
||||
class TestSignTxOmni(unittest.TestCase):
|
||||
|
@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import bitcoin, helpers
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import bitcoin, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
@ -16,8 +16,8 @@ from trezor.messages import OutputScriptType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.common.seed import Keychain
|
||||
from apps.wallet.keychain import get_namespaces_for_coin
|
||||
from apps.wallet.sign_tx import bitcoinlike, helpers
|
||||
from apps.bitcoin.keychain import get_namespaces_for_coin
|
||||
from apps.bitcoin.sign_tx import bitcoinlike, helpers
|
||||
|
||||
|
||||
EMPTY_SERIALIZED = TxRequestSerializedType(serialized_tx=bytearray())
|
@ -6,8 +6,8 @@ from trezor.messages import OutputScriptType
|
||||
from trezor.crypto import bip32, bip39
|
||||
|
||||
from apps.common import coins
|
||||
from apps.wallet.sign_tx.tx_weight import *
|
||||
from apps.wallet.sign_tx.scripts import output_derive_script
|
||||
from apps.bitcoin.sign_tx.tx_weight import *
|
||||
from apps.bitcoin.scripts import output_derive_script
|
||||
|
||||
|
||||
class TestCalculateTxWeight(unittest.TestCase):
|
@ -5,10 +5,10 @@ from trezor.messages.TxInputType import TxInputType
|
||||
from trezor.messages.TxOutputBinType import TxOutputBinType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.wallet.sign_tx.writers import get_tx_hash
|
||||
from apps.bitcoin.writers import get_tx_hash
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
from apps.wallet.sign_tx.zcash import Overwintered
|
||||
from apps.bitcoin.sign_tx.zcash import Overwintered
|
||||
|
||||
|
||||
# test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0143.py
|
@ -5,10 +5,10 @@ from trezor.messages.TxInputType import TxInputType
|
||||
from trezor.messages.TxOutputBinType import TxOutputBinType
|
||||
|
||||
from apps.common import coins
|
||||
from apps.wallet.sign_tx.writers import get_tx_hash
|
||||
from apps.bitcoin.writers import get_tx_hash
|
||||
|
||||
if not utils.BITCOIN_ONLY:
|
||||
from apps.wallet.sign_tx.zcash import Overwintered
|
||||
from apps.bitcoin.sign_tx.zcash import Overwintered
|
||||
|
||||
|
||||
# test vectors inspired from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/zip_0243.py
|
@ -1,12 +1,10 @@
|
||||
from common import *
|
||||
|
||||
from storage import cache
|
||||
from apps.common import HARDENED, coins
|
||||
from apps.common import HARDENED
|
||||
from apps.common.seed import Keychain, Slip21Node, _path_hardened, get_keychain, with_slip44_keychain
|
||||
from apps.wallet.sign_tx import scripts, addresses
|
||||
from trezor import wire
|
||||
from trezor.crypto import bip39
|
||||
from trezor.crypto.curve import secp256k1
|
||||
|
||||
class TestKeychain(unittest.TestCase):
|
||||
|
||||
|
@ -4,7 +4,7 @@ from trezor import wire
|
||||
from trezor.crypto import bip39
|
||||
from apps.common.paths import HARDENED
|
||||
|
||||
from apps.wallet.keychain import get_keychain_for_coin
|
||||
from apps.bitcoin.keychain import get_keychain_for_coin
|
||||
|
||||
|
||||
class TestBitcoinKeychain(unittest.TestCase):
|
||||
|
@ -6,11 +6,11 @@ Each app has a `boot()` function in the module's \_\_init\_\_ file. This functio
|
||||
|
||||
## Example
|
||||
|
||||
This binds the message GetAddress to function `get_address` inside the `apps.wallet` module.
|
||||
This binds the message GetAddress to function `get_address` inside the `apps.bitcoin` module.
|
||||
|
||||
```python
|
||||
from trezor import wire
|
||||
from trezor.messages import MessageType
|
||||
|
||||
wire.add(MessageType.GetAddress, apps.wallet, "get_address")
|
||||
wire.add(MessageType.GetAddress, apps.bitcoin, "get_address")
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user