abstract-solana 0.0.0.22__tar.gz → 0.0.0.24__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of abstract-solana might be problematic. Click here for more details.
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/PKG-INFO +1 -1
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/setup.py +1 -1
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/constants.py +8 -14
- abstract_solana-0.0.0.24/src/abstract_solana/keypair_utils.py +13 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/utils.py +4 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/PKG-INFO +1 -1
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/SOURCES.txt +1 -1
- abstract_solana-0.0.0.24/test/test_abstract_solana.py +186 -0
- abstract_solana-0.0.0.22/src/abstract_solana/pumpFunKeys.py +0 -94
- abstract_solana-0.0.0.22/test/test_abstract_solana.py +0 -106
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/README.md +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/setup.cfg +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/__init__.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/account_key_utils.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/genesis_functions.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/index_utils.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/log_message_functions.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/price_utils.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/pubkey_utils.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/signature_data_parse.py +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/dependency_links.txt +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/requires.txt +0 -0
- {abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/top_level.txt +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
from .pubkey_utils import get_pubkey
|
|
2
|
-
|
|
3
|
-
SYSTEM_PROGRAM = "11111111111111111111111111111111"
|
|
4
|
-
SYSTEM_PROGRAM_PUBKEY = get_pubkey(SYSTEM_PROGRAM)
|
|
5
2
|
RENT = "SysvarRent111111111111111111111111111111111"
|
|
6
3
|
RENT_PUBKEY= get_pubkey(RENT)
|
|
7
4
|
TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
|
8
5
|
TOKEN_PROGRAM_ID_PUBKEY = get_pubkey(TOKEN_PROGRAM_ID)
|
|
9
|
-
|
|
6
|
+
SYSTEM_PROGRAM = "11111111111111111111111111111111"
|
|
7
|
+
SYSTEM_PROGRAM_PUBKEY = get_pubkey(SYSTEM_PROGRAM)
|
|
8
|
+
SOL_MINT = "So11111111111111111111111111111111111111112"
|
|
9
|
+
SOL_MINT_PUBKEY=get_pubkey(SOL_MINT)
|
|
10
|
+
|
|
10
11
|
PUMP_FUN_GLOBAL = "4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"
|
|
11
12
|
PUMP_FUN_GLOBAL_PUBKEY = get_pubkey(PUMP_FUN_GLOBAL)
|
|
12
|
-
|
|
13
|
+
FEE_RECIPIENT = "CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM"
|
|
13
14
|
PUMP_FUN_FEE_RECIPIENT_PUBKEY = get_pubkey(PUMP_FUN_FEE_RECIPIENT)
|
|
14
15
|
PUMP_FUN_ASSOC_TOKEN_ACC_PROG = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
|
15
16
|
PUMP_FUN_ASSOC_TOKEN_ACC_PROG_PUBKEY = get_pubkey(PUMP_FUN_ASSOC_TOKEN_ACC_PROG)
|
|
@@ -17,20 +18,13 @@ PUMP_FUN_EVENT_AUTHORITY = "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"
|
|
|
17
18
|
PUMP_FUN_EVENT_AUTHORITY_PUBKEY = get_pubkey(PUMP_FUN_EVENT_AUTHORITY)
|
|
18
19
|
PUMP_FUN_PROGRAM = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
|
|
19
20
|
PUMP_FUN_PROGRAM_PUBKEY = get_pubkey(PUMP_FUN_PROGRAM)
|
|
20
|
-
PUMP_FUN_SYSTEM_PROGRAM=SYSTEM_PROGRAM
|
|
21
|
-
PUMP_FUN_SYSTEM_PROGRAM_PUBKEY = SYSTEM_PROGRAM_PUBKEY
|
|
22
|
-
PUMP_FUN_TOKEN_PROGRAM_ID=TOKEN_PROGRAM_ID
|
|
23
|
-
PUMP_FUN_TOKEN_PROGRAM_ID_PUBKEY=TOKEN_PROGRAM_ID_PUBKEY
|
|
24
|
-
PUMP_FUN_RENT = RENT
|
|
25
|
-
PUMP_FUN_RENT_PUBKEY = RENT_PUBKEY
|
|
26
21
|
|
|
27
22
|
RAYDIUM_POOL_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
|
|
28
23
|
RAYDIUM_POOL_V4_PROGRAM_ID_PUBKEY=get_pubkey(RAYDIUM_POOL_V4_PROGRAM_ID)
|
|
29
|
-
SOL_MINT = "So11111111111111111111111111111111111111112"
|
|
30
|
-
SOL_MINT_PUBKEY=get_pubkey(SOL_MINT)
|
|
31
|
-
|
|
32
24
|
|
|
33
25
|
LAMPORTS_PER_SOL = 1_000_000_000
|
|
34
26
|
UNIT_PRICE = 1_000_000
|
|
35
27
|
UNIT_BUDGET = 100_000
|
|
36
28
|
SOL_DECIMALS = 9
|
|
29
|
+
SOL_DECIMAL_EXP = 10**9
|
|
30
|
+
TOKEN_DECIMAL_EXP = 10**6
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from abstract_security import *
|
|
2
|
+
def load_from_private_key(env_key='AMM_P'):
|
|
3
|
+
env_value = get_env_value(key=env_key)
|
|
4
|
+
if env_value:
|
|
5
|
+
return Keypair.from_base58_string(env_value)
|
|
6
|
+
|
|
7
|
+
def load_keypair_from_file(filename):
|
|
8
|
+
curr = os.path.join(sys.path[0], 'data', filename)
|
|
9
|
+
with open(curr, 'r') as file:
|
|
10
|
+
secret = json.load(file)
|
|
11
|
+
secret_key = bytes(secret)
|
|
12
|
+
print(base58.b58encode(secret_key))
|
|
13
|
+
return Keypair.from_bytete_key()
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/SOURCES.txt
RENAMED
|
@@ -5,10 +5,10 @@ src/abstract_solana/account_key_utils.py
|
|
|
5
5
|
src/abstract_solana/constants.py
|
|
6
6
|
src/abstract_solana/genesis_functions.py
|
|
7
7
|
src/abstract_solana/index_utils.py
|
|
8
|
+
src/abstract_solana/keypair_utils.py
|
|
8
9
|
src/abstract_solana/log_message_functions.py
|
|
9
10
|
src/abstract_solana/price_utils.py
|
|
10
11
|
src/abstract_solana/pubkey_utils.py
|
|
11
|
-
src/abstract_solana/pumpFunKeys.py
|
|
12
12
|
src/abstract_solana/signature_data_parse.py
|
|
13
13
|
src/abstract_solana/utils.py
|
|
14
14
|
src/abstract_solana.egg-info/PKG-INFO
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
from abstract_solana import Pubkey,get_pubkey,Optional,Union,LAMPORTS_PER_SOL,get_any_value
|
|
2
|
+
from abstract_solana.pumpFunKeys import get_pump_fun_data
|
|
3
|
+
from abstract_solcatcher import *
|
|
4
|
+
from abstract_security import *
|
|
5
|
+
import struct
|
|
6
|
+
import base58,time
|
|
7
|
+
from solders.hash import Hash
|
|
8
|
+
from solders.instruction import Instruction
|
|
9
|
+
from solders.compute_budget import set_compute_unit_limit, set_compute_unit_price #type: ignore
|
|
10
|
+
from solana.rpc.types import TokenAccountOpts,TxOpts
|
|
11
|
+
from solders.keypair import Keypair
|
|
12
|
+
from solana.transaction import AccountMeta, Transaction
|
|
13
|
+
from construct import Padding, Struct, Int64ul, Flag
|
|
14
|
+
LAMPORTS_PER_SOL = 1_000_000_000
|
|
15
|
+
UNIT_PRICE = 1_000_000
|
|
16
|
+
UNIT_BUDGET = 100_000
|
|
17
|
+
def sendTransaction(txn: Transaction, payer_keypair, opts=TxOpts(skip_preflight=True)) -> dict:
|
|
18
|
+
# Sign the transaction
|
|
19
|
+
txn.sign(payer_keypair)
|
|
20
|
+
|
|
21
|
+
# Serialize the transaction to a base64 string
|
|
22
|
+
txn_base64 = base58.b58encode(txn.serialize()).decode('utf-8')
|
|
23
|
+
|
|
24
|
+
# Prepare the RPC request payload
|
|
25
|
+
payload = {
|
|
26
|
+
"jsonrpc": "2.0",
|
|
27
|
+
"id": 1,
|
|
28
|
+
"method": "sendTransaction",
|
|
29
|
+
"params": [txn_base64, {"skipPreflight": opts.skip_preflight, "preflightCommitment": "finalized"}]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Send the transaction
|
|
33
|
+
response = requests.post(
|
|
34
|
+
url="https://rpc.ankr.com/solana/c3b7fd92e298d5682b6ef095eaa4e92160989a713f5ee9ac2693b4da8ff5a370",
|
|
35
|
+
json=payload
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Parse the JSON response
|
|
39
|
+
response_json = response.json()
|
|
40
|
+
|
|
41
|
+
# Return the result or the entire response in case of error
|
|
42
|
+
return response_json.get('result', response_json)
|
|
43
|
+
def load_from_private_key(env_key='AMM_P'):
|
|
44
|
+
env_value = get_env_value(key=env_key)
|
|
45
|
+
if env_value:
|
|
46
|
+
return Keypair.from_base58_string(env_value)
|
|
47
|
+
|
|
48
|
+
def load_keypair_from_file(filename):
|
|
49
|
+
curr = os.path.join(sys.path[0], 'data', filename)
|
|
50
|
+
with open(curr, 'r') as file:
|
|
51
|
+
secret = json.load(file)
|
|
52
|
+
secret_key = bytes(secret)
|
|
53
|
+
print(base58.b58encode(secret_key))
|
|
54
|
+
return Keypair.from_bytete_key()
|
|
55
|
+
payer_keypair = load_from_private_key()
|
|
56
|
+
payer_pubkey = str(payer_keypair.pubkey())
|
|
57
|
+
owner=Pubkey.from_string(payer_pubkey)
|
|
58
|
+
def get_token_balance(payer,mint_str: str):
|
|
59
|
+
|
|
60
|
+
response = getTokenAccountBalance(str(payer),str(mint_str))
|
|
61
|
+
response=response.get('value',response)
|
|
62
|
+
ui_amount = get_any_value(response, "uiAmount") or 0
|
|
63
|
+
return float(ui_amount)
|
|
64
|
+
def check_existing_token_account(owner: Pubkey, mint: Pubkey):
|
|
65
|
+
try:
|
|
66
|
+
account_data = get_account_by_owner(str(owner), str(mint))
|
|
67
|
+
if account_data:
|
|
68
|
+
token_account = account_data['pubkey']
|
|
69
|
+
print(f"Existing token account found: {token_account}")
|
|
70
|
+
return token_account, None
|
|
71
|
+
else:
|
|
72
|
+
print("No existing token account found. Creating a new one...")
|
|
73
|
+
token_account = get_associated_token_address(owner, mint)
|
|
74
|
+
token_account_instructions = create_associated_token_account(owner, owner, mint)
|
|
75
|
+
return token_account, token_account_instructions
|
|
76
|
+
except Exception as e:
|
|
77
|
+
print(f"Error checking or creating token account: {e}")
|
|
78
|
+
return None, None
|
|
79
|
+
def confirm_txn(txn_sig, max_retries=20, retry_interval=3):
|
|
80
|
+
retries = 0
|
|
81
|
+
|
|
82
|
+
while retries < max_retries:
|
|
83
|
+
try:
|
|
84
|
+
|
|
85
|
+
txn_res = get_transaction(signature=str(txn_sig))
|
|
86
|
+
if txn_res:
|
|
87
|
+
print(txn_res)
|
|
88
|
+
print(f"\n\nhttps://solscan.io/tx/{str(txn_sig)}")
|
|
89
|
+
break
|
|
90
|
+
txn_json = safe_json_loads(txn_res.get('transaction',{}).get('meta',{}))
|
|
91
|
+
error = txn_json.get('err')
|
|
92
|
+
if error is None:
|
|
93
|
+
print("Transaction confirmed... try count:", retries+1)
|
|
94
|
+
return True
|
|
95
|
+
print("Error: Transaction not confirmed. Retrying...")
|
|
96
|
+
if error:
|
|
97
|
+
print("Transaction failed.")
|
|
98
|
+
return False
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print("Awaiting confirmation... try count:", retries+1)
|
|
101
|
+
retries += 1
|
|
102
|
+
time.sleep(retry_interval)
|
|
103
|
+
print("Max retries reached. Transaction confirmation failed.")
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
def get_coin_data(mint_str):
|
|
107
|
+
return get_pump_fun_data(str(mint_str))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def buildTxn(mint, amount, slippage, token_account_pubkey,sol_in=0,token_price=None,token_balance=None,token_account_instructions=None,close_token_account=False,buy=True):
|
|
112
|
+
# Get keys for the transaction, pass the token account's pubkey instead of the AccountMeta object
|
|
113
|
+
keys = getKeys(get_coin_data(mint), token_account_pubkey, owner,buy=buy)
|
|
114
|
+
|
|
115
|
+
if buy:
|
|
116
|
+
# Calculate max_sol_cost
|
|
117
|
+
slippage_adjustment = 1 + (slippage / 100)
|
|
118
|
+
sol_in_with_slippage = sol_in * slippage_adjustment
|
|
119
|
+
max_sol_cost = int(sol_in_with_slippage * LAMPORTS_PER_SOL)
|
|
120
|
+
print("Max Sol Cost:", sol_in_with_slippage)
|
|
121
|
+
hex_data = bytes.fromhex("66063d1201daebea")
|
|
122
|
+
solCost = max_sol_cost
|
|
123
|
+
else:
|
|
124
|
+
# Calculate minimum SOL output
|
|
125
|
+
sol_out = float(token_balance) * float(token_price)
|
|
126
|
+
slippage_adjustment = 1 - (slippage / 100)
|
|
127
|
+
sol_out_with_slippage = sol_out * slippage_adjustment
|
|
128
|
+
min_sol_output = int(sol_out_with_slippage * LAMPORTS_PER_SOL)
|
|
129
|
+
print("Min Sol Output:", sol_out_with_slippage)
|
|
130
|
+
hex_data = bytes.fromhex("33e685a4017f83ad")
|
|
131
|
+
solCost = min_sol_output
|
|
132
|
+
|
|
133
|
+
data = bytearray()
|
|
134
|
+
data.extend(hex_data)
|
|
135
|
+
data.extend(struct.pack('<Q', amount))
|
|
136
|
+
data.extend(struct.pack('<Q', solCost))
|
|
137
|
+
data = bytes(data)
|
|
138
|
+
PUMP_FUN_PROGRAM = Pubkey.from_string("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P")
|
|
139
|
+
|
|
140
|
+
swap_instruction = Instruction(PUMP_FUN_PROGRAM, data, keys)
|
|
141
|
+
blockHash = requests.post(url="https://rpc.ankr.com/solana/c3b7fd92e298d5682b6ef095eaa4e92160989a713f5ee9ac2693b4da8ff5a370",data=json.dumps({"id":1,"jsonrpc":"2.0","method":"getLatestBlockhash","params":[{"commitment":"processed"}]}))
|
|
142
|
+
recent_blockhash = get_any_value(blockHash.json(),'blockhash')
|
|
143
|
+
recent_blockhash = Hash.from_string(recent_blockhash)
|
|
144
|
+
txn = Transaction(recent_blockhash=recent_blockhash, fee_payer=owner)
|
|
145
|
+
txn.add(set_compute_unit_price(UNIT_PRICE))
|
|
146
|
+
txn.add(set_compute_unit_limit(UNIT_BUDGET))
|
|
147
|
+
|
|
148
|
+
if buy:
|
|
149
|
+
if token_account_instructions:
|
|
150
|
+
txn.add(token_account_instructions)
|
|
151
|
+
txn.add(swap_instruction)
|
|
152
|
+
else:
|
|
153
|
+
txn.add(swap_instruction)
|
|
154
|
+
if close_token_account:
|
|
155
|
+
close_account_instructions = close_account(CloseAccountParams(PUMP_FUN_PROGRAM_PUBKEY, token_account_pubkey, owner, owner))
|
|
156
|
+
txn.add(close_account_instructions)
|
|
157
|
+
|
|
158
|
+
txn.sign(payer_keypair)
|
|
159
|
+
# Send and confirm transaction
|
|
160
|
+
txn_sig = sendTransaction(txn, payer_keypair, TxOpts(skip_preflight=True))
|
|
161
|
+
print("Transaction Signature", txn_sig)
|
|
162
|
+
confirm = confirm_txn(txn_sig)
|
|
163
|
+
print(confirm)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def isListZero(obj):
|
|
171
|
+
if obj and isinstance(obj, list):
|
|
172
|
+
return obj[0]
|
|
173
|
+
return obj
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
mint_str = "3bb6QmvustnZ627Kg2QvwTSi8gmxp7Y6orwXUokEwUyV"
|
|
182
|
+
result = pump_fun_sell(mint_str=mint_str, token_balance=None, slippage=25)
|
|
183
|
+
# Example usage
|
|
184
|
+
input(result)
|
|
185
|
+
|
|
186
|
+
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
from .pubkey_utils import get_pubkey,derive_bonding_curve,derive_associated_bonding_curve
|
|
2
|
-
from .log_message_functions import get_for_program_ids_info
|
|
3
|
-
from spl.token.instructions import create_associated_token_account, get_associated_token_address
|
|
4
|
-
from abstract_solcatcher import getGenesisSignature,getTransaction,getAccountInfo
|
|
5
|
-
from construct import Padding, Struct, Int64ul, Flag
|
|
6
|
-
import base64
|
|
7
|
-
|
|
8
|
-
# Change dictionary keys to lowercase and replace spaces with underscores
|
|
9
|
-
def change_keys_lower(dict_obj):
|
|
10
|
-
new_dict = {}
|
|
11
|
-
for key, value in dict_obj.items():
|
|
12
|
-
new_dict[key.lower().replace(' ', '_')] = value
|
|
13
|
-
return new_dict
|
|
14
|
-
|
|
15
|
-
# Predefined map for different transaction types
|
|
16
|
-
def get_create_map():
|
|
17
|
-
return [
|
|
18
|
-
{'instruction_number': '1', 'instruction_name': 'Mint', 'token_address': 'AkAUSJg1v9xYT3HUxdALH7NsrC6owmwoZuP9MLw8fxTL', 'token_name': '3CAT'},
|
|
19
|
-
{'instruction_number': '2', 'instruction_name': 'Mint Authority', 'token_address': 'TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM', 'token_name': 'Pump.fun Token Mint Authority'},
|
|
20
|
-
{'instruction_number': '3', 'instruction_name': 'Bonding Curve', 'token_address': '9nhxvNxfSUaJddVco6oa6NodtsCscqCScp6UU1hZkfGm', 'token_name': 'Pump.fun (3CAT) Bonding Curve'},
|
|
21
|
-
{'instruction_number': '4', 'instruction_name': 'Associated Bonding Curve', 'token_address': '889XLp3qvVAHpTYQmhn6cBpYSppV8Gi8E2Rgp9RH2vRy', 'token_name': 'Pump.fun (3CAT) Vault'},
|
|
22
|
-
{'instruction_number': '5', 'instruction_name': 'Global', 'token_address': '4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf', 'token_name': '4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf'},
|
|
23
|
-
{'instruction_number': '6', 'instruction_name': 'Mpl Token Metadata', 'token_address': 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s', 'token_name': 'Metaplex Token Metadata'},
|
|
24
|
-
{'instruction_number': '7', 'instruction_name': 'Metadata', 'token_address': 'CH41RxpjSXHqr1vfLTVYJMsfNs2fBCCWoAE13tPihXh7', 'token_name': 'CH41RxpjSXHqr1vfLTVYJMsfNs2fBCCWoAE13tPihXh7'},
|
|
25
|
-
{'instruction_number': '8', 'instruction_name': 'User', 'token_address': 'Fuy5MvbgzjSok1U8hH6mUY6WnLynzUextDxfEWMiTkn4', 'token_name': 'Fuy5MvbgzjSok1U8hH6mUY6WnLynzUextDxfEWMiTkn4'},
|
|
26
|
-
{'instruction_number': '9', 'instruction_name': 'System Program', 'token_address': '11111111111111111111111111111111', 'token_name': 'System Program'},
|
|
27
|
-
{'instruction_number': '10', 'instruction_name': 'Token Program', 'token_address': 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', 'token_name': 'Token Program'},
|
|
28
|
-
{'instruction_number': '11', 'instruction_name': 'Associated Token Program', 'token_address': 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL', 'token_name': 'Associated Token Account Program'},
|
|
29
|
-
{'instruction_number': '12', 'instruction_name': 'Rent', 'token_address': 'SysvarRent111111111111111111111111111111111', 'token_name': 'Rent Program'},
|
|
30
|
-
{'instruction_number': '13', 'instruction_name': 'Event Authority', 'token_address': 'Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1', 'token_name': 'Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1'},
|
|
31
|
-
{'instruction_number': '14', 'instruction_name': 'Program', 'token_address': '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P', 'token_name': 'Pump.fun'}
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
# Fetches and organizes transaction types based on provided mint
|
|
35
|
-
def getTxnTypes(mint):
|
|
36
|
-
bonding_curve = str(derive_bonding_curve(mint)[0])
|
|
37
|
-
bonding_curve_signature = getGenesisSignature(address=bonding_curve)
|
|
38
|
-
txn_data = getTransaction(signature=bonding_curve_signature)
|
|
39
|
-
txn_data = get_for_program_ids_info(txn_data)
|
|
40
|
-
|
|
41
|
-
for new_map in get_create_map():
|
|
42
|
-
instructions = txn_data['transaction']['message']['instructions']
|
|
43
|
-
inner_instructions = txn_data['meta']['innerInstructions'][0]['instructions']
|
|
44
|
-
all_instructions = instructions + inner_instructions
|
|
45
|
-
|
|
46
|
-
instruction = [inst for inst in all_instructions if len(inst.get('associatedAccounts', [])) > 13]
|
|
47
|
-
txn_types = {create_index['instruction_name']: instruction[0]['associatedAccounts'][int(create_index['instruction_number']) - 1] for create_index in get_create_map()}
|
|
48
|
-
|
|
49
|
-
if txn_types:
|
|
50
|
-
txn_types['signature'] = bonding_curve_signature
|
|
51
|
-
break
|
|
52
|
-
return txn_types
|
|
53
|
-
|
|
54
|
-
# Retrieve virtual reserves for a bonding curve using a structured layout
|
|
55
|
-
def get_virtual_reserves(bonding_curve: Pubkey):
|
|
56
|
-
bonding_curve_struct = Struct(
|
|
57
|
-
Padding(8),
|
|
58
|
-
"virtualTokenReserves" / Int64ul,
|
|
59
|
-
"virtualSolReserves" / Int64ul,
|
|
60
|
-
"realTokenReserves" / Int64ul,
|
|
61
|
-
"realSolReserves" / Int64ul,
|
|
62
|
-
"tokenTotalSupply" / Int64ul,
|
|
63
|
-
"complete" / Flag
|
|
64
|
-
)
|
|
65
|
-
account_info = getAccountInfo(account=str(bonding_curve[0]))
|
|
66
|
-
|
|
67
|
-
if not account_info or 'value' not in account_info or 'data' not in account_info['value']:
|
|
68
|
-
print("Failed to retrieve account info.")
|
|
69
|
-
return None
|
|
70
|
-
|
|
71
|
-
data_base64 = account_info['value']['data'][0]
|
|
72
|
-
data = base64.b64decode(data_base64)
|
|
73
|
-
parsed_data = bonding_curve_struct.parse(data)
|
|
74
|
-
return parsed_data
|
|
75
|
-
|
|
76
|
-
# Retrieves comprehensive transaction and reserve data for the mint
|
|
77
|
-
def get_pump_fun_data(mint_str: str):
|
|
78
|
-
txn_types = change_keys_lower(getTxnTypes(mint_str))
|
|
79
|
-
bonding_curve = derive_bonding_curve(mint_str)
|
|
80
|
-
virtual_reserves = get_virtual_reserves(bonding_curve)
|
|
81
|
-
if virtual_reserves is None:
|
|
82
|
-
return None
|
|
83
|
-
|
|
84
|
-
txn_types.update({
|
|
85
|
-
"mint": mint_str,
|
|
86
|
-
"bonding_curve": str(bonding_curve[0]),
|
|
87
|
-
"associated_bonding_curve": str(derive_associated_bonding_curve(mint_str)),
|
|
88
|
-
"virtual_token_reserves": int(virtual_reserves.virtualTokenReserves),
|
|
89
|
-
"virtual_sol_reserves": int(virtual_reserves.virtualSolReserves),
|
|
90
|
-
"token_total_supply": int(virtual_reserves.tokenTotalSupply),
|
|
91
|
-
"complete": bool(virtual_reserves.complete)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
return txn_types
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
from abstract_solana import *
|
|
2
|
-
from spl.token.instructions import create_associated_token_account, get_associated_token_address
|
|
3
|
-
from abstract_solcatcher import getGenesisSignature,getTransaction,getAccountInfo
|
|
4
|
-
from construct import Padding, Struct, Int64ul, Flag
|
|
5
|
-
import base64
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# Change dictionary keys to lowercase and replace spaces with underscores
|
|
10
|
-
def change_keys_lower(dict_obj):
|
|
11
|
-
new_dict = {}
|
|
12
|
-
for key, value in dict_obj.items():
|
|
13
|
-
new_dict[key.lower().replace(' ', '_')] = value
|
|
14
|
-
return new_dict
|
|
15
|
-
|
|
16
|
-
# Predefined map for different transaction types
|
|
17
|
-
def get_create_map():
|
|
18
|
-
return [
|
|
19
|
-
{'instruction_number': '1', 'instruction_name': 'Mint', 'token_address': 'AkAUSJg1v9xYT3HUxdALH7NsrC6owmwoZuP9MLw8fxTL', 'token_name': '3CAT'},
|
|
20
|
-
{'instruction_number': '2', 'instruction_name': 'Mint Authority', 'token_address': 'TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM', 'token_name': 'Pump.fun Token Mint Authority'},
|
|
21
|
-
{'instruction_number': '3', 'instruction_name': 'Bonding Curve', 'token_address': '9nhxvNxfSUaJddVco6oa6NodtsCscqCScp6UU1hZkfGm', 'token_name': 'Pump.fun (3CAT) Bonding Curve'},
|
|
22
|
-
{'instruction_number': '4', 'instruction_name': 'Associated Bonding Curve', 'token_address': '889XLp3qvVAHpTYQmhn6cBpYSppV8Gi8E2Rgp9RH2vRy', 'token_name': 'Pump.fun (3CAT) Vault'},
|
|
23
|
-
{'instruction_number': '5', 'instruction_name': 'Global', 'token_address': '4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf', 'token_name': '4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf'},
|
|
24
|
-
{'instruction_number': '6', 'instruction_name': 'Mpl Token Metadata', 'token_address': 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s', 'token_name': 'Metaplex Token Metadata'},
|
|
25
|
-
{'instruction_number': '7', 'instruction_name': 'Metadata', 'token_address': 'CH41RxpjSXHqr1vfLTVYJMsfNs2fBCCWoAE13tPihXh7', 'token_name': 'CH41RxpjSXHqr1vfLTVYJMsfNs2fBCCWoAE13tPihXh7'},
|
|
26
|
-
{'instruction_number': '8', 'instruction_name': 'User', 'token_address': 'Fuy5MvbgzjSok1U8hH6mUY6WnLynzUextDxfEWMiTkn4', 'token_name': 'Fuy5MvbgzjSok1U8hH6mUY6WnLynzUextDxfEWMiTkn4'},
|
|
27
|
-
{'instruction_number': '9', 'instruction_name': 'System Program', 'token_address': '11111111111111111111111111111111', 'token_name': 'System Program'},
|
|
28
|
-
{'instruction_number': '10', 'instruction_name': 'Token Program', 'token_address': 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', 'token_name': 'Token Program'},
|
|
29
|
-
{'instruction_number': '11', 'instruction_name': 'Associated Token Program', 'token_address': 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL', 'token_name': 'Associated Token Account Program'},
|
|
30
|
-
{'instruction_number': '12', 'instruction_name': 'Rent', 'token_address': 'SysvarRent111111111111111111111111111111111', 'token_name': 'Rent Program'},
|
|
31
|
-
{'instruction_number': '13', 'instruction_name': 'Event Authority', 'token_address': 'Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1', 'token_name': 'Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1'},
|
|
32
|
-
{'instruction_number': '14', 'instruction_name': 'Program', 'token_address': '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P', 'token_name': 'Pump.fun'}
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
# Fetches and organizes transaction types based on provided mint
|
|
36
|
-
def getTxnTypes(mint):
|
|
37
|
-
bonding_curve = str(derive_bonding_curve(mint)[0])
|
|
38
|
-
bonding_curve_signature = getGenesisSignature(address=bonding_curve)
|
|
39
|
-
txn_data = getTransaction(signature=bonding_curve_signature)
|
|
40
|
-
txn_data = get_for_program_ids_info(txn_data)
|
|
41
|
-
|
|
42
|
-
for new_map in get_create_map():
|
|
43
|
-
instructions = txn_data['transaction']['message']['instructions']
|
|
44
|
-
inner_instructions = txn_data['meta']['innerInstructions'][0]['instructions']
|
|
45
|
-
all_instructions = instructions + inner_instructions
|
|
46
|
-
|
|
47
|
-
instruction = [inst for inst in all_instructions if len(inst.get('associatedAccounts', [])) > 13]
|
|
48
|
-
txn_types = {create_index['instruction_name']: instruction[0]['associatedAccounts'][int(create_index['instruction_number']) - 1] for create_index in get_create_map()}
|
|
49
|
-
|
|
50
|
-
if txn_types:
|
|
51
|
-
txn_types['signature'] = bonding_curve_signature
|
|
52
|
-
break
|
|
53
|
-
return txn_types
|
|
54
|
-
|
|
55
|
-
# Retrieve virtual reserves for a bonding curve using a structured layout
|
|
56
|
-
def get_virtual_reserves(bonding_curve: Pubkey):
|
|
57
|
-
bonding_curve_struct = Struct(
|
|
58
|
-
Padding(8),
|
|
59
|
-
"virtualTokenReserves" / Int64ul,
|
|
60
|
-
"virtualSolReserves" / Int64ul,
|
|
61
|
-
"realTokenReserves" / Int64ul,
|
|
62
|
-
"realSolReserves" / Int64ul,
|
|
63
|
-
"tokenTotalSupply" / Int64ul,
|
|
64
|
-
"complete" / Flag
|
|
65
|
-
)
|
|
66
|
-
account_info = getAccountInfo(account=str(bonding_curve[0]))
|
|
67
|
-
|
|
68
|
-
if not account_info or 'value' not in account_info or 'data' not in account_info['value']:
|
|
69
|
-
print("Failed to retrieve account info.")
|
|
70
|
-
return None
|
|
71
|
-
|
|
72
|
-
data_base64 = account_info['value']['data'][0]
|
|
73
|
-
data = base64.b64decode(data_base64)
|
|
74
|
-
parsed_data = bonding_curve_struct.parse(data)
|
|
75
|
-
return parsed_data
|
|
76
|
-
|
|
77
|
-
# Retrieves comprehensive transaction and reserve data for the mint
|
|
78
|
-
def get_pump_fun_data(mint_str: str):
|
|
79
|
-
txn_types = change_keys_lower(getTxnTypes(mint_str))
|
|
80
|
-
bonding_curve = derive_bonding_curve(mint_str)
|
|
81
|
-
virtual_reserves = get_virtual_reserves(bonding_curve)
|
|
82
|
-
if virtual_reserves is None:
|
|
83
|
-
return None
|
|
84
|
-
|
|
85
|
-
txn_types.update({
|
|
86
|
-
"mint": mint_str,
|
|
87
|
-
"bonding_curve": str(bonding_curve[0]),
|
|
88
|
-
"associated_bonding_curve": str(derive_associated_bonding_curve(mint_str)),
|
|
89
|
-
"virtual_token_reserves": int(virtual_reserves.virtualTokenReserves),
|
|
90
|
-
"virtual_sol_reserves": int(virtual_reserves.virtualSolReserves),
|
|
91
|
-
"token_total_supply": int(virtual_reserves.tokenTotalSupply),
|
|
92
|
-
"complete": bool(virtual_reserves.complete)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
return txn_types
|
|
96
|
-
|
|
97
|
-
# Example usage
|
|
98
|
-
mint = "911eA3wRZ85ZiSTpmCH1hksPGLGgzyVpfMXtJ4zSzVJ5"
|
|
99
|
-
mint_pub_key = get_pubkey(mint)
|
|
100
|
-
|
|
101
|
-
if not mint_pub_key.is_on_curve():
|
|
102
|
-
print('Mint public key is not on curve')
|
|
103
|
-
|
|
104
|
-
txn_types = get_pump_fun_data(mint)
|
|
105
|
-
|
|
106
|
-
input(txn_types)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/account_key_utils.py
RENAMED
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/genesis_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/log_message_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana/signature_data_parse.py
RENAMED
|
File without changes
|
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/requires.txt
RENAMED
|
File without changes
|
{abstract_solana-0.0.0.22 → abstract_solana-0.0.0.24}/src/abstract_solana.egg-info/top_level.txt
RENAMED
|
File without changes
|