Added a 'create-wallet' command, made other commands more consistent.

This commit is contained in:
Geoff Taylor 2021-05-07 10:47:01 +01:00
parent 0f05be4fc7
commit db91e1d9d8
10 changed files with 91 additions and 30 deletions

View File

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
"id": "retired-result",
"id": "explicit-citizen",
"metadata": {},
"source": [
"# ⚠ Warning\n",
@ -16,7 +16,7 @@
},
{
"cell_type": "markdown",
"id": "embedded-exclusion",
"id": "marine-insertion",
"metadata": {},
"source": [
"# 🥭 Wallet\n",
@ -29,7 +29,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "genetic-daniel",
"id": "micro-eleven",
"metadata": {
"jupyter": {
"source_hidden": true
@ -50,7 +50,7 @@
},
{
"cell_type": "markdown",
"id": "governing-knock",
"id": "bored-polymer",
"metadata": {},
"source": [
"## Wallet class\n",
@ -69,7 +69,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "explicit-transparency",
"id": "narrow-birth",
"metadata": {},
"outputs": [],
"source": [
@ -89,6 +89,13 @@
" largest_account = context.fetch_largest_token_account_for_owner(self.address, token_mint)\n",
" return largest_account\n",
"\n",
" def save(self, filename: str, overwrite: bool = False):\n",
" if os.path.isfile(filename) and not overwrite:\n",
" raise Exception(f\"Wallet file '{filename}' already exists.\")\n",
"\n",
" with open(filename, \"w\") as json_file:\n",
" json.dump(list(self.secret_key), json_file)\n",
"\n",
" @staticmethod\n",
" def load(filename: str = _DEFAULT_WALLET_FILENAME) -> \"Wallet\":\n",
" if not os.path.isfile(filename):\n",
@ -97,12 +104,18 @@
" else:\n",
" with open(filename) as json_file:\n",
" data = json.load(json_file)\n",
" return Wallet(data)\n"
" return Wallet(data)\n",
"\n",
" @staticmethod\n",
" def create() -> \"Wallet\":\n",
" new_account = Account()\n",
" new_secret_key = new_account.secret_key()\n",
" return Wallet(new_secret_key)\n"
]
},
{
"cell_type": "markdown",
"id": "headed-collectible",
"id": "qualified-playlist",
"metadata": {},
"source": [
"# default_wallet object\n",
@ -113,18 +126,21 @@
{
"cell_type": "code",
"execution_count": null,
"id": "numeric-efficiency",
"id": "placed-start",
"metadata": {},
"outputs": [],
"source": [
"default_wallet = None\n",
"if os.path.isfile(_DEFAULT_WALLET_FILENAME):\n",
" default_wallet = Wallet.load(_DEFAULT_WALLET_FILENAME)\n"
" try:\n",
" default_wallet = Wallet.load(_DEFAULT_WALLET_FILENAME)\n",
" except Exception as exception:\n",
" logging.warning(f\"Failed to load default wallet from file '{_DEFAULT_WALLET_FILENAME}' - exception: {exception}\")\n"
]
},
{
"cell_type": "markdown",
"id": "pediatric-finding",
"id": "sonic-financing",
"metadata": {},
"source": [
"# 🏃 Running\n",
@ -137,7 +153,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "simple-programming",
"id": "extensive-tourist",
"metadata": {},
"outputs": [],
"source": [

45
bin/create-wallet Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env pyston3
import os, sys
from pathlib import Path
# Get the full path to this script.
script_path = Path(os.path.realpath(__file__))
# The parent of the script is the bin directory.
# The parent of the bin directory is the notebook directory.
# It's this notebook directory we want.
notebook_directory = script_path.parent.parent
# Add the notebook directory to our import path.
sys.path.append(str(notebook_directory))
# Add the startup directory to our import path.
startup_directory = notebook_directory / "meta" / "startup"
sys.path.append(str(startup_directory))
import argparse
import logging
import projectsetup
from solana.account import Account
from Constants import WARNING_DISCLAIMER_TEXT
from Wallet import Wallet
parser = argparse.ArgumentParser(description='Creates a new wallet and private key, and saves it to a file.')
parser.add_argument("--id-file", type=str, default="id.json",
help="file containing the JSON-formatted wallet private key")
parser.add_argument("--log-level", default=logging.WARNING, type=lambda level: getattr(logging, level),
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument("--overwrite", action="store_true", default=False,
help="overwrite the ID file, if it exists (use with care!)")
args = parser.parse_args()
logging.getLogger().setLevel(args.log_level)
logging.warning(WARNING_DISCLAIMER_TEXT)
new_wallet = Wallet.create()
new_wallet.save(args.id_file, args.overwrite)
print(f"Wallet created in file: '{args.id_file}'")

View File

@ -36,7 +36,7 @@ from WalletBalancer import TargetBalanceParser, WalletBalancer
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Balance the value of tokens in a Mango Markets group to specific values or percentages.')
parser = argparse.ArgumentParser(description="Balance the value of tokens in a Mango Markets group to specific values or percentages.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -53,13 +53,13 @@ parser.add_argument("--id-file", type=str, default="id.json",
help="file containing the JSON-formatted wallet private key")
parser.add_argument("--log-level", default=logging.WARNING, type=lambda level: getattr(logging, level),
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument("--target", type=str, action='append', required=True,
parser.add_argument("--target", type=str, action="append", required=True,
help="token symbol plus target value or percentage, separated by a colon (e.g. 'ETH:2.5' or 'ETH:33%')")
parser.add_argument("--action-threshold", type=Decimal, default=Decimal("0.01"),
help="fraction of total wallet value a trade must be above to be carried out")
parser.add_argument("--adjustment-factor", type=Decimal, default=Decimal("0.05"),
help="factor by which to adjust the SELL price (akin to maximum slippage)")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -32,7 +32,7 @@ from Wallet import Wallet
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Buys one of the tokens in a Mango Markets group.')
parser = argparse.ArgumentParser(description="Display the balances of all grop tokens in the current wallet.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,

View File

@ -35,7 +35,7 @@ from Wallet import Wallet
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Buys one of the tokens in a Mango Markets group.')
parser = argparse.ArgumentParser(description="Buys one of the tokens in a Mango Markets group.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -56,7 +56,7 @@ parser.add_argument("--token-symbol", type=str, required=True, help="token symbo
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity of token to buy")
parser.add_argument("--adjustment-factor", type=Decimal, default=Decimal("0.05"),
help="factor by which to adjust the BUY price (akin to maximum slippage)")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -35,7 +35,7 @@ from Wallet import Wallet
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Sells one of the tokens in a Mango Markets group.')
parser = argparse.ArgumentParser(description="Sells one of the tokens in a Mango Markets group.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -56,7 +56,7 @@ parser.add_argument("--token-symbol", type=str, required=True, help="token symbo
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity of token to buy")
parser.add_argument("--adjustment-factor", type=Decimal, default=Decimal("0.05"),
help="factor by which to adjust the SELL price (akin to maximum slippage)")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -36,7 +36,7 @@ from Wallet import Wallet
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Liquidate a single margin account.')
parser = argparse.ArgumentParser(description="Liquidate a single margin account.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -53,9 +53,9 @@ parser.add_argument("--id-file", type=str, default="id.json",
help="file containing the JSON-formatted wallet private key")
parser.add_argument("--log-level", default=logging.INFO, type=lambda level: getattr(logging, level),
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument('--margin-account-address', type=PublicKey,
parser.add_argument("--margin-account-address", type=PublicKey,
help="Solana address of the Mango Markets margin account to be liquidated")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -40,7 +40,7 @@ from WalletBalancer import LiveWalletBalancer, NullWalletBalancer, TargetBalance
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Run a liquidator for a Mango Markets group.')
parser = argparse.ArgumentParser(description="Run a liquidator for a Mango Markets group.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -59,13 +59,13 @@ parser.add_argument("--log-level", default=logging.INFO, type=lambda level: geta
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument("--throttle-to-seconds", type=int, default=60,
help="minimum number of seconds between each loop (including time taken processing accounts)")
parser.add_argument("--target", type=str, action='append',
parser.add_argument("--target", type=str, action="append",
help="token symbol plus target value or percentage, separated by a colon (e.g. 'ETH:2.5' or 'ETH:33%')")
parser.add_argument("--action-threshold", type=Decimal, default=Decimal("0.01"),
help="fraction of total wallet value a trade must be above to be carried out")
parser.add_argument("--adjustment-factor", type=Decimal, default=Decimal("0.05"),
help="factor by which to adjust the SELL price (akin to maximum slippage)")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -36,7 +36,7 @@ from WalletBalancer import NullWalletBalancer
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Run a single pass of the liquidator for a Mango Markets group.')
parser = argparse.ArgumentParser(description="Run a single pass of the liquidator for a Mango Markets group.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -53,7 +53,7 @@ parser.add_argument("--id-file", type=str, default="id.json",
help="file containing the JSON-formatted wallet private key")
parser.add_argument("--log-level", default=logging.INFO, type=lambda level: getattr(logging, level),
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument("--dry-run", type=bool,
parser.add_argument("--dry-run", action="store_true", default=False,
help="runs as read-only and does not perform any transactions")
args = parser.parse_args()

View File

@ -34,7 +34,7 @@ from Context import Context, default_cluster, default_cluster_url, default_progr
# We explicitly want argument parsing to be outside the main try-except block because some arguments
# (like --help) will cause an exit, which our except: block traps.
parser = argparse.ArgumentParser(description='Liquidate a single margin account.')
parser = argparse.ArgumentParser(description="Fetch Mango Markets objects and show their contents.")
parser.add_argument("--cluster", type=str, default=default_cluster,
help="Solana RPC cluster name")
parser.add_argument("--cluster-url", type=str, default=default_cluster_url,
@ -51,9 +51,9 @@ parser.add_argument("--id-file", type=str, default="id.json",
help="file containing the JSON-formatted wallet private key")
parser.add_argument("--log-level", default=logging.WARNING, type=lambda level: getattr(logging, level),
help="level of verbosity to log (possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument('--type', type=str,
parser.add_argument("--type", type=str,
help="type of object to be fetched (can be OPEN-ORDERS or MARGIN-ACCOUNT)")
parser.add_argument('--address', type=PublicKey,
parser.add_argument("--address", type=PublicKey,
help="Solana address of the Mango Markets object to be fetched")
args = parser.parse_args()