Anything imported from pyserum should now be imported as a PySerumXYZ to avoid confusion with Mango Explorer classes.

This commit is contained in:
Geoff Taylor 2021-08-21 18:24:53 +01:00
parent 8a83c73ea8
commit 191d3e644c
11 changed files with 49 additions and 47 deletions

View File

@ -16,7 +16,7 @@
import typing
from pyserum._layouts.instructions import InstructionType as SerumInstructionType
from pyserum._layouts.instructions import InstructionType as PySerumInstructionType
from solana.publickey import PublicKey
from solana.transaction import TransactionInstruction
@ -56,7 +56,7 @@ class SerumInstructionReporter(InstructionReporter):
def report(self, instruction: TransactionInstruction) -> str:
initial = layouts.SERUM_INSTRUCTION_VARIANT_FINDER.parse(instruction.data)
instruction_type = SerumInstructionType(initial.variant)
instruction_type = PySerumInstructionType(initial.variant)
return f"« Serum Instruction: {instruction_type.name}: " + "".join("{:02x}".format(x) for x in instruction.data) + "»"

View File

@ -18,10 +18,11 @@ import pyserum.enums
import typing
from decimal import Decimal
from pyserum.enums import OrderType as SerumOrderType, Side as SerumSide
from pyserum.instructions import settle_funds, SettleFundsParams
from pyserum._layouts.instructions import INSTRUCTIONS_LAYOUT as PYSERUM_INSTRUCTIONS_LAYOUT, InstructionType as PySerumInstructionType
from pyserum.enums import OrderType as PySerumOrderType, Side as PySerumSide
from pyserum.instructions import settle_funds as pyserum_settle_funds, SettleFundsParams as PySerumSettleFundsParams
from pyserum.market import Market as PySerumMarket
from pyserum.open_orders_account import make_create_account_instruction
from pyserum.open_orders_account import make_create_account_instruction as pyserum_make_create_account_instruction
from solana.account import Account as SolanaAccount
from solana.publickey import PublicKey
from solana.system_program import CreateAccountParams, create_account
@ -29,7 +30,6 @@ from solana.sysvar import SYSVAR_RENT_PUBKEY
from solana.transaction import AccountMeta, TransactionInstruction
from spl.token.constants import ACCOUNT_LEN, TOKEN_PROGRAM_ID
from spl.token.instructions import CloseAccountParams, InitializeAccountParams, Transfer2Params, close_account, create_associated_token_account, initialize_account, transfer2
from pyserum._layouts.instructions import INSTRUCTIONS_LAYOUT, InstructionType
from .account import Account
from .combinableinstructions import CombinableInstructions
@ -132,7 +132,7 @@ def build_close_spl_account_instructions(context: Context, wallet: Wallet, addre
def build_create_serum_open_orders_instructions(context: Context, wallet: Wallet, market: PySerumMarket) -> CombinableInstructions:
new_open_orders_account = SolanaAccount()
minimum_balance = context.client.get_minimum_balance_for_rent_exemption(layouts.OPEN_ORDERS.sizeof())
instruction = make_create_account_instruction(
instruction = pyserum_make_create_account_instruction(
owner_address=wallet.address,
new_account_address=new_open_orders_account.public_key(),
lamports=minimum_balance,
@ -148,8 +148,8 @@ def build_create_serum_open_orders_instructions(context: Context, wallet: Wallet
#
def build_serum_place_order_instructions(context: Context, wallet: Wallet, market: PySerumMarket, source: PublicKey, open_orders_address: PublicKey, order_type: OrderType, side: Side, price: Decimal, quantity: Decimal, client_id: int, fee_discount_address: typing.Optional[PublicKey]) -> CombinableInstructions:
serum_order_type: SerumOrderType = SerumOrderType.POST_ONLY if order_type == OrderType.POST_ONLY else SerumOrderType.IOC if order_type == OrderType.IOC else SerumOrderType.LIMIT
serum_side: SerumSide = SerumSide.SELL if side == Side.SELL else SerumSide.BUY
serum_order_type: PySerumOrderType = PySerumOrderType.POST_ONLY if order_type == OrderType.POST_ONLY else PySerumOrderType.IOC if order_type == OrderType.IOC else PySerumOrderType.LIMIT
serum_side: PySerumSide = PySerumSide.SELL if side == Side.SELL else PySerumSide.BUY
instruction = market.make_place_order_instruction(
source,
@ -178,8 +178,8 @@ def build_serum_consume_events_instructions(context: Context, market_address: Pu
for pubkey in [*open_orders_addresses, market_address, event_queue_address]
],
program_id=context.dex_program_id,
data=INSTRUCTIONS_LAYOUT.build(
dict(instruction_type=InstructionType.CONSUME_EVENTS, args=dict(limit=limit))
data=PYSERUM_INSTRUCTIONS_LAYOUT.build(
dict(instruction_type=PySerumInstructionType.CONSUME_EVENTS, args=dict(limit=limit))
),
)
@ -201,8 +201,8 @@ def build_serum_settle_instructions(context: Context, wallet: Wallet, market: Py
[bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
market.state.program_id(),
)
instruction = settle_funds(
SettleFundsParams(
instruction = pyserum_settle_funds(
PySerumSettleFundsParams(
market=market.state.public_key(),
open_orders=open_orders_address,
owner=wallet.address,
@ -764,8 +764,8 @@ def build_mango_settle_instructions(context: Context, wallet: Wallet, market: Py
[bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
market.state.program_id(),
)
instruction = settle_funds(
SettleFundsParams(
instruction = pyserum_settle_funds(
PySerumSettleFundsParams(
market=market.state.public_key(),
open_orders=open_orders_address,
owner=wallet.address,

View File

@ -17,7 +17,7 @@
import typing
from decimal import Decimal
from pyserum.open_orders_account import OpenOrdersAccount
from pyserum.open_orders_account import OpenOrdersAccount as PySerumOpenOrdersAccount
from solana.publickey import PublicKey
from solana.rpc.types import MemcmpOpts
@ -54,9 +54,9 @@ class OpenOrders(AddressableAccount):
self.placed_orders: typing.Sequence[PlacedOrder] = placed_orders
self.referrer_rebate_accrued: Decimal = referrer_rebate_accrued
# Sometimes pyserum wants to take its own OpenOrdersAccount as a parameter (e.g. in settle_funds())
def to_pyserum(self) -> OpenOrdersAccount:
return OpenOrdersAccount.from_bytes(self.address, self.account_info.data)
# Sometimes pyserum wants to take its own PySerumOpenOrdersAccount as a parameter (e.g. in settle_funds())
def to_pyserum(self) -> PySerumOpenOrdersAccount:
return PySerumOpenOrdersAccount.from_bytes(self.address, self.account_info.data)
@staticmethod
def from_layout(layout: layouts.OPEN_ORDERS, account_info: AccountInfo,

View File

@ -79,7 +79,7 @@ class OrderBookSide(AddressableAccount):
raise Exception(f"OrderBookSide account not found at address '{address}'")
return OrderBookSide.parse(context, account_info, perp_market_details)
def orders(self):
def orders(self) -> typing.Generator[Order, None, None]:
if self.leaf_count == 0:
return

View File

@ -20,7 +20,7 @@ import pyserum.enums
import typing
from decimal import Decimal
from pyserum.market.types import Order as SerumOrder
from pyserum.market.types import Order as PySerumOrder
from solana.publickey import PublicKey
from .constants import SYSTEM_PROGRAM_ADDRESS
@ -123,7 +123,7 @@ class Order(typing.NamedTuple):
client_id=client_id, owner=self.owner, order_type=self.order_type)
@staticmethod
def from_serum_order(serum_order: SerumOrder) -> "Order":
def from_serum_order(serum_order: PySerumOrder) -> "Order":
price = Decimal(serum_order.info.price)
quantity = Decimal(serum_order.info.size)
side = Side.from_value(serum_order.side)

View File

@ -17,7 +17,7 @@ import itertools
import typing
from pyserum.market import Market as PySerumMarket
from pyserum.market.orderbook import OrderBook as SerumOrderBook
from pyserum.market.orderbook import OrderBook as PySerumOrderBook
from solana.publickey import PublicKey
from .accountinfo import AccountInfo
@ -45,8 +45,8 @@ class SerumMarket(Market):
raw_market = self.underlying_serum_market
[bids_info, asks_info] = AccountInfo.load_multiple(
context, [raw_market.state.bids(), raw_market.state.asks()])
bids_orderbook = SerumOrderBook.from_bytes(raw_market.state, bids_info.data)
asks_orderbook = SerumOrderBook.from_bytes(raw_market.state, asks_info.data)
bids_orderbook = PySerumOrderBook.from_bytes(raw_market.state, bids_info.data)
asks_orderbook = PySerumOrderBook.from_bytes(raw_market.state, asks_info.data)
return list(map(Order.from_serum_order, itertools.chain(bids_orderbook.orders(), asks_orderbook.orders())))

View File

@ -18,7 +18,7 @@ import pyserum.enums
import typing
from decimal import Decimal
from pyserum.market import Market
from pyserum.market import Market as PySerumMarket
from solana.publickey import PublicKey
from .combinableinstructions import CombinableInstructions
@ -42,12 +42,12 @@ from .wallet import Wallet
# on initial setup in the `load()` method.
#
class SerumMarketInstructionBuilder(MarketInstructionBuilder):
def __init__(self, context: Context, wallet: Wallet, serum_market: SerumMarket, raw_market: Market, base_token_account: TokenAccount, quote_token_account: TokenAccount, open_orders_address: typing.Optional[PublicKey], fee_discount_token_address: typing.Optional[PublicKey]):
def __init__(self, context: Context, wallet: Wallet, serum_market: SerumMarket, raw_market: PySerumMarket, base_token_account: TokenAccount, quote_token_account: TokenAccount, open_orders_address: typing.Optional[PublicKey], fee_discount_token_address: typing.Optional[PublicKey]):
super().__init__()
self.context: Context = context
self.wallet: Wallet = wallet
self.serum_market: SerumMarket = serum_market
self.raw_market: Market = raw_market
self.raw_market: PySerumMarket = raw_market
self.base_token_account: TokenAccount = base_token_account
self.quote_token_account: TokenAccount = quote_token_account
self.open_orders_address: typing.Optional[PublicKey] = open_orders_address
@ -55,7 +55,8 @@ class SerumMarketInstructionBuilder(MarketInstructionBuilder):
@staticmethod
def load(context: Context, wallet: Wallet, serum_market: SerumMarket) -> "SerumMarketInstructionBuilder":
raw_market: Market = Market.load(context.client.compatible_client, serum_market.address, context.dex_program_id)
raw_market: PySerumMarket = PySerumMarket.load(
context.client.compatible_client, serum_market.address, context.dex_program_id)
fee_discount_token_address: typing.Optional[PublicKey] = None
srm_token = context.token_lookup.find_by_symbol("SRM")

View File

@ -17,7 +17,7 @@ import itertools
import typing
from pyserum.market import Market as PySerumMarket
from pyserum.market.orderbook import OrderBook as SerumOrderBook
from pyserum.market.orderbook import OrderBook as PySerumOrderBook
from solana.publickey import PublicKey
from .accountinfo import AccountInfo
@ -47,8 +47,8 @@ class SpotMarket(Market):
raw_market = self.underlying_serum_market
[bids_info, asks_info] = AccountInfo.load_multiple(
context, [raw_market.state.bids(), raw_market.state.asks()])
bids_orderbook = SerumOrderBook.from_bytes(raw_market.state, bids_info.data)
asks_orderbook = SerumOrderBook.from_bytes(raw_market.state, asks_info.data)
bids_orderbook = PySerumOrderBook.from_bytes(raw_market.state, bids_info.data)
asks_orderbook = PySerumOrderBook.from_bytes(raw_market.state, asks_info.data)
return list(map(Order.from_serum_order, itertools.chain(bids_orderbook.orders(), asks_orderbook.orders())))

View File

@ -16,7 +16,7 @@
import typing
from decimal import Decimal
from pyserum.market import Market
from pyserum.market import Market as PySerumMarket
from solana.publickey import PublicKey
from .account import Account
@ -42,14 +42,14 @@ from .wallet import Wallet
#
class SpotMarketInstructionBuilder(MarketInstructionBuilder):
def __init__(self, context: Context, wallet: Wallet, group: Group, account: Account, spot_market: SpotMarket, raw_market: Market, market_index: int, fee_discount_token_address: typing.Optional[PublicKey]):
def __init__(self, context: Context, wallet: Wallet, group: Group, account: Account, spot_market: SpotMarket, raw_market: PySerumMarket, market_index: int, fee_discount_token_address: typing.Optional[PublicKey]):
super().__init__()
self.context: Context = context
self.wallet: Wallet = wallet
self.group: Group = group
self.account: Account = account
self.spot_market: SpotMarket = spot_market
self.raw_market: Market = raw_market
self.raw_market: PySerumMarket = raw_market
self.market_index: int = market_index
self.fee_discount_token_address: typing.Optional[PublicKey] = fee_discount_token_address
@ -57,7 +57,8 @@ class SpotMarketInstructionBuilder(MarketInstructionBuilder):
@staticmethod
def load(context: Context, wallet: Wallet, group: Group, account: Account, spot_market: SpotMarket) -> "SpotMarketInstructionBuilder":
raw_market: Market = Market.load(context.client.compatible_client, spot_market.address, context.dex_program_id)
raw_market: PySerumMarket = PySerumMarket.load(
context.client.compatible_client, spot_market.address, context.dex_program_id)
fee_discount_token_address: typing.Optional[PublicKey] = None
srm_token = context.token_lookup.find_by_symbol("SRM")

View File

@ -2,8 +2,8 @@ import datetime
import mango
from decimal import Decimal
from pyserum import market
from pyserum.market.state import MarketState
from pyserum.market import Market as PySerumMarket
from pyserum.market.state import MarketState as PySerumMarketState
from solana.account import Account
from solana.publickey import PublicKey
from solana.rpc.types import RPCResponse
@ -66,10 +66,10 @@ def fake_context() -> mango.Context:
return context
def fake_market() -> market.Market:
def fake_market() -> PySerumMarket:
Container = NamedTuple("Container", [("own_address", PublicKey), ("vault_signer_nonce", int)])
container = Container(own_address=fake_seeded_public_key("market address"), vault_signer_nonce=2)
state = MarketState(container, fake_seeded_public_key("program ID"), 6, 6)
state = PySerumMarketState(container, fake_seeded_public_key("program ID"), 6, 6)
state.base_vault = lambda: fake_seeded_public_key("base vault")
state.quote_vault = lambda: fake_seeded_public_key("quote vault")
state.event_queue = lambda: fake_seeded_public_key("event queue")
@ -78,7 +78,7 @@ def fake_market() -> market.Market:
state.asks = lambda: fake_seeded_public_key("asks")
state.base_lot_size = lambda: 1
state.quote_lot_size = lambda: 1
return market.Market(None, state)
return PySerumMarket(None, state)
def fake_spot_market_stub() -> mango.SpotMarketStub:

View File

@ -4,8 +4,8 @@ from .context import mango
from .fakes import fake_context, fake_market, fake_seeded_public_key, fake_token, fake_wallet
from decimal import Decimal
from pyserum.enums import OrderType, Side
from pyserum.market.market import Market
from pyserum.enums import OrderType as PySerumOrderType, Side as PySerumSide
from pyserum.market.market import Market as PySerumMarket
from solana.publickey import PublicKey
from solana.transaction import TransactionInstruction
@ -66,7 +66,7 @@ def test_build_close_spl_account_instructions():
def test_build_create_serum_open_orders_instructions():
context: mango.Context = fake_context()
wallet: mango.Wallet = fake_wallet()
market: Market = fake_market()
market: PySerumMarket = fake_market()
actual = mango.build_create_serum_open_orders_instructions(context, wallet, market)
assert actual is not None
assert len(actual.signers) == 1
@ -78,11 +78,11 @@ def test_build_create_serum_open_orders_instructions():
def test_build_serum_place_order_instructions():
context: mango.Context = fake_context()
wallet: mango.Wallet = fake_wallet()
market: Market = fake_market()
market: PySerumMarket = fake_market()
source: PublicKey = fake_seeded_public_key("source")
open_orders_address: PublicKey = fake_seeded_public_key("open orders account")
order_type: OrderType = OrderType.IOC
side: Side = Side.BUY
order_type: PySerumOrderType = PySerumOrderType.IOC
side: PySerumSide = PySerumSide.BUY
price: Decimal = Decimal(72)
quantity: Decimal = Decimal("0.05")
client_id: int = 53