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 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.publickey import PublicKey
from solana.transaction import TransactionInstruction from solana.transaction import TransactionInstruction
@ -56,7 +56,7 @@ class SerumInstructionReporter(InstructionReporter):
def report(self, instruction: TransactionInstruction) -> str: def report(self, instruction: TransactionInstruction) -> str:
initial = layouts.SERUM_INSTRUCTION_VARIANT_FINDER.parse(instruction.data) 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) + "»" 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 import typing
from decimal import Decimal from decimal import Decimal
from pyserum.enums import OrderType as SerumOrderType, Side as SerumSide from pyserum._layouts.instructions import INSTRUCTIONS_LAYOUT as PYSERUM_INSTRUCTIONS_LAYOUT, InstructionType as PySerumInstructionType
from pyserum.instructions import settle_funds, SettleFundsParams 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.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.account import Account as SolanaAccount
from solana.publickey import PublicKey from solana.publickey import PublicKey
from solana.system_program import CreateAccountParams, create_account 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 solana.transaction import AccountMeta, TransactionInstruction
from spl.token.constants import ACCOUNT_LEN, TOKEN_PROGRAM_ID 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 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 .account import Account
from .combinableinstructions import CombinableInstructions 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: def build_create_serum_open_orders_instructions(context: Context, wallet: Wallet, market: PySerumMarket) -> CombinableInstructions:
new_open_orders_account = SolanaAccount() new_open_orders_account = SolanaAccount()
minimum_balance = context.client.get_minimum_balance_for_rent_exemption(layouts.OPEN_ORDERS.sizeof()) 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, owner_address=wallet.address,
new_account_address=new_open_orders_account.public_key(), new_account_address=new_open_orders_account.public_key(),
lamports=minimum_balance, 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: 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_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: SerumSide = SerumSide.SELL if side == Side.SELL else SerumSide.BUY serum_side: PySerumSide = PySerumSide.SELL if side == Side.SELL else PySerumSide.BUY
instruction = market.make_place_order_instruction( instruction = market.make_place_order_instruction(
source, 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] for pubkey in [*open_orders_addresses, market_address, event_queue_address]
], ],
program_id=context.dex_program_id, program_id=context.dex_program_id,
data=INSTRUCTIONS_LAYOUT.build( data=PYSERUM_INSTRUCTIONS_LAYOUT.build(
dict(instruction_type=InstructionType.CONSUME_EVENTS, args=dict(limit=limit)) 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")], [bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
market.state.program_id(), market.state.program_id(),
) )
instruction = settle_funds( instruction = pyserum_settle_funds(
SettleFundsParams( PySerumSettleFundsParams(
market=market.state.public_key(), market=market.state.public_key(),
open_orders=open_orders_address, open_orders=open_orders_address,
owner=wallet.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")], [bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
market.state.program_id(), market.state.program_id(),
) )
instruction = settle_funds( instruction = pyserum_settle_funds(
SettleFundsParams( PySerumSettleFundsParams(
market=market.state.public_key(), market=market.state.public_key(),
open_orders=open_orders_address, open_orders=open_orders_address,
owner=wallet.address, owner=wallet.address,

View File

@ -17,7 +17,7 @@
import typing import typing
from decimal import Decimal 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.publickey import PublicKey
from solana.rpc.types import MemcmpOpts from solana.rpc.types import MemcmpOpts
@ -54,9 +54,9 @@ class OpenOrders(AddressableAccount):
self.placed_orders: typing.Sequence[PlacedOrder] = placed_orders self.placed_orders: typing.Sequence[PlacedOrder] = placed_orders
self.referrer_rebate_accrued: Decimal = referrer_rebate_accrued self.referrer_rebate_accrued: Decimal = referrer_rebate_accrued
# Sometimes pyserum wants to take its own OpenOrdersAccount as a parameter (e.g. in settle_funds()) # Sometimes pyserum wants to take its own PySerumOpenOrdersAccount as a parameter (e.g. in settle_funds())
def to_pyserum(self) -> OpenOrdersAccount: def to_pyserum(self) -> PySerumOpenOrdersAccount:
return OpenOrdersAccount.from_bytes(self.address, self.account_info.data) return PySerumOpenOrdersAccount.from_bytes(self.address, self.account_info.data)
@staticmethod @staticmethod
def from_layout(layout: layouts.OPEN_ORDERS, account_info: AccountInfo, 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}'") raise Exception(f"OrderBookSide account not found at address '{address}'")
return OrderBookSide.parse(context, account_info, perp_market_details) 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: if self.leaf_count == 0:
return return

View File

@ -20,7 +20,7 @@ import pyserum.enums
import typing import typing
from decimal import Decimal 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 solana.publickey import PublicKey
from .constants import SYSTEM_PROGRAM_ADDRESS 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) client_id=client_id, owner=self.owner, order_type=self.order_type)
@staticmethod @staticmethod
def from_serum_order(serum_order: SerumOrder) -> "Order": def from_serum_order(serum_order: PySerumOrder) -> "Order":
price = Decimal(serum_order.info.price) price = Decimal(serum_order.info.price)
quantity = Decimal(serum_order.info.size) quantity = Decimal(serum_order.info.size)
side = Side.from_value(serum_order.side) side = Side.from_value(serum_order.side)

View File

@ -17,7 +17,7 @@ import itertools
import typing import typing
from pyserum.market import Market as PySerumMarket 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 solana.publickey import PublicKey
from .accountinfo import AccountInfo from .accountinfo import AccountInfo
@ -45,8 +45,8 @@ class SerumMarket(Market):
raw_market = self.underlying_serum_market raw_market = self.underlying_serum_market
[bids_info, asks_info] = AccountInfo.load_multiple( [bids_info, asks_info] = AccountInfo.load_multiple(
context, [raw_market.state.bids(), raw_market.state.asks()]) context, [raw_market.state.bids(), raw_market.state.asks()])
bids_orderbook = SerumOrderBook.from_bytes(raw_market.state, bids_info.data) bids_orderbook = PySerumOrderBook.from_bytes(raw_market.state, bids_info.data)
asks_orderbook = SerumOrderBook.from_bytes(raw_market.state, asks_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()))) 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 import typing
from decimal import Decimal from decimal import Decimal
from pyserum.market import Market from pyserum.market import Market as PySerumMarket
from solana.publickey import PublicKey from solana.publickey import PublicKey
from .combinableinstructions import CombinableInstructions from .combinableinstructions import CombinableInstructions
@ -42,12 +42,12 @@ from .wallet import Wallet
# on initial setup in the `load()` method. # on initial setup in the `load()` method.
# #
class SerumMarketInstructionBuilder(MarketInstructionBuilder): 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__() super().__init__()
self.context: Context = context self.context: Context = context
self.wallet: Wallet = wallet self.wallet: Wallet = wallet
self.serum_market: SerumMarket = serum_market 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.base_token_account: TokenAccount = base_token_account
self.quote_token_account: TokenAccount = quote_token_account self.quote_token_account: TokenAccount = quote_token_account
self.open_orders_address: typing.Optional[PublicKey] = open_orders_address self.open_orders_address: typing.Optional[PublicKey] = open_orders_address
@ -55,7 +55,8 @@ class SerumMarketInstructionBuilder(MarketInstructionBuilder):
@staticmethod @staticmethod
def load(context: Context, wallet: Wallet, serum_market: SerumMarket) -> "SerumMarketInstructionBuilder": 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 fee_discount_token_address: typing.Optional[PublicKey] = None
srm_token = context.token_lookup.find_by_symbol("SRM") srm_token = context.token_lookup.find_by_symbol("SRM")

View File

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

View File

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

View File

@ -2,8 +2,8 @@ import datetime
import mango import mango
from decimal import Decimal from decimal import Decimal
from pyserum import market from pyserum.market import Market as PySerumMarket
from pyserum.market.state import MarketState from pyserum.market.state import MarketState as PySerumMarketState
from solana.account import Account from solana.account import Account
from solana.publickey import PublicKey from solana.publickey import PublicKey
from solana.rpc.types import RPCResponse from solana.rpc.types import RPCResponse
@ -66,10 +66,10 @@ def fake_context() -> mango.Context:
return context return context
def fake_market() -> market.Market: def fake_market() -> PySerumMarket:
Container = NamedTuple("Container", [("own_address", PublicKey), ("vault_signer_nonce", int)]) Container = NamedTuple("Container", [("own_address", PublicKey), ("vault_signer_nonce", int)])
container = Container(own_address=fake_seeded_public_key("market address"), vault_signer_nonce=2) 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.base_vault = lambda: fake_seeded_public_key("base vault")
state.quote_vault = lambda: fake_seeded_public_key("quote vault") state.quote_vault = lambda: fake_seeded_public_key("quote vault")
state.event_queue = lambda: fake_seeded_public_key("event queue") 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.asks = lambda: fake_seeded_public_key("asks")
state.base_lot_size = lambda: 1 state.base_lot_size = lambda: 1
state.quote_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: 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 .fakes import fake_context, fake_market, fake_seeded_public_key, fake_token, fake_wallet
from decimal import Decimal from decimal import Decimal
from pyserum.enums import OrderType, Side from pyserum.enums import OrderType as PySerumOrderType, Side as PySerumSide
from pyserum.market.market import Market from pyserum.market.market import Market as PySerumMarket
from solana.publickey import PublicKey from solana.publickey import PublicKey
from solana.transaction import TransactionInstruction from solana.transaction import TransactionInstruction
@ -66,7 +66,7 @@ def test_build_close_spl_account_instructions():
def test_build_create_serum_open_orders_instructions(): def test_build_create_serum_open_orders_instructions():
context: mango.Context = fake_context() context: mango.Context = fake_context()
wallet: mango.Wallet = fake_wallet() wallet: mango.Wallet = fake_wallet()
market: Market = fake_market() market: PySerumMarket = fake_market()
actual = mango.build_create_serum_open_orders_instructions(context, wallet, market) actual = mango.build_create_serum_open_orders_instructions(context, wallet, market)
assert actual is not None assert actual is not None
assert len(actual.signers) == 1 assert len(actual.signers) == 1
@ -78,11 +78,11 @@ def test_build_create_serum_open_orders_instructions():
def test_build_serum_place_order_instructions(): def test_build_serum_place_order_instructions():
context: mango.Context = fake_context() context: mango.Context = fake_context()
wallet: mango.Wallet = fake_wallet() wallet: mango.Wallet = fake_wallet()
market: Market = fake_market() market: PySerumMarket = fake_market()
source: PublicKey = fake_seeded_public_key("source") source: PublicKey = fake_seeded_public_key("source")
open_orders_address: PublicKey = fake_seeded_public_key("open orders account") open_orders_address: PublicKey = fake_seeded_public_key("open orders account")
order_type: OrderType = OrderType.IOC order_type: PySerumOrderType = PySerumOrderType.IOC
side: Side = Side.BUY side: PySerumSide = PySerumSide.BUY
price: Decimal = Decimal(72) price: Decimal = Decimal(72)
quantity: Decimal = Decimal("0.05") quantity: Decimal = Decimal("0.05")
client_id: int = 53 client_id: int = 53