Added instructions and commands for account delegation.
This commit is contained in:
parent
f9b7d7b03f
commit
f1b14acdcf
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "..")))
|
||||
import mango # nopep8
|
||||
|
||||
parser = argparse.ArgumentParser(description="Delegate operational authority of a Mango account to another account.")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--account-address", type=PublicKey, required=True,
|
||||
help="address of the Mango account to delegate")
|
||||
parser.add_argument("--delegate-address", type=PublicKey, required=False,
|
||||
help="address of the account to which to delegate operational control of the Mango account")
|
||||
parser.add_argument("--revoke", action="store_true", default=False,
|
||||
help="revoke any previous account delegation")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
||||
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_address)
|
||||
account: mango.Account = mango.Account.load(context, args.account_address, group)
|
||||
if account.owner != wallet.address:
|
||||
raise Exception(f"Account {account.address} is not owned by current wallet {wallet.address}.")
|
||||
|
||||
all_instructions: mango.CombinableInstructions = mango.CombinableInstructions.from_signers([wallet.keypair])
|
||||
if args.revoke:
|
||||
unset_delegate_instructions = mango.build_unset_account_delegate_instructions(context, wallet, group, account)
|
||||
all_instructions += unset_delegate_instructions
|
||||
else:
|
||||
if args.delegate_address is None:
|
||||
raise Exception("No delegate address specified")
|
||||
|
||||
set_delegate_instructions = mango.build_set_account_delegate_instructions(
|
||||
context, wallet, group, account, args.delegate_address)
|
||||
all_instructions += set_delegate_instructions
|
||||
|
||||
transaction_ids = all_instructions.execute(context)
|
||||
mango.output(f"Transaction IDs: {transaction_ids}")
|
10
bin/deposit
10
bin/deposit
|
@ -6,6 +6,7 @@ import os.path
|
|||
import sys
|
||||
|
||||
from decimal import Decimal
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
@ -16,18 +17,15 @@ mango.ContextBuilder.add_command_line_parameters(parser)
|
|||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--symbol", type=str, required=True, help="token symbol to deposit (e.g. USDC)")
|
||||
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity token to deposit")
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
parser.add_argument("--account-address", type=PublicKey,
|
||||
help="address of the specific account to use, if more than one available")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
||||
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_address)
|
||||
accounts = mango.Account.load_all_for_owner(context, wallet.address, group)
|
||||
if len(accounts) == 0:
|
||||
raise Exception(f"Could not find any Mango accounts for '{wallet.address}'.")
|
||||
account = accounts[args.account_index]
|
||||
account = mango.Account.load_for_owner_by_address(context, wallet.address, group, args.account_address)
|
||||
|
||||
instrument = context.instrument_lookup.find_by_symbol(args.symbol)
|
||||
if instrument is None:
|
||||
|
|
|
@ -5,6 +5,8 @@ import os
|
|||
import os.path
|
||||
import sys
|
||||
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..')))
|
||||
import mango # nopep8
|
||||
|
@ -12,9 +14,9 @@ import mango # nopep8
|
|||
parser = argparse.ArgumentParser(description="Ensure an OpenOrders account exists for the wallet and market.")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
parser.add_argument("--market", type=str, required=True, help="market symbol to buy (e.g. ETH/USDC)")
|
||||
parser.add_argument("--account-address", type=PublicKey,
|
||||
help="address of the specific account to use, if more than one available")
|
||||
parser.add_argument("--dry-run", action="store_true", default=False,
|
||||
help="runs as read-only and does not perform any transactions")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
@ -23,10 +25,7 @@ context = mango.ContextBuilder.from_command_line_parameters(args)
|
|||
wallet = mango.Wallet.from_command_line_parameters_or_raise(args)
|
||||
|
||||
group = mango.Group.load(context)
|
||||
accounts = mango.Account.load_all_for_owner(context, wallet.address, group)
|
||||
if len(accounts) == 0:
|
||||
raise Exception(f"No Mango account exists for group {group.address} and wallet {wallet.address}")
|
||||
account = accounts[args.account_index]
|
||||
account = mango.Account.load_for_owner_by_address(context, wallet.address, group, args.account_address)
|
||||
|
||||
market = context.market_lookup.find_by_symbol(args.market)
|
||||
if market is None:
|
||||
|
|
|
@ -11,7 +11,7 @@ sys.path.insert(0, os.path.abspath(
|
|||
os.path.join(os.path.dirname(__file__), "..")))
|
||||
import mango # nopep8
|
||||
|
||||
parser = argparse.ArgumentParser(description="Shows details of a Merps account.")
|
||||
parser = argparse.ArgumentParser(description="Shows details of a Mango account.")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--address", type=PublicKey, required=False,
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "..")))
|
||||
import mango # nopep8
|
||||
|
||||
parser = argparse.ArgumentParser(description="Shows details of a Mango account.")
|
||||
mango.ContextBuilder.add_command_line_parameters(parser)
|
||||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--address", type=PublicKey, required=False,
|
||||
help="address of the delegate of the account (defaults to the root address of the wallet)")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
||||
context = mango.ContextBuilder.from_command_line_parameters(args)
|
||||
|
||||
delegate = args.address
|
||||
if delegate is None:
|
||||
wallet = mango.Wallet.from_command_line_parameters_or_raise(args)
|
||||
delegate = wallet.address
|
||||
|
||||
group = mango.Group.load(context, context.group_address)
|
||||
mango_accounts = mango.Account.load_all_for_delegate(context, delegate, group)
|
||||
if len(mango_accounts) == 0:
|
||||
mango.output(f"Account {delegate} has no accounts delegated to it.")
|
||||
else:
|
||||
mango.output(mango_accounts)
|
|
@ -17,8 +17,8 @@ mango.ContextBuilder.add_command_line_parameters(parser)
|
|||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--address", type=PublicKey,
|
||||
help="Root address to check (if not provided, the wallet address is used)")
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
parser.add_argument("--account-address", type=PublicKey,
|
||||
help="address of the specific account to use, if more than one available")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
||||
context = mango.ContextBuilder.from_command_line_parameters(args)
|
||||
|
@ -28,8 +28,7 @@ if address is None:
|
|||
address = wallet.address
|
||||
|
||||
group = mango.Group.load(context)
|
||||
accounts = mango.Account.load_all_for_owner(context, address, group)
|
||||
account = accounts[args.account_index]
|
||||
account = mango.Account.load_for_owner_by_address(context, wallet.address, group, args.account_address)
|
||||
|
||||
at_least_one_open_orders_account = False
|
||||
quote_token_bank = group.shared_quote_token
|
||||
|
|
10
bin/withdraw
10
bin/withdraw
|
@ -6,6 +6,7 @@ import os.path
|
|||
import sys
|
||||
|
||||
from decimal import Decimal
|
||||
from solana.publickey import PublicKey
|
||||
|
||||
sys.path.insert(0, os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
@ -16,8 +17,8 @@ mango.ContextBuilder.add_command_line_parameters(parser)
|
|||
mango.Wallet.add_command_line_parameters(parser)
|
||||
parser.add_argument("--symbol", type=str, required=True, help="token symbol to withdraw (e.g. USDC)")
|
||||
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity token to withdraw")
|
||||
parser.add_argument("--account-index", type=int, default=0,
|
||||
help="index of the account to use, if more than one available")
|
||||
parser.add_argument("--account-address", type=PublicKey,
|
||||
help="address of the specific account to use, if more than one available")
|
||||
parser.add_argument("--allow-borrow", action="store_true", default=False,
|
||||
help="allow borrowing to fund the withdrawal")
|
||||
args: argparse.Namespace = mango.parse_args(parser)
|
||||
|
@ -26,10 +27,7 @@ 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_address)
|
||||
accounts = mango.Account.load_all_for_owner(context, wallet.address, group)
|
||||
if len(accounts) == 0:
|
||||
raise Exception(f"Could not find any margin accounts for '{wallet.address}'.")
|
||||
account = accounts[args.account_index]
|
||||
account = mango.Account.load_for_owner_by_address(context, wallet.address, group, args.account_address)
|
||||
|
||||
instrument = context.instrument_lookup.find_by_symbol(args.symbol)
|
||||
if instrument is None:
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
# 🥭 Mango Explorer
|
||||
|
||||
# 🔥 Delegation
|
||||
|
||||
Mango Account Delegation is a feature that allows a separate account limited access to the Mango Account's features.
|
||||
|
||||
Delegation can provide some additional security for more sophisticated key management procedures.
|
||||
|
||||
A delegated account *can*, for example:
|
||||
* Deposit funds
|
||||
* Place orders
|
||||
* Cancel orders
|
||||
|
||||
A delegated account *cannot*, for example:
|
||||
* Withdraw funds
|
||||
* Close the Mango Account
|
||||
|
||||
A Mango Account can have at most one delegate. The owner of the Mango Account continues to have full control of the Mango Account irrespective of delegation.
|
||||
|
||||
|
||||
# 🆒 Commands
|
||||
|
||||
`mango-explorer` provides two commands for delegation: `delegate-account` and `show-delegated-accounts`.
|
||||
|
||||
You can see exactly what additional parameters a command takes by specifying the `--help` parameter.
|
||||
|
||||
## `delegate-account`
|
||||
|
||||
> Accepts parameter: `--account-address <ACCOUNT-PUBLIC-KEY>` (required, `PublicKey`, no default)
|
||||
|
||||
> Accepts parameter: `--delegate-address <DELEGATE-PUBLIC-KEY>` (optional, `PublicKey`, no default)
|
||||
|
||||
> Accepts parameter: `--revoke` (optional, TRUE if specified otherwise FALSE)
|
||||
|
||||
`delegate-account` allows you to set or revoke delegation of a Mango Account. It must be run by the owner of the Mango Account.
|
||||
|
||||
|
||||
## `show-delegated-accounts`
|
||||
|
||||
> Accepts parameter: `--address <DELEGATE-PUBLIC-KEY>` (optional, `PublicKey`, default value: wallet root address)
|
||||
|
||||
`show-delegated-accounts` will list all accounts for which the current wallet is nominated as the delegate. **It will not** list accounts *owned* by the current wallet, only those in which it is listed as a delegate.
|
||||
|
||||
|
||||
# ✅ Example Walkthrough
|
||||
|
||||
To run this walkthrough, you need to set up 2 different Solana wallets and 1 Mango Account. Choose one of the wallets as the Owner and use it to create a Mango Account. The other wallet is the Delegate.
|
||||
|
||||
In these examples,
|
||||
* `ALBdwdFnHsmTAQ3xGqkDK8hcTMXeuMNyCNkz1ikBzv3L` is the address of the Mango Account Owner's wallet
|
||||
* `7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62` is the address of the Mango Account
|
||||
* `6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB` is the address of Delegate's wallet
|
||||
|
||||
|
||||
## Show No Delegate
|
||||
|
||||
*Run as Owner of the Mango Account*
|
||||
|
||||
This command will show the Mango Account, including what account (if any) is listed as a delegate:
|
||||
```
|
||||
show-accounts
|
||||
```
|
||||
This will output something like (abridged):
|
||||
```
|
||||
« Account (un-named), Version.V3 [7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62]
|
||||
« Metadata Version.V2 - Account: Initialized »
|
||||
Owner: ALBdwdFnHsmTAQ3xGqkDK8hcTMXeuMNyCNkz1ikBzv3L
|
||||
Delegated To: None
|
||||
```
|
||||
|
||||
|
||||
## Delegate Account
|
||||
|
||||
*Run as Owner of the Mango Account*
|
||||
|
||||
This command will grant the Delegate limited access to the Mango Account:
|
||||
```
|
||||
delegate-account --account-address 7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62 --delegate-address 6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB
|
||||
```
|
||||
|
||||
|
||||
## Show Delegate
|
||||
|
||||
*Run as Owner of the Mango Account*
|
||||
|
||||
This command will now show the Mango Account with `6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB` listed as a delegate:
|
||||
```
|
||||
show-accounts
|
||||
```
|
||||
This will output the address of the Delegate in the 'Delegated To' line (abridged):
|
||||
```
|
||||
« Account (un-named), Version.V3 [7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62]
|
||||
« Metadata Version.V2 - Account: Initialized »
|
||||
Owner: ALBdwdFnHsmTAQ3xGqkDK8hcTMXeuMNyCNkz1ikBzv3L
|
||||
Delegated To: 6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB
|
||||
```
|
||||
|
||||
|
||||
## Show Delegated Account
|
||||
|
||||
*Run as Delegate*
|
||||
|
||||
This command will show all Mango Accounts with the current user listed as a delegate. If it is run as the user with the wallet address `6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB` (the Delegate)
|
||||
```
|
||||
show-delegated-accounts
|
||||
```
|
||||
It will show the same output as `show-account` run by the Owner:
|
||||
```
|
||||
« Account (un-named), Version.V3 [7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62]
|
||||
« Metadata Version.V2 - Account: Initialized »
|
||||
Owner: ALBdwdFnHsmTAQ3xGqkDK8hcTMXeuMNyCNkz1ikBzv3L
|
||||
Delegated To: 6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB
|
||||
```
|
||||
|
||||
|
||||
## Deposit
|
||||
|
||||
*Run as Delegate*
|
||||
|
||||
Delegates can deposit funds from their own wallet (not the Owner's wallet).
|
||||
```
|
||||
deposit --symbol SOL --quantity 1 --account-address 7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62
|
||||
```
|
||||
Note that to target an account which has been delegated, the `--account-address` parameter must be specified. (This is the same way an account is specified for wallets that hold multiple Mango Accounts.)
|
||||
|
||||
|
||||
## Place Order
|
||||
|
||||
*Run as Delegate*
|
||||
|
||||
Delegates can place and cancel orders using the delegated Mango Account.
|
||||
```
|
||||
place-order --market SOL-PERP --quantity 1 --side BUY --order-type LIMIT --price 10 --skip-preflight --account-address 7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62
|
||||
```
|
||||
|
||||
**Note**: it is the Delegate running this command so it is the Delegate that pays the SOL for the transaction.
|
||||
|
||||
|
||||
## Withdraw
|
||||
|
||||
*Run as Delegate*
|
||||
|
||||
Delegates **cannot** withdraw funds from the delegated Mango Account. **This will fail**:
|
||||
```
|
||||
withdraw --symbol SOL --quantity 1 --account-address 7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62
|
||||
```
|
||||
**This will fail** with an error containing the following in the transaction logs:
|
||||
```
|
||||
Program log: MangoErrorCode::InvalidOwner; src/processor.rs
|
||||
```
|
||||
|
||||
## Revoke Delegation
|
||||
|
||||
*Run as Owner of the Mango Account*
|
||||
|
||||
This command will revoke the delegated authority to the Delegate, removing their access to the Mango Account:
|
||||
```
|
||||
delegate-account --account-address 7zTdp1YhPdBQw8nFJJXkmTewZf4zPwDbjktKzQLaQr62 --revoke
|
||||
```
|
||||
|
||||
|
||||
## Show No Delegated Accounts
|
||||
|
||||
*Run as Delegate*
|
||||
|
||||
Running the same command as earlier:
|
||||
```
|
||||
show-delegated-accounts
|
||||
```
|
||||
Now shows no delegated accounts, since the delegation was revoked:
|
||||
```
|
||||
Account 6aNN6nbAm9Dbqex9kKGAYcMFJg7Jhertwew9JhRv4QfB has no accounts delegated to it.
|
||||
```
|
|
@ -88,8 +88,10 @@ from .instructions import build_redeem_accrued_mango_instructions as build_redee
|
|||
from .instructions import build_serum_consume_events_instructions as build_serum_consume_events_instructions
|
||||
from .instructions import build_serum_place_order_instructions as build_serum_place_order_instructions
|
||||
from .instructions import build_serum_settle_instructions as build_serum_settle_instructions
|
||||
from .instructions import build_set_account_delegate_instructions as build_set_account_delegate_instructions
|
||||
from .instructions import build_spot_place_order_instructions as build_spot_place_order_instructions
|
||||
from .instructions import build_transfer_spl_tokens_instructions as build_transfer_spl_tokens_instructions
|
||||
from .instructions import build_unset_account_delegate_instructions as build_unset_account_delegate_instructions
|
||||
from .instructions import build_withdraw_instructions as build_withdraw_instructions
|
||||
from .instructionreporter import InstructionReporter as InstructionReporter
|
||||
from .instructionreporter import SerumInstructionReporter as SerumInstructionReporter
|
||||
|
|
|
@ -344,6 +344,34 @@ class Account(AddressableAccount):
|
|||
accounts += [account]
|
||||
return accounts
|
||||
|
||||
@staticmethod
|
||||
def load_all_for_delegate(context: Context, delegate: PublicKey, group: Group) -> typing.Sequence["Account"]:
|
||||
# mango_group is just after the METADATA, which is the first entry.
|
||||
group_offset = layouts.METADATA.sizeof()
|
||||
# delegate is a PublicKey which is 32 bytes that ends 5 bytes before the end of the layout
|
||||
delegate_offset = layouts.MANGO_ACCOUNT.sizeof() - 37
|
||||
filters = [
|
||||
MemcmpOpts(
|
||||
offset=group_offset,
|
||||
bytes=encode_key(group.address)
|
||||
),
|
||||
MemcmpOpts(
|
||||
offset=delegate_offset,
|
||||
bytes=encode_key(delegate)
|
||||
)
|
||||
]
|
||||
|
||||
results = context.client.get_program_accounts(
|
||||
context.mango_program_address, memcmp_opts=filters, data_size=layouts.MANGO_ACCOUNT.sizeof())
|
||||
cache: Cache = group.fetch_cache(context)
|
||||
accounts: typing.List[Account] = []
|
||||
for account_data in results:
|
||||
address = PublicKey(account_data["pubkey"])
|
||||
account_info = AccountInfo._from_response_values(account_data["account"], address)
|
||||
account = Account.parse(account_info, group, cache)
|
||||
accounts += [account]
|
||||
return accounts
|
||||
|
||||
@staticmethod
|
||||
def load_for_owner_by_address(context: Context, owner: PublicKey, group: Group, account_address: typing.Optional[PublicKey]) -> "Account":
|
||||
if account_address is not None:
|
||||
|
|
|
@ -879,3 +879,37 @@ def build_faucet_airdrop_instructions(token_mint: PublicKey, destination: Public
|
|||
})
|
||||
)
|
||||
return CombinableInstructions(signers=[], instructions=[faucet_airdrop_instruction])
|
||||
|
||||
|
||||
# # 🥭 build_set_account_delegate_instructions function
|
||||
#
|
||||
# Creates an instruction to delegate account operations (except Withdraw and CloseAccount) to a
|
||||
# different account.
|
||||
#
|
||||
# Set to SYSTEM_PROGRAM_ADDRESS to revoke delegate.
|
||||
#
|
||||
def build_set_account_delegate_instructions(context: Context, wallet: Wallet, group: Group, account: Account, delegate: PublicKey) -> CombinableInstructions:
|
||||
# /// https://github.com/blockworks-foundation/mango-v3/pull/97/
|
||||
# /// Set delegate authority to mango account which can do everything regular account can do
|
||||
# /// except Withdraw and CloseMangoAccount. Set to Pubkey::default() to revoke delegate
|
||||
# ///
|
||||
# /// Accounts expected: 4
|
||||
# /// 0. `[]` mango_group_ai - MangoGroup
|
||||
# /// 1. `[writable]` mango_account_ai - MangoAccount
|
||||
# /// 2. `[signer]` owner_ai - Owner of Mango Account
|
||||
# /// 3. `[]` delegate_ai - delegate
|
||||
set_delegate_instruction = TransactionInstruction(
|
||||
keys=[
|
||||
AccountMeta(is_signer=False, is_writable=False, pubkey=group.address),
|
||||
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=delegate)
|
||||
],
|
||||
program_id=context.mango_program_address,
|
||||
data=layouts.SET_DELEGATE.build({})
|
||||
)
|
||||
return CombinableInstructions(signers=[], instructions=[set_delegate_instruction])
|
||||
|
||||
|
||||
def build_unset_account_delegate_instructions(context: Context, wallet: Wallet, group: Group, account: Account) -> CombinableInstructions:
|
||||
return build_set_account_delegate_instructions(context, wallet, group, account, SYSTEM_PROGRAM_ADDRESS)
|
||||
|
|
|
@ -1570,6 +1570,20 @@ CREATE_MANGO_ACCOUNT = construct.Struct(
|
|||
)
|
||||
|
||||
|
||||
# /// https://github.com/blockworks-foundation/mango-v3/pull/97/
|
||||
# /// Set delegate authority to mango account which can do everything regular account can do
|
||||
# /// except Withdraw and CloseMangoAccount. Set to Pubkey::default() to revoke delegate
|
||||
# ///
|
||||
# /// Accounts expected: 4
|
||||
# /// 0. `[]` mango_group_ai - MangoGroup
|
||||
# /// 1. `[writable]` mango_account_ai - MangoAccount
|
||||
# /// 2. `[signer]` owner_ai - Owner of Mango Account
|
||||
# /// 3. `[]` delegate_ai - delegate
|
||||
SET_DELEGATE = construct.Struct(
|
||||
"variant" / construct.Const(58, construct.BytesInteger(4, swapped=True))
|
||||
)
|
||||
|
||||
|
||||
UNSPECIFIED = construct.Struct(
|
||||
"variant" / DecimalAdapter(4)
|
||||
)
|
||||
|
@ -1633,7 +1647,7 @@ InstructionParsersByVariant = {
|
|||
55: CREATE_MANGO_ACCOUNT, # CREATE_MANGO_ACCOUNT,
|
||||
56: UNSPECIFIED, # UPGRADE_MANGO_ACCOUNT_V0_V1,
|
||||
57: UNSPECIFIED, # CANCEL_PERP_ORDER_SIDE,
|
||||
58: UNSPECIFIED, # SET_DELEGATE,
|
||||
58: SET_DELEGATE, # SET_DELEGATE,
|
||||
59: UNSPECIFIED, # CHANGE_SPOT_MARKET_PARAMS,
|
||||
60: UNSPECIFIED, # CREATE_SPOT_OPEN_ORDERS,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue