Last active
August 14, 2025 19:14
-
-
Save ngundotra/03545235ca3b6f9e6153a2c3c1f4a041 to your computer and use it in GitHub Desktop.
Surfpool-Jupiter Transaction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Jupiter Swap Test Transaction for Surfpool | |
* Creates a test transaction that can be executed in the Surfpool environment | |
* bun run surfpool-jupiter-test.ts | |
*/ | |
import { | |
Connection, | |
PublicKey, | |
VersionedTransaction, | |
Keypair, | |
Transaction, | |
SystemProgram, | |
LAMPORTS_PER_SOL | |
} from '@solana/web3.js'; | |
import { NATIVE_MINT } from '@solana/spl-token'; | |
import bs58 from 'bs58'; | |
// This function matches the signature expected by the skill runner | |
export async function executeSkill(blockhash: string): Promise<string> { | |
const connection = new Connection('http://localhost:8899'); | |
const kp = Keypair.generate(); | |
connection.requestAirdrop(kp.publicKey, 10 * LAMPORTS_PER_SOL); | |
// Use a test pubkey (replace with actual agent pubkey in production) | |
const agentPubkey = kp.publicKey; | |
console.log('π Jupiter Swap - executeSkill'); | |
console.log(' Agent:', agentPubkey.toString()); | |
console.log(' Blockhash:', blockhash); | |
// Step 1: Get quote from Jupiter | |
const quoteResponse = await fetch( | |
'https://quote-api.jup.ag/v6/quote?' + | |
new URLSearchParams({ | |
inputMint: NATIVE_MINT.toString(), | |
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC | |
amount: '1000000', // 0.001 SOL | |
slippageBps: '100' // 1% slippage | |
}) | |
); | |
const quote = await quoteResponse.json(); | |
if (quote.error) { | |
throw new Error(`Quote error: ${quote.error}`); | |
} | |
console.log('β Quote received:'); | |
console.log(' Output:', (parseInt(quote.outAmount) / 1e6).toFixed(6), 'USDC'); | |
console.log(' Routes:', quote.routePlan?.length || 0); | |
// Step 2: Get swap transaction from Jupiter | |
const swapResponse = await fetch('https://quote-api.jup.ag/v6/swap', { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify({ | |
quoteResponse: quote, | |
userPublicKey: agentPubkey.toString(), | |
wrapAndUnwrapSol: true, | |
dynamicComputeUnitLimit: true, | |
prioritizationFeeLamports: 'auto' | |
}) | |
}); | |
const swapData = await swapResponse.json(); | |
if (!swapData.swapTransaction) { | |
throw new Error(`Swap error: ${JSON.stringify(swapData)}`); | |
} | |
console.log('β Swap transaction received'); | |
// Step 3: Process transaction for Surfpool | |
const swapTxBuf = Buffer.from(swapData.swapTransaction, 'base64'); | |
const transaction = VersionedTransaction.deserialize(swapTxBuf); | |
// Update blockhash for Surfpool | |
transaction.message.recentBlockhash = blockhash; | |
transaction.sign([kp]); | |
// Serialize and return | |
const serialized = Buffer.from(transaction.serialize()).toString('base64'); | |
console.log('β Transaction serialized, length:', serialized.length); | |
return serialized; | |
} | |
// Test function to run the skill | |
async function testSkill() { | |
console.log('\n' + '='.repeat(60)); | |
console.log('π§ͺ TESTING JUPITER SWAP SKILL FOR SURFPOOL'); | |
console.log('='.repeat(60) + '\n'); | |
try { | |
// Connect to Surfpool | |
const connection = new Connection('http://localhost:8899', 'confirmed'); | |
const { blockhash } = await connection.getLatestBlockhash(); | |
console.log('π‘ Connected to Surfpool'); | |
console.log(' Blockhash:', blockhash, '\n'); | |
// Execute the skill | |
const serializedTx = await executeSkill(blockhash); | |
console.log('\n' + '='.repeat(60)); | |
console.log('β SUCCESS - Transaction ready for Surfpool'); | |
console.log('='.repeat(60)); | |
console.log('\nSerialized transaction (base64):'); | |
console.log(serializedTx); | |
// Verify transaction structure | |
const txBuf = Buffer.from(serializedTx, 'base64'); | |
const tx = VersionedTransaction.deserialize(txBuf); | |
const simulation = await connection.simulateTransaction(tx); | |
const sig = await connection.sendTransaction(tx); | |
console.log('Signature:', sig); | |
// console.log('Simulation:', simulation); | |
console.log('\nπ Transaction Analysis:'); | |
console.log(' Version:', tx.version === 0 ? 'v0' : 'Legacy'); | |
console.log(' Blockhash matches:', tx.message.recentBlockhash === blockhash); | |
console.log(' Instructions:', tx.message.compiledInstructions.length); | |
// Check for Jupiter program | |
const jupiterProgram = 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4'; | |
const hasJupiter = tx.message.staticAccountKeys.some( | |
key => key.toString() === jupiterProgram | |
); | |
console.log(' Has Jupiter program:', hasJupiter ? 'β ' : 'β'); | |
return serializedTx; | |
} catch (error) { | |
console.error('\nβ Test failed:', error); | |
throw error; | |
} | |
} | |
// Run test if executed directly | |
if (require.main === module) { | |
testSkill() | |
.then(() => { | |
console.log('\n⨠Test complete!'); | |
process.exit(0); | |
}) | |
.catch((err) => { | |
console.error('\nπ₯ Fatal error:', err); | |
process.exit(1); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment