I'm trying to create a swap transaction using the Jupiter API, and all seems to be done correctly until the part where I have to sign the transaction, it just fails and for me makes no sense since I'm using the Keypair for signing as the same as for interacting with the JUP API. Below is the code. Does anyone know what is happening here? Thanks!
from solders.hash import Hash
from solana.rpc.api import Client
from spl.token.client import Token
from solders.pubkey import Pubkey
from solders.keypair import Keypair
from solders.signature import Signature
from solders.system_program import TransferParams, transfer
from solana.transaction import Transaction
import requests
import base64
import json
LAMPORT_PER_SOL = 1000000000
# Get your keypair
keypair = Keypair().from_base58_string("x Base58 string obv")
# Create the client
client = Client("https://api.devnet.solana.com")
recent_blockhash = client.get_latest_blockhash()
# Print the public key of the new account
print(f"Your solana address (Public key): {keypair.pubkey()}")
"""
response = client.request_airdrop(keypair.pubkey(), 1_000_000_000)
print(response.to_json())
signature = Signature.from_string(json.loads(response.to_json())['result'])
# Confirm the transaction
client.confirm_transaction(signature)
print("Airdrop successful!")"""
# Check the balance
balance = json.loads(client.get_balance(keypair.pubkey()).to_json())
print(f"Balance for {keypair.pubkey()} is {balance['result']['value'] / LAMPORT_PER_SOL} SOL")
#####################################
while True:
# Fetching the quote for swapping SOL to USDC
quote_url = "https://quote-api.jup.ag/v6/quote"
quote_params = {
"inputMint": "So11111111111111111111111111111111111111112",
"outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # USDC
"amount": 100000000,
"slippageBps": 50
}
quote_response = requests.get(quote_url, params=quote_params)
quote_data = quote_response.json()
# Fetching the serialized transaction for the swap
swap_url = "https://quote-api.jup.ag/v6/swap"
swap_payload = {
"quoteResponse": quote_data,
"userPublicKey": str(keypair.pubkey()),
"wrapAndUnwrapSol": True
}
swap_response = requests.post(swap_url, headers={'Content-Type': 'application/json'}, data=json.dumps(swap_payload))
swap_data = swap_response.json()
swap_transaction = swap_data.get('swapTransaction')
try:
transaction = Transaction.deserialize(base64.b64decode(swap_transaction))
transaction.recent_blockhash = recent_blockhash.value.blockhash
transaction.sign(keypair)
raw_transaction = transaction.serialize()
print(raw_transaction)
# tx_signature = client.send_raw_transaction(raw_transaction)
# print(f"Transaction Signature: {tx_signature}")
except ValueError:
print('Error deserializing swap transaction')
Basically the error is at transaction.sign(keypair)
Traceback (most recent call last):
File "C:\Users\Account\Downloads\sol_sign.py", line 71, in <module>
transaction.sign_partial(keypair)
File "C:\Users\Account\AppData\Local\Programs\Python\Python310\lib\site-packages\solana\transaction.py", line 225, in sign_partial
self._solders.partial_sign(partial_signers, self._solders.message.recent_blockhash)
solders.SignerError: keypair-pubkey mismatch
IMPORTANT EDIT: I changed the code to:
try:
raw_transaction = VersionedTransaction.from_bytes(base64.b64decode(swap_transaction))
print('Raw transaction: ', raw_transaction)
print(raw_transaction.message.recent_blockhash)
signature = keypair.sign_message(to_bytes_versioned(raw_transaction.message))
signed_transaction = VersionedTransaction.populate(raw_transaction.message, [signature])
print('Signed transaction: ', signed_transaction)
tx_signature = client.simulate_transaction(signed_transaction).value
print(f"Transaction Signature: {tx_signature}")
except ValueError as e:
print('Error deserializing swap transaction', e)
Now im getting err: Some(BlockhashNotFound) when simulating the transaction, which doesnt makes sense since is retrieved from JUP API