Added a redeem-mango command.
This commit is contained in:
parent
7c6d1d43cf
commit
162f41e2d0
|
@ -15,7 +15,7 @@ import mango # nopep8
|
|||
parser = argparse.ArgumentParser(description="Cranks all openorders in the market.")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--market", type=str, required=True, help="market symbol to make market upon (e.g. ETH/USDC)")
|
||||
parser.add_argument("--market", type=str, required=True, help="market symbol to crank (e.g. ETH/USDC)")
|
||||
parser.add_argument("--limit", type=Decimal, default=Decimal(32), help="maximum number of events to be processed")
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env pyston3
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import typing
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..')))
|
||||
import mango # nopep8
|
||||
|
||||
|
||||
def report_accrued(basket_token: mango.AccountBasketBaseToken):
|
||||
symbol: str = basket_token.token_info.token.symbol
|
||||
accrued: mango.TokenValue = basket_token.perp_account.mngo_accrued
|
||||
print(f"Accrued in perp market [{symbol:>5}]: {accrued}")
|
||||
|
||||
|
||||
def load_perp_market(context: mango.Context, group: mango.Group, group_basket_market: mango.GroupBasketMarket):
|
||||
perp_market_details = mango.PerpMarketDetails.load(context, group_basket_market.perp_market_info.address, group)
|
||||
perp_market = mango.PerpMarket(group_basket_market.perp_market_info.address, group_basket_market.base_token_info.token,
|
||||
group_basket_market.quote_token_info.token, perp_market_details)
|
||||
|
||||
return perp_market
|
||||
|
||||
|
||||
def find_basket_token_in_account(account: mango.Account, token: mango.Token) -> typing.Optional[mango.AccountBasketBaseToken]:
|
||||
basket_tokens = [in_basket for in_basket in account.basket if in_basket.token_info.token == token]
|
||||
|
||||
if len(basket_tokens) == 0:
|
||||
return None
|
||||
else:
|
||||
return basket_tokens[0]
|
||||
|
||||
|
||||
def build_redeem_instruction_for_account(context: mango.Context, wallet: mango.Wallet, group: mango.Group,
|
||||
mngo: mango.TokenInfo, account: mango.Account,
|
||||
perp_market: mango.PerpMarket,
|
||||
basket_token: typing.Optional[mango.AccountBasketBaseToken]):
|
||||
if (basket_token is None) or basket_token.perp_account.mngo_accrued.value == 0:
|
||||
return mango.CombinableInstructions.empty()
|
||||
|
||||
report_accrued(basket_token)
|
||||
redeem = mango.build_redeem_accrued_mango_instructions(context, wallet, perp_market, group, account, mngo)
|
||||
|
||||
return redeem
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description="redeems accrued MNGO from a Mango account")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--market", type=str, help="perp market symbol with accrued MNGO (e.g. ETH-PERP)")
|
||||
parser.add_argument("--all", action="store_true", default=False,
|
||||
help="redeem all MNGO in all perp markets in the account")
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
parser.add_argument("--wait", action="store_true", default=False,
|
||||
help="wait until the transaction is confirmed")
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.getLogger().setLevel(args.log_level)
|
||||
logging.warning(mango.WARNING_DISCLAIMER_TEXT)
|
||||
|
||||
if (not args.all) and (args.market is None):
|
||||
raise Exception("Must specify either an individual market (using --market) or use --all for all markets")
|
||||
|
||||
context = mango.ContextBuilder.from_command_line_parameters(args)
|
||||
wallet = mango.Wallet.from_command_line_parameters_or_raise(args)
|
||||
|
||||
group = mango.Group.load(context, context.group_id)
|
||||
mngo = group.find_token_info_by_symbol("MNGO")
|
||||
account = mango.Account.load_for_owner_by_index(context, wallet.address, group, args.account_index)
|
||||
|
||||
signers: mango.CombinableInstructions = mango.CombinableInstructions.from_wallet(wallet)
|
||||
all_instructions: mango.CombinableInstructions = signers
|
||||
|
||||
if args.all:
|
||||
for group_basket_market in group.basket:
|
||||
perp_market = load_perp_market(context, group, group_basket_market)
|
||||
basket_token = find_basket_token_in_account(account, group_basket_market.base_token_info.token)
|
||||
all_instructions += build_redeem_instruction_for_account(context,
|
||||
wallet, group, mngo, account, perp_market, basket_token)
|
||||
else:
|
||||
market_symbol = args.market.upper()
|
||||
market = context.market_lookup.find_by_symbol(market_symbol)
|
||||
if market is None:
|
||||
raise Exception(f"Could not find market {market_symbol}")
|
||||
|
||||
perp_market = mango.ensure_market_loaded(context, market)
|
||||
if not isinstance(perp_market, mango.PerpMarket):
|
||||
raise Exception(f"Market {market_symbol} is not a perp market")
|
||||
|
||||
basket_token = find_basket_token_in_account(account, perp_market.base)
|
||||
all_instructions += build_redeem_instruction_for_account(context,
|
||||
wallet, group, mngo, account, perp_market, basket_token)
|
||||
|
||||
transaction_ids = all_instructions.execute(context)
|
||||
print("Transaction IDs:", transaction_ids)
|
||||
|
||||
if args.wait:
|
||||
context.client.wait_for_confirmation(transaction_ids)
|
||||
reloaded_account = mango.Account.load_for_owner_by_index(context, wallet.address, group, args.account_index)
|
||||
if args.all:
|
||||
for group_basket_market in group.basket:
|
||||
basket_token = find_basket_token_in_account(reloaded_account, group_basket_market.base_token_info.token)
|
||||
if basket_token is not None:
|
||||
report_accrued(basket_token)
|
||||
else:
|
||||
basket_token = find_basket_token_in_account(reloaded_account, perp_market.base)
|
||||
if basket_token is not None:
|
||||
report_accrued(basket_token)
|
|
@ -20,7 +20,7 @@ from .group import GroupBasketMarket, Group
|
|||
from .idsjsontokenlookup import IdsJsonTokenLookup
|
||||
from .idsjsonmarketlookup import IdsJsonMarketLookup
|
||||
from .inventory import Inventory, InventoryAccountWatcher, spl_token_inventory_loader, account_inventory_loader
|
||||
from .instructions import build_create_solana_account_instructions, build_create_spl_account_instructions, build_create_associated_spl_account_instructions, build_transfer_spl_tokens_instructions, build_close_spl_account_instructions, build_create_serum_open_orders_instructions, build_serum_place_order_instructions, build_serum_consume_events_instructions, build_serum_settle_instructions, build_spot_place_order_instructions, build_cancel_spot_order_instructions, build_cancel_perp_order_instructions, build_mango_consume_events_instructions, build_create_account_instructions, build_place_perp_order_instructions, build_deposit_instructions, build_withdraw_instructions
|
||||
from .instructions import build_create_solana_account_instructions, build_create_spl_account_instructions, build_create_associated_spl_account_instructions, build_transfer_spl_tokens_instructions, build_close_spl_account_instructions, build_create_serum_open_orders_instructions, build_serum_place_order_instructions, build_serum_consume_events_instructions, build_serum_settle_instructions, build_spot_place_order_instructions, build_cancel_spot_order_instructions, build_cancel_perp_order_instructions, build_mango_consume_events_instructions, build_create_account_instructions, build_place_perp_order_instructions, build_deposit_instructions, build_withdraw_instructions, build_redeem_accrued_mango_instructions
|
||||
from .instructiontype import InstructionType
|
||||
from .liquidatablereport import LiquidatableState, LiquidatableReport
|
||||
from .liquidationevent import LiquidationEvent
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# [Github](https://github.com/blockworks-foundation)
|
||||
# [Email](mailto:hello@blockworks.foundation)
|
||||
|
||||
import datetime
|
||||
import itertools
|
||||
import json
|
||||
import logging
|
||||
|
@ -434,16 +435,20 @@ class BetterClient:
|
|||
def wait_for_confirmation(self, transaction_ids: typing.Sequence[str], max_wait_in_seconds: int = 60) -> typing.Sequence[str]:
|
||||
self.logger.info(f"Waiting up to {max_wait_in_seconds} seconds for {transaction_ids}.")
|
||||
all_confirmed: typing.List[str] = []
|
||||
for wait in range(0, max_wait_in_seconds):
|
||||
for transaction_id in transaction_ids:
|
||||
start_time: datetime.datetime = datetime.datetime.now()
|
||||
cutoff: datetime.datetime = start_time + datetime.timedelta(seconds=max_wait_in_seconds)
|
||||
for transaction_id in transaction_ids:
|
||||
while datetime.datetime.now() < cutoff:
|
||||
time.sleep(1)
|
||||
confirmed = self.get_confirmed_transaction(transaction_id)
|
||||
if confirmed is not None:
|
||||
self.logger.info(f"Confirmed {transaction_id} after {wait} seconds.")
|
||||
self.logger.info(
|
||||
f"Confirmed {transaction_id} after {datetime.datetime.now() - start_time} seconds.")
|
||||
all_confirmed += [transaction_id]
|
||||
break
|
||||
|
||||
if len(all_confirmed) != len(transaction_ids):
|
||||
self.logger.info(f"Timed out after {wait} seconds waiting on transaction {transaction_id}.")
|
||||
self.logger.info(f"Timed out after {max_wait_in_seconds} seconds waiting on transaction {transaction_id}.")
|
||||
return all_confirmed
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
|
|
@ -213,6 +213,13 @@ class Group(AddressableAccount):
|
|||
|
||||
raise Exception(f"Could not find token info for mint {token.mint} in group {self.address}")
|
||||
|
||||
def find_token_info_by_symbol(self, symbol: str) -> TokenInfo:
|
||||
for token_info in self.tokens:
|
||||
if token_info is not None and token_info.token.symbol_matches(symbol):
|
||||
return token_info
|
||||
|
||||
raise Exception(f"Could not find token info for symbol '{symbol}' in group {self.address}")
|
||||
|
||||
def fetch_balances(self, context: Context, root_address: PublicKey) -> typing.Sequence[TokenValue]:
|
||||
balances: typing.List[TokenValue] = []
|
||||
sol_balance = context.client.get_balance(root_address)
|
||||
|
|
|
@ -20,7 +20,7 @@ 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.market import Market
|
||||
from pyserum.market import Market as PySerumMarket
|
||||
from pyserum.open_orders_account import make_create_account_instruction
|
||||
from solana.account import Account as SolanaAccount
|
||||
from solana.publickey import PublicKey
|
||||
|
@ -38,10 +38,12 @@ from .context import Context
|
|||
from .group import Group
|
||||
from .layouts import layouts
|
||||
from .orders import Order, OrderType, Side
|
||||
from .perpmarket import PerpMarket
|
||||
from .perpmarketdetails import PerpMarketDetails
|
||||
from .rootbank import NodeBank, RootBank
|
||||
from .token import Token
|
||||
from .tokenaccount import TokenAccount
|
||||
from .tokeninfo import TokenInfo
|
||||
from .wallet import Wallet
|
||||
|
||||
|
||||
|
@ -127,7 +129,7 @@ def build_close_spl_account_instructions(context: Context, wallet: Wallet, addre
|
|||
# Creates a Serum openorders-creating instruction.
|
||||
#
|
||||
|
||||
def build_create_serum_open_orders_instructions(context: Context, wallet: Wallet, market: Market) -> CombinableInstructions:
|
||||
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(
|
||||
|
@ -145,7 +147,7 @@ def build_create_serum_open_orders_instructions(context: Context, wallet: Wallet
|
|||
# Creates a Serum order-placing instruction using V3 of the NewOrder instruction.
|
||||
#
|
||||
|
||||
def build_serum_place_order_instructions(context: Context, wallet: Wallet, market: Market, 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_side: SerumSide = SerumSide.SELL if side == Side.SELL else SerumSide.BUY
|
||||
|
||||
|
@ -194,7 +196,7 @@ def build_serum_consume_events_instructions(context: Context, market_address: Pu
|
|||
# Creates a 'settle' instruction.
|
||||
#
|
||||
|
||||
def build_serum_settle_instructions(context: Context, wallet: Wallet, market: Market, open_orders_address: PublicKey, base_token_account_address: PublicKey, quote_token_account_address: PublicKey) -> CombinableInstructions:
|
||||
def build_serum_settle_instructions(context: Context, wallet: Wallet, market: PySerumMarket, open_orders_address: PublicKey, base_token_account_address: PublicKey, quote_token_account_address: PublicKey) -> CombinableInstructions:
|
||||
vault_signer = PublicKey.create_program_address(
|
||||
[bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
|
||||
market.state.program_id(),
|
||||
|
@ -239,12 +241,12 @@ def build_serum_settle_instructions(context: Context, wallet: Wallet, market: Ma
|
|||
# /// 13. `[writable]` quote_node_bank_ai - MangoGroup quote vault acc
|
||||
# /// 14. `[writable]` base_vault_ai - MangoGroup base vault acc
|
||||
# /// 15. `[writable]` quote_vault_ai - MangoGroup quote vault acc
|
||||
# /// 16. `[]` dex_signer_ai - dex Market signer account
|
||||
# /// 16. `[]` dex_signer_ai - dex PySerumMarket signer account
|
||||
# /// 17. `[]` spl token program
|
||||
|
||||
|
||||
def build_spot_settle_instructions(context: Context, wallet: Wallet, account: Account,
|
||||
market: Market, group: Group, open_orders_address: PublicKey,
|
||||
market: PySerumMarket, group: Group, open_orders_address: PublicKey,
|
||||
base_rootbank: RootBank, base_nodebank: NodeBank,
|
||||
quote_rootbank: RootBank, quote_nodebank: NodeBank) -> CombinableInstructions:
|
||||
vault_signer = PublicKey.create_program_address(
|
||||
|
@ -300,7 +302,7 @@ def build_spot_settle_instructions(context: Context, wallet: Wallet, account: Ac
|
|||
# orderbook).
|
||||
#
|
||||
|
||||
def build_compound_serum_place_order_instructions(context: Context, wallet: Wallet, market: Market, source: PublicKey, open_orders_address: PublicKey, all_open_orders_addresses: typing.Sequence[PublicKey], order_type: OrderType, side: Side, price: Decimal, quantity: Decimal, client_id: int, base_token_account_address: PublicKey, quote_token_account_address: PublicKey, fee_discount_address: typing.Optional[PublicKey], consume_limit: int = 32) -> CombinableInstructions:
|
||||
def build_compound_serum_place_order_instructions(context: Context, wallet: Wallet, market: PySerumMarket, source: PublicKey, open_orders_address: PublicKey, all_open_orders_addresses: typing.Sequence[PublicKey], order_type: OrderType, side: Side, price: Decimal, quantity: Decimal, client_id: int, base_token_account_address: PublicKey, quote_token_account_address: PublicKey, fee_discount_address: typing.Optional[PublicKey], consume_limit: int = 32) -> CombinableInstructions:
|
||||
place_order = build_serum_place_order_instructions(
|
||||
context, wallet, market, source, open_orders_address, order_type, side, price, quantity, client_id, fee_discount_address)
|
||||
consume_events = build_serum_consume_events_instructions(
|
||||
|
@ -553,7 +555,7 @@ def build_withdraw_instructions(context: Context, wallet: Wallet, group: Group,
|
|||
return CombinableInstructions(signers=[], instructions=[withdraw])
|
||||
|
||||
|
||||
def build_spot_openorders_instructions(context: Context, wallet: Wallet, group: Group, account: Account, market: Market) -> CombinableInstructions:
|
||||
def build_spot_openorders_instructions(context: Context, wallet: Wallet, group: Group, account: Account, market: PySerumMarket) -> CombinableInstructions:
|
||||
instructions: CombinableInstructions = CombinableInstructions.empty()
|
||||
create_open_orders = build_create_solana_account_instructions(
|
||||
context, wallet, context.dex_program_id, layouts.OPEN_ORDERS.sizeof())
|
||||
|
@ -611,7 +613,7 @@ def build_spot_openorders_instructions(context: Context, wallet: Wallet, group:
|
|||
# })),
|
||||
|
||||
def build_spot_place_order_instructions(context: Context, wallet: Wallet, group: Group, account: Account,
|
||||
market: Market,
|
||||
market: PySerumMarket,
|
||||
order_type: OrderType, side: Side, price: Decimal,
|
||||
quantity: Decimal, client_id: int,
|
||||
fee_discount_address: typing.Optional[PublicKey]) -> CombinableInstructions:
|
||||
|
@ -701,7 +703,7 @@ def build_spot_place_order_instructions(context: Context, wallet: Wallet, group:
|
|||
#
|
||||
|
||||
|
||||
def build_cancel_spot_order_instructions(context: Context, wallet: Wallet, group: Group, account: Account, market: Market, order: Order, open_orders_address: PublicKey) -> CombinableInstructions:
|
||||
def build_cancel_spot_order_instructions(context: Context, wallet: Wallet, group: Group, account: Account, market: PySerumMarket, order: Order, open_orders_address: PublicKey) -> CombinableInstructions:
|
||||
# { buy: 0, sell: 1 }
|
||||
raw_side: int = 1 if order.side == Side.SELL else 0
|
||||
|
||||
|
@ -741,13 +743,12 @@ def build_cancel_spot_order_instructions(context: Context, wallet: Wallet, group
|
|||
]
|
||||
return CombinableInstructions(signers=[], instructions=instructions)
|
||||
|
||||
|
||||
# # 🥭 build_mango_settle_instructions function
|
||||
#
|
||||
# Creates a 'settle' instruction for Mango accounts.
|
||||
#
|
||||
|
||||
|
||||
def build_mango_settle_instructions(context: Context, wallet: Wallet, market: Market, open_orders_address: PublicKey, base_token_account_address: PublicKey, quote_token_account_address: PublicKey) -> CombinableInstructions:
|
||||
def build_mango_settle_instructions(context: Context, wallet: Wallet, market: PySerumMarket, open_orders_address: PublicKey, base_token_account_address: PublicKey, quote_token_account_address: PublicKey) -> CombinableInstructions:
|
||||
vault_signer = PublicKey.create_program_address(
|
||||
[bytes(market.state.public_key()), market.state.vault_signer_nonce().to_bytes(8, byteorder="little")],
|
||||
market.state.program_id(),
|
||||
|
@ -767,3 +768,43 @@ def build_mango_settle_instructions(context: Context, wallet: Wallet, market: Ma
|
|||
)
|
||||
|
||||
return CombinableInstructions(signers=[], instructions=[instruction])
|
||||
|
||||
|
||||
# # 🥭 build_redeem_accrued_mango_instructions function
|
||||
#
|
||||
# Creates a 'RedeemMngo' instruction for Mango accounts.
|
||||
#
|
||||
def build_redeem_accrued_mango_instructions(context: Context, wallet: Wallet, perp_market: PerpMarket, group: Group, account: Account, mngo: TokenInfo) -> CombinableInstructions:
|
||||
node_bank: NodeBank = mngo.root_bank.pick_node_bank(context)
|
||||
# /// Redeem the mngo_accrued in a PerpAccount for MNGO in MangoAccount deposits
|
||||
# ///
|
||||
# /// Accounts expected by this instruction (11):
|
||||
# /// 0. `[]` mango_group_ai - MangoGroup that this mango account is for
|
||||
# /// 1. `[]` mango_cache_ai - MangoCache
|
||||
# /// 2. `[writable]` mango_account_ai - MangoAccount
|
||||
# /// 3. `[signer]` owner_ai - MangoAccount owner
|
||||
# /// 4. `[]` perp_market_ai - PerpMarket
|
||||
# /// 5. `[writable]` mngo_perp_vault_ai
|
||||
# /// 6. `[]` mngo_root_bank_ai
|
||||
# /// 7. `[writable]` mngo_node_bank_ai
|
||||
# /// 8. `[writable]` mngo_bank_vault_ai
|
||||
# /// 9. `[]` signer_ai - Group Signer Account
|
||||
# /// 10. `[]` token_prog_ai - SPL Token program id
|
||||
redeem_accrued_mango_instruction = TransactionInstruction(
|
||||
keys=[
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=group.address),
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=group.cache),
|
||||
AccountMeta(is_signer=False, is_writable=True, pubkey=account.address),
|
||||
AccountMeta(is_signer=True, is_writable=False, pubkey=wallet.address),
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=perp_market.address),
|
||||
AccountMeta(is_signer=False, is_writable=True, pubkey=perp_market.underlying_perp_market.mngo_vault),
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=mngo.root_bank.address),
|
||||
AccountMeta(is_signer=False, is_writable=True, pubkey=node_bank.address),
|
||||
AccountMeta(is_signer=False, is_writable=True, pubkey=node_bank.vault),
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=group.signer_key),
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=TOKEN_PROGRAM_ID)
|
||||
],
|
||||
program_id=context.program_id,
|
||||
data=layouts.REDEEM_MNGO.build(dict())
|
||||
)
|
||||
return CombinableInstructions(signers=[], instructions=[redeem_accrued_mango_instruction])
|
||||
|
|
|
@ -1335,6 +1335,24 @@ INIT_SPOT_OPEN_ORDERS = construct.Struct(
|
|||
"variant" / construct.Const(32, construct.BytesInteger(4, swapped=True))
|
||||
)
|
||||
|
||||
# /// Redeem the mngo_accrued in a PerpAccount for MNGO in MangoAccount deposits
|
||||
# ///
|
||||
# /// Accounts expected by this instruction (11):
|
||||
# /// 0. `[]` mango_group_ai - MangoGroup that this mango account is for
|
||||
# /// 1. `[]` mango_cache_ai - MangoCache
|
||||
# /// 2. `[writable]` mango_account_ai - MangoAccount
|
||||
# /// 3. `[signer]` owner_ai - MangoAccount owner
|
||||
# /// 4. `[]` perp_market_ai - PerpMarket
|
||||
# /// 5. `[writable]` mngo_perp_vault_ai
|
||||
# /// 6. `[]` mngo_root_bank_ai
|
||||
# /// 7. `[writable]` mngo_node_bank_ai
|
||||
# /// 8. `[writable]` mngo_bank_vault_ai
|
||||
# /// 9. `[]` signer_ai - Group Signer Account
|
||||
# /// 10. `[]` token_prog_ai - SPL Token program id
|
||||
REDEEM_MNGO = construct.Struct(
|
||||
"variant" / construct.Const(33, construct.BytesInteger(4, swapped=True))
|
||||
)
|
||||
|
||||
UNSPECIFIED = construct.Struct(
|
||||
"variant" / DecimalAdapter(4)
|
||||
)
|
||||
|
@ -1373,7 +1391,7 @@ InstructionParsersByVariant = {
|
|||
30: UNSPECIFIED, # RESOLVE_PERP_BANKRUPTCY,
|
||||
31: UNSPECIFIED, # RESOLVE_TOKEN_BANKRUPTCY,
|
||||
32: INIT_SPOT_OPEN_ORDERS, # INIT_SPOT_OPEN_ORDERS,
|
||||
33: UNSPECIFIED, # REDEEM_MNGO,
|
||||
33: REDEEM_MNGO, # REDEEM_MNGO,
|
||||
34: UNSPECIFIED, # ADD_MANGO_ACCOUNT_INFO,
|
||||
35: UNSPECIFIED, # DEPOSIT_MSRM,
|
||||
36: UNSPECIFIED, # WITHDRAW_MSRM
|
||||
|
|
Loading…
Reference in New Issue