mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-30 09:11:07 +00:00
feat(common & core & legacy): Stellar, add support for StellarPathPaymentStrictSendOp.
This commit is contained in:
parent
1dcb8e4913
commit
d064aae3f9
@ -75,6 +75,7 @@ message StellarSignTx {
|
||||
* @next StellarPaymentOp
|
||||
* @next StellarCreateAccountOp
|
||||
* @next StellarPathPaymentStrictReceiveOp
|
||||
* @next StellarPathPaymentStrictSendOp
|
||||
* @next StellarManageSellOfferOp
|
||||
* @next StellarManageBuyOfferOp
|
||||
* @next StellarCreatePassiveOfferOp
|
||||
@ -118,12 +119,27 @@ message StellarCreateAccountOp {
|
||||
*/
|
||||
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;
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
50
common/tests/fixtures/stellar/sign_tx.json
vendored
50
common/tests/fixtures/stellar/sign_tx.json
vendored
@ -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": {
|
||||
|
@ -1 +1 @@
|
||||
Stellar: add support for StellarManageBuyOfferOp.
|
||||
Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp.
|
||||
|
@ -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
|
||||
|
||||
|
@ -17,6 +17,7 @@ if False:
|
||||
StellarManageBuyOfferOp,
|
||||
StellarManageSellOfferOp,
|
||||
StellarPathPaymentStrictReceiveOp,
|
||||
StellarPathPaymentStrictSendOp,
|
||||
StellarPaymentOp,
|
||||
StellarSetOptionsOp,
|
||||
)
|
||||
@ -32,6 +33,7 @@ if False:
|
||||
StellarManageBuyOfferOp,
|
||||
StellarManageSellOfferOp,
|
||||
StellarPathPaymentStrictReceiveOp,
|
||||
StellarPathPaymentStrictSendOp,
|
||||
StellarPaymentOp,
|
||||
StellarSetOptionsOp,
|
||||
]
|
||||
@ -52,6 +54,7 @@ op_codes: dict[int, int] = {
|
||||
MessageType.StellarManageBuyOfferOp: 12,
|
||||
MessageType.StellarManageSellOfferOp: 3,
|
||||
MessageType.StellarPathPaymentStrictReceiveOp: 2,
|
||||
MessageType.StellarPathPaymentStrictSendOp: 13,
|
||||
MessageType.StellarPaymentOp: 1,
|
||||
MessageType.StellarSetOptionsOp: 5,
|
||||
}
|
||||
@ -67,6 +70,7 @@ op_wire_types = [
|
||||
MessageType.StellarManageBuyOfferOp,
|
||||
MessageType.StellarManageSellOfferOp,
|
||||
MessageType.StellarPathPaymentStrictReceiveOp,
|
||||
MessageType.StellarPathPaymentStrictSendOp,
|
||||
MessageType.StellarPaymentOp,
|
||||
MessageType.StellarSetOptionsOp,
|
||||
]
|
||||
|
@ -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)
|
||||
|
@ -11,6 +11,7 @@ from trezor.messages import (
|
||||
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,
|
||||
|
@ -11,6 +11,7 @@ from trezor.messages import (
|
||||
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)
|
||||
|
@ -131,6 +131,7 @@ if not utils.BITCOIN_ONLY:
|
||||
StellarManageDataOp = 220
|
||||
StellarBumpSequenceOp = 221
|
||||
StellarManageBuyOfferOp = 222
|
||||
StellarPathPaymentStrictSendOp = 223
|
||||
StellarSignedTx = 230
|
||||
CardanoSignTx = 303
|
||||
CardanoGetPublicKey = 305
|
||||
|
@ -136,6 +136,7 @@ if TYPE_CHECKING:
|
||||
StellarManageDataOp = 220
|
||||
StellarBumpSequenceOp = 221
|
||||
StellarManageBuyOfferOp = 222
|
||||
StellarPathPaymentStrictSendOp = 223
|
||||
StellarSignedTx = 230
|
||||
CardanoSignTx = 303
|
||||
CardanoGetPublicKey = 305
|
||||
|
@ -4798,6 +4798,32 @@ if TYPE_CHECKING:
|
||||
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"
|
||||
|
@ -1 +1 @@
|
||||
Stellar: add support for StellarManageBuyOfferOp.
|
||||
Stellar: add support for StellarManageBuyOfferOp and StellarPathPaymentStrictSendOp.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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 @@ class StellarPathPaymentStrictReceiveOp(protobuf.MessageType):
|
||||
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 = {
|
||||
|
@ -35,6 +35,7 @@ try:
|
||||
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__}")
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user