133 lines
4.5 KiB
Plaintext
Executable File
133 lines
4.5 KiB
Plaintext
Executable File
#!/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.")
|