NOTE
Lite URL: https://lite-api.jup.ag/send/v1
Pro URL: https://api.jup.ag/send/v1
To upgrade to Pro or understand our rate limiting, please refer to this section.
Overview
Load public key from invite.
Post request to get Clawback transaction.
Sign with sender keypair, then send transaction and wait for confirmation.
import { invite_code_to_priv_key } from "./utils.js" ;
import {
Connection ,
Keypair ,
PublicKey ,
VersionedTransaction ,
} from "@solana/web3.js" ;
import fs from "fs" ;
const connection = new Connection ( 'insert-rpc' );
const senderPrivateKey = JSON . parse ( fs . readFileSync ( '/Path/to/sender/id.json' , 'utf8' ). trim ());
const sender = Keypair . fromSecretKey ( new Uint8Array ( senderPrivateKey ));
process . loadEnvFile ( '.env' );
// STEP 1: Load invite code
const invite_code = process . env . INVITE_CODE ;
// STEP 2: Load the public key from the invite code
const secret_key = invite_code_to_priv_key ( invite_code );
const pubkey = Keypair . fromSecretKey ( secret_key ). publicKey ;
// STEP 3: Find the Program Derived Address (PDA) for the invite
// Uses `"invite"` as seed + the public key
// PDAs are deterministic addresses owned by the program
const invite_pda = PublicKey . findProgramAddressSync (
[ Buffer . from ( "invite" ), pubkey . toBuffer ()],
new PublicKey ( "inv1tEtSwRMtM44tbvJGNiTxMvDfPVnX9StyqXfDfks" )
)[ 0 ];
// STEP 4: Post request for a Clawback transaction
const craftClawbackTransaction = await (
await fetch ( 'https://lite-api.jup.ag/send/v1/craft-clawback' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
invitePDA: invite_pda . toBase58 (),
sender: sender . publicKey . toBase58 (),
}, null , 2 )
})
). json ();
// STEP 5: Use sender keypair to sign and send to network
const transaction = VersionedTransaction . deserialize ( Buffer . from ( craftClawbackTransaction . tx , 'base64' ));
transaction . sign ([ sender ]); // SIGN with SENDER
const transactionBinary = transaction . serialize ();
const blockhashInfo = await connection . getLatestBlockhashAndContext ({ commitment: "confirmed" });
const signature = await connection . sendRawTransaction ( transactionBinary , {
maxRetries: 0 ,
skipPreflight: true ,
});
// Log the signature immediately after sending, before confirmation
console . log ( `Transaction sent: https://solscan.io/tx/ ${ signature } ` );
try {
const confirmation = await connection . confirmTransaction ({
signature ,
blockhash: blockhashInfo . value . blockhash ,
lastValidBlockHeight: blockhashInfo . value . lastValidBlockHeight ,
}, "confirmed" );
if ( confirmation . value . err ) {
console . error ( `Transaction failed: ${ JSON . stringify ( confirmation . value . err ) } ` );
console . log ( `Examine the failed transaction: https://solscan.io/tx/ ${ signature } ` );
} else {
console . log ( `Transaction successful: https://solscan.io/tx/ ${ signature } ` );
}
} catch ( error ) {
console . error ( `Error confirming transaction: ${ error } ` );
console . log ( `Examine the transaction status: https://solscan.io/tx/ ${ signature } ` );
}
Imports
import { invite_code_to_priv_key } from "./utils.js" ;
import {
Connection ,
Keypair ,
PublicKey ,
VersionedTransaction ,
} from "@solana/web3.js" ;
import fs from "fs" ;
const connection = new Connection ( 'insert-rpc' );
const senderPrivateKey = JSON . parse ( fs . readFileSync ( '/Path/to/sender/id.json' , 'utf8' ). trim ());
const sender = Keypair . fromSecretKey ( new Uint8Array ( senderPrivateKey ));
process . loadEnvFile ( '.env' );
Invite Code and Public Key
// STEP 1: Load invite code
const invite_code = process . env . INVITE_CODE ;
// STEP 2: Load the public key from the invite code
const secret_key = invite_code_to_priv_key ( invite_code ); // Follow the utils.js guide
const pubkey = Keypair . fromSecretKey ( secret_key ). publicKey ;
Invite PDA
// STEP 3: Find the Program Derived Address (PDA) for the invite
// Uses `"invite"` as seed + the public key
// PDAs are deterministic addresses owned by the program
const invite_pda = PublicKey . findProgramAddressSync (
[ Buffer . from ( "invite" ), pubkey . toBuffer ()],
new PublicKey ( "inv1tEtSwRMtM44tbvJGNiTxMvDfPVnX9StyqXfDfks" )
)[ 0 ];
Craft Clawback
NOTE The clawback will return the full amount including leftover transaction fees and/or rent back to the sender.
// STEP 4: Post request for a Clawback transaction
const craftClawbackTransaction = await (
await fetch ( 'https://lite-api.jup.ag/send/v1/craft-clawback' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
invitePDA: invite_pda . toBase58 (),
sender: sender . publicKey . toBase58 (),
}, null , 2 )
})
). json ();