def serialize_manage_offer_op(w, msg: StellarManageOfferOp): _serialize_asset(w, msg.selling_asset) _serialize_asset(w, msg.buying_asset) writers.write_uint64(w, msg.amount) # amount to sell writers.write_uint32(w, msg.price_n) # numerator writers.write_uint32(w, msg.price_d) # denominator writers.write_uint64(w, msg.offer_id)
def _serialize_asset(w, asset: StellarAssetType): if asset is None: writers.write_uint32(w, 0) return writers.write_uint32(w, asset.type) _serialize_asset_code(w, asset.type, asset.code) writers.write_pubkey(w, asset.issuer)
def serialize_allow_trust_op(w, msg: StellarAllowTrustOp): # trustor account (the account being allowed to access the asset) writers.write_pubkey(w, msg.trusted_account) writers.write_uint32(w, msg.asset_type) _serialize_asset_code(w, msg.asset_type, msg.asset_code) writers.write_bool(w, msg.is_authorized)
async def _memo(ctx, w: bytearray, msg: StellarSignTx): if msg.memo_type is None: msg.memo_type = consts.MEMO_TYPE_NONE writers.write_uint32(w, msg.memo_type) if msg.memo_type == consts.MEMO_TYPE_NONE: # nothing is serialized memo_confirm_text = "" elif msg.memo_type == consts.MEMO_TYPE_TEXT: # Text: 4 bytes (size) + up to 28 bytes if len(msg.memo_text) > 28: raise ProcessError( "Stellar: max length of a memo text is 28 bytes") writers.write_string(w, msg.memo_text) memo_confirm_text = msg.memo_text elif msg.memo_type == consts.MEMO_TYPE_ID: # ID: 64 bit unsigned integer writers.write_uint64(w, msg.memo_id) memo_confirm_text = str(msg.memo_id) elif msg.memo_type in (consts.MEMO_TYPE_HASH, consts.MEMO_TYPE_RETURN): # Hash/Return: 32 byte hash writers.write_bytes_unchecked(w, bytearray(msg.memo_hash)) memo_confirm_text = hexlify(msg.memo_hash).decode() else: raise ProcessError("Stellar invalid memo type") await layout.require_confirm_memo(ctx, msg.memo_type, memo_confirm_text)
def _write_asset(w, asset: StellarAssetType): if asset is None or asset.type == consts.ASSET_TYPE_NATIVE: writers.write_uint32(w, 0) return writers.write_uint32(w, asset.type) _write_asset_code(w, asset.type, asset.code) writers.write_pubkey(w, asset.issuer)
def serialize_manage_data_op(w, msg: StellarManageDataOp): if len(msg.key) > 64: raise ProcessError("Stellar: max length of a key is 64 bytes") writers.write_string(w, msg.key) writers.write_bool(w, bool(msg.value)) if msg.value: writers.write_uint32(w, len(msg.value)) writers.write_bytes(w, msg.value)
def serialize_path_payment_op(w, msg: StellarPathPaymentOp): _serialize_asset(w, msg.send_asset) writers.write_uint64(w, msg.send_max) writers.write_pubkey(w, msg.destination_account) _serialize_asset(w, msg.destination_asset) writers.write_uint64(w, msg.destination_amount) writers.write_uint32(w, len(msg.paths)) for p in msg.paths: _serialize_asset(w, p)
async def _init(ctx, w: bytearray, pubkey: bytes, msg: StellarSignTx): network_passphrase_hash = sha256(msg.network_passphrase).digest() writers.write_bytes(w, network_passphrase_hash) writers.write_bytes(w, consts.TX_TYPE) address = helpers.address_from_public_key(pubkey) writers.write_pubkey(w, address) if helpers.public_key_from_address(msg.source_account) != pubkey: raise ProcessError("Stellar: source account does not match address_n") writers.write_uint32(w, msg.fee) writers.write_uint64(w, msg.sequence_number) # confirm init await layout.require_confirm_init(ctx, address, msg.network_passphrase)
async def _init(ctx, w: bytearray, pubkey: bytes, msg: StellarSignTx): network_passphrase_hash = sha256(msg.network_passphrase).digest() writers.write_bytes_unchecked(w, network_passphrase_hash) writers.write_bytes_unchecked(w, consts.TX_TYPE) address = helpers.address_from_public_key(pubkey) accounts_match = msg.source_account == address writers.write_pubkey(w, msg.source_account) writers.write_uint32(w, msg.fee) writers.write_uint64(w, msg.sequence_number) # confirm init await layout.require_confirm_init(ctx, msg.source_account, msg.network_passphrase, accounts_match)
async def operation(ctx, w, op): if op.source_account: await layout.confirm_source_account(ctx, op.source_account) serialize.serialize_account(w, op.source_account) writers.write_uint32(w, consts.get_op_code(op)) if isinstance(op, serialize.StellarAccountMergeOp): await layout.confirm_account_merge_op(ctx, op) serialize.serialize_account_merge_op(w, op) elif isinstance(op, serialize.StellarAllowTrustOp): await layout.confirm_allow_trust_op(ctx, op) serialize.serialize_allow_trust_op(w, op) elif isinstance(op, serialize.StellarBumpSequenceOp): await layout.confirm_bump_sequence_op(ctx, op) serialize.serialize_bump_sequence_op(w, op) elif isinstance(op, serialize.StellarChangeTrustOp): await layout.confirm_change_trust_op(ctx, op) serialize.serialize_change_trust_op(w, op) elif isinstance(op, serialize.StellarCreateAccountOp): await layout.confirm_create_account_op(ctx, op) serialize.serialize_create_account_op(w, op) elif isinstance(op, serialize.StellarCreatePassiveOfferOp): await layout.confirm_create_passive_offer_op(ctx, op) serialize.serialize_create_passive_offer_op(w, op) elif isinstance(op, serialize.StellarManageDataOp): await layout.confirm_manage_data_op(ctx, op) serialize.serialize_manage_data_op(w, op) elif isinstance(op, serialize.StellarManageOfferOp): await layout.confirm_manage_offer_op(ctx, op) serialize.serialize_manage_offer_op(w, op) elif isinstance(op, serialize.StellarPathPaymentOp): await layout.confirm_path_payment_op(ctx, op) serialize.serialize_path_payment_op(w, op) elif isinstance(op, serialize.StellarPaymentOp): await layout.confirm_payment_op(ctx, op) serialize.serialize_payment_op(w, op) elif isinstance(op, serialize.StellarSetOptionsOp): await layout.confirm_set_options_op(ctx, op) serialize.serialize_set_options_op(w, op) else: raise ValueError("serialize.Stellar: unknown operation")
def write_set_options_op(w, msg: StellarSetOptionsOp): # inflation destination if msg.inflation_destination_account is None: writers.write_bool(w, False) else: writers.write_bool(w, True) writers.write_pubkey(w, msg.inflation_destination_account) # clear flags _write_set_options_int(w, msg.clear_flags) # set flags _write_set_options_int(w, msg.set_flags) # account thresholds _write_set_options_int(w, msg.master_weight) _write_set_options_int(w, msg.low_threshold) _write_set_options_int(w, msg.medium_threshold) _write_set_options_int(w, msg.high_threshold) # home domain if msg.home_domain is None: writers.write_bool(w, False) else: writers.write_bool(w, True) if len(msg.home_domain) > 32: raise ProcessError( "Stellar: max length of a home domain is 32 bytes") writers.write_string(w, msg.home_domain) # signer if msg.signer_type is None: writers.write_bool(w, False) elif msg.signer_type in consts.SIGN_TYPES: writers.write_bool(w, True) writers.write_uint32(w, msg.signer_type) writers.write_bytes_unchecked(w, msg.signer_key) writers.write_uint32(w, msg.signer_weight) else: raise ProcessError("Stellar: unknown signer type")
async def _operations(ctx, w: bytearray, num_operations: int): writers.write_uint32(w, num_operations) for i in range(num_operations): op = await ctx.call_any(StellarTxOpRequest(), *consts.op_wire_types) await process_operation(ctx, w, op)
async def _final(ctx, w: bytearray, msg: StellarSignTx): # 4 null bytes representing a (currently unused) empty union writers.write_uint32(w, 0) # final confirm await layout.require_confirm_final(ctx, msg.fee, msg.num_operations)
def serialize_set_options_op(w, msg: StellarSetOptionsOp): # inflation destination writers.write_bool(w, bool(msg.inflation_destination_account)) if msg.inflation_destination_account: writers.write_pubkey(w, msg.inflation_destination_account) # clear flags writers.write_bool(w, bool(msg.clear_flags)) if msg.clear_flags: writers.write_uint32(w, msg.clear_flags) # set flags writers.write_bool(w, bool(msg.set_flags)) if msg.set_flags: writers.write_uint32(w, msg.set_flags) # account thresholds writers.write_bool(w, bool(msg.master_weight)) if msg.master_weight: writers.write_uint32(w, msg.master_weight) writers.write_bool(w, bool(msg.low_threshold)) if msg.low_threshold: writers.write_uint32(w, msg.low_threshold) writers.write_bool(w, bool(msg.medium_threshold)) if msg.medium_threshold: writers.write_uint32(w, msg.medium_threshold) writers.write_bool(w, bool(msg.high_threshold)) if msg.high_threshold: writers.write_uint32(w, msg.high_threshold) # home domain writers.write_bool(w, bool(msg.home_domain)) if msg.home_domain: if len(msg.home_domain) > 32: raise ProcessError( "Stellar: max length of a home domain is 32 bytes") writers.write_string(w, msg.home_domain) # signer writers.write_bool(w, bool(msg.signer_type)) if msg.signer_type: # signer type writers.write_uint32(w, msg.signer_type) writers.write_bytes(w, msg.signer_key) writers.write_uint32(w, msg.signer_weight)
def serialize_create_passive_offer_op(w, msg: StellarCreatePassiveOfferOp): _serialize_asset(w, msg.selling_asset) _serialize_asset(w, msg.buying_asset) writers.write_uint64(w, msg.amount) writers.write_uint32(w, msg.price_n) writers.write_uint32(w, msg.price_d)
def _write_set_options_int(w, value: int): if value is None: writers.write_bool(w, False) else: writers.write_bool(w, True) writers.write_uint32(w, value)