Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: parse muxed account, used to generate XDR containing muxed account. #326

Merged
merged 5 commits into from
Jun 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stellar_sdk/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
__description__ = "The Python Stellar SDK library provides APIs to build transactions and connect to Horizon."
__url__ = "https://github.com/StellarCN/py-stellar-base"
__issues__ = "{}/issues".format(__url__)
__version__ = "2.3.2"
__version__ = "2.5.2-dev"
__author__ = "Eno, overcat"
__author_email__ = "[email protected], [email protected]"
__license__ = "Apache License 2.0"
26 changes: 22 additions & 4 deletions stellar_sdk/fee_bump_transaction.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Union
from typing import Union, Optional

from .exceptions import ValueError
from .keypair import Keypair
Expand Down Expand Up @@ -38,7 +38,8 @@ def __init__(
if isinstance(fee_source, str):
fee_source = Keypair.from_public_key(fee_source)

self.fee_source: Keypair = fee_source
self._fee_source: Keypair = fee_source
self._fee_source_muxed: Optional[Xdr.types.MuxedAccount] = None
self.base_fee = base_fee
self.inner_transaction_envelope = inner_transaction_envelope
self._inner_transaction = inner_transaction_envelope.transaction
Expand All @@ -55,12 +56,27 @@ def __init__(
)
)

@property
def fee_source(self) -> Keypair:
return self._fee_source

@fee_source.setter
def fee_source(self, value: Union[Keypair, str]):
if isinstance(value, str):
value = Keypair.from_public_key(value)

self._fee_source: Keypair = value
self._fee_source_muxed: Optional[Xdr.types.MuxedAccount] = None

def to_xdr_object(self) -> Xdr.types.FeeBumpTransaction:
"""Get an XDR object representation of this :class:`FeeBumpTransaction`.

:return: XDR Transaction object
"""
fee_source = self.fee_source.xdr_muxed_account()
if self._fee_source_muxed is not None:
fee_source = self._fee_source_muxed
else:
fee_source = self._fee_source.xdr_muxed_account()
fee = self.base_fee * (len(self._inner_transaction.operations) + 1)
ext = Xdr.nullclass()
ext.v = 0
Expand Down Expand Up @@ -92,11 +108,13 @@ def from_xdr_object(
inner_transaction_envelope.transaction.operations
)
base_fee = int(tx_xdr_object.fee / (inner_transaction_operation_length + 1))
return cls(
tx = cls(
fee_source=source,
base_fee=base_fee,
inner_transaction_envelope=inner_transaction_envelope,
)
tx._fee_source_muxed = tx_xdr_object.feeSource
return tx

@classmethod
def from_xdr(cls, xdr: str, network_passphrase: str) -> "FeeBumpTransaction":
Expand Down
27 changes: 23 additions & 4 deletions stellar_sdk/operation/account_merge.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Optional

from .operation import Operation
from .utils import check_ed25519_public_key
from ..keypair import Keypair
Expand All @@ -22,16 +24,31 @@ class AccountMerge(Operation):
def __init__(self, destination: str, source: str = None,) -> None:
super().__init__(source)
check_ed25519_public_key(destination)
self.destination: str = destination
self._destination: str = destination
self._destination_muxed: Optional[Xdr.types.MuxedAccount] = None

@property
def destination(self) -> str:
return self._destination

@destination.setter
def destination(self, value: str):
check_ed25519_public_key(value)
self._destination_muxed = None
self._destination = value

@classmethod
def type_code(cls) -> int:
return Xdr.const.ACCOUNT_MERGE

def _to_operation_body(self) -> Xdr.nullclass:
if self._destination_muxed is not None:
destination = self._destination_muxed
else:
destination = Keypair.from_public_key(self._destination).xdr_muxed_account()
body = Xdr.nullclass()
body.type = Xdr.const.ACCOUNT_MERGE
body.destination = Keypair.from_public_key(self.destination).xdr_muxed_account()
body.destination = destination
return body

@classmethod
Expand All @@ -46,5 +63,7 @@ def from_xdr_object(
destination = parse_ed25519_account_id_from_muxed_account_xdr_object(
operation_xdr_object.body.destination
)

return cls(source=source, destination=destination)
op = cls(source=source, destination=destination)
op._destination_muxed = operation_xdr_object.body.destination
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/allow_trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ def from_xdr_object(cls, operation_xdr_object: Xdr.types.Operation) -> "AllowTru
)

asset_code = asset_code.rstrip("\x00")
return cls(
op = cls(
source=source, trustor=trustor, authorize=authorize, asset_code=asset_code
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/bump_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ def from_xdr_object(
source = Operation.get_source_from_xdr_obj(operation_xdr_object)

bump_to = operation_xdr_object.body.bumpSequenceOp.bumpTo
return cls(source=source, bump_to=bump_to)
op = cls(source=source, bump_to=bump_to)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/change_trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ def from_xdr_object(
line = Asset.from_xdr_object(operation_xdr_object.body.changeTrustOp.line)
limit = Operation.from_xdr_amount(operation_xdr_object.body.changeTrustOp.limit)

return cls(source=source, asset=line, limit=limit)
op = cls(source=source, asset=line, limit=limit)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/create_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def from_xdr_object(
operation_xdr_object.body.createAccountOp.startingBalance
)

return cls(
op = cls(
source=source, destination=destination, starting_balance=starting_balance
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/create_passive_sell_offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def from_xdr_object(
operation_xdr_object.body.createPassiveSellOfferOp.price
)

return cls(
op = cls(
source=source, selling=selling, buying=buying, amount=amount, price=price
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/inflation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ def from_xdr_object(cls, operation_xdr_object: Xdr.types.Operation) -> "Inflatio

"""
source = Operation.get_source_from_xdr_obj(operation_xdr_object)
return cls(source)
op = cls(source)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/manage_buy_offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,13 @@ def from_xdr_object(
price = Price.from_xdr_object(operation_xdr_object.body.manageBuyOfferOp.price)
offer_id = operation_xdr_object.body.manageBuyOfferOp.offerID

return cls(
op = cls(
source=source,
selling=selling,
buying=buying,
amount=amount,
price=price,
offer_id=offer_id,
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/manage_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,6 @@ def from_xdr_object(cls, operation_xdr_object: Xdr.types.Operation) -> "ManageDa
data_name = operation_xdr_object.body.manageDataOp.dataName.decode()

data_value = unpack_xdr_array(operation_xdr_object.body.manageDataOp.dataValue)
return cls(data_name=data_name, data_value=data_value, source=source)
op = cls(data_name=data_name, data_value=data_value, source=source)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
4 changes: 3 additions & 1 deletion stellar_sdk/operation/manage_sell_offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,13 @@ def from_xdr_object(
price = Price.from_xdr_object(operation_xdr_object.body.manageSellOfferOp.price)
offer_id = operation_xdr_object.body.manageSellOfferOp.offerID

return cls(
op = cls(
source=source,
selling=selling,
buying=buying,
amount=amount,
price=price,
offer_id=offer_id,
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
32 changes: 28 additions & 4 deletions stellar_sdk/operation/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,18 @@ class Operation(metaclass=ABCMeta):

def __init__(self, source: str = None) -> None:
check_source(source)
self.source = source
self.source: Optional[str] = source
self._source: Optional[str] = source
self._source_muxed: Optional[Xdr.types.MuxedAccount] = None

@property
def source(self) -> str:
return self._source

@source.setter
def source(self, value: str):
check_source(value)
self._source_muxed = None
self._source = value

@classmethod
def type_code(cls) -> int:
Expand Down Expand Up @@ -120,9 +130,10 @@ def to_xdr_object(self) -> Xdr.types.Operation:

"""
source_account: List[Xdr.types.MuxedAccount] = []
if self.source is not None:
if self._source_muxed is not None:
source_account = [self._source_muxed]
elif self.source is not None:
source_account = [Keypair.from_public_key(self.source).xdr_muxed_account()]

return Xdr.types.Operation(source_account, self._to_operation_body())

@classmethod
Expand Down Expand Up @@ -154,6 +165,19 @@ def get_source_from_xdr_obj(xdr_object: Xdr.types.Operation,) -> Optional[str]:
)
return None

@staticmethod
def get_source_muxed_from_xdr_obj(
xdr_object: Xdr.types.Operation,
) -> Optional[Xdr.types.MuxedAccount]:
"""Get the source account from account the operation xdr object.

:param xdr_object: the operation xdr object.
:return: The source account from account the operation xdr object.
"""
if xdr_object.sourceAccount:
return xdr_object.sourceAccount[0]
return None

def __eq__(self, other: object) -> bool:
if not isinstance(other, self.__class__):
return NotImplemented # pragma: no cover
Expand Down
27 changes: 23 additions & 4 deletions stellar_sdk/operation/path_payment_strict_receive.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from decimal import Decimal
from typing import List, Union
from typing import List, Union, Optional

from .operation import Operation
from .utils import check_amount, check_ed25519_public_key
Expand Down Expand Up @@ -43,19 +43,33 @@ def __init__(
check_amount(send_max)
check_amount(dest_amount)
check_ed25519_public_key(destination)
self.destination: str = destination
self._destination: str = destination
self._destination_muxed: Optional[Xdr.types.MuxedAccount] = None
self.send_asset: Asset = send_asset
self.send_max: Union[str, Decimal] = send_max
self.dest_asset: Asset = dest_asset
self.dest_amount: Union[str, Decimal] = dest_amount
self.path: List[Asset] = path # a list of paths/assets

@property
def destination(self) -> str:
return self._destination

@destination.setter
def destination(self, value: str):
check_ed25519_public_key(value)
self._destination_muxed = None
self._destination = value

@classmethod
def type_code(cls) -> int:
return Xdr.const.PATH_PAYMENT_STRICT_RECEIVE

def _to_operation_body(self) -> Xdr.nullclass:
destination = Keypair.from_public_key(self.destination).xdr_muxed_account()
if self._destination_muxed is not None:
destination = self._destination_muxed
else:
destination = Keypair.from_public_key(self._destination).xdr_muxed_account()
send_asset = self.send_asset.to_xdr_object()
dest_asset = self.dest_asset.to_xdr_object()
path = [asset.to_xdr_object() for asset in self.path]
Expand Down Expand Up @@ -104,7 +118,7 @@ def from_xdr_object(
for x in operation_xdr_object.body.pathPaymentStrictReceiveOp.path:
path.append(Asset.from_xdr_object(x))

return cls(
op = cls(
source=source,
destination=destination,
send_asset=send_asset,
Expand All @@ -113,3 +127,8 @@ def from_xdr_object(
dest_amount=dest_amount,
path=path,
)
op._destination_muxed = (
operation_xdr_object.body.pathPaymentStrictReceiveOp.destination
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
27 changes: 23 additions & 4 deletions stellar_sdk/operation/path_payment_strict_send.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from decimal import Decimal
from typing import List, Union
from typing import List, Union, Optional

from .operation import Operation
from .utils import check_amount, check_ed25519_public_key
Expand Down Expand Up @@ -43,19 +43,33 @@ def __init__(
check_amount(send_amount)
check_amount(dest_min)
check_ed25519_public_key(destination)
self.destination: str = destination
self._destination: str = destination
self._destination_muxed: Optional[Xdr.types.MuxedAccount] = None
self.send_asset: Asset = send_asset
self.send_amount: Union[str, Decimal] = send_amount
self.dest_asset: Asset = dest_asset
self.dest_min: Union[str, Decimal] = dest_min
self.path: List[Asset] = path # a list of paths/assets

@property
def destination(self) -> str:
return self._destination

@destination.setter
def destination(self, value: str):
check_ed25519_public_key(value)
self._destination_muxed = None
self._destination = value

@classmethod
def type_code(cls) -> int:
return Xdr.const.PATH_PAYMENT_STRICT_SEND

def _to_operation_body(self) -> Xdr.nullclass:
destination = Keypair.from_public_key(self.destination).xdr_muxed_account()
if self._destination_muxed is not None:
destination = self._destination_muxed
else:
destination = Keypair.from_public_key(self._destination).xdr_muxed_account()
send_asset = self.send_asset.to_xdr_object()
dest_asset = self.dest_asset.to_xdr_object()
path = [asset.to_xdr_object() for asset in self.path]
Expand Down Expand Up @@ -104,7 +118,7 @@ def from_xdr_object(
for x in operation_xdr_object.body.pathPaymentStrictSendOp.path:
path.append(Asset.from_xdr_object(x))

return cls(
op = cls(
source=source,
destination=destination,
send_asset=send_asset,
Expand All @@ -113,3 +127,8 @@ def from_xdr_object(
dest_min=dest_min,
path=path,
)
op._destination_muxed = (
operation_xdr_object.body.pathPaymentStrictSendOp.destination
)
op._source_muxed = Operation.get_source_muxed_from_xdr_obj(operation_xdr_object)
return op
Loading