1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 04:18:10 +00:00

feat(python): allow for chunkifying addresses in trezorlib functions and CLI

This commit is contained in:
grdddj 2023-09-14 12:23:04 +02:00 committed by Jiří Musil
parent 04e3b02030
commit 68013bdb1b
20 changed files with 160 additions and 44 deletions

View File

@ -28,10 +28,15 @@ if TYPE_CHECKING:
@expect(messages.BinanceAddress, field="address", ret_type=str)
def get_address(
client: "TrezorClient", address_n: "Address", show_display: bool = False
client: "TrezorClient",
address_n: "Address",
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.BinanceGetAddress(address_n=address_n, show_display=show_display)
messages.BinanceGetAddress(
address_n=address_n, show_display=show_display, chunkify=chunkify
)
)
@ -46,12 +51,13 @@ def get_public_key(
@session
def sign_tx(
client: "TrezorClient", address_n: "Address", tx_json: dict
client: "TrezorClient", address_n: "Address", tx_json: dict, chunkify: bool = False
) -> messages.BinanceSignedTx:
msg = tx_json["msgs"][0]
tx_msg = tx_json.copy()
tx_msg["msg_count"] = 1
tx_msg["address_n"] = address_n
tx_msg["chunkify"] = chunkify
envelope = dict_to_proto(messages.BinanceSignTx, tx_msg)
response = client.call(envelope)

View File

@ -152,6 +152,7 @@ def get_authenticated_address(
ignore_xpub_magic: bool = False,
unlock_path: Optional[List[int]] = None,
unlock_path_mac: Optional[bytes] = None,
chunkify: bool = False,
) -> "MessageType":
if unlock_path:
res = client.call(
@ -168,6 +169,7 @@ def get_authenticated_address(
multisig=multisig,
script_type=script_type,
ignore_xpub_magic=ignore_xpub_magic,
chunkify=chunkify,
)
)

View File

@ -781,6 +781,7 @@ def get_address(
network_id: int = NETWORK_IDS["mainnet"],
show_display: bool = False,
derivation_type: messages.CardanoDerivationType = messages.CardanoDerivationType.ICARUS,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.CardanoGetAddress(
@ -789,6 +790,7 @@ def get_address(
network_id=network_id,
show_display=show_display,
derivation_type=derivation_type,
chunkify=chunkify,
)
)
@ -848,6 +850,7 @@ def sign_tx(
additional_witness_requests: Sequence[Path] = (),
derivation_type: messages.CardanoDerivationType = messages.CardanoDerivationType.ICARUS,
include_network_id: bool = False,
chunkify: bool = False,
) -> Dict[str, Any]:
UNEXPECTED_RESPONSE_ERROR = exceptions.TrezorException("Unexpected response")
@ -884,6 +887,7 @@ def sign_tx(
witness_requests_count=len(witness_requests),
derivation_type=derivation_type,
include_network_id=include_network_id,
chunkify=chunkify,
)
)
if not isinstance(response, messages.CardanoTxItemAck):

View File

@ -38,11 +38,14 @@ def cli() -> None:
@cli.command()
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(client: "TrezorClient", address: str, show_display: bool) -> str:
def get_address(
client: "TrezorClient", address: str, show_display: bool, chunkify: bool
) -> str:
"""Get Binance address for specified path."""
address_n = tools.parse_path(address)
return binance.get_address(client, address_n, show_display)
return binance.get_address(client, address_n, show_display, chunkify)
@cli.command()
@ -59,13 +62,14 @@ def get_public_key(client: "TrezorClient", address: str, show_display: bool) ->
@click.argument("file", type=click.File("r"))
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def sign_tx(
client: "TrezorClient", address: str, file: TextIO
client: "TrezorClient", address: str, file: TextIO, chunkify: bool
) -> "messages.BinanceSignedTx":
"""Sign Binance transaction.
Transaction must be provided as a JSON file.
"""
address_n = tools.parse_path(address)
return binance.sign_tx(client, address_n, json.load(file))
return binance.sign_tx(client, address_n, json.load(file), chunkify=chunkify)

View File

@ -167,6 +167,7 @@ def cli() -> None:
type=int,
default=2,
)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(
client: "TrezorClient",
@ -177,6 +178,7 @@ def get_address(
multisig_xpub: List[str],
multisig_threshold: Optional[int],
multisig_suffix_length: int,
chunkify: bool,
) -> str:
"""Get address for specified path.
@ -225,6 +227,7 @@ def get_address(
script_type=script_type,
multisig=multisig,
unlock_path=get_unlock_path(address_n),
chunkify=chunkify,
)
@ -366,9 +369,10 @@ def get_descriptor(
@cli.command()
@click.option("-c", "--coin", is_flag=True, hidden=True, expose_value=False)
@click.option("-C", "--chunkify", is_flag=True)
@click.argument("json_file", type=click.File())
@with_client
def sign_tx(client: "TrezorClient", json_file: TextIO) -> None:
def sign_tx(client: "TrezorClient", json_file: TextIO, chunkify: bool) -> None:
"""Sign transaction.
Transaction data must be provided in a JSON file. See `transaction-format.md` for
@ -398,6 +402,7 @@ def sign_tx(client: "TrezorClient", json_file: TextIO) -> None:
inputs,
outputs,
prev_txes=prev_txes,
chunkify=chunkify,
**details,
)

View File

@ -60,6 +60,7 @@ def cli() -> None:
default=messages.CardanoDerivationType.ICARUS,
)
@click.option("-i", "--include-network-id", is_flag=True)
@click.option("-C", "chunkify", is_flag=True)
@with_client
def sign_tx(
client: "TrezorClient",
@ -70,6 +71,7 @@ def sign_tx(
testnet: str,
derivation_type: messages.CardanoDerivationType,
include_network_id: bool,
chunkify: bool,
) -> cardano.SignTxResponse:
"""Sign Cardano transaction."""
transaction = json.load(file)
@ -143,6 +145,7 @@ def sign_tx(
additional_witness_requests,
derivation_type=derivation_type,
include_network_id=include_network_id,
chunkify=chunkify,
)
sign_tx_response["tx_hash"] = sign_tx_response["tx_hash"].hex()
@ -200,6 +203,7 @@ def sign_tx(
type=ChoiceType({m.name: m for m in messages.CardanoDerivationType}),
default=messages.CardanoDerivationType.ICARUS,
)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(
client: "TrezorClient",
@ -217,6 +221,7 @@ def get_address(
show_display: bool,
testnet: str,
derivation_type: messages.CardanoDerivationType,
chunkify: bool,
) -> str:
"""
Get Cardano address.
@ -260,6 +265,7 @@ def get_address(
network_id,
show_display,
derivation_type=derivation_type,
chunkify=chunkify,
)

View File

@ -49,12 +49,19 @@ def get_public_key(client: "TrezorClient", address: str, show_display: bool) ->
@click.argument("file", type=click.File("r"))
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def sign_transaction(
client: "TrezorClient", address: str, file: TextIO
client: "TrezorClient", address: str, file: TextIO, chunkify: bool
) -> "messages.EosSignedTx":
"""Sign EOS transaction."""
tx_json = json.load(file)
address_n = tools.parse_path(address)
return eos.sign_tx(client, address_n, tx_json["transaction"], tx_json["chain_id"])
return eos.sign_tx(
client,
address_n,
tx_json["transaction"],
tx_json["chain_id"],
chunkify=chunkify,
)

View File

@ -273,12 +273,15 @@ def cli(
@cli.command()
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(client: "TrezorClient", address: str, show_display: bool) -> str:
def get_address(
client: "TrezorClient", address: str, show_display: bool, chunkify: bool
) -> str:
"""Get Ethereum address in hex encoding."""
address_n = tools.parse_path(address)
network = ethereum.network_from_address_n(address_n, DEFINITIONS_SOURCE)
return ethereum.get_address(client, address_n, show_display, network)
return ethereum.get_address(client, address_n, show_display, network, chunkify)
@cli.command()
@ -344,6 +347,7 @@ def get_public_node(client: "TrezorClient", address: str, show_display: bool) ->
callback=_list_units,
expose_value=False,
)
@click.option("-C", "--chunkify", is_flag=True)
@click.argument("to_address")
@click.argument("amount", callback=_amount_to_int)
@with_client
@ -364,6 +368,7 @@ def sign_tx(
max_priority_fee: Optional[int],
access_list: List[ethereum.messages.EthereumAccessList],
eip2718_type: Optional[int],
chunkify: bool,
) -> str:
"""Sign (and optionally publish) Ethereum transaction.
@ -462,6 +467,7 @@ def sign_tx(
max_priority_fee=max_priority_fee,
access_list=access_list,
definitions=defs,
chunkify=chunkify,
)
else:
if gas_price is None:
@ -479,6 +485,7 @@ def sign_tx(
data=data_bytes,
chain_id=chain_id,
definitions=defs,
chunkify=chunkify,
)
to = ethereum.decode_hex(to_address)

View File

@ -41,16 +41,18 @@ def cli() -> None:
type=ChoiceType({m.name: m for m in messages.MoneroNetworkType}),
default=messages.MoneroNetworkType.MAINNET,
)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(
client: "TrezorClient",
address: str,
show_display: bool,
network_type: messages.MoneroNetworkType,
chunkify: bool,
) -> bytes:
"""Get Monero address for specified path."""
address_n = tools.parse_path(address)
return monero.get_address(client, address_n, show_display, network_type)
return monero.get_address(client, address_n, show_display, network_type, chunkify)
@cli.command()

View File

@ -38,13 +38,18 @@ def cli() -> None:
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-N", "--network", type=int, default=0x68)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(
client: "TrezorClient", address: str, network: int, show_display: bool
client: "TrezorClient",
address: str,
network: int,
show_display: bool,
chunkify: bool,
) -> str:
"""Get NEM address for specified path."""
address_n = tools.parse_path(address)
return nem.get_address(client, address_n, network, show_display)
return nem.get_address(client, address_n, network, show_display, chunkify)
@cli.command()
@ -52,16 +57,21 @@ def get_address(
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False)
@click.option("-b", "--broadcast", help="NIS to announce transaction to")
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def sign_tx(
client: "TrezorClient", address: str, file: TextIO, broadcast: Optional[str]
client: "TrezorClient",
address: str,
file: TextIO,
broadcast: Optional[str],
chunkify: bool,
) -> dict:
"""Sign (and optionally broadcast) NEM transaction.
Transaction file is expected in the NIS (RequestPrepareAnnounce) format.
"""
address_n = tools.parse_path(address)
transaction = nem.sign_tx(client, address_n, json.load(file))
transaction = nem.sign_tx(client, address_n, json.load(file), chunkify=chunkify)
payload = {"data": transaction.data.hex(), "signature": transaction.signature.hex()}

View File

@ -36,24 +36,28 @@ def cli() -> None:
@cli.command()
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(client: "TrezorClient", address: str, show_display: bool) -> str:
def get_address(
client: "TrezorClient", address: str, show_display: bool, chunkify: bool
) -> str:
"""Get Ripple address"""
address_n = tools.parse_path(address)
return ripple.get_address(client, address_n, show_display)
return ripple.get_address(client, address_n, show_display, chunkify)
@cli.command()
@click.argument("file", type=click.File("r"))
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def sign_tx(client: "TrezorClient", address: str, file: TextIO) -> None:
def sign_tx(client: "TrezorClient", address: str, file: TextIO, chunkify: bool) -> None:
"""Sign Ripple transaction"""
address_n = tools.parse_path(address)
msg = ripple.create_sign_tx_msg(json.load(file))
result = ripple.sign_tx(client, address_n, msg)
result = ripple.sign_tx(client, address_n, msg, chunkify=chunkify)
click.echo("Signature:")
click.echo(result.signature.hex())
click.echo()

View File

@ -51,11 +51,14 @@ def cli() -> None:
default=stellar.DEFAULT_BIP32_PATH,
)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(client: "TrezorClient", address: str, show_display: bool) -> str:
def get_address(
client: "TrezorClient", address: str, show_display: bool, chunkify: bool
) -> str:
"""Get Stellar public address."""
address_n = tools.parse_path(address)
return stellar.get_address(client, address_n, show_display)
return stellar.get_address(client, address_n, show_display, chunkify)
@cli.command()

View File

@ -36,11 +36,14 @@ def cli() -> None:
@cli.command()
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-d", "--show-display", is_flag=True)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def get_address(client: "TrezorClient", address: str, show_display: bool) -> str:
def get_address(
client: "TrezorClient", address: str, show_display: bool, chunkify: bool
) -> str:
"""Get Tezos address for specified path."""
address_n = tools.parse_path(address)
return tezos.get_address(client, address_n, show_display)
return tezos.get_address(client, address_n, show_display, chunkify)
@cli.command()
@ -57,11 +60,12 @@ def get_public_key(client: "TrezorClient", address: str, show_display: bool) ->
@click.argument("file", type=click.File("r"))
@click.option("-n", "--address", required=True, help=PATH_HELP)
@click.option("-f", "--file", "_ignore", is_flag=True, hidden=True, expose_value=False)
@click.option("-C", "--chunkify", is_flag=True)
@with_client
def sign_tx(
client: "TrezorClient", address: str, file: TextIO
client: "TrezorClient", address: str, file: TextIO, chunkify: bool
) -> messages.TezosSignedTx:
"""Sign Tezos transaction."""
address_n = tools.parse_path(address)
msg = protobuf.dict_to_proto(messages.TezosSignTx, json.load(file))
return tezos.sign_tx(client, address_n, msg)
return tezos.sign_tx(client, address_n, msg, chunkify=chunkify)

View File

@ -331,7 +331,11 @@ def get_public_key(
@session
def sign_tx(
client: "TrezorClient", address: "Address", transaction: dict, chain_id: str
client: "TrezorClient",
address: "Address",
transaction: dict,
chain_id: str,
chunkify: bool = False,
) -> messages.EosSignedTx:
header, actions = parse_transaction_json(transaction)
@ -340,6 +344,7 @@ def sign_tx(
chain_id=bytes.fromhex(chain_id),
header=header,
num_actions=len(actions),
chunkify=chunkify,
)
response = client.call(msg)

View File

@ -167,12 +167,14 @@ def get_address(
n: "Address",
show_display: bool = False,
encoded_network: Optional[bytes] = None,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.EthereumGetAddress(
address_n=n,
show_display=show_display,
encoded_network=encoded_network,
chunkify=chunkify,
)
)
@ -199,6 +201,7 @@ def sign_tx(
chain_id: Optional[int] = None,
tx_type: Optional[int] = None,
definitions: Optional[messages.EthereumDefinitions] = None,
chunkify: bool = False,
) -> Tuple[int, bytes, bytes]:
if chain_id is None:
raise exceptions.TrezorException("Chain ID cannot be undefined")
@ -213,6 +216,7 @@ def sign_tx(
chain_id=chain_id,
tx_type=tx_type,
definitions=definitions,
chunkify=chunkify,
)
if data is None:
@ -258,6 +262,7 @@ def sign_tx_eip1559(
max_priority_fee: int,
access_list: Optional[List[messages.EthereumAccessList]] = None,
definitions: Optional[messages.EthereumDefinitions] = None,
chunkify: bool = False,
) -> Tuple[int, bytes, bytes]:
length = len(data)
data, chunk = data[1024:], data[:1024]
@ -274,6 +279,7 @@ def sign_tx_eip1559(
data_length=length,
data_initial_chunk=chunk,
definitions=definitions,
chunkify=chunkify,
)
response = client.call(msg)

View File

@ -37,10 +37,14 @@ def get_address(
n: "Address",
show_display: bool = False,
network_type: messages.MoneroNetworkType = messages.MoneroNetworkType.MAINNET,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.MoneroGetAddress(
address_n=n, show_display=show_display, network_type=network_type
address_n=n,
show_display=show_display,
network_type=network_type,
chunkify=chunkify,
)
)

View File

@ -174,10 +174,11 @@ def fill_transaction_by_type(msg: messages.NEMSignTx, transaction: dict) -> None
raise ValueError("Unknown transaction type")
def create_sign_tx(transaction: dict) -> messages.NEMSignTx:
def create_sign_tx(transaction: dict, chunkify: bool = False) -> messages.NEMSignTx:
msg = messages.NEMSignTx(
transaction=create_transaction_common(transaction),
cosigning=transaction["type"] == TYPE_MULTISIG_SIGNATURE,
chunkify=chunkify,
)
if transaction["type"] in (TYPE_MULTISIG_SIGNATURE, TYPE_MULTISIG):
@ -197,17 +198,25 @@ def create_sign_tx(transaction: dict) -> messages.NEMSignTx:
@expect(messages.NEMAddress, field="address", ret_type=str)
def get_address(
client: "TrezorClient", n: "Address", network: int, show_display: bool = False
client: "TrezorClient",
n: "Address",
network: int,
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.NEMGetAddress(address_n=n, network=network, show_display=show_display)
messages.NEMGetAddress(
address_n=n, network=network, show_display=show_display, chunkify=chunkify
)
)
@expect(messages.NEMSignedTx)
def sign_tx(client: "TrezorClient", n: "Address", transaction: dict) -> "MessageType":
def sign_tx(
client: "TrezorClient", n: "Address", transaction: dict, chunkify: bool = False
) -> "MessageType":
try:
msg = create_sign_tx(transaction)
msg = create_sign_tx(transaction, chunkify=chunkify)
except ValueError as e:
raise exceptions.TrezorException("Failed to encode transaction") from e

View File

@ -31,18 +31,27 @@ REQUIRED_PAYMENT_FIELDS = ("Amount", "Destination")
@expect(messages.RippleAddress, field="address", ret_type=str)
def get_address(
client: "TrezorClient", address_n: "Address", show_display: bool = False
client: "TrezorClient",
address_n: "Address",
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.RippleGetAddress(address_n=address_n, show_display=show_display)
messages.RippleGetAddress(
address_n=address_n, show_display=show_display, chunkify=chunkify
)
)
@expect(messages.RippleSignedTx)
def sign_tx(
client: "TrezorClient", address_n: "Address", msg: messages.RippleSignTx
client: "TrezorClient",
address_n: "Address",
msg: messages.RippleSignTx,
chunkify: bool = False,
) -> "MessageType":
msg.address_n = address_n
msg.chunkify = chunkify
return client.call(msg)

View File

@ -324,10 +324,15 @@ def _read_asset(asset: "Asset") -> messages.StellarAsset:
@expect(messages.StellarAddress, field="address", ret_type=str)
def get_address(
client: "TrezorClient", address_n: "Address", show_display: bool = False
client: "TrezorClient",
address_n: "Address",
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.StellarGetAddress(address_n=address_n, show_display=show_display)
messages.StellarGetAddress(
address_n=address_n, show_display=show_display, chunkify=chunkify
)
)

View File

@ -27,25 +27,39 @@ if TYPE_CHECKING:
@expect(messages.TezosAddress, field="address", ret_type=str)
def get_address(
client: "TrezorClient", address_n: "Address", show_display: bool = False
client: "TrezorClient",
address_n: "Address",
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.TezosGetAddress(address_n=address_n, show_display=show_display)
messages.TezosGetAddress(
address_n=address_n, show_display=show_display, chunkify=chunkify
)
)
@expect(messages.TezosPublicKey, field="public_key", ret_type=str)
def get_public_key(
client: "TrezorClient", address_n: "Address", show_display: bool = False
client: "TrezorClient",
address_n: "Address",
show_display: bool = False,
chunkify: bool = False,
) -> "MessageType":
return client.call(
messages.TezosGetPublicKey(address_n=address_n, show_display=show_display)
messages.TezosGetPublicKey(
address_n=address_n, show_display=show_display, chunkify=chunkify
)
)
@expect(messages.TezosSignedTx)
def sign_tx(
client: "TrezorClient", address_n: "Address", sign_tx_msg: messages.TezosSignTx
client: "TrezorClient",
address_n: "Address",
sign_tx_msg: messages.TezosSignTx,
chunkify: bool = False,
) -> "MessageType":
sign_tx_msg.address_n = address_n
sign_tx_msg.chunkify = chunkify
return client.call(sign_tx_msg)