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 ();