From f1bf7232edeafa30ed53fb0c9bbfa59699a6d63b Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Thu, 7 Oct 2021 09:58:52 +0800 Subject: [PATCH 1/6] refactor(common & core & legacy): Stellar, rename StellarManageOfferOp to StellarManageSellOfferOp and rename StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp. --- common/protob/messages-stellar.proto | 8 ++++---- common/protob/messages.proto | 4 ++-- common/tests/fixtures/stellar/sign_tx.json | 8 ++++---- core/.changelog.d/1838.incompatible | 1 + core/src/apps/stellar/README.md | 4 ++-- core/src/apps/stellar/consts.py | 16 ++++++++-------- core/src/apps/stellar/operations/__init__.py | 12 ++++++------ core/src/apps/stellar/operations/layout.py | 16 ++++++++++------ core/src/apps/stellar/operations/serialize.py | 10 ++++++---- core/src/trezor/enums/MessageType.py | 4 ++-- core/src/trezor/enums/__init__.py | 4 ++-- core/src/trezor/messages.py | 8 ++++---- legacy/firmware/.changelog.d/1838.incompatible | 1 + legacy/firmware/fsm.h | 5 +++-- legacy/firmware/fsm_msg_stellar.h | 9 +++++---- legacy/firmware/protob/messages-stellar.options | 8 ++++---- legacy/firmware/stellar.c | 5 +++-- legacy/firmware/stellar.h | 5 +++-- python/src/trezorlib/messages.py | 8 ++++---- python/src/trezorlib/stellar.py | 4 ++-- python/tests/test_stellar.py | 6 +++--- tests/ui_tests/fixtures.json | 4 ++-- 22 files changed, 81 insertions(+), 69 deletions(-) create mode 100644 core/.changelog.d/1838.incompatible create mode 100644 legacy/firmware/.changelog.d/1838.incompatible diff --git a/common/protob/messages-stellar.proto b/common/protob/messages-stellar.proto index 5be931ec4d2..f31df2f0348 100644 --- a/common/protob/messages-stellar.proto +++ b/common/protob/messages-stellar.proto @@ -74,8 +74,8 @@ message StellarSignTx { * Response: device is ready for client to send the next operation * @next StellarPaymentOp * @next StellarCreateAccountOp - * @next StellarPathPaymentOp - * @next StellarManageOfferOp + * @next StellarPathPaymentStrictReceiveOp + * @next StellarManageSellOfferOp * @next StellarCreatePassiveOfferOp * @next StellarSetOptionsOp * @next StellarChangeTrustOp @@ -115,7 +115,7 @@ message StellarCreateAccountOp { * @next StellarTxOpRequest * @next StellarSignedTx */ -message StellarPathPaymentOp { +message StellarPathPaymentStrictReceiveOp { optional string source_account = 1; // (optional) source address required StellarAsset send_asset = 2; required sint64 send_max = 3; @@ -130,7 +130,7 @@ message StellarPathPaymentOp { * @next StellarTxOpRequest * @next StellarSignedTx */ -message StellarManageOfferOp { +message StellarManageSellOfferOp { optional string source_account = 1; // (optional) source account address required StellarAsset selling_asset = 2; required StellarAsset buying_asset = 3; diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 138f9b190a0..88bce340412 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -229,8 +229,8 @@ enum MessageType { MessageType_StellarAddress = 208 [(wire_out) = true]; MessageType_StellarCreateAccountOp = 210 [(wire_in) = true]; MessageType_StellarPaymentOp = 211 [(wire_in) = true]; - MessageType_StellarPathPaymentOp = 212 [(wire_in) = true]; - MessageType_StellarManageOfferOp = 213 [(wire_in) = true]; + MessageType_StellarPathPaymentStrictReceiveOp = 212 [(wire_in) = true]; + MessageType_StellarManageSellOfferOp = 213 [(wire_in) = true]; MessageType_StellarCreatePassiveOfferOp = 214 [(wire_in) = true]; MessageType_StellarSetOptionsOp = 215 [(wire_in) = true]; MessageType_StellarChangeTrustOp = 216 [(wire_in) = true]; diff --git a/common/tests/fixtures/stellar/sign_tx.json b/common/tests/fixtures/stellar/sign_tx.json index 81e7f17cf4c..0f01048eda1 100644 --- a/common/tests/fixtures/stellar/sign_tx.json +++ b/common/tests/fixtures/stellar/sign_tx.json @@ -336,7 +336,7 @@ } }, { - "name": "StellarManageOfferOp", + "name": "StellarManageSellOfferOp", "parameters": { "xdr": "AAAAAgAAAAAvIrnGLwi3dPPr5t1ufbk8PsLL3gJ5Vho9nFIluMMikgAAAGQAAAAAAAAD6AAAAAEAAAAAG4J3zQAAAABd5CqEAAAAAAAAAAEAAAAAAAAAAwAAAAJBQkNERUZHSElKS0wAAAAAKYSWAsIOWDZfEjwS2HocpFUNEM0hsK4OGNROPlb9ahUAAAABWAAAAAAAAAAphJYCwg5YNl8SPBLYehykVQ0QzSGwrg4Y1E4+Vv1qFQAAAAAdzxaYAAAAAwAAAAQAAAAAAAAFOQAAAAAAAAAA", "address_n": "m/44'/148'/0'", @@ -351,7 +351,7 @@ }, "operations": [ { - "_message_type": "StellarManageOfferOp", + "_message_type": "StellarManageSellOfferOp", "selling_asset": { "type": "ALPHANUM12", "code": "ABCDEFGHIJKL", @@ -375,7 +375,7 @@ } }, { - "name": "StellarPathPaymentOp", + "name": "StellarPathPaymentStrictReceiveOp", "parameters": { "xdr": "AAAAAgAAAAAvIrnGLwi3dPPr5t1ufbk8PsLL3gJ5Vho9nFIluMMikgAAAGQAAAAAAAAD6AAAAAEAAAAAG4J3zQAAAABd5CqEAAAAAAAAAAEAAAAAAAAAAgAAAAFYAAAAAAAAACmElgLCDlg2XxI8Eth6HKRVDRDNIbCuDhjUTj5W/WoVAAAAAB3PFpgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAACQUJDREVGR0hJSktMAAAAACmElgLCDlg2XxI8Eth6HKRVDRDNIbCuDhjUTj5W/WoVAAAAAAAB4kAAAAAAAAAAAAAAAAA=", "address_n": "m/44'/148'/0'", @@ -390,7 +390,7 @@ }, "operations": [ { - "_message_type": "StellarPathPaymentOp", + "_message_type": "StellarPathPaymentStrictReceiveOp", "send_asset": { "type": "ALPHANUM4", "code": "X", diff --git a/core/.changelog.d/1838.incompatible b/core/.changelog.d/1838.incompatible new file mode 100644 index 00000000000..0f2b478a616 --- /dev/null +++ b/core/.changelog.d/1838.incompatible @@ -0,0 +1 @@ +Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp and StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp. diff --git a/core/src/apps/stellar/README.md b/core/src/apps/stellar/README.md index 9d5ef2d4ef1..eb5acdb9a12 100644 --- a/core/src/apps/stellar/README.md +++ b/core/src/apps/stellar/README.md @@ -25,8 +25,8 @@ Stellar transaction is composed of one or more operations. We support all [opera - Create Account - Create Passive Offer - Manage Data -- Manage Offer -- Path Payment +- Manage Sell Offer +- Path Payment Strict Receive - Payment - Set Options diff --git a/core/src/apps/stellar/consts.py b/core/src/apps/stellar/consts.py index 04ebe99ba67..f2b7ddf5410 100644 --- a/core/src/apps/stellar/consts.py +++ b/core/src/apps/stellar/consts.py @@ -14,8 +14,8 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, - StellarManageOfferOp, - StellarPathPaymentOp, + StellarManageSellOfferOp, + StellarPathPaymentStrictReceiveOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -28,8 +28,8 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, - StellarManageOfferOp, - StellarPathPaymentOp, + StellarManageSellOfferOp, + StellarPathPaymentStrictReceiveOp, StellarPaymentOp, StellarSetOptionsOp, ] @@ -47,8 +47,8 @@ MessageType.StellarCreateAccountOp: 0, MessageType.StellarCreatePassiveOfferOp: 4, MessageType.StellarManageDataOp: 10, - MessageType.StellarManageOfferOp: 3, - MessageType.StellarPathPaymentOp: 2, + MessageType.StellarManageSellOfferOp: 3, + MessageType.StellarPathPaymentStrictReceiveOp: 2, MessageType.StellarPaymentOp: 1, MessageType.StellarSetOptionsOp: 5, } @@ -61,8 +61,8 @@ MessageType.StellarCreateAccountOp, MessageType.StellarCreatePassiveOfferOp, MessageType.StellarManageDataOp, - MessageType.StellarManageOfferOp, - MessageType.StellarPathPaymentOp, + MessageType.StellarManageSellOfferOp, + MessageType.StellarPathPaymentStrictReceiveOp, MessageType.StellarPaymentOp, MessageType.StellarSetOptionsOp, ] diff --git a/core/src/apps/stellar/operations/__init__.py b/core/src/apps/stellar/operations/__init__.py index dbac9834cc5..57a3f7e857e 100644 --- a/core/src/apps/stellar/operations/__init__.py +++ b/core/src/apps/stellar/operations/__init__.py @@ -34,12 +34,12 @@ async def process_operation( elif serialize.StellarManageDataOp.is_type_of(op): await layout.confirm_manage_data_op(ctx, op) serialize.write_manage_data_op(w, op) - elif serialize.StellarManageOfferOp.is_type_of(op): - await layout.confirm_manage_offer_op(ctx, op) - serialize.write_manage_offer_op(w, op) - elif serialize.StellarPathPaymentOp.is_type_of(op): - await layout.confirm_path_payment_op(ctx, op) - serialize.write_path_payment_op(w, op) + elif serialize.StellarManageSellOfferOp.is_type_of(op): + await layout.confirm_manage_sell_offer_op(ctx, op) + serialize.write_manage_sell_offer_op(w, op) + elif serialize.StellarPathPaymentStrictReceiveOp.is_type_of(op): + await layout.confirm_path_payment_strict_receive_op(ctx, op) + serialize.write_path_payment_strict_receive_op(w, op) elif serialize.StellarPaymentOp.is_type_of(op): await layout.confirm_payment_op(ctx, op) serialize.write_payment_op(w, op) diff --git a/core/src/apps/stellar/operations/layout.py b/core/src/apps/stellar/operations/layout.py index 7d627fcb34f..9a4fc3aebac 100644 --- a/core/src/apps/stellar/operations/layout.py +++ b/core/src/apps/stellar/operations/layout.py @@ -8,8 +8,8 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, - StellarManageOfferOp, - StellarPathPaymentOp, + StellarManageSellOfferOp, + StellarPathPaymentStrictReceiveOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -106,7 +106,9 @@ async def confirm_create_passive_offer_op( await _confirm_offer(ctx, text, op) -async def confirm_manage_offer_op(ctx: Context, op: StellarManageOfferOp) -> None: +async def confirm_manage_sell_offer_op( + ctx: Context, op: StellarManageSellOfferOp +) -> None: if op.offer_id == 0: text = "New Offer" else: @@ -121,7 +123,7 @@ async def confirm_manage_offer_op(ctx: Context, op: StellarManageOfferOp) -> Non async def _confirm_offer( ctx: Context, title: str, - op: StellarCreatePassiveOfferOp | StellarManageOfferOp, + op: StellarCreatePassiveOfferOp | StellarManageSellOfferOp, ) -> None: await confirm_properties( ctx, @@ -161,7 +163,9 @@ async def confirm_manage_data_op(ctx: Context, op: StellarManageDataOp) -> None: ) -async def confirm_path_payment_op(ctx: Context, op: StellarPathPaymentOp) -> None: +async def confirm_path_payment_strict_receive_op( + ctx: Context, op: StellarPathPaymentStrictReceiveOp +) -> None: await confirm_output( ctx, address=op.destination_account, @@ -175,7 +179,7 @@ async def confirm_path_payment_op(ctx: Context, op: StellarPathPaymentOp) -> Non title="Debited amount", amount=format_amount(op.send_max, op.send_asset), description="Pay at most:", - br_type="op_path_payment", + br_type="op_path_payment_strict_receive", ) await confirm_asset_issuer(ctx, op.send_asset) diff --git a/core/src/apps/stellar/operations/serialize.py b/core/src/apps/stellar/operations/serialize.py index a7546e182a6..138a92092bc 100644 --- a/core/src/apps/stellar/operations/serialize.py +++ b/core/src/apps/stellar/operations/serialize.py @@ -8,8 +8,8 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, - StellarManageOfferOp, - StellarPathPaymentOp, + StellarManageSellOfferOp, + StellarPathPaymentStrictReceiveOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -65,7 +65,7 @@ def write_manage_data_op(w: Writer, msg: StellarManageDataOp) -> None: writers.write_string(w, msg.value) -def write_manage_offer_op(w: Writer, msg: StellarManageOfferOp) -> None: +def write_manage_sell_offer_op(w: Writer, msg: StellarManageSellOfferOp) -> None: _write_asset(w, msg.selling_asset) _write_asset(w, msg.buying_asset) writers.write_uint64(w, msg.amount) # amount to sell @@ -74,7 +74,9 @@ def write_manage_offer_op(w: Writer, msg: StellarManageOfferOp) -> None: writers.write_uint64(w, msg.offer_id) -def write_path_payment_op(w: Writer, msg: StellarPathPaymentOp) -> None: +def write_path_payment_strict_receive_op( + w: Writer, msg: StellarPathPaymentStrictReceiveOp +) -> None: _write_asset(w, msg.send_asset) writers.write_uint64(w, msg.send_max) writers.write_pubkey(w, msg.destination_account) diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index dec7d1ddf4f..76cf118157d 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -121,8 +121,8 @@ StellarAddress = 208 StellarCreateAccountOp = 210 StellarPaymentOp = 211 - StellarPathPaymentOp = 212 - StellarManageOfferOp = 213 + StellarPathPaymentStrictReceiveOp = 212 + StellarManageSellOfferOp = 213 StellarCreatePassiveOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 1f5b23d3f32..16803018b0b 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -126,8 +126,8 @@ class MessageType(IntEnum): StellarAddress = 208 StellarCreateAccountOp = 210 StellarPaymentOp = 211 - StellarPathPaymentOp = 212 - StellarManageOfferOp = 213 + StellarPathPaymentStrictReceiveOp = 212 + StellarManageSellOfferOp = 213 StellarCreatePassiveOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 289776c986f..275be74781b 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -4772,7 +4772,7 @@ def __init__( def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarCreateAccountOp"]: return isinstance(msg, cls) - class StellarPathPaymentOp(protobuf.MessageType): + class StellarPathPaymentStrictReceiveOp(protobuf.MessageType): source_account: "str | None" send_asset: "StellarAsset" send_max: "int" @@ -4795,10 +4795,10 @@ def __init__( pass @classmethod - def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarPathPaymentOp"]: + def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarPathPaymentStrictReceiveOp"]: return isinstance(msg, cls) - class StellarManageOfferOp(protobuf.MessageType): + class StellarManageSellOfferOp(protobuf.MessageType): source_account: "str | None" selling_asset: "StellarAsset" buying_asset: "StellarAsset" @@ -4821,7 +4821,7 @@ def __init__( pass @classmethod - def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarManageOfferOp"]: + def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarManageSellOfferOp"]: return isinstance(msg, cls) class StellarCreatePassiveOfferOp(protobuf.MessageType): diff --git a/legacy/firmware/.changelog.d/1838.incompatible b/legacy/firmware/.changelog.d/1838.incompatible new file mode 100644 index 00000000000..0f2b478a616 --- /dev/null +++ b/legacy/firmware/.changelog.d/1838.incompatible @@ -0,0 +1 @@ +Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp and StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp. diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index 156057c87bd..6a3bbcdf17f 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -118,8 +118,9 @@ void fsm_msgStellarGetAddress(const StellarGetAddress *msg); void fsm_msgStellarSignTx(const StellarSignTx *msg); void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg); void fsm_msgStellarCreateAccountOp(const StellarCreateAccountOp *msg); -void fsm_msgStellarPathPaymentOp(const StellarPathPaymentOp *msg); -void fsm_msgStellarManageOfferOp(const StellarManageOfferOp *msg); +void fsm_msgStellarPathPaymentStrictReceiveOp( + const StellarPathPaymentStrictReceiveOp *msg); +void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg); void fsm_msgStellarCreatePassiveOfferOp(const StellarCreatePassiveOfferOp *msg); void fsm_msgStellarSetOptionsOp(const StellarSetOptionsOp *msg); void fsm_msgStellarChangeTrustOp(const StellarChangeTrustOp *msg); diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 06582de135f..96b0995ec08 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -109,8 +109,9 @@ void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg) { } } -void fsm_msgStellarPathPaymentOp(const StellarPathPaymentOp *msg) { - if (!stellar_confirmPathPaymentOp(msg)) return; +void fsm_msgStellarPathPaymentStrictReceiveOp( + const StellarPathPaymentStrictReceiveOp *msg) { + if (!stellar_confirmPathPaymentStrictReceiveOp(msg)) return; if (stellar_allOperationsConfirmed()) { RESP_INIT(StellarSignedTx); @@ -127,8 +128,8 @@ void fsm_msgStellarPathPaymentOp(const StellarPathPaymentOp *msg) { } } -void fsm_msgStellarManageOfferOp(const StellarManageOfferOp *msg) { - if (!stellar_confirmManageOfferOp(msg)) return; +void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg) { + if (!stellar_confirmManageSellOfferOp(msg)) return; if (stellar_allOperationsConfirmed()) { RESP_INIT(StellarSignedTx); diff --git a/legacy/firmware/protob/messages-stellar.options b/legacy/firmware/protob/messages-stellar.options index d76de77a5ed..c87ed96dd5c 100644 --- a/legacy/firmware/protob/messages-stellar.options +++ b/legacy/firmware/protob/messages-stellar.options @@ -17,12 +17,12 @@ StellarPaymentOp.destination_account max_size:57 StellarCreateAccountOp.source_account max_size:57 StellarCreateAccountOp.new_account max_size:57 -StellarPathPaymentOp.source_account max_size:57 -StellarPathPaymentOp.destination_account max_size:57 -StellarPathPaymentOp.paths max_count:5 +StellarPathPaymentStrictReceiveOp.source_account max_size:57 +StellarPathPaymentStrictReceiveOp.destination_account max_size:57 +StellarPathPaymentStrictReceiveOp.paths max_count:5 -StellarManageOfferOp.source_account max_size:57 +StellarManageSellOfferOp.source_account max_size:57 StellarCreatePassiveOfferOp.source_account max_size:57 diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index c09c543527c..dab37524010 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -289,7 +289,8 @@ bool stellar_confirmPaymentOp(const StellarPaymentOp *msg) { return true; } -bool stellar_confirmPathPaymentOp(const StellarPathPaymentOp *msg) { +bool stellar_confirmPathPaymentStrictReceiveOp( + const StellarPathPaymentStrictReceiveOp *msg) { if (!stellar_signing) return false; if (!stellar_confirmSourceAccount(msg->has_source_account, @@ -387,7 +388,7 @@ bool stellar_confirmPathPaymentOp(const StellarPathPaymentOp *msg) { return true; } -bool stellar_confirmManageOfferOp(const StellarManageOfferOp *msg) { +bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { if (!stellar_signing) return false; if (!stellar_confirmSourceAccount(msg->has_source_account, diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h index 5f67d55219c..0f28878b991 100644 --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -59,8 +59,9 @@ bool stellar_confirmSourceAccount(bool has_source_account, const char *str_account); bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg); bool stellar_confirmPaymentOp(const StellarPaymentOp *msg); -bool stellar_confirmPathPaymentOp(const StellarPathPaymentOp *msg); -bool stellar_confirmManageOfferOp(const StellarManageOfferOp *msg); +bool stellar_confirmPathPaymentStrictReceiveOp( + const StellarPathPaymentStrictReceiveOp *msg); +bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg); bool stellar_confirmCreatePassiveOfferOp( const StellarCreatePassiveOfferOp *msg); bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg); diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index c9cf4e5c865..278d43c24dd 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -147,8 +147,8 @@ class MessageType(IntEnum): StellarAddress = 208 StellarCreateAccountOp = 210 StellarPaymentOp = 211 - StellarPathPaymentOp = 212 - StellarManageOfferOp = 213 + StellarPathPaymentStrictReceiveOp = 212 + StellarManageSellOfferOp = 213 StellarCreatePassiveOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 @@ -6324,7 +6324,7 @@ def __init__( self.source_account = source_account -class StellarPathPaymentOp(protobuf.MessageType): +class StellarPathPaymentStrictReceiveOp(protobuf.MessageType): MESSAGE_WIRE_TYPE = 212 FIELDS = { 1: protobuf.Field("source_account", "string", repeated=False, required=False), @@ -6356,7 +6356,7 @@ def __init__( self.source_account = source_account -class StellarManageOfferOp(protobuf.MessageType): +class StellarManageSellOfferOp(protobuf.MessageType): MESSAGE_WIRE_TYPE = 213 FIELDS = { 1: protobuf.Field("source_account", "string", repeated=False, required=False), diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index b664e55d006..8e6814a5778 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -128,7 +128,7 @@ def _read_operation(op: "Operation"): amount=_read_amount(op.amount), ) if isinstance(op, PathPaymentStrictReceive): - operation = messages.StellarPathPaymentOp( + operation = messages.StellarPathPaymentStrictReceiveOp( source_account=source_account, send_asset=_read_asset(op.send_asset), send_max=_read_amount(op.send_max), @@ -140,7 +140,7 @@ def _read_operation(op: "Operation"): return operation if isinstance(op, ManageSellOffer): price = _read_price(op.price) - return messages.StellarManageOfferOp( + return messages.StellarManageSellOfferOp( source_account=source_account, selling_asset=_read_asset(op.selling), buying_asset=_read_asset(op.buying), diff --git a/python/tests/test_stellar.py b/python/tests/test_stellar.py index e0b9d254c1e..3d9f0020443 100644 --- a/python/tests/test_stellar.py +++ b/python/tests/test_stellar.py @@ -325,7 +325,7 @@ def test_path_payment_strict_receive(): tx, operations = stellar.from_envelope(envelope) assert len(operations) == 1 - assert isinstance(operations[0], messages.StellarPathPaymentOp) + assert isinstance(operations[0], messages.StellarPathPaymentStrictReceiveOp) assert operations[0].source_account == operation_source assert operations[0].destination_account == destination assert operations[0].send_asset.type == messages.StellarAssetType.NATIVE @@ -368,7 +368,7 @@ def test_manage_sell_offer_new_offer(): tx, operations = stellar.from_envelope(envelope) assert len(operations) == 1 - assert isinstance(operations[0], messages.StellarManageOfferOp) + assert isinstance(operations[0], messages.StellarManageSellOfferOp) assert operations[0].source_account == operation_source assert operations[0].selling_asset.type == messages.StellarAssetType.NATIVE assert operations[0].buying_asset.type == messages.StellarAssetType.ALPHANUM4 @@ -408,7 +408,7 @@ def test_manage_sell_offer_update_offer(): tx, operations = stellar.from_envelope(envelope) assert len(operations) == 1 - assert isinstance(operations[0], messages.StellarManageOfferOp) + assert isinstance(operations[0], messages.StellarManageSellOfferOp) assert operations[0].source_account == operation_source assert operations[0].selling_asset.type == messages.StellarAssetType.NATIVE assert operations[0].buying_asset.type == messages.StellarAssetType.ALPHANUM4 diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index 9bef01a9dc3..d793b94a84f 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -846,8 +846,8 @@ "test_stellar.py::test_sign_tx[StellarCreateAccountOp]": "2582717c25974d2b3ee156624b00375148ff7fd12eeea73625a7c367fa610373", "test_stellar.py::test_sign_tx[StellarCreatePassiveOfferOp]": "6b0f0d2b746f98e2c85006ea7e2d5c49cd9277662e47f223138ff418066791e3", "test_stellar.py::test_sign_tx[StellarManageDataOp]": "8fbec6547a8f9d1f002181db0cbe57fe86abef8d365b1c06fd14292cd0b068a7", -"test_stellar.py::test_sign_tx[StellarManageOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", -"test_stellar.py::test_sign_tx[StellarPathPaymentOp]": "58f3bfaece0706bc172d6e6564b728ec0b7f8e2629d8c64dc60672786586076d", +"test_stellar.py::test_sign_tx[StellarManageSellOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", +"test_stellar.py::test_sign_tx[StellarPathPaymentStrictReceiveOp]": "58f3bfaece0706bc172d6e6564b728ec0b7f8e2629d8c64dc60672786586076d", "test_stellar.py::test_sign_tx[StellarPaymentOp-asset12]": "1d8e9d5d65420a259f7e2deef1efaf0ce5be966a0f1e5b8e95b832f176f00de2", "test_stellar.py::test_sign_tx[StellarPaymentOp-asset4]": "0de0b815dad5d348a3b9d06e37da94800363e5de8e6ca9cd0f84e5070f7e1b22", "test_stellar.py::test_sign_tx[StellarPaymentOp-native_asset]": "b2015b9e0f9ff60e2ea4fca2942e97b70a320386c2043fb36acde4a830272098", From 4ef6eac04aab3a2dd4de2f98ba13a8109d715dbe Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Thu, 7 Oct 2021 11:48:45 +0800 Subject: [PATCH 2/6] feat(common & core & legacy): Stellar, add support for StellarManageBuyOfferOp. --- common/protob/messages-stellar.proto | 16 ++++ common/protob/messages.proto | 1 + common/tests/fixtures/stellar/sign_tx.json | 39 +++++++++ core/.changelog.d/1838.added | 1 + core/src/apps/stellar/README.md | 1 + core/src/apps/stellar/consts.py | 6 +- core/src/apps/stellar/operations/__init__.py | 3 + core/src/apps/stellar/operations/layout.py | 57 +++++++++--- core/src/apps/stellar/operations/serialize.py | 13 ++- core/src/trezor/enums/MessageType.py | 1 + core/src/trezor/enums/__init__.py | 1 + core/src/trezor/messages.py | 26 ++++++ legacy/firmware/.changelog.d/1838.added | 1 + legacy/firmware/fsm.h | 1 + legacy/firmware/fsm_msg_stellar.h | 18 ++++ .../firmware/protob/messages-stellar.options | 1 + legacy/firmware/stellar.c | 87 +++++++++++++++++++ legacy/firmware/stellar.h | 1 + python/src/trezorlib/messages.py | 33 +++++++ python/src/trezorlib/stellar.py | 12 +++ python/tests/test_stellar.py | 70 +++++++++++++++ tests/ui_tests/fixtures.json | 1 + 22 files changed, 374 insertions(+), 16 deletions(-) create mode 100644 core/.changelog.d/1838.added create mode 100644 legacy/firmware/.changelog.d/1838.added diff --git a/common/protob/messages-stellar.proto b/common/protob/messages-stellar.proto index f31df2f0348..21ca7e8a7b5 100644 --- a/common/protob/messages-stellar.proto +++ b/common/protob/messages-stellar.proto @@ -76,6 +76,7 @@ message StellarSignTx { * @next StellarCreateAccountOp * @next StellarPathPaymentStrictReceiveOp * @next StellarManageSellOfferOp + * @next StellarManageBuyOfferOp * @next StellarCreatePassiveOfferOp * @next StellarSetOptionsOp * @next StellarChangeTrustOp @@ -140,6 +141,21 @@ message StellarManageSellOfferOp { required uint64 offer_id = 7; // Offer ID for updating an existing offer } +/** + * Request: ask device to confirm this operation type + * @next StellarTxOpRequest + * @next StellarSignedTx + */ +message StellarManageBuyOfferOp { + optional string source_account = 1; // (optional) source account address + required StellarAsset selling_asset = 2; + required StellarAsset buying_asset = 3; + required sint64 amount = 4; + required uint32 price_n = 5; // Price numerator + required uint32 price_d = 6; // Price denominator + required uint64 offer_id = 7; // Offer ID for updating an existing offer +} + /** * Request: ask device to confirm this operation type * @next StellarTxOpRequest diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 88bce340412..935d8e43a39 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -239,6 +239,7 @@ enum MessageType { // omitted: StellarInflationOp is not a supported operation, would be 219 MessageType_StellarManageDataOp = 220 [(wire_in) = true]; MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; + MessageType_StellarManageBuyOfferOp = 222 [(wire_in) = true]; MessageType_StellarSignedTx = 230 [(wire_out) = true]; // Cardano diff --git a/common/tests/fixtures/stellar/sign_tx.json b/common/tests/fixtures/stellar/sign_tx.json index 0f01048eda1..455db179b9f 100644 --- a/common/tests/fixtures/stellar/sign_tx.json +++ b/common/tests/fixtures/stellar/sign_tx.json @@ -335,6 +335,45 @@ "signature": "y9xb8IgPpkjgFa87I9alTD0mVc6EUcJrD7erZVPVGLdDs7rjh7fVtLAJS7iin85Yle0AwnqqEADYAjVzHzz7Bg==" } }, + { + "name": "StellarManageBuyOfferOp", + "parameters": { + "xdr": "AAAAAgAAAAAvIrnGLwi3dPPr5t1ufbk8PsLL3gJ5Vho9nFIluMMikgAAAGQAAAAAAAAD6AAAAAEAAAAAG4J3zQAAAABd5CqEAAAAAAAAAAEAAAAAAAAADAAAAAJBQkNERUZHSElKS0wAAAAAKYSWAsIOWDZfEjwS2HocpFUNEM0hsK4OGNROPlb9ahUAAAABWAAAAAAAAABwi6oxX35cFm2EtGS/s4/WJXj+OtJyJ+dsy7ehecRRIQAAAAAdzxaYAAAAAwAAAAQAAAAAAAAFOQAAAAAAAAAA", + "address_n": "m/44'/148'/0'", + "network_passphrase": "Test SDF Network ; September 2015", + "tx": { + "source_account": "GAXSFOOGF4ELO5HT5PTN23T5XE6D5QWL3YBHSVQ2HWOFEJNYYMRJENBV", + "fee": 100, + "sequence_number": 1000, + "timebounds_start": 461535181, + "timebounds_end": 1575234180, + "memo_type": "NONE" + }, + "operations": [ + { + "_message_type": "StellarManageBuyOfferOp", + "selling_asset": { + "type": "ALPHANUM12", + "code": "ABCDEFGHIJKL", + "issuer": "GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC" + }, + "buying_asset": { + "type": "ALPHANUM4", + "code": "X", + "issuer": "GBYIXKRRL57FYFTNQS2GJP5TR7LCK6H6HLJHEJ7HNTF3PILZYRISDLNQ" + }, + "amount": 500111000, + "price_n": 3, + "price_d": 4, + "offer_id": 1337 + } + ] + }, + "result": { + "public_key": "2f22b9c62f08b774f3ebe6dd6e7db93c3ec2cbde0279561a3d9c5225b8c32292", + "signature": "sDQuKEm7j6Lsuw+QUTrotSloZiF+8LrXsuoLCBadewWpArO8+qmMgonrG3bJfaZ4dYdD8WcpfP5LNLOfU+lDBA==" + } + }, { "name": "StellarManageSellOfferOp", "parameters": { diff --git a/core/.changelog.d/1838.added b/core/.changelog.d/1838.added new file mode 100644 index 00000000000..657fef175b1 --- /dev/null +++ b/core/.changelog.d/1838.added @@ -0,0 +1 @@ +Stellar: add support for StellarManageBuyOfferOp. diff --git a/core/src/apps/stellar/README.md b/core/src/apps/stellar/README.md index eb5acdb9a12..e0ed211732d 100644 --- a/core/src/apps/stellar/README.md +++ b/core/src/apps/stellar/README.md @@ -25,6 +25,7 @@ Stellar transaction is composed of one or more operations. We support all [opera - Create Account - Create Passive Offer - Manage Data +- Manage Buy Offer - Manage Sell Offer - Path Payment Strict Receive - Payment diff --git a/core/src/apps/stellar/consts.py b/core/src/apps/stellar/consts.py index f2b7ddf5410..7028db6d914 100644 --- a/core/src/apps/stellar/consts.py +++ b/core/src/apps/stellar/consts.py @@ -14,6 +14,7 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, + StellarManageBuyOfferOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, StellarPaymentOp, @@ -28,6 +29,7 @@ StellarCreateAccountOp, StellarCreatePassiveOfferOp, StellarManageDataOp, + StellarManageBuyOfferOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, StellarPaymentOp, @@ -37,7 +39,7 @@ TX_TYPE = b"\x00\x00\x00\x02" -# source: https://github.com/stellar/go/blob/3d2c1defe73dbfed00146ebe0e8d7e07ce4bb1b6/xdr/Stellar-transaction.x#L16 +# source: https://github.com/stellar/go/blob/a1db2a6b1f/xdr/Stellar-transaction.x#L35 # Inflation not supported see https://github.com/trezor/trezor-core/issues/202#issuecomment-393342089 op_codes: dict[int, int] = { MessageType.StellarAccountMergeOp: 8, @@ -47,6 +49,7 @@ MessageType.StellarCreateAccountOp: 0, MessageType.StellarCreatePassiveOfferOp: 4, MessageType.StellarManageDataOp: 10, + MessageType.StellarManageBuyOfferOp: 12, MessageType.StellarManageSellOfferOp: 3, MessageType.StellarPathPaymentStrictReceiveOp: 2, MessageType.StellarPaymentOp: 1, @@ -61,6 +64,7 @@ MessageType.StellarCreateAccountOp, MessageType.StellarCreatePassiveOfferOp, MessageType.StellarManageDataOp, + MessageType.StellarManageBuyOfferOp, MessageType.StellarManageSellOfferOp, MessageType.StellarPathPaymentStrictReceiveOp, MessageType.StellarPaymentOp, diff --git a/core/src/apps/stellar/operations/__init__.py b/core/src/apps/stellar/operations/__init__.py index 57a3f7e857e..058e5ae306e 100644 --- a/core/src/apps/stellar/operations/__init__.py +++ b/core/src/apps/stellar/operations/__init__.py @@ -34,6 +34,9 @@ async def process_operation( elif serialize.StellarManageDataOp.is_type_of(op): await layout.confirm_manage_data_op(ctx, op) serialize.write_manage_data_op(w, op) + elif serialize.StellarManageBuyOfferOp.is_type_of(op): + await layout.confirm_manage_buy_offer_op(ctx, op) + serialize.write_manage_buy_offer_op(w, op) elif serialize.StellarManageSellOfferOp.is_type_of(op): await layout.confirm_manage_sell_offer_op(ctx, op) serialize.write_manage_sell_offer_op(w, op) diff --git a/core/src/apps/stellar/operations/layout.py b/core/src/apps/stellar/operations/layout.py index 9a4fc3aebac..e5e3e85961c 100644 --- a/core/src/apps/stellar/operations/layout.py +++ b/core/src/apps/stellar/operations/layout.py @@ -7,6 +7,7 @@ StellarChangeTrustOp, StellarCreateAccountOp, StellarCreatePassiveOfferOp, + StellarManageBuyOfferOp, StellarManageDataOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, @@ -106,8 +107,20 @@ async def confirm_create_passive_offer_op( await _confirm_offer(ctx, text, op) +async def confirm_manage_buy_offer_op( + ctx: Context, op: StellarManageBuyOfferOp +) -> None: + await _confirm_manage_offer_op_common(ctx, op) + + async def confirm_manage_sell_offer_op( ctx: Context, op: StellarManageSellOfferOp +) -> None: + await _confirm_manage_offer_op_common(ctx, op) + + +async def _confirm_manage_offer_op_common( + ctx: Context, op: StellarManageBuyOfferOp | StellarManageSellOfferOp ) -> None: if op.offer_id == 0: text = "New Offer" @@ -123,21 +136,37 @@ async def confirm_manage_sell_offer_op( async def _confirm_offer( ctx: Context, title: str, - op: StellarCreatePassiveOfferOp | StellarManageSellOfferOp, + op: StellarCreatePassiveOfferOp + | StellarManageSellOfferOp + | StellarManageBuyOfferOp, ) -> None: - await confirm_properties( - ctx, - "op_offer", - title=title, - props=( - ("Selling:", format_amount(op.amount, op.selling_asset)), - ("Buying:", format_asset(op.buying_asset)), - ( - f"Price per {format_asset(op.buying_asset)}:", - str(op.price_n / op.price_d), - ), - ), - ) + if StellarManageBuyOfferOp.is_type_of(op): + buying = ("Buying:", format_amount(op.amount, op.buying_asset)) + selling = ("Selling:", format_asset(op.selling_asset)) + price = ( + f"Price per {format_asset(op.selling_asset)}:", + str(op.price_n / op.price_d), + ) + await confirm_properties( + ctx, + "op_offer", + title=title, + props=(buying, selling, price), + ) + else: + selling = ("Selling:", format_amount(op.amount, op.selling_asset)) + buying = ("Buying:", format_asset(op.buying_asset)) + price = ( + f"Price per {format_asset(op.buying_asset)}:", + str(op.price_n / op.price_d), + ) + await confirm_properties( + ctx, + "op_offer", + title=title, + props=(selling, buying, price), + ) + await confirm_asset_issuer(ctx, op.selling_asset) await confirm_asset_issuer(ctx, op.buying_asset) diff --git a/core/src/apps/stellar/operations/serialize.py b/core/src/apps/stellar/operations/serialize.py index 138a92092bc..e730958e89b 100644 --- a/core/src/apps/stellar/operations/serialize.py +++ b/core/src/apps/stellar/operations/serialize.py @@ -7,6 +7,7 @@ StellarChangeTrustOp, StellarCreateAccountOp, StellarCreatePassiveOfferOp, + StellarManageBuyOfferOp, StellarManageDataOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, @@ -65,10 +66,20 @@ def write_manage_data_op(w: Writer, msg: StellarManageDataOp) -> None: writers.write_string(w, msg.value) +def write_manage_buy_offer_op(w: Writer, msg: StellarManageBuyOfferOp) -> None: + _write_manage_offer_op_common(w, msg) + + def write_manage_sell_offer_op(w: Writer, msg: StellarManageSellOfferOp) -> None: + _write_manage_offer_op_common(w, msg) + + +def _write_manage_offer_op_common( + w: Writer, msg: StellarManageSellOfferOp | StellarManageBuyOfferOp +) -> None: _write_asset(w, msg.selling_asset) _write_asset(w, msg.buying_asset) - writers.write_uint64(w, msg.amount) # amount to sell + writers.write_uint64(w, msg.amount) # amount to sell / buy writers.write_uint32(w, msg.price_n) # numerator writers.write_uint32(w, msg.price_d) # denominator writers.write_uint64(w, msg.offer_id) diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 76cf118157d..da6cba09b09 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -130,6 +130,7 @@ StellarAccountMergeOp = 218 StellarManageDataOp = 220 StellarBumpSequenceOp = 221 + StellarManageBuyOfferOp = 222 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 16803018b0b..37c9ec91761 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -135,6 +135,7 @@ class MessageType(IntEnum): StellarAccountMergeOp = 218 StellarManageDataOp = 220 StellarBumpSequenceOp = 221 + StellarManageBuyOfferOp = 222 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 275be74781b..c1d357c8a77 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -4824,6 +4824,32 @@ def __init__( def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarManageSellOfferOp"]: return isinstance(msg, cls) + class StellarManageBuyOfferOp(protobuf.MessageType): + source_account: "str | None" + selling_asset: "StellarAsset" + buying_asset: "StellarAsset" + amount: "int" + price_n: "int" + price_d: "int" + offer_id: "int" + + def __init__( + self, + *, + selling_asset: "StellarAsset", + buying_asset: "StellarAsset", + amount: "int", + price_n: "int", + price_d: "int", + offer_id: "int", + source_account: "str | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarManageBuyOfferOp"]: + return isinstance(msg, cls) + class StellarCreatePassiveOfferOp(protobuf.MessageType): source_account: "str | None" selling_asset: "StellarAsset" diff --git a/legacy/firmware/.changelog.d/1838.added b/legacy/firmware/.changelog.d/1838.added new file mode 100644 index 00000000000..657fef175b1 --- /dev/null +++ b/legacy/firmware/.changelog.d/1838.added @@ -0,0 +1 @@ +Stellar: add support for StellarManageBuyOfferOp. diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index 6a3bbcdf17f..aad610bb089 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -120,6 +120,7 @@ void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg); void fsm_msgStellarCreateAccountOp(const StellarCreateAccountOp *msg); void fsm_msgStellarPathPaymentStrictReceiveOp( const StellarPathPaymentStrictReceiveOp *msg); +void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg); void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg); void fsm_msgStellarCreatePassiveOfferOp(const StellarCreatePassiveOfferOp *msg); void fsm_msgStellarSetOptionsOp(const StellarSetOptionsOp *msg); diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 96b0995ec08..62c4ba4c281 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -128,6 +128,24 @@ void fsm_msgStellarPathPaymentStrictReceiveOp( } } +void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { + if (!stellar_confirmManageBuyOfferOp(msg)) return; + + if (stellar_allOperationsConfirmed()) { + RESP_INIT(StellarSignedTx); + + stellar_fillSignedTx(resp); + msg_write(MessageType_MessageType_StellarSignedTx, resp); + layoutHome(); + } + // Request the next operation to sign + else { + RESP_INIT(StellarTxOpRequest); + + msg_write(MessageType_MessageType_StellarTxOpRequest, resp); + } +} + void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg) { if (!stellar_confirmManageSellOfferOp(msg)) return; diff --git a/legacy/firmware/protob/messages-stellar.options b/legacy/firmware/protob/messages-stellar.options index c87ed96dd5c..61ccb204b60 100644 --- a/legacy/firmware/protob/messages-stellar.options +++ b/legacy/firmware/protob/messages-stellar.options @@ -21,6 +21,7 @@ StellarPathPaymentStrictReceiveOp.source_account max_size:57 StellarPathPaymentStrictReceiveOp.destination_account max_size:57 StellarPathPaymentStrictReceiveOp.paths max_count:5 +StellarManageBuyOfferOp.source_account max_size:57 StellarManageSellOfferOp.source_account max_size:57 diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index dab37524010..4a13e72a4fd 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -388,6 +388,93 @@ bool stellar_confirmPathPaymentStrictReceiveOp( return true; } +bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { + if (!stellar_signing) return false; + + if (!stellar_confirmSourceAccount(msg->has_source_account, + msg->source_account)) { + stellar_signingAbort(_("Source account error")); + return false; + } + + // Hash: operation type + stellar_hashupdate_uint32(12); + + // New Offer / Delete #123 / Update #123 + char str_offer[32] = {0}; + if (msg->offer_id == 0) { + strlcpy(str_offer, _("New Offer"), sizeof(str_offer)); + } else { + char str_offer_id[20] = {0}; + stellar_format_uint64(msg->offer_id, str_offer_id, sizeof(str_offer_id)); + + if (msg->amount == 0) { + strlcpy(str_offer, _("Delete #"), sizeof(str_offer)); + } else { + strlcpy(str_offer, _("Update #"), sizeof(str_offer)); + } + + strlcat(str_offer, str_offer_id, sizeof(str_offer)); + } + + char str_buying[32] = {0}; + char str_buying_amount[32] = {0}; + char str_buying_asset[32] = {0}; + + stellar_format_asset(&(msg->buying_asset), str_buying_asset, + sizeof(str_buying_asset)); + stellar_format_stroops(msg->amount, str_buying_amount, + sizeof(str_buying_amount)); + + /* + Buy 200 + XLM (Native Asset) + */ + strlcpy(str_buying, _("Buy "), sizeof(str_buying)); + strlcat(str_buying, str_buying_amount, sizeof(str_buying)); + + char str_selling[32] = {0}; + char str_selling_asset[32] = {0}; + char str_price[32] = {0}; + + stellar_format_asset(&(msg->selling_asset), str_selling_asset, + sizeof(str_selling_asset)); + stellar_format_price(msg->price_n, msg->price_d, str_price, + sizeof(str_price)); + + /* + For 0.675952 Per + USD (G12345678) + */ + strlcpy(str_selling, _("For "), sizeof(str_selling)); + strlcat(str_selling, str_price, sizeof(str_selling)); + strlcat(str_selling, _(" Per"), sizeof(str_selling)); + + stellar_layoutTransactionDialog(str_offer, str_buying, str_buying_asset, + str_selling, str_selling_asset); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + stellar_signingAbort(_("User canceled")); + return false; + } + + // Hash selling asset + stellar_hashupdate_asset(&(msg->selling_asset)); + // buying asset + stellar_hashupdate_asset(&(msg->buying_asset)); + // amount to buy (signed vs. unsigned doesn't matter wrt hashing) + stellar_hashupdate_uint64(msg->amount); + // numerator + stellar_hashupdate_uint32(msg->price_n); + // denominator + stellar_hashupdate_uint32(msg->price_d); + // offer ID + stellar_hashupdate_uint64(msg->offer_id); + + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + return true; +} + bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { if (!stellar_signing) return false; diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h index 0f28878b991..d50c6663550 100644 --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -61,6 +61,7 @@ bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg); bool stellar_confirmPaymentOp(const StellarPaymentOp *msg); bool stellar_confirmPathPaymentStrictReceiveOp( const StellarPathPaymentStrictReceiveOp *msg); +bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg); bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg); bool stellar_confirmCreatePassiveOfferOp( const StellarCreatePassiveOfferOp *msg); diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 278d43c24dd..52b7c3bb33e 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -156,6 +156,7 @@ class MessageType(IntEnum): StellarAccountMergeOp = 218 StellarManageDataOp = 220 StellarBumpSequenceOp = 221 + StellarManageBuyOfferOp = 222 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 @@ -6388,6 +6389,38 @@ def __init__( self.source_account = source_account +class StellarManageBuyOfferOp(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 222 + FIELDS = { + 1: protobuf.Field("source_account", "string", repeated=False, required=False), + 2: protobuf.Field("selling_asset", "StellarAsset", repeated=False, required=True), + 3: protobuf.Field("buying_asset", "StellarAsset", repeated=False, required=True), + 4: protobuf.Field("amount", "sint64", repeated=False, required=True), + 5: protobuf.Field("price_n", "uint32", repeated=False, required=True), + 6: protobuf.Field("price_d", "uint32", repeated=False, required=True), + 7: protobuf.Field("offer_id", "uint64", repeated=False, required=True), + } + + def __init__( + self, + *, + selling_asset: "StellarAsset", + buying_asset: "StellarAsset", + amount: "int", + price_n: "int", + price_d: "int", + offer_id: "int", + source_account: Optional["str"] = None, + ) -> None: + self.selling_asset = selling_asset + self.buying_asset = buying_asset + self.amount = amount + self.price_n = price_n + self.price_d = price_d + self.offer_id = offer_id + self.source_account = source_account + + class StellarCreatePassiveOfferOp(protobuf.MessageType): MESSAGE_WIRE_TYPE = 214 FIELDS = { diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index 8e6814a5778..b0f969f8f9f 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -43,6 +43,7 @@ TrustLineEntryFlag, Price, Network, + ManageBuyOffer, ) from stellar_sdk.xdr.signer_key_type import SignerKeyType @@ -225,6 +226,17 @@ def _read_operation(op: "Operation"): return messages.StellarBumpSequenceOp( source_account=source_account, bump_to=op.bump_to ) + if isinstance(op, ManageBuyOffer): + price = _read_price(op.price) + return messages.StellarManageBuyOfferOp( + source_account=source_account, + selling_asset=_read_asset(op.selling), + buying_asset=_read_asset(op.buying), + amount=_read_amount(op.amount), + price_n=price.n, + price_d=price.d, + offer_id=op.offer_id, + ) raise ValueError(f"Unknown operation type: {op.__class__.__name__}") diff --git a/python/tests/test_stellar.py b/python/tests/test_stellar.py index 3d9f0020443..ebd773a816b 100644 --- a/python/tests/test_stellar.py +++ b/python/tests/test_stellar.py @@ -712,3 +712,73 @@ def test_bump_sequence(): assert isinstance(operations[0], messages.StellarBumpSequenceOp) assert operations[0].source_account == operation_source assert operations[0].bump_to == bump_to + + +def test_manage_buy_offer_new_offer(): + tx = make_default_tx() + price = "0.5" + amount = "50.0111" + selling_code = "XLM" + selling_issuer = None + buying_code = "USD" + buying_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF" + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + + envelope = tx.append_manage_buy_offer_op( + selling_code=selling_code, + selling_issuer=selling_issuer, + buying_code=buying_code, + buying_issuer=buying_issuer, + amount=amount, + price=price, + source=operation_source, + ).build() + + tx, operations = stellar.from_envelope(envelope) + assert len(operations) == 1 + assert isinstance(operations[0], messages.StellarManageBuyOfferOp) + assert operations[0].source_account == operation_source + assert operations[0].selling_asset.type == messages.StellarAssetType.NATIVE + assert operations[0].buying_asset.type == messages.StellarAssetType.ALPHANUM4 + assert operations[0].buying_asset.code == buying_code + assert operations[0].buying_asset.issuer == buying_issuer + assert operations[0].amount == 500111000 + assert operations[0].price_n == 1 + assert operations[0].price_d == 2 + assert operations[0].offer_id == 0 # indicates a new offer + + +def test_manage_buy_offer_update_offer(): + tx = make_default_tx() + price = "0.5" + amount = "50.0111" + selling_code = "XLM" + selling_issuer = None + buying_code = "USD" + buying_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF" + offer_id = 12345 + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + + envelope = tx.append_manage_buy_offer_op( + selling_code=selling_code, + selling_issuer=selling_issuer, + buying_code=buying_code, + buying_issuer=buying_issuer, + amount=amount, + price=price, + offer_id=offer_id, + source=operation_source, + ).build() + + tx, operations = stellar.from_envelope(envelope) + assert len(operations) == 1 + assert isinstance(operations[0], messages.StellarManageBuyOfferOp) + assert operations[0].source_account == operation_source + assert operations[0].selling_asset.type == messages.StellarAssetType.NATIVE + assert operations[0].buying_asset.type == messages.StellarAssetType.ALPHANUM4 + assert operations[0].buying_asset.code == buying_code + assert operations[0].buying_asset.issuer == buying_issuer + assert operations[0].amount == 500111000 + assert operations[0].price_n == 1 + assert operations[0].price_d == 2 + assert operations[0].offer_id == offer_id diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index d793b94a84f..cd80afe6673 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -846,6 +846,7 @@ "test_stellar.py::test_sign_tx[StellarCreateAccountOp]": "2582717c25974d2b3ee156624b00375148ff7fd12eeea73625a7c367fa610373", "test_stellar.py::test_sign_tx[StellarCreatePassiveOfferOp]": "6b0f0d2b746f98e2c85006ea7e2d5c49cd9277662e47f223138ff418066791e3", "test_stellar.py::test_sign_tx[StellarManageDataOp]": "8fbec6547a8f9d1f002181db0cbe57fe86abef8d365b1c06fd14292cd0b068a7", +"test_stellar.py::test_sign_tx[StellarManageBuyOfferOp]": "fc57e1ca8b65588aa16cc3524d6dc0f01e094ad5d16a6f7e739a69c101b554bc", "test_stellar.py::test_sign_tx[StellarManageSellOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", "test_stellar.py::test_sign_tx[StellarPathPaymentStrictReceiveOp]": "58f3bfaece0706bc172d6e6564b728ec0b7f8e2629d8c64dc60672786586076d", "test_stellar.py::test_sign_tx[StellarPaymentOp-asset12]": "1d8e9d5d65420a259f7e2deef1efaf0ce5be966a0f1e5b8e95b832f176f00de2", From e8dc9bc49b41127fe44ceda83dc6d6fc56b9f334 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Thu, 7 Oct 2021 22:06:08 +0800 Subject: [PATCH 3/6] feat(common & core & legacy): Stellar, add support for StellarPathPaymentStrictSendOp. --- common/protob/messages-stellar.proto | 30 +++-- common/protob/messages.proto | 1 + common/tests/fixtures/stellar/sign_tx.json | 50 +++++++++ core/.changelog.d/1838.added | 2 +- core/src/apps/stellar/README.md | 1 + core/src/apps/stellar/consts.py | 4 + core/src/apps/stellar/operations/__init__.py | 3 + core/src/apps/stellar/operations/layout.py | 22 ++++ core/src/apps/stellar/operations/serialize.py | 15 +++ core/src/trezor/enums/MessageType.py | 1 + core/src/trezor/enums/__init__.py | 1 + core/src/trezor/messages.py | 26 +++++ legacy/firmware/.changelog.d/1838.added | 2 +- legacy/firmware/fsm.h | 2 + legacy/firmware/fsm_msg_stellar.h | 19 ++++ .../firmware/protob/messages-stellar.options | 4 + legacy/firmware/stellar.c | 104 +++++++++++++++++- legacy/firmware/stellar.h | 2 + python/src/trezorlib/messages.py | 33 ++++++ python/src/trezorlib/stellar.py | 12 ++ python/tests/test_stellar.py | 55 +++++++++ tests/ui_tests/fixtures.json | 1 + 22 files changed, 378 insertions(+), 12 deletions(-) diff --git a/common/protob/messages-stellar.proto b/common/protob/messages-stellar.proto index 21ca7e8a7b5..22473f7f4ef 100644 --- a/common/protob/messages-stellar.proto +++ b/common/protob/messages-stellar.proto @@ -75,6 +75,7 @@ message StellarSignTx { * @next StellarPaymentOp * @next StellarCreateAccountOp * @next StellarPathPaymentStrictReceiveOp + * @next StellarPathPaymentStrictSendOp * @next StellarManageSellOfferOp * @next StellarManageBuyOfferOp * @next StellarCreatePassiveOfferOp @@ -117,13 +118,28 @@ message StellarCreateAccountOp { * @next StellarSignedTx */ message StellarPathPaymentStrictReceiveOp { - optional string source_account = 1; // (optional) source address - required StellarAsset send_asset = 2; - required sint64 send_max = 3; - required string destination_account = 4; - required StellarAsset destination_asset = 5; - required sint64 destination_amount = 6; - repeated StellarAsset paths = 7; + optional string source_account = 1; // (optional) source address + required StellarAsset send_asset = 2; // asset we pay with + required sint64 send_max = 3; // the maximum amount of sendAsset to send (excluding fees) + required string destination_account = 4; // recipient of the payment + required StellarAsset destination_asset = 5; // what they end up with + required sint64 destination_amount = 6; // amount they end up with + repeated StellarAsset paths = 7; // additional hops it must go through to get there +} + +/** + * Request: ask device to confirm this operation type + * @next StellarTxOpRequest + * @next StellarSignedTx + */ +message StellarPathPaymentStrictSendOp { + optional string source_account = 1; // (optional) source address + required StellarAsset send_asset = 2; // asset we pay with + required sint64 send_amount = 3; // amount of sendAsset to send (excluding fees) + required string destination_account = 4; // recipient of the payment + required StellarAsset destination_asset = 5; // what they end up with + required sint64 destination_min = 6; // the minimum amount of dest asset to be received + repeated StellarAsset paths = 7; //additional hops it must go through to get there } /** diff --git a/common/protob/messages.proto b/common/protob/messages.proto index 935d8e43a39..fa6e9e363aa 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -240,6 +240,7 @@ enum MessageType { MessageType_StellarManageDataOp = 220 [(wire_in) = true]; MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; MessageType_StellarManageBuyOfferOp = 222 [(wire_in) = true]; + MessageType_StellarPathPaymentStrictSendOp = 223 [(wire_in) = true]; MessageType_StellarSignedTx = 230 [(wire_out) = true]; // Cardano diff --git a/common/tests/fixtures/stellar/sign_tx.json b/common/tests/fixtures/stellar/sign_tx.json index 455db179b9f..587b6858929 100644 --- a/common/tests/fixtures/stellar/sign_tx.json +++ b/common/tests/fixtures/stellar/sign_tx.json @@ -451,6 +451,56 @@ "signature": "A/ccrRMTEy3GXaZ7Lo5frX3ME5fy3bDMrmYaZ8oPtpPk+cnRStbcSAgdTKnRq/dPGRLfh2btvPJD9ETMe1ajDA==" } }, + { + "name": "StellarPathPaymentStrictSendOp", + "parameters": { + "xdr": "AAAAAgAAAAAvIrnGLwi3dPPr5t1ufbk8PsLL3gJ5Vho9nFIluMMikgAAAGQAAAAAAAAD6AAAAAEAAAAAG4J3zQAAAABd5CqEAAAAAAAAAAEAAAAAAAAADQAAAAFYAAAAAAAAAHCLqjFfflwWbYS0ZL+zj9YleP460nIn52zLt6F5xFEhAAAAAB3PFpgAAAAAXVVkJGaxhbhDFS6eIZFR28WJICfsQBAaUXvtXKAwwuAAAAACQUJDREVGR0hJSktMAAAAACmElgLCDlg2XxI8Eth6HKRVDRDNIbCuDhjUTj5W/WoVAAAAAAAB4kAAAAACAAAAAUpQWQAAAAAA/Pr8d4Jv8Bq3LDTJiXMR/LjsnkO0R2sDyP5fodnIhB4AAAACQkFOQU5BAAAAAAAAAAAAAL5FO387ZKhuvo51/hHfkV1gShE677dHpUZV6jK+Wgg7AAAAAAAAAAA=", + "address_n": "m/44'/148'/0'", + "network_passphrase": "Test SDF Network ; September 2015", + "tx": { + "source_account": "GAXSFOOGF4ELO5HT5PTN23T5XE6D5QWL3YBHSVQ2HWOFEJNYYMRJENBV", + "fee": 100, + "sequence_number": 1000, + "timebounds_start": 461535181, + "timebounds_end": 1575234180, + "memo_type": "NONE" + }, + "operations": [ + { + "_message_type": "StellarPathPaymentStrictSendOp", + "send_asset": { + "type": "ALPHANUM4", + "code": "X", + "issuer": "GBYIXKRRL57FYFTNQS2GJP5TR7LCK6H6HLJHEJ7HNTF3PILZYRISDLNQ" + }, + "send_amount": 500111000, + "destination_account": "GBOVKZBEM2YYLOCDCUXJ4IMRKHN4LCJAE7WEAEA2KF562XFAGDBOB64V", + "destination_asset": { + "type": "ALPHANUM12", + "code": "ABCDEFGHIJKL", + "issuer": "GAUYJFQCYIHFQNS7CI6BFWD2DSSFKDIQZUQ3BLQODDKE4PSW7VVBKENC" + }, + "destination_min": 123456, + "paths": [ + { + "type": "ALPHANUM4", + "code": "JPY", + "issuer": "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ" + }, + { + "type": "ALPHANUM12", + "code": "BANANA", + "issuer": "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ" + } + ] + } + ] + }, + "result": { + "public_key": "2f22b9c62f08b774f3ebe6dd6e7db93c3ec2cbde0279561a3d9c5225b8c32292", + "signature": "ZoJRiq9zQsbv/w5CA4IOqRPsPY46kzrQ0uMgY+Y9Ec6kKk/0ktFt2icEKNvVAKZUYmfEEigKhki/Rt9meN43CQ==" + } + }, { "name": "StellarManageDataOp", "parameters": { diff --git a/core/.changelog.d/1838.added b/core/.changelog.d/1838.added index 657fef175b1..43800dd7673 100644 --- a/core/.changelog.d/1838.added +++ b/core/.changelog.d/1838.added @@ -1 +1 @@ -Stellar: add support for StellarManageBuyOfferOp. +Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp. diff --git a/core/src/apps/stellar/README.md b/core/src/apps/stellar/README.md index e0ed211732d..5597523c6fd 100644 --- a/core/src/apps/stellar/README.md +++ b/core/src/apps/stellar/README.md @@ -28,6 +28,7 @@ Stellar transaction is composed of one or more operations. We support all [opera - Manage Buy Offer - Manage Sell Offer - Path Payment Strict Receive +- Path Payment Strict Send - Payment - Set Options diff --git a/core/src/apps/stellar/consts.py b/core/src/apps/stellar/consts.py index 7028db6d914..45cbb0ff12d 100644 --- a/core/src/apps/stellar/consts.py +++ b/core/src/apps/stellar/consts.py @@ -17,6 +17,7 @@ StellarManageBuyOfferOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, + StellarPathPaymentStrictSendOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -32,6 +33,7 @@ StellarManageBuyOfferOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, + StellarPathPaymentStrictSendOp, StellarPaymentOp, StellarSetOptionsOp, ] @@ -52,6 +54,7 @@ MessageType.StellarManageBuyOfferOp: 12, MessageType.StellarManageSellOfferOp: 3, MessageType.StellarPathPaymentStrictReceiveOp: 2, + MessageType.StellarPathPaymentStrictSendOp: 13, MessageType.StellarPaymentOp: 1, MessageType.StellarSetOptionsOp: 5, } @@ -67,6 +70,7 @@ MessageType.StellarManageBuyOfferOp, MessageType.StellarManageSellOfferOp, MessageType.StellarPathPaymentStrictReceiveOp, + MessageType.StellarPathPaymentStrictSendOp, MessageType.StellarPaymentOp, MessageType.StellarSetOptionsOp, ] diff --git a/core/src/apps/stellar/operations/__init__.py b/core/src/apps/stellar/operations/__init__.py index 058e5ae306e..e1d93063ca7 100644 --- a/core/src/apps/stellar/operations/__init__.py +++ b/core/src/apps/stellar/operations/__init__.py @@ -43,6 +43,9 @@ async def process_operation( elif serialize.StellarPathPaymentStrictReceiveOp.is_type_of(op): await layout.confirm_path_payment_strict_receive_op(ctx, op) serialize.write_path_payment_strict_receive_op(w, op) + elif serialize.StellarPathPaymentStrictSendOp.is_type_of(op): + await layout.confirm_path_payment_strict_send_op(ctx, op) + serialize.write_path_payment_strict_send_op(w, op) elif serialize.StellarPaymentOp.is_type_of(op): await layout.confirm_payment_op(ctx, op) serialize.write_payment_op(w, op) diff --git a/core/src/apps/stellar/operations/layout.py b/core/src/apps/stellar/operations/layout.py index e5e3e85961c..53c3ab0ce5e 100644 --- a/core/src/apps/stellar/operations/layout.py +++ b/core/src/apps/stellar/operations/layout.py @@ -11,6 +11,7 @@ StellarManageDataOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, + StellarPathPaymentStrictSendOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -213,6 +214,27 @@ async def confirm_path_payment_strict_receive_op( await confirm_asset_issuer(ctx, op.send_asset) +async def confirm_path_payment_strict_send_op( + ctx: Context, op: StellarPathPaymentStrictSendOp +) -> None: + await confirm_output( + ctx, + address=op.destination_account, + amount=format_amount(op.destination_min, op.destination_asset), + title="Path Pay at least", + ) + await confirm_asset_issuer(ctx, op.destination_asset) + # confirm what the sender is using to pay + await confirm_amount( + ctx, + title="Debited amount", + amount=format_amount(op.send_amount, op.send_asset), + description="Pay:", + br_type="op_path_payment_strict_send", + ) + await confirm_asset_issuer(ctx, op.send_asset) + + async def confirm_payment_op(ctx: Context, op: StellarPaymentOp) -> None: await confirm_output( ctx, diff --git a/core/src/apps/stellar/operations/serialize.py b/core/src/apps/stellar/operations/serialize.py index e730958e89b..5ac50276b3f 100644 --- a/core/src/apps/stellar/operations/serialize.py +++ b/core/src/apps/stellar/operations/serialize.py @@ -11,6 +11,7 @@ StellarManageDataOp, StellarManageSellOfferOp, StellarPathPaymentStrictReceiveOp, + StellarPathPaymentStrictSendOp, StellarPaymentOp, StellarSetOptionsOp, ) @@ -99,6 +100,20 @@ def write_path_payment_strict_receive_op( _write_asset(w, p) +def write_path_payment_strict_send_op( + w: Writer, msg: StellarPathPaymentStrictSendOp +) -> None: + _write_asset(w, msg.send_asset) + writers.write_uint64(w, msg.send_amount) + writers.write_pubkey(w, msg.destination_account) + + _write_asset(w, msg.destination_asset) + writers.write_uint64(w, msg.destination_min) + writers.write_uint32(w, len(msg.paths)) + for p in msg.paths: + _write_asset(w, p) + + def write_payment_op(w: Writer, msg: StellarPaymentOp) -> None: writers.write_pubkey(w, msg.destination_account) _write_asset(w, msg.asset) diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index da6cba09b09..925178e3608 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -131,6 +131,7 @@ StellarManageDataOp = 220 StellarBumpSequenceOp = 221 StellarManageBuyOfferOp = 222 + StellarPathPaymentStrictSendOp = 223 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 37c9ec91761..ff51725a19c 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -136,6 +136,7 @@ class MessageType(IntEnum): StellarManageDataOp = 220 StellarBumpSequenceOp = 221 StellarManageBuyOfferOp = 222 + StellarPathPaymentStrictSendOp = 223 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index c1d357c8a77..e401fa96fa7 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -4798,6 +4798,32 @@ def __init__( def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarPathPaymentStrictReceiveOp"]: return isinstance(msg, cls) + class StellarPathPaymentStrictSendOp(protobuf.MessageType): + source_account: "str | None" + send_asset: "StellarAsset" + send_amount: "int" + destination_account: "str" + destination_asset: "StellarAsset" + destination_min: "int" + paths: "list[StellarAsset]" + + def __init__( + self, + *, + send_asset: "StellarAsset", + send_amount: "int", + destination_account: "str", + destination_asset: "StellarAsset", + destination_min: "int", + paths: "list[StellarAsset] | None" = None, + source_account: "str | None" = None, + ) -> None: + pass + + @classmethod + def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarPathPaymentStrictSendOp"]: + return isinstance(msg, cls) + class StellarManageSellOfferOp(protobuf.MessageType): source_account: "str | None" selling_asset: "StellarAsset" diff --git a/legacy/firmware/.changelog.d/1838.added b/legacy/firmware/.changelog.d/1838.added index 657fef175b1..43800dd7673 100644 --- a/legacy/firmware/.changelog.d/1838.added +++ b/legacy/firmware/.changelog.d/1838.added @@ -1 +1 @@ -Stellar: add support for StellarManageBuyOfferOp. +Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp. diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index aad610bb089..e27dad935b7 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -120,6 +120,8 @@ void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg); void fsm_msgStellarCreateAccountOp(const StellarCreateAccountOp *msg); void fsm_msgStellarPathPaymentStrictReceiveOp( const StellarPathPaymentStrictReceiveOp *msg); +void fsm_msgStellarPathPaymentStrictSendOp( + const StellarPathPaymentStrictSendOp *msg); void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg); void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg); void fsm_msgStellarCreatePassiveOfferOp(const StellarCreatePassiveOfferOp *msg); diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 62c4ba4c281..84a074764d7 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -128,6 +128,25 @@ void fsm_msgStellarPathPaymentStrictReceiveOp( } } +void fsm_msgStellarPathPaymentStrictSendOp( + const StellarPathPaymentStrictSendOp *msg) { + if (!stellar_confirmPathPaymentStrictSendOp(msg)) return; + + if (stellar_allOperationsConfirmed()) { + RESP_INIT(StellarSignedTx); + + stellar_fillSignedTx(resp); + msg_write(MessageType_MessageType_StellarSignedTx, resp); + layoutHome(); + } + // Request the next operation to sign + else { + RESP_INIT(StellarTxOpRequest); + + msg_write(MessageType_MessageType_StellarTxOpRequest, resp); + } +} + void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { if (!stellar_confirmManageBuyOfferOp(msg)) return; diff --git a/legacy/firmware/protob/messages-stellar.options b/legacy/firmware/protob/messages-stellar.options index 61ccb204b60..748f9aa3af9 100644 --- a/legacy/firmware/protob/messages-stellar.options +++ b/legacy/firmware/protob/messages-stellar.options @@ -21,6 +21,10 @@ StellarPathPaymentStrictReceiveOp.source_account max_size:57 StellarPathPaymentStrictReceiveOp.destination_account max_size:57 StellarPathPaymentStrictReceiveOp.paths max_count:5 +StellarPathPaymentStrictSendOp.source_account max_size:57 +StellarPathPaymentStrictSendOp.destination_account max_size:57 +StellarPathPaymentStrictSendOp.paths max_count:5 + StellarManageBuyOfferOp.source_account max_size:57 StellarManageSellOfferOp.source_account max_size:57 diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index 4a13e72a4fd..4167c781137 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -356,9 +356,9 @@ bool stellar_confirmPathPaymentStrictReceiveOp( strlcpy(str_source_amount, _("Pay Using "), sizeof(str_source_amount)); strlcat(str_source_amount, str_source_number, sizeof(str_source_amount)); - stellar_layoutTransactionDialog(str_source_amount, str_send_asset, NULL, - _("This is the amount debited"), - _("from your account.")); + stellar_layoutTransactionDialog(str_source_amount, str_send_asset, + _("This is the max"), + _("amount debited from your"), _("account.")); if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { stellar_signingAbort(_("User canceled")); return false; @@ -388,6 +388,104 @@ bool stellar_confirmPathPaymentStrictReceiveOp( return true; } +bool stellar_confirmPathPaymentStrictSendOp( + const StellarPathPaymentStrictSendOp *msg) { + if (!stellar_signing) return false; + + if (!stellar_confirmSourceAccount(msg->has_source_account, + msg->source_account)) { + stellar_signingAbort(_("Source account error")); + return false; + } + + // Hash: operation type + stellar_hashupdate_uint32(13); + + // Validate destination account and convert to bytes + uint8_t destination_account_bytes[STELLAR_KEY_SIZE] = {0}; + if (!stellar_getAddressBytes(msg->destination_account, + destination_account_bytes)) { + stellar_signingAbort(_("Invalid destination account")); + return false; + } + const char **str_dest_rows = + stellar_lineBreakAddress(destination_account_bytes); + + // To: G... + char str_to[32] = {0}; + strlcpy(str_to, _("To: "), sizeof(str_to)); + strlcat(str_to, str_dest_rows[0], sizeof(str_to)); + + char str_send_asset[32] = {0}; + char str_dest_asset[32] = {0}; + stellar_format_asset(&(msg->send_asset), str_send_asset, + sizeof(str_send_asset)); + stellar_format_asset(&(msg->destination_asset), str_dest_asset, + sizeof(str_dest_asset)); + + char str_pay_amount[32] = {0}; + char str_amount[32] = {0}; + stellar_format_stroops(msg->destination_min, str_amount, sizeof(str_amount)); + + strlcat(str_pay_amount, str_amount, sizeof(str_pay_amount)); + + // Confirm what the receiver will get + /* + Path Pay at least + 100.0000000 + JPY (G1234ABCDEF) + To: G.... + .... + .... + */ + stellar_layoutTransactionDialog(_("Path Pay at least"), str_pay_amount, + str_dest_asset, str_to, str_dest_rows[1]); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + stellar_signingAbort(_("User canceled")); + return false; + } + + // Confirm what the sender is using to pay + char str_source_amount[32] = {0}; + char str_source_number[32] = {0}; + stellar_format_stroops(msg->send_amount, str_source_number, + sizeof(str_source_number)); + + strlcpy(str_source_amount, _("Pay Using "), sizeof(str_source_amount)); + strlcat(str_source_amount, str_source_number, sizeof(str_source_amount)); + + stellar_layoutTransactionDialog( + str_dest_rows[2], str_source_amount, str_send_asset, + _("This is the amount debited"), _("from your account.")); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + stellar_signingAbort(_("User canceled")); + return false; + } + // Note: no confirmation for intermediate steps since they don't impact the + // user + + // Hash send asset + stellar_hashupdate_asset(&(msg->send_asset)); + // send amount (signed vs. unsigned doesn't matter wrt hashing) + stellar_hashupdate_uint64(msg->send_amount); + // destination account + stellar_hashupdate_address(destination_account_bytes); + // destination asset + stellar_hashupdate_asset(&(msg->destination_asset)); + // destination amount + stellar_hashupdate_uint64(msg->destination_min); + + // paths are stored as an array so hash the number of elements as a uint32 + stellar_hashupdate_uint32(msg->paths_count); + for (uint8_t i = 0; i < msg->paths_count; i++) { + stellar_hashupdate_asset(&(msg->paths[i])); + } + + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + return true; +} + bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { if (!stellar_signing) return false; diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h index d50c6663550..9fecb69567f 100644 --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -61,6 +61,8 @@ bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg); bool stellar_confirmPaymentOp(const StellarPaymentOp *msg); bool stellar_confirmPathPaymentStrictReceiveOp( const StellarPathPaymentStrictReceiveOp *msg); +bool stellar_confirmPathPaymentStrictSendOp( + const StellarPathPaymentStrictSendOp *msg); bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg); bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg); bool stellar_confirmCreatePassiveOfferOp( diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 52b7c3bb33e..830f69bf5c4 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -157,6 +157,7 @@ class MessageType(IntEnum): StellarManageDataOp = 220 StellarBumpSequenceOp = 221 StellarManageBuyOfferOp = 222 + StellarPathPaymentStrictSendOp = 223 StellarSignedTx = 230 CardanoSignTx = 303 CardanoGetPublicKey = 305 @@ -6357,6 +6358,38 @@ def __init__( self.source_account = source_account +class StellarPathPaymentStrictSendOp(protobuf.MessageType): + MESSAGE_WIRE_TYPE = 223 + FIELDS = { + 1: protobuf.Field("source_account", "string", repeated=False, required=False), + 2: protobuf.Field("send_asset", "StellarAsset", repeated=False, required=True), + 3: protobuf.Field("send_amount", "sint64", repeated=False, required=True), + 4: protobuf.Field("destination_account", "string", repeated=False, required=True), + 5: protobuf.Field("destination_asset", "StellarAsset", repeated=False, required=True), + 6: protobuf.Field("destination_min", "sint64", repeated=False, required=True), + 7: protobuf.Field("paths", "StellarAsset", repeated=True, required=False), + } + + def __init__( + self, + *, + send_asset: "StellarAsset", + send_amount: "int", + destination_account: "str", + destination_asset: "StellarAsset", + destination_min: "int", + paths: Optional[List["StellarAsset"]] = None, + source_account: Optional["str"] = None, + ) -> None: + self.paths = paths if paths is not None else [] + self.send_asset = send_asset + self.send_amount = send_amount + self.destination_account = destination_account + self.destination_asset = destination_asset + self.destination_min = destination_min + self.source_account = source_account + + class StellarManageSellOfferOp(protobuf.MessageType): MESSAGE_WIRE_TYPE = 213 FIELDS = { diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index b0f969f8f9f..00561f51f1f 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -35,6 +35,7 @@ NoneMemo, Operation, PathPaymentStrictReceive, + PathPaymentStrictSend, Payment, ReturnHashMemo, SetOptions, @@ -237,6 +238,17 @@ def _read_operation(op: "Operation"): price_d=price.d, offer_id=op.offer_id, ) + if isinstance(op, PathPaymentStrictSend): + operation = messages.StellarPathPaymentStrictSendOp( + source_account=source_account, + send_asset=_read_asset(op.send_asset), + send_amount=_read_amount(op.send_amount), + destination_account=op.destination.account_id, + destination_asset=_read_asset(op.dest_asset), + destination_min=_read_amount(op.dest_min), + paths=[_read_asset(asset) for asset in op.path], + ) + return operation raise ValueError(f"Unknown operation type: {op.__class__.__name__}") diff --git a/python/tests/test_stellar.py b/python/tests/test_stellar.py index ebd773a816b..2fcbc03a8b6 100644 --- a/python/tests/test_stellar.py +++ b/python/tests/test_stellar.py @@ -330,6 +330,7 @@ def test_path_payment_strict_receive(): assert operations[0].destination_account == destination assert operations[0].send_asset.type == messages.StellarAssetType.NATIVE assert operations[0].send_max == 500111000 + assert operations[0].destination_amount == 1000000000 assert operations[0].destination_asset.type == messages.StellarAssetType.ALPHANUM4 assert operations[0].destination_asset.code == dest_code assert operations[0].destination_asset.issuer == dest_issuer @@ -782,3 +783,57 @@ def test_manage_buy_offer_update_offer(): assert operations[0].price_n == 1 assert operations[0].price_d == 2 assert operations[0].offer_id == offer_id + + +def test_path_payment_strict_send(): + tx = make_default_tx() + destination = "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6" + send_amount = "50.0112" + dest_min = "120" + send_code = "XLM" + send_issuer = None + dest_code = "USD" + dest_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF" + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + path_asset1 = Asset( + "JPY", "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ" + ) + path_asset2 = Asset( + "BANANA", "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ" + ) + + envelope = ( + tx + .append_path_payment_strict_send_op( + destination=destination, + send_code=send_code, + send_issuer=send_issuer, + send_amount=send_amount, + dest_code=dest_code, + dest_issuer=dest_issuer, + dest_min=dest_min, + path=[path_asset1, path_asset2], + source=operation_source, + ) + .build() + ) + + tx, operations = stellar.from_envelope(envelope) + assert len(operations) == 1 + + assert isinstance(operations[0], messages.StellarPathPaymentStrictSendOp) + assert operations[0].source_account == operation_source + assert operations[0].destination_account == destination + assert operations[0].send_asset.type == messages.StellarAssetType.NATIVE + assert operations[0].send_amount == 500112000 + assert operations[0].destination_min == 1200000000 + assert operations[0].destination_asset.type == messages.StellarAssetType.ALPHANUM4 + assert operations[0].destination_asset.code == dest_code + assert operations[0].destination_asset.issuer == dest_issuer + assert len(operations[0].paths) == 2 + assert operations[0].paths[0].type == messages.StellarAssetType.ALPHANUM4 + assert operations[0].paths[0].code == path_asset1.code + assert operations[0].paths[0].issuer == path_asset1.issuer + assert operations[0].paths[1].type == messages.StellarAssetType.ALPHANUM12 + assert operations[0].paths[1].code == path_asset2.code + assert operations[0].paths[1].issuer == path_asset2.issuer diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index cd80afe6673..cfc76e58a27 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -849,6 +849,7 @@ "test_stellar.py::test_sign_tx[StellarManageBuyOfferOp]": "fc57e1ca8b65588aa16cc3524d6dc0f01e094ad5d16a6f7e739a69c101b554bc", "test_stellar.py::test_sign_tx[StellarManageSellOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", "test_stellar.py::test_sign_tx[StellarPathPaymentStrictReceiveOp]": "58f3bfaece0706bc172d6e6564b728ec0b7f8e2629d8c64dc60672786586076d", +"test_stellar.py::test_sign_tx[StellarPathPaymentStrictSendOp]": "fdd36a59520317d514e03f535dfeb93339af0f7ea5ee07c556bee3c8784c94ed", "test_stellar.py::test_sign_tx[StellarPaymentOp-asset12]": "1d8e9d5d65420a259f7e2deef1efaf0ce5be966a0f1e5b8e95b832f176f00de2", "test_stellar.py::test_sign_tx[StellarPaymentOp-asset4]": "0de0b815dad5d348a3b9d06e37da94800363e5de8e6ca9cd0f84e5070f7e1b22", "test_stellar.py::test_sign_tx[StellarPaymentOp-native_asset]": "b2015b9e0f9ff60e2ea4fca2942e97b70a320386c2043fb36acde4a830272098", From 19afb6d5255b3a1f4d7a529a6b3c7ed0e965aec8 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Fri, 8 Oct 2021 07:33:09 +0800 Subject: [PATCH 4/6] refactor(common & core & legacy): Stellar, rename StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp. --- common/protob/messages-stellar.proto | 4 ++-- common/protob/messages.proto | 2 +- common/tests/fixtures/stellar/sign_tx.json | 6 +++--- core/.changelog.d/1838.incompatible | 2 +- core/src/apps/stellar/README.md | 2 +- core/src/apps/stellar/consts.py | 8 ++++---- core/src/apps/stellar/operations/__init__.py | 6 +++--- core/src/apps/stellar/operations/layout.py | 8 ++++---- core/src/apps/stellar/operations/serialize.py | 6 ++++-- core/src/trezor/enums/MessageType.py | 2 +- core/src/trezor/enums/__init__.py | 2 +- core/src/trezor/messages.py | 4 ++-- legacy/firmware/.changelog.d/1838.incompatible | 2 +- legacy/firmware/fsm.h | 3 ++- legacy/firmware/fsm_msg_stellar.h | 6 +++--- legacy/firmware/protob/messages-stellar.options | 2 +- legacy/firmware/stellar.c | 4 ++-- legacy/firmware/stellar.h | 4 ++-- python/src/trezorlib/messages.py | 4 ++-- python/src/trezorlib/stellar.py | 2 +- python/tests/test_stellar.py | 2 +- tests/ui_tests/fixtures.json | 2 +- 22 files changed, 43 insertions(+), 40 deletions(-) diff --git a/common/protob/messages-stellar.proto b/common/protob/messages-stellar.proto index 22473f7f4ef..8970a33002c 100644 --- a/common/protob/messages-stellar.proto +++ b/common/protob/messages-stellar.proto @@ -78,7 +78,7 @@ message StellarSignTx { * @next StellarPathPaymentStrictSendOp * @next StellarManageSellOfferOp * @next StellarManageBuyOfferOp - * @next StellarCreatePassiveOfferOp + * @next StellarCreatePassiveSellOfferOp * @next StellarSetOptionsOp * @next StellarChangeTrustOp * @next StellarAllowTrustOp @@ -177,7 +177,7 @@ message StellarManageBuyOfferOp { * @next StellarTxOpRequest * @next StellarSignedTx */ -message StellarCreatePassiveOfferOp { +message StellarCreatePassiveSellOfferOp { optional string source_account = 1; // (optional) source account address required StellarAsset selling_asset = 2; required StellarAsset buying_asset = 3; diff --git a/common/protob/messages.proto b/common/protob/messages.proto index fa6e9e363aa..fa2f9fd6335 100644 --- a/common/protob/messages.proto +++ b/common/protob/messages.proto @@ -231,7 +231,7 @@ enum MessageType { MessageType_StellarPaymentOp = 211 [(wire_in) = true]; MessageType_StellarPathPaymentStrictReceiveOp = 212 [(wire_in) = true]; MessageType_StellarManageSellOfferOp = 213 [(wire_in) = true]; - MessageType_StellarCreatePassiveOfferOp = 214 [(wire_in) = true]; + MessageType_StellarCreatePassiveSellOfferOp = 214 [(wire_in) = true]; MessageType_StellarSetOptionsOp = 215 [(wire_in) = true]; MessageType_StellarChangeTrustOp = 216 [(wire_in) = true]; MessageType_StellarAllowTrustOp = 217 [(wire_in) = true]; diff --git a/common/tests/fixtures/stellar/sign_tx.json b/common/tests/fixtures/stellar/sign_tx.json index 587b6858929..d3e6353fd54 100644 --- a/common/tests/fixtures/stellar/sign_tx.json +++ b/common/tests/fixtures/stellar/sign_tx.json @@ -298,7 +298,7 @@ } }, { - "name": "StellarCreatePassiveOfferOp", + "name": "StellarCreatePassiveSellOfferOp", "parameters": { "xdr": "AAAAAgAAAAAvIrnGLwi3dPPr5t1ufbk8PsLL3gJ5Vho9nFIluMMikgAAAGQAAAAAAAAD6AAAAAEAAAAAG4J3zQAAAABd5CqEAAAAAAAAAAEAAAAAAAAABAAAAAJBQkNERUZHSElKS0wAAAAAKYSWAsIOWDZfEjwS2HocpFUNEM0hsK4OGNROPlb9ahUAAAABWAAAAAAAAAAphJYCwg5YNl8SPBLYehykVQ0QzSGwrg4Y1E4+Vv1qFQAAAAAdzxaYAAAAAwAAAAQAAAAAAAAAAA==", "address_n": "m/44'/148'/0'", @@ -313,7 +313,7 @@ }, "operations": [ { - "_message_type": "StellarCreatePassiveOfferOp", + "_message_type": "StellarCreatePassiveSellOfferOp", "selling_asset": { "type": "ALPHANUM12", "code": "ABCDEFGHIJKL", @@ -888,7 +888,7 @@ "starting_balance": 100000000 }, { - "_message_type": "StellarCreatePassiveOfferOp", + "_message_type": "StellarCreatePassiveSellOfferOp", "selling_asset": { "type": "ALPHANUM12", "code": "ABCDEFGHIJKL", diff --git a/core/.changelog.d/1838.incompatible b/core/.changelog.d/1838.incompatible index 0f2b478a616..3c6f73c6d6b 100644 --- a/core/.changelog.d/1838.incompatible +++ b/core/.changelog.d/1838.incompatible @@ -1 +1 @@ -Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp and StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp. +Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp. diff --git a/core/src/apps/stellar/README.md b/core/src/apps/stellar/README.md index 5597523c6fd..3ad19ad8c9f 100644 --- a/core/src/apps/stellar/README.md +++ b/core/src/apps/stellar/README.md @@ -23,7 +23,7 @@ Stellar transaction is composed of one or more operations. We support all [opera - Bump Sequence - Change Trust - Create Account -- Create Passive Offer +- Create Passive Sell Offer - Manage Data - Manage Buy Offer - Manage Sell Offer diff --git a/core/src/apps/stellar/consts.py b/core/src/apps/stellar/consts.py index 45cbb0ff12d..0a08476d07f 100644 --- a/core/src/apps/stellar/consts.py +++ b/core/src/apps/stellar/consts.py @@ -12,7 +12,7 @@ StellarBumpSequenceOp, StellarChangeTrustOp, StellarCreateAccountOp, - StellarCreatePassiveOfferOp, + StellarCreatePassiveSellOfferOp, StellarManageDataOp, StellarManageBuyOfferOp, StellarManageSellOfferOp, @@ -28,7 +28,7 @@ StellarBumpSequenceOp, StellarChangeTrustOp, StellarCreateAccountOp, - StellarCreatePassiveOfferOp, + StellarCreatePassiveSellOfferOp, StellarManageDataOp, StellarManageBuyOfferOp, StellarManageSellOfferOp, @@ -49,7 +49,7 @@ MessageType.StellarBumpSequenceOp: 11, MessageType.StellarChangeTrustOp: 6, MessageType.StellarCreateAccountOp: 0, - MessageType.StellarCreatePassiveOfferOp: 4, + MessageType.StellarCreatePassiveSellOfferOp: 4, MessageType.StellarManageDataOp: 10, MessageType.StellarManageBuyOfferOp: 12, MessageType.StellarManageSellOfferOp: 3, @@ -65,7 +65,7 @@ MessageType.StellarBumpSequenceOp, MessageType.StellarChangeTrustOp, MessageType.StellarCreateAccountOp, - MessageType.StellarCreatePassiveOfferOp, + MessageType.StellarCreatePassiveSellOfferOp, MessageType.StellarManageDataOp, MessageType.StellarManageBuyOfferOp, MessageType.StellarManageSellOfferOp, diff --git a/core/src/apps/stellar/operations/__init__.py b/core/src/apps/stellar/operations/__init__.py index e1d93063ca7..bf5c6b62534 100644 --- a/core/src/apps/stellar/operations/__init__.py +++ b/core/src/apps/stellar/operations/__init__.py @@ -28,9 +28,9 @@ async def process_operation( elif serialize.StellarCreateAccountOp.is_type_of(op): await layout.confirm_create_account_op(ctx, op) serialize.write_create_account_op(w, op) - elif serialize.StellarCreatePassiveOfferOp.is_type_of(op): - await layout.confirm_create_passive_offer_op(ctx, op) - serialize.write_create_passive_offer_op(w, op) + elif serialize.StellarCreatePassiveSellOfferOp.is_type_of(op): + await layout.confirm_create_passive_sell_offer_op(ctx, op) + serialize.write_create_passive_sell_offer_op(w, op) elif serialize.StellarManageDataOp.is_type_of(op): await layout.confirm_manage_data_op(ctx, op) serialize.write_manage_data_op(w, op) diff --git a/core/src/apps/stellar/operations/layout.py b/core/src/apps/stellar/operations/layout.py index 53c3ab0ce5e..a6f447f6920 100644 --- a/core/src/apps/stellar/operations/layout.py +++ b/core/src/apps/stellar/operations/layout.py @@ -6,7 +6,7 @@ StellarBumpSequenceOp, StellarChangeTrustOp, StellarCreateAccountOp, - StellarCreatePassiveOfferOp, + StellarCreatePassiveSellOfferOp, StellarManageBuyOfferOp, StellarManageDataOp, StellarManageSellOfferOp, @@ -98,8 +98,8 @@ async def confirm_create_account_op(ctx: Context, op: StellarCreateAccountOp) -> ) -async def confirm_create_passive_offer_op( - ctx: Context, op: StellarCreatePassiveOfferOp +async def confirm_create_passive_sell_offer_op( + ctx: Context, op: StellarCreatePassiveSellOfferOp ) -> None: if op.amount == 0: text = "Delete Passive Offer" @@ -137,7 +137,7 @@ async def _confirm_manage_offer_op_common( async def _confirm_offer( ctx: Context, title: str, - op: StellarCreatePassiveOfferOp + op: StellarCreatePassiveSellOfferOp | StellarManageSellOfferOp | StellarManageBuyOfferOp, ) -> None: diff --git a/core/src/apps/stellar/operations/serialize.py b/core/src/apps/stellar/operations/serialize.py index 5ac50276b3f..d18fcb5b122 100644 --- a/core/src/apps/stellar/operations/serialize.py +++ b/core/src/apps/stellar/operations/serialize.py @@ -6,7 +6,7 @@ StellarBumpSequenceOp, StellarChangeTrustOp, StellarCreateAccountOp, - StellarCreatePassiveOfferOp, + StellarCreatePassiveSellOfferOp, StellarManageBuyOfferOp, StellarManageDataOp, StellarManageSellOfferOp, @@ -50,7 +50,9 @@ def write_create_account_op(w: Writer, msg: StellarCreateAccountOp) -> None: writers.write_uint64(w, msg.starting_balance) -def write_create_passive_offer_op(w: Writer, msg: StellarCreatePassiveOfferOp) -> None: +def write_create_passive_sell_offer_op( + w: Writer, msg: StellarCreatePassiveSellOfferOp +) -> None: _write_asset(w, msg.selling_asset) _write_asset(w, msg.buying_asset) writers.write_uint64(w, msg.amount) diff --git a/core/src/trezor/enums/MessageType.py b/core/src/trezor/enums/MessageType.py index 925178e3608..8d9ea143eb0 100644 --- a/core/src/trezor/enums/MessageType.py +++ b/core/src/trezor/enums/MessageType.py @@ -123,7 +123,7 @@ StellarPaymentOp = 211 StellarPathPaymentStrictReceiveOp = 212 StellarManageSellOfferOp = 213 - StellarCreatePassiveOfferOp = 214 + StellarCreatePassiveSellOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 StellarAllowTrustOp = 217 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index ff51725a19c..babfefc3824 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -128,7 +128,7 @@ class MessageType(IntEnum): StellarPaymentOp = 211 StellarPathPaymentStrictReceiveOp = 212 StellarManageSellOfferOp = 213 - StellarCreatePassiveOfferOp = 214 + StellarCreatePassiveSellOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 StellarAllowTrustOp = 217 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index e401fa96fa7..82c9294a578 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -4876,7 +4876,7 @@ def __init__( def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarManageBuyOfferOp"]: return isinstance(msg, cls) - class StellarCreatePassiveOfferOp(protobuf.MessageType): + class StellarCreatePassiveSellOfferOp(protobuf.MessageType): source_account: "str | None" selling_asset: "StellarAsset" buying_asset: "StellarAsset" @@ -4897,7 +4897,7 @@ def __init__( pass @classmethod - def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarCreatePassiveOfferOp"]: + def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["StellarCreatePassiveSellOfferOp"]: return isinstance(msg, cls) class StellarSetOptionsOp(protobuf.MessageType): diff --git a/legacy/firmware/.changelog.d/1838.incompatible b/legacy/firmware/.changelog.d/1838.incompatible index 0f2b478a616..3c6f73c6d6b 100644 --- a/legacy/firmware/.changelog.d/1838.incompatible +++ b/legacy/firmware/.changelog.d/1838.incompatible @@ -1 +1 @@ -Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp and StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp. +Stellar: rename StellarManageOfferOp to StellarManageSellOfferOp, StellarPathPaymentOp to StellarPathPaymentStrictReceiveOp and StellarCreatePassiveOfferOp to StellarCreatePassiveSellOfferOp. diff --git a/legacy/firmware/fsm.h b/legacy/firmware/fsm.h index e27dad935b7..bffb24ad8f0 100644 --- a/legacy/firmware/fsm.h +++ b/legacy/firmware/fsm.h @@ -124,7 +124,8 @@ void fsm_msgStellarPathPaymentStrictSendOp( const StellarPathPaymentStrictSendOp *msg); void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg); void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg); -void fsm_msgStellarCreatePassiveOfferOp(const StellarCreatePassiveOfferOp *msg); +void fsm_msgStellarCreatePassiveSellOfferOp( + const StellarCreatePassiveSellOfferOp *msg); void fsm_msgStellarSetOptionsOp(const StellarSetOptionsOp *msg); void fsm_msgStellarChangeTrustOp(const StellarChangeTrustOp *msg); void fsm_msgStellarAllowTrustOp(const StellarAllowTrustOp *msg); diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 84a074764d7..5eb4e41ac34 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -183,9 +183,9 @@ void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg) { } } -void fsm_msgStellarCreatePassiveOfferOp( - const StellarCreatePassiveOfferOp *msg) { - if (!stellar_confirmCreatePassiveOfferOp(msg)) return; +void fsm_msgStellarCreatePassiveSellOfferOp( + const StellarCreatePassiveSellOfferOp *msg) { + if (!stellar_confirmCreatePassiveSellOfferOp(msg)) return; if (stellar_allOperationsConfirmed()) { RESP_INIT(StellarSignedTx); diff --git a/legacy/firmware/protob/messages-stellar.options b/legacy/firmware/protob/messages-stellar.options index 748f9aa3af9..1e26c4827e4 100644 --- a/legacy/firmware/protob/messages-stellar.options +++ b/legacy/firmware/protob/messages-stellar.options @@ -29,7 +29,7 @@ StellarManageBuyOfferOp.source_account max_size:57 StellarManageSellOfferOp.source_account max_size:57 -StellarCreatePassiveOfferOp.source_account max_size:57 +StellarCreatePassiveSellOfferOp.source_account max_size:57 StellarSetOptionsOp.source_account max_size:57 StellarSetOptionsOp.inflation_destination_account max_size:57 diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c index 4167c781137..886a68d624e 100644 --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -659,8 +659,8 @@ bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { return true; } -bool stellar_confirmCreatePassiveOfferOp( - const StellarCreatePassiveOfferOp *msg) { +bool stellar_confirmCreatePassiveSellOfferOp( + const StellarCreatePassiveSellOfferOp *msg) { if (!stellar_signing) return false; if (!stellar_confirmSourceAccount(msg->has_source_account, diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h index 9fecb69567f..7ba4e8353ff 100644 --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -65,8 +65,8 @@ bool stellar_confirmPathPaymentStrictSendOp( const StellarPathPaymentStrictSendOp *msg); bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg); bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg); -bool stellar_confirmCreatePassiveOfferOp( - const StellarCreatePassiveOfferOp *msg); +bool stellar_confirmCreatePassiveSellOfferOp( + const StellarCreatePassiveSellOfferOp *msg); bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg); bool stellar_confirmChangeTrustOp(const StellarChangeTrustOp *msg); bool stellar_confirmAllowTrustOp(const StellarAllowTrustOp *msg); diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 830f69bf5c4..484e78c40ce 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -149,7 +149,7 @@ class MessageType(IntEnum): StellarPaymentOp = 211 StellarPathPaymentStrictReceiveOp = 212 StellarManageSellOfferOp = 213 - StellarCreatePassiveOfferOp = 214 + StellarCreatePassiveSellOfferOp = 214 StellarSetOptionsOp = 215 StellarChangeTrustOp = 216 StellarAllowTrustOp = 217 @@ -6454,7 +6454,7 @@ def __init__( self.source_account = source_account -class StellarCreatePassiveOfferOp(protobuf.MessageType): +class StellarCreatePassiveSellOfferOp(protobuf.MessageType): MESSAGE_WIRE_TYPE = 214 FIELDS = { 1: protobuf.Field("source_account", "string", repeated=False, required=False), diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index 00561f51f1f..401c84e5cde 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -153,7 +153,7 @@ def _read_operation(op: "Operation"): ) if isinstance(op, CreatePassiveSellOffer): price = _read_price(op.price) - return messages.StellarCreatePassiveOfferOp( + return messages.StellarCreatePassiveSellOfferOp( source_account=source_account, selling_asset=_read_asset(op.selling), buying_asset=_read_asset(op.buying), diff --git a/python/tests/test_stellar.py b/python/tests/test_stellar.py index 2fcbc03a8b6..c93c975c214 100644 --- a/python/tests/test_stellar.py +++ b/python/tests/test_stellar.py @@ -447,7 +447,7 @@ def test_create_passive_sell_offer(): tx, operations = stellar.from_envelope(envelope) assert len(operations) == 1 - assert isinstance(operations[0], messages.StellarCreatePassiveOfferOp) + assert isinstance(operations[0], messages.StellarCreatePassiveSellOfferOp) assert operations[0].source_account == operation_source assert operations[0].selling_asset.type == messages.StellarAssetType.NATIVE assert operations[0].buying_asset.type == messages.StellarAssetType.ALPHANUM4 diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json index cfc76e58a27..381e442626c 100644 --- a/tests/ui_tests/fixtures.json +++ b/tests/ui_tests/fixtures.json @@ -844,7 +844,7 @@ "test_stellar.py::test_sign_tx[StellarChangeTrustOp-add]": "7a8d420121a13e34f6ca7ad224e01a3b189ceb8e8d104cf9ec9b329222670936", "test_stellar.py::test_sign_tx[StellarChangeTrustOp-delete]": "ec26e6883ba9405412674431e0ec07504b3f25682ce7d76ebd445b809194198a", "test_stellar.py::test_sign_tx[StellarCreateAccountOp]": "2582717c25974d2b3ee156624b00375148ff7fd12eeea73625a7c367fa610373", -"test_stellar.py::test_sign_tx[StellarCreatePassiveOfferOp]": "6b0f0d2b746f98e2c85006ea7e2d5c49cd9277662e47f223138ff418066791e3", +"test_stellar.py::test_sign_tx[StellarCreatePassiveSellOfferOp]": "6b0f0d2b746f98e2c85006ea7e2d5c49cd9277662e47f223138ff418066791e3", "test_stellar.py::test_sign_tx[StellarManageDataOp]": "8fbec6547a8f9d1f002181db0cbe57fe86abef8d365b1c06fd14292cd0b068a7", "test_stellar.py::test_sign_tx[StellarManageBuyOfferOp]": "fc57e1ca8b65588aa16cc3524d6dc0f01e094ad5d16a6f7e739a69c101b554bc", "test_stellar.py::test_sign_tx[StellarManageSellOfferOp]": "6ed84765b2ed46711be0ed1219d91c27e927119d352f37b2baf8c6501186bbce", From 54002cb161452ade3b04c7afa49badeed98ef063 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Fri, 8 Oct 2021 08:06:16 +0800 Subject: [PATCH 5/6] refactor(python/stellar): Since the firmware does not support MuxedAccount, we refuse to process this type of transaction. --- python/.changelog.d/1838.changed | 1 + python/src/trezorlib/stellar.py | 14 +++ python/tests/test_stellar.py | 169 ++++++++++++++++++++++++++++++- 3 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 python/.changelog.d/1838.changed diff --git a/python/.changelog.d/1838.changed b/python/.changelog.d/1838.changed new file mode 100644 index 00000000000..5589843da0b --- /dev/null +++ b/python/.changelog.d/1838.changed @@ -0,0 +1 @@ +`trezorlib.stellar` will refuse to process transactions containing MuxedAccount diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index 401c84e5cde..3b86413a7d5 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -45,6 +45,7 @@ Price, Network, ManageBuyOffer, + MuxedAccount, ) from stellar_sdk.xdr.signer_key_type import SignerKeyType @@ -92,6 +93,7 @@ def from_envelope(envelope: "TransactionEnvelope"): else: raise ValueError("Unsupported memo type") + _raise_if_account_muxed_id_exists(parsed_tx.source) tx = messages.StellarSignTx( source_account=parsed_tx.source.account_id, fee=parsed_tx.fee, @@ -113,6 +115,7 @@ def from_envelope(envelope: "TransactionEnvelope"): def _read_operation(op: "Operation"): # TODO: Let's add muxed account support later. if op.source: + _raise_if_account_muxed_id_exists(op.source) source_account = op.source.account_id else: source_account = None @@ -123,6 +126,7 @@ def _read_operation(op: "Operation"): starting_balance=_read_amount(op.starting_balance), ) if isinstance(op, Payment): + _raise_if_account_muxed_id_exists(op.destination) return messages.StellarPaymentOp( source_account=source_account, destination_account=op.destination.account_id, @@ -130,6 +134,7 @@ def _read_operation(op: "Operation"): amount=_read_amount(op.amount), ) if isinstance(op, PathPaymentStrictReceive): + _raise_if_account_muxed_id_exists(op.destination) operation = messages.StellarPathPaymentStrictReceiveOp( source_account=source_account, send_asset=_read_asset(op.send_asset), @@ -212,6 +217,7 @@ def _read_operation(op: "Operation"): is_authorized=bool(op.authorize.value), ) if isinstance(op, AccountMerge): + _raise_if_account_muxed_id_exists(op.destination) return messages.StellarAccountMergeOp( source_account=source_account, destination_account=op.destination.account_id, @@ -239,6 +245,7 @@ def _read_operation(op: "Operation"): offer_id=op.offer_id, ) if isinstance(op, PathPaymentStrictSend): + _raise_if_account_muxed_id_exists(op.destination) operation = messages.StellarPathPaymentStrictSendOp( source_account=source_account, send_asset=_read_asset(op.send_asset), @@ -252,6 +259,13 @@ def _read_operation(op: "Operation"): raise ValueError(f"Unknown operation type: {op.__class__.__name__}") +def _raise_if_account_muxed_id_exists(account: "MuxedAccount"): + # Currently Trezor firmware does not support MuxedAccount, + # so we throw an exception here. + if account.account_muxed_id is not None: + raise ValueError("MuxedAccount is not supported") + + def _read_amount(amount: str) -> int: return Operation.to_xdr_amount(amount) diff --git a/python/tests/test_stellar.py b/python/tests/test_stellar.py index c93c975c214..f6667b32e12 100644 --- a/python/tests/test_stellar.py +++ b/python/tests/test_stellar.py @@ -14,7 +14,14 @@ # You should have received a copy of the License along with this library. # If not, see . import pytest -from stellar_sdk import Account, Asset, Network, TransactionBuilder, TrustLineEntryFlag +from stellar_sdk import ( + Account, + Asset, + Network, + TransactionBuilder, + TrustLineEntryFlag, + MuxedAccount, +) from stellar_sdk.strkey import StrKey from trezorlib import messages, stellar @@ -837,3 +844,163 @@ def test_path_payment_strict_send(): assert operations[0].paths[1].type == messages.StellarAssetType.ALPHANUM12 assert operations[0].paths[1].code == path_asset2.code assert operations[0].paths[1].issuer == path_asset2.issuer + + +def test_payment_muxed_account_not_support_raise(): + tx = make_default_tx() + destination = MuxedAccount( + "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1 + ) + amount = "50.0111" + asset_code = "XLM" + asset_issuer = None + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + + envelope = tx.append_payment_op( + destination=destination, + amount=amount, + asset_code=asset_code, + asset_issuer=asset_issuer, + source=operation_source, + ).build() + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) + + +def test_path_payment_strict_send_muxed_account_not_support_raise(): + tx = make_default_tx() + destination = MuxedAccount( + "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1 + ) + send_amount = "50.0112" + dest_min = "120" + send_code = "XLM" + send_issuer = None + dest_code = "USD" + dest_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF" + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + path_asset1 = Asset( + "JPY", "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ" + ) + path_asset2 = Asset( + "BANANA", "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ" + ) + + envelope = tx.append_path_payment_strict_send_op( + destination=destination, + send_code=send_code, + send_issuer=send_issuer, + send_amount=send_amount, + dest_code=dest_code, + dest_issuer=dest_issuer, + dest_min=dest_min, + path=[path_asset1, path_asset2], + source=operation_source, + ).build() + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) + + +def test_path_payment_strict_receive_muxed_account_not_support_raise(): + tx = make_default_tx() + destination = MuxedAccount( + "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1 + ) + send_max = "50.0111" + dest_amount = "100" + send_code = "XLM" + send_issuer = None + dest_code = "USD" + dest_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF" + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + path_asset1 = Asset( + "JPY", "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ" + ) + path_asset2 = Asset( + "BANANA", "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ" + ) + + envelope = tx.append_path_payment_strict_receive_op( + destination=destination, + send_code=send_code, + send_issuer=send_issuer, + send_max=send_max, + dest_code=dest_code, + dest_issuer=dest_issuer, + dest_amount=dest_amount, + path=[path_asset1, path_asset2], + source=operation_source, + ).build() + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) + + +def test_account_merge_muxed_account_not_support_raise(): + tx = make_default_tx() + destination = MuxedAccount( + "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1 + ) + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + + envelope = tx.append_account_merge_op( + destination=destination, source=operation_source + ).build() + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) + + +def test_op_source_muxed_account_not_support_raise(): + tx = make_default_tx() + destination = "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6" + amount = "50.0111" + asset_code = "XLM" + asset_issuer = None + operation_source = MuxedAccount( + "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V", 2 + ) + + envelope = tx.append_payment_op( + destination=destination, + amount=amount, + asset_code=asset_code, + asset_issuer=asset_issuer, + source=operation_source, + ).build() + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) + + +def test_tx_source_muxed_account_not_support_raise(): + source_account = Account( + account_id=MuxedAccount(TX_SOURCE, 123456), sequence=SEQUENCE + ) + destination = "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6" + amount = "50.0111" + asset_code = "XLM" + asset_issuer = None + operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V" + + envelope = ( + TransactionBuilder( + source_account=source_account, + network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE, + base_fee=BASE_FEE, + ) + .add_time_bounds(TIMEBOUNDS_START, TIMEBOUNDS_END) + .append_payment_op( + destination=destination, + amount=amount, + asset_code=asset_code, + asset_issuer=asset_issuer, + source=operation_source, + ) + .build() + ) + + with pytest.raises(ValueError, match="MuxedAccount is not supported"): + stellar.from_envelope(envelope) From fe008b0995e398a6368169d64a2c170aa2643f7f Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Fri, 8 Oct 2021 08:39:00 +0800 Subject: [PATCH 6/6] chore(python/stellar): bump stellar-sdk to 5.0.0. [no changelog] --- python/requirements-optional.txt | 2 +- python/setup.py | 2 +- python/src/trezorlib/stellar.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/requirements-optional.txt b/python/requirements-optional.txt index cd93c76756d..21a4f936764 100644 --- a/python/requirements-optional.txt +++ b/python/requirements-optional.txt @@ -2,4 +2,4 @@ hidapi >= 0.7.99.post20 rlp >= 1.1.0 web3 >= 4.8 Pillow -stellar-sdk>=4.0.0,<5.0.0 +stellar-sdk>=4.0.0,<6.0.0 diff --git a/python/setup.py b/python/setup.py index 3c49b9ada9a..4253102400b 100755 --- a/python/setup.py +++ b/python/setup.py @@ -22,7 +22,7 @@ "ethereum": ["rlp>=1.1.0", "web3>=4.8"], "qt-widgets": ["PyQt5"], "extra": ["Pillow"], - "stellar": ["stellar-sdk>=4.0.0,<5.0.0"], + "stellar": ["stellar-sdk>=4.0.0,<6.0.0"], } extras_require["full"] = sum(extras_require.values(), []) diff --git a/python/src/trezorlib/stellar.py b/python/src/trezorlib/stellar.py index 3b86413a7d5..d6c4ad156c1 100644 --- a/python/src/trezorlib/stellar.py +++ b/python/src/trezorlib/stellar.py @@ -271,7 +271,7 @@ def _read_amount(amount: str) -> int: def _read_price(price: Union["Price", str, Decimal]) -> "Price": - # In the coming stellar-sdk 5.x, the type of price must be Price, + # In the coming stellar-sdk 6.x, the type of price must be Price, # at that time we can remove this function if isinstance(price, Price): return price