Added commands to wrap and unwrap SOL.
This commit is contained in:
parent
e0c552ca55
commit
cd7cdab540
130
BaseModel.ipynb
130
BaseModel.ipynb
|
@ -2,7 +2,7 @@
|
|||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "biological-pontiac",
|
||||
"id": "interesting-continuity",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ⚠ Warning\n",
|
||||
|
@ -16,7 +16,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "moral-enemy",
|
||||
"id": "chemical-paper",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 🥭 BaseModel\n",
|
||||
|
@ -33,7 +33,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "reverse-trade",
|
||||
"id": "herbal-bracket",
|
||||
"metadata": {
|
||||
"jupyter": {
|
||||
"source_hidden": true
|
||||
|
@ -69,7 +69,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "forty-booth",
|
||||
"id": "aboriginal-active",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Version enum\n",
|
||||
|
@ -80,7 +80,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "honest-development",
|
||||
"id": "stretch-analyst",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -95,7 +95,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "western-cookbook",
|
||||
"id": "cooked-india",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## InstructionType enum\n",
|
||||
|
@ -106,7 +106,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "reverse-patch",
|
||||
"id": "composite-scotland",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -135,7 +135,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "presidential-glass",
|
||||
"id": "rubber-wisconsin",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Internal functions\n",
|
||||
|
@ -146,7 +146,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "recreational-success",
|
||||
"id": "certain-particular",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -162,7 +162,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "pacific-medline",
|
||||
"id": "innovative-conditioning",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## AccountInfo class\n"
|
||||
|
@ -171,7 +171,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "framed-miller",
|
||||
"id": "beneficial-weekly",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -243,7 +243,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "developing-immune",
|
||||
"id": "planned-referral",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## AddressableAccount class\n",
|
||||
|
@ -256,7 +256,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ruled-concern",
|
||||
"id": "expired-stopping",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -275,7 +275,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "convinced-princeton",
|
||||
"id": "unsigned-circus",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## SerumAccountFlags class\n",
|
||||
|
@ -286,7 +286,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "handmade-browser",
|
||||
"id": "spare-large",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -329,7 +329,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dramatic-armor",
|
||||
"id": "substantial-worcester",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## MangoAccountFlags class\n",
|
||||
|
@ -340,7 +340,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "thorough-helicopter",
|
||||
"id": "integral-uniform",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -373,7 +373,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "empty-sheffield",
|
||||
"id": "tired-collins",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Index class"
|
||||
|
@ -382,7 +382,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "partial-decimal",
|
||||
"id": "designed-syndicate",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -409,7 +409,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "optimum-milton",
|
||||
"id": "democratic-thread",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## AggregatorConfig class"
|
||||
|
@ -418,7 +418,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "parallel-absence",
|
||||
"id": "coordinate-headquarters",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -451,7 +451,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "increased-leone",
|
||||
"id": "therapeutic-audit",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Round class"
|
||||
|
@ -460,7 +460,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "compatible-toronto",
|
||||
"id": "liquid-solution",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -485,7 +485,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "improved-promise",
|
||||
"id": "rural-candidate",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Answer class"
|
||||
|
@ -494,7 +494,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "dying-insurance",
|
||||
"id": "graphic-release",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -520,7 +520,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "straight-purse",
|
||||
"id": "established-exemption",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aggregator class"
|
||||
|
@ -529,7 +529,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "conceptual-harvest",
|
||||
"id": "refined-alexander",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -595,7 +595,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "medical-rogers",
|
||||
"id": "varied-batch",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Token class\n",
|
||||
|
@ -606,7 +606,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "solar-chambers",
|
||||
"id": "three-legislature",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -661,7 +661,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "higher-carbon",
|
||||
"id": "optimum-packaging",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## SolToken object\n",
|
||||
|
@ -672,7 +672,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "motivated-suite",
|
||||
"id": "resistant-lawsuit",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -681,7 +681,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "prime-accused",
|
||||
"id": "dimensional-interference",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## TokenLookup class\n",
|
||||
|
@ -703,7 +703,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "careful-thanksgiving",
|
||||
"id": "attached-stocks",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -743,7 +743,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "intelligent-harmony",
|
||||
"id": "informative-fortune",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## SpotMarket class"
|
||||
|
@ -752,7 +752,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "attempted-prayer",
|
||||
"id": "rational-drain",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -776,7 +776,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "abandoned-network",
|
||||
"id": "cordless-diversity",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## SpotMarketLookup class\n",
|
||||
|
@ -801,7 +801,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "grateful-child",
|
||||
"id": "civic-sunset",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -883,7 +883,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "affecting-orlando",
|
||||
"id": "satellite-shadow",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## BasketToken class\n",
|
||||
|
@ -894,7 +894,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "consistent-senator",
|
||||
"id": "breathing-drove",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -950,7 +950,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "swiss-opinion",
|
||||
"id": "centered-locking",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## TokenValue class\n",
|
||||
|
@ -961,7 +961,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "strange-pierre",
|
||||
"id": "limited-wrapping",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1046,7 +1046,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "forty-quebec",
|
||||
"id": "metallic-director",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## OwnedTokenValue class\n",
|
||||
|
@ -1057,7 +1057,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "lovely-association",
|
||||
"id": "honey-longitude",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1097,7 +1097,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ceramic-walker",
|
||||
"id": "capable-sauce",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## MarketMetadata class"
|
||||
|
@ -1106,7 +1106,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "exact-writer",
|
||||
"id": "continent-bookmark",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1144,7 +1144,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "intellectual-biotechnology",
|
||||
"id": "elect-principal",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Group class\n",
|
||||
|
@ -1155,7 +1155,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "adverse-crisis",
|
||||
"id": "premier-vaccine",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1414,7 +1414,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "opposed-front",
|
||||
"id": "rotary-therapist",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## TokenAccount class"
|
||||
|
@ -1423,7 +1423,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "clean-laundry",
|
||||
"id": "little-portfolio",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1502,12 +1502,12 @@
|
|||
" return TokenAccount.parse(account_info)\n",
|
||||
"\n",
|
||||
" def __str__(self) -> str:\n",
|
||||
" return f\"« Token: Mint: {self.mint}, Owner: {self.owner}, Amount: {self.amount} »\"\n"
|
||||
" return f\"« Token: Address: {self.address}, Mint: {self.mint}, Owner: {self.owner}, Amount: {self.amount} »\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "blocked-sudan",
|
||||
"id": "exact-emergency",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## OpenOrders class\n"
|
||||
|
@ -1516,7 +1516,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "taken-shock",
|
||||
"id": "spanish-promise",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1636,7 +1636,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "elder-retailer",
|
||||
"id": "listed-error",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## BalanceSheet class"
|
||||
|
@ -1645,7 +1645,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "featured-bandwidth",
|
||||
"id": "vulnerable-conjunction",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1692,7 +1692,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "manual-bubble",
|
||||
"id": "seeing-victorian",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## MarginAccount class\n"
|
||||
|
@ -1701,7 +1701,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "expected-winner",
|
||||
"id": "sunset-chase",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1952,7 +1952,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "pointed-coral",
|
||||
"id": "extraordinary-mozambique",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## MarginAccountMetadata class"
|
||||
|
@ -1961,7 +1961,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "approved-giving",
|
||||
"id": "connected-cattle",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -1987,7 +1987,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fossil-reserve",
|
||||
"id": "green-boxing",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Events"
|
||||
|
@ -1995,7 +1995,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "blessed-chain",
|
||||
"id": "biological-penny",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## LiquidationEvent"
|
||||
|
@ -2004,7 +2004,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "parallel-ethics",
|
||||
"id": "affecting-hydrogen",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -2040,7 +2040,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "threatened-union",
|
||||
"id": "geological-pantyhose",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ✅ Testing"
|
||||
|
@ -2049,7 +2049,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "internal-thong",
|
||||
"id": "saving-lending",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
@ -2128,7 +2128,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "virgin-waterproof",
|
||||
"id": "insured-tackle",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 🏃 Running"
|
||||
|
@ -2137,7 +2137,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "color-ultimate",
|
||||
"id": "identified-margin",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/env pyston3
|
||||
|
||||
import os
|
||||
import 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 # noqa: F401
|
||||
import typing
|
||||
|
||||
from solana.account import Account
|
||||
from solana.publickey import PublicKey
|
||||
from spl.token.constants import TOKEN_PROGRAM_ID
|
||||
from solana.transaction import Transaction
|
||||
from spl.token.instructions import CloseAccountParams, close_account
|
||||
|
||||
from BaseModel import TokenAccount, TokenLookup
|
||||
from Constants import WARNING_DISCLAIMER_TEXT
|
||||
from Context import default_context as context
|
||||
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("--address", type=PublicKey,
|
||||
help="Public key of the Wrapped SOL account to close")
|
||||
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)
|
||||
|
||||
id_filename = args.id_file
|
||||
if not os.path.isfile(id_filename):
|
||||
logging.error(f"Wallet file '{id_filename}' is not present.")
|
||||
sys.exit(1)
|
||||
wallet = Wallet.load(id_filename)
|
||||
|
||||
lookups = TokenLookup.default_lookups()
|
||||
wrapped_sol = lookups.find_by_symbol("SOL")
|
||||
|
||||
token_account = TokenAccount.load(context, args.address)
|
||||
if (token_account is None) or (token_account.mint != wrapped_sol.mint):
|
||||
raise Exception(f"Account {args.address} is not a {wrapped_sol.name} account.")
|
||||
|
||||
transaction = Transaction()
|
||||
signers: typing.List[Account] = [wallet.account]
|
||||
payer = wallet.address
|
||||
|
||||
transaction.add(
|
||||
close_account(
|
||||
CloseAccountParams(
|
||||
account=args.address,
|
||||
owner=wallet.address,
|
||||
dest=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
print(f"Closing account: {args.address} with balance {token_account.amount} lamports.")
|
||||
|
||||
response = context.client.send_transaction(transaction, *signers)
|
||||
transaction_id = context.unwrap_transaction_id_or_raise_exception(response)
|
||||
print(f"Waiting on transaction ID: {transaction_id}")
|
||||
|
||||
context.wait_for_confirmation(transaction_id)
|
||||
print("Done.")
|
|
@ -31,7 +31,7 @@ from solana.publickey import PublicKey
|
|||
from solana.system_program import TransferParams, transfer
|
||||
from solana.transaction import Transaction
|
||||
|
||||
from Constants import WARNING_DISCLAIMER_TEXT
|
||||
from Constants import SOL_DECIMAL_DIVISOR, WARNING_DISCLAIMER_TEXT
|
||||
from Context import Context, default_cluster, default_cluster_url, default_program_id, default_dex_program_id, default_group_name, default_group_id
|
||||
from Wallet import Wallet
|
||||
|
||||
|
@ -81,7 +81,7 @@ try:
|
|||
print(f"Balance: {sol_balance} SOL")
|
||||
|
||||
# "A lamport has a value of 0.000000001 SOL." from https://docs.solana.com/introduction
|
||||
lamports = int(args.quantity * Decimal(10 ** 9))
|
||||
lamports = int(args.quantity * SOL_DECIMAL_DIVISOR)
|
||||
source = wallet.address
|
||||
destination = args.address
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env pyston3
|
||||
|
||||
import os
|
||||
import 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 # noqa: F401
|
||||
|
||||
from BaseModel import TokenAccount, TokenLookup
|
||||
from Constants import WARNING_DISCLAIMER_TEXT
|
||||
from Context import default_context as context
|
||||
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)
|
||||
|
||||
id_filename = args.id_file
|
||||
if not os.path.isfile(id_filename):
|
||||
logging.error(f"Wallet file '{id_filename}' is not present.")
|
||||
sys.exit(1)
|
||||
wallet = Wallet.load(id_filename)
|
||||
|
||||
|
||||
lookups = TokenLookup.default_lookups()
|
||||
wrapped_sol = lookups.find_by_symbol("SOL")
|
||||
|
||||
token_accounts = TokenAccount.fetch_all_for_owner_and_token(context, wallet.address, wrapped_sol)
|
||||
|
||||
if len(token_accounts) == 0:
|
||||
print("No wrapped SOL accounts")
|
||||
else:
|
||||
print(f"{wrapped_sol.name}:")
|
||||
for account in token_accounts:
|
||||
print(f" {account.address}: {account.amount:>18,.8f} {wrapped_sol.symbol}")
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/env pyston3
|
||||
|
||||
import os
|
||||
import 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 # noqa: F401
|
||||
import typing
|
||||
|
||||
from decimal import Decimal
|
||||
from solana.account import Account
|
||||
from solana.system_program import CreateAccountParams, create_account
|
||||
from solana.transaction import Transaction
|
||||
from spl.token.constants import ACCOUNT_LEN, TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT
|
||||
from spl.token.instructions import CloseAccountParams, InitializeAccountParams, Transfer2Params, close_account, initialize_account, transfer2
|
||||
|
||||
from BaseModel import TokenAccount, TokenLookup
|
||||
from Constants import SOL_DECIMAL_DIVISOR, SOL_DECIMALS, WARNING_DISCLAIMER_TEXT
|
||||
from Context import default_context as context
|
||||
from Wallet import Wallet
|
||||
|
||||
parser = argparse.ArgumentParser(description='Unwraps Wrapped SOL to Pure SOL and adds it to the wallet account.')
|
||||
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity of SOL to unwrap")
|
||||
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)
|
||||
|
||||
id_filename = args.id_file
|
||||
if not os.path.isfile(id_filename):
|
||||
logging.error(f"Wallet file '{id_filename}' is not present.")
|
||||
sys.exit(1)
|
||||
wallet = Wallet.load(id_filename)
|
||||
|
||||
|
||||
lookups = TokenLookup.default_lookups()
|
||||
wrapped_sol = lookups.find_by_symbol("SOL")
|
||||
|
||||
largest_token_account = TokenAccount.fetch_largest_for_owner_and_token(context, wallet.address, wrapped_sol)
|
||||
if largest_token_account is None:
|
||||
raise Exception(f"No {wrapped_sol.name} accounts found for owner {wallet.address}.")
|
||||
|
||||
# Overpay - remainder should be sent back to our wallet.
|
||||
FEE = Decimal(".005")
|
||||
lamports_to_transfer = int((args.quantity + FEE) * SOL_DECIMAL_DIVISOR)
|
||||
|
||||
transaction = Transaction()
|
||||
signers: typing.List[Account] = [wallet.account]
|
||||
|
||||
wrapped_sol_account = Account()
|
||||
signers.append(wrapped_sol_account)
|
||||
|
||||
transaction.add(
|
||||
create_account(
|
||||
CreateAccountParams(
|
||||
from_pubkey=wallet.address,
|
||||
new_account_pubkey=wrapped_sol_account.public_key(),
|
||||
lamports=int(FEE * SOL_DECIMAL_DIVISOR),
|
||||
space=ACCOUNT_LEN,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
transaction.add(
|
||||
initialize_account(
|
||||
InitializeAccountParams(
|
||||
account=wrapped_sol_account.public_key(),
|
||||
mint=WRAPPED_SOL_MINT,
|
||||
owner=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
transaction.add(
|
||||
transfer2(
|
||||
Transfer2Params(
|
||||
amount=int(args.quantity * SOL_DECIMAL_DIVISOR),
|
||||
decimals=int(SOL_DECIMALS),
|
||||
dest=wrapped_sol_account.public_key(),
|
||||
mint=WRAPPED_SOL_MINT,
|
||||
owner=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
source=largest_token_account.address
|
||||
)
|
||||
)
|
||||
)
|
||||
transaction.add(
|
||||
close_account(
|
||||
CloseAccountParams(
|
||||
account=wrapped_sol_account.public_key(),
|
||||
owner=wallet.address,
|
||||
dest=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
print("Unwrapping SOL:")
|
||||
print(f" Temporary account: {wrapped_sol_account.public_key()}")
|
||||
print(f" Source: {largest_token_account.address}")
|
||||
print(f" Destination: {wallet.address}")
|
||||
|
||||
response = context.client.send_transaction(transaction, *signers)
|
||||
transaction_id = context.unwrap_transaction_id_or_raise_exception(response)
|
||||
print(f"Waiting on transaction ID: {transaction_id}")
|
||||
|
||||
context.wait_for_confirmation(transaction_id)
|
||||
print("Transaction confirmed.")
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/env pyston3
|
||||
|
||||
import os
|
||||
import 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 # noqa: F401
|
||||
import typing
|
||||
|
||||
from decimal import Decimal
|
||||
from solana.account import Account
|
||||
from solana.system_program import CreateAccountParams, create_account
|
||||
from solana.transaction import Transaction
|
||||
from spl.token.constants import ACCOUNT_LEN, TOKEN_PROGRAM_ID, WRAPPED_SOL_MINT
|
||||
from spl.token.instructions import CloseAccountParams, InitializeAccountParams, Transfer2Params, close_account, initialize_account, transfer2
|
||||
|
||||
from BaseModel import TokenAccount, TokenLookup
|
||||
from Constants import SOL_DECIMAL_DIVISOR, SOL_DECIMALS, WARNING_DISCLAIMER_TEXT
|
||||
from Context import default_context as context
|
||||
from Wallet import Wallet
|
||||
|
||||
parser = argparse.ArgumentParser(description='Creates a new wallet and private key, and saves it to a file.')
|
||||
parser.add_argument("--quantity", type=Decimal, required=True, help="quantity of SOL to wrap")
|
||||
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)
|
||||
|
||||
id_filename = args.id_file
|
||||
if not os.path.isfile(id_filename):
|
||||
logging.error(f"Wallet file '{id_filename}' is not present.")
|
||||
sys.exit(1)
|
||||
wallet = Wallet.load(id_filename)
|
||||
|
||||
|
||||
lookups = TokenLookup.default_lookups()
|
||||
wrapped_sol = lookups.find_by_symbol("SOL")
|
||||
|
||||
token_accounts = TokenAccount.fetch_all_for_owner_and_token(context, wallet.address, wrapped_sol)
|
||||
|
||||
if len(token_accounts) == 0:
|
||||
close_wrapping_account = False
|
||||
else:
|
||||
close_wrapping_account = True
|
||||
|
||||
# Overpay - remainder should be sent back to our wallet.
|
||||
FEE = Decimal(".005")
|
||||
lamports_to_transfer = int((args.quantity + FEE) * SOL_DECIMAL_DIVISOR)
|
||||
|
||||
transaction = Transaction()
|
||||
signers: typing.List[Account] = [wallet.account]
|
||||
|
||||
wrapped_sol_account = Account()
|
||||
signers.append(wrapped_sol_account)
|
||||
|
||||
transaction.add(
|
||||
create_account(
|
||||
CreateAccountParams(
|
||||
from_pubkey=wallet.address,
|
||||
new_account_pubkey=wrapped_sol_account.public_key(),
|
||||
lamports=lamports_to_transfer,
|
||||
space=ACCOUNT_LEN,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
transaction.add(
|
||||
initialize_account(
|
||||
InitializeAccountParams(
|
||||
account=wrapped_sol_account.public_key(),
|
||||
mint=WRAPPED_SOL_MINT,
|
||||
owner=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
print("Wrapping SOL:")
|
||||
if len(token_accounts) == 0:
|
||||
print(f" Source: {wallet.address}")
|
||||
print(f" Destination: {wrapped_sol_account.public_key()}")
|
||||
else:
|
||||
print(f" Temporary account: {wrapped_sol_account.public_key()}")
|
||||
print(f" Source: {wallet.address}")
|
||||
print(f" Destination: {token_accounts[0].address}")
|
||||
transaction.add(
|
||||
transfer2(
|
||||
Transfer2Params(
|
||||
amount=int(args.quantity * SOL_DECIMAL_DIVISOR),
|
||||
decimals=int(SOL_DECIMALS),
|
||||
dest=token_accounts[0].address,
|
||||
mint=WRAPPED_SOL_MINT,
|
||||
owner=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
source=wrapped_sol_account.public_key()
|
||||
)
|
||||
)
|
||||
)
|
||||
transaction.add(
|
||||
close_account(
|
||||
CloseAccountParams(
|
||||
account=wrapped_sol_account.public_key(),
|
||||
owner=wallet.address,
|
||||
dest=wallet.address,
|
||||
program_id=TOKEN_PROGRAM_ID,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
response = context.client.send_transaction(transaction, *signers)
|
||||
transaction_id = context.unwrap_transaction_id_or_raise_exception(response)
|
||||
print(f"Waiting on transaction ID: {transaction_id}")
|
||||
context.wait_for_confirmation(transaction_id)
|
||||
print("Done.")
|
Loading…
Reference in New Issue