API Reference

Checking for Transaction Sponsorship

To check whether a swap is sponsorable, first send your unsigned transaction to your RPC endpoint at https://sol.blinklabs.xyz/v1/<API_KEY> with the following POST request

pm_isSponsorable

{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pm_isSponsorable",
    "params": [
        "unsigned_transaction_string_base64"
        {
            "encoding": "base64",
        }
    ]
}

Example response:

{
    "id": 1,
    "result": {
        "sponsorable": true,
        "sponsorName": "Blink",
        "sponsorIcon": "https://framerusercontent.com/images/o61GQaQ3nRGkpdVnUD5P3HhDxx0.png",
        "sponsorWebsite": "https://blinklabs.xyz/",
        "sponsorWallet": "7czf8vVLjGUaLqn9DBneEz1sNwP3gLx8Usrq3zMctify",
        "activeSponsorTransfer": "5000000"
    },
    "jsonrpc": "2.0"
}

If the response returns true, your transaction is sponsorable. You're free to submit it even if your simulations fail or the user does not seem to have enough funds. We will do our best to get the transaction on-chain. Alternatively, you can improve those chances by using our active sponsorship.

Active sponsorship

There is no need to request an active sponsorship as we will detect these automatically. After you have confirmation that your transaction is generally sponsorable, simply append a instruction to the end of your unsigned transaction. This is a basic transfer instruction with an amount (in Lamports) equal to the activeSponsorAmount (0.005 SOL) with the receiving address set to the value returned in the sponsorWallet field. Here is an example typescript code snippet for appending this instruction to an existing unsigned transaction:

import {
    Keypair,
    SystemProgram,
    VersionedTransaction,
    PublicKey,
    TransactionMessage,
  } from "@solana/web3.js";
  
const userAddress = "wqkFNErNLVpS71UXy1qF4N4icTa5ZXLJ4i9JrPb7ho2"
const sponsorWallet = "7czf8vVLjGUaLqn9DBneEz1sNwP3gLx8Usrq3zMctify"
const sponsorTransferNeeded = 5000000

const unsignedTransaction = "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAIAAQMODHsGxabeQ4cLySnfz0GMwRF0iz3nQAZUpQXk+qVHnbpQlroNX6im7FPcmWooVNPTOosfeQqVfa+5ah5JlbvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJwvDgxnL3f8yMhTmBsBauj53N/5nYFTlk03hSAASqDQECAgEBDAIAAAC3kvUFAAAAAAA="

async function appendTransfer() {
    let transaction = VersionedTransaction.deserialize(Buffer.from(unsignedTransaction, 'base64'));
    
    // Extract existing instructions from the transaction
    const existingInstructions = TransactionMessage.decompile(transaction.message).instructions;
    
    // Create the transfer instruction
    let transferInstruction = SystemProgram.transfer({
      fromPubkey: new PublicKey(userAddress),
      toPubkey: new PublicKey(sponsorWallet),
      lamports: sopnsorTransferNeeded, // Transfer full balance in LAMPORTS
    });
    
    // Combine existing instructions with the new transfer instruction
    const allInstructions = [...existingInstructions, transferInstruction];
    
    // Create new transaction message with all instructions
    const newMessage = new TransactionMessage({
      payerKey: senderKeyPair.publicKey, // First account is typically the payer
      recentBlockhash: transaction.message.recentBlockhash,
      instructions: allInstructions,
    });
    
    // Compile into a new versioned transaction
    const newTransaction = new VersionedTransaction(newMessage.compileToV0Message());

    // Sign the transaction
    newTransaction.sign([senderKeyPair]);

    // Convert to Buffer array format used by sendTransaction RPC
    const serializedTransaction = newTransaction.serialize();
    const transactionBuffer = Buffer.from(serializedTransaction);

    // Get transaction signature and send it
    console.log("base64",transactionBuffer.toString("base64"));
}

appendTransfer();

Then simply submit this new transaction as you would a passive sponsorship. We guarantee that we will always sponsor the user with more SOL than what is being transferred back to us at the end of the transaction.

Passive Sponsorship

Simply send your signed transaction to your RPC endpoint at https://sol.blinklabs.xyz/v1/<API_KEY> with the following POST request. Make sure that you set the skipPreflight flag to true otherwise the transaction will fail in preflight simulations.

{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "sendTransaction",
    "params": [
        "transaction_string_base64_or_base58"
        {
            "skipPreflight": true
        }
    ]
}

Example:

curl --location 'https://sol.blinklabs.xyz/v1/<API_KEY>'
--header 'Content-Type: application/json'
--data ' {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "sendTransaction",
    "params": [
        "3iBrudA8jK7QATBJbwBhJFeFkhAASoytXQVG92wVjZGNNCgw1W2cySaauv66fXuVjfqMWLmjH53NKQRHaW9MqJMiC2Ua95DGkdLyXDizW1Zgmmhrm9nq451r8EYihBbReecLHWTUhy9hMXet1REj5T4N95WEmjb3yxsTkkFZbqQps3sFCfasc7NrXeZCAPeEC2ifuwiy55h7Dr2rEQr4vr8JUbzHfVkfKrCaRP5SQDGZsLo5Zv7D5buGxg6ztiLTNTR3TusMeHGXGCjmUThgcSyyDofre5WbZSauBqYnvGeemvR3SvNaAJfDHdejs6Z6dUMccnYpK6vGA4DVxqd3fdme1wLxmFZNKovNnqaWP1h2C5GYLPvoAaKQkHVbmWxDo5va4g11iR7rvHkdauG7qHG8EPAh6ZL6AaT19t2pi4UnhD5X4jynLgY3cCDfmLPoM4PdNeAXDYCoHscCzMQEFdj6BYoBLw4UxykGthnvMHTx6QvQY8udhRbT6HDbhXA9LCv64KsZmDFektxd4DMRtTskiAo8NMbAbxHJWDUY4MtMrhVGGePd7LvwdQW5jL1iPsLeDWMHVbytPjJinFsqivUxSQB3TvGCvkVE5iEiahZ9zziHfbpwvzJDSqzerzXHRTX5UVBRsBe3KfLtQYDYRC8ZfM5Ud5cJ2jMdCR4aA2RtLDkEP6DeQPZwGi8weuU6CBpEm8H3xiGGAZTQXHzNtRrPebgY8dnCZWQvmhRprsab5Ehg512tSui1j3bL1KT5orJJEJktuKyen7KWkU343EBFKi9yndBCsQJrbtnjxT3LvRzCKUDhf2ysoyV8TLMwynmaSM3ubuDHshfMWw3E5pqRBTKQypDQf9mknXvjiLvFLiWRdyfaJTfSGsxt1zjbbaBTJPCxQxaQntpNiyRgxgsGMk931nxDbWmV1E2Uj4V749bH4uPLwhkrTF22k7zTnH9pgqMMzavLMWbsFAMdyKBZbZZ86E76jmZuFBC6q4bqjAV1bHcNFae8vjEHTVHbb6NDagZ2HSus1QcEe49GkGJm6wVBd3t3TFW7XoVBnx6Cyai78qC3w6NWD2c3xHitjmdQP32u2Dj5hsUG5mY4AvULy8QXqDTi4Hjvu96tiNMjY83FtqLTTUs61gxNPUrpgUdfc2CKTCVTSoys6kRcubDJRCiZ3tWK25oAXyvyokT1gzvzMhDwNocSEAbobG7ZXACJgNe6nGKzUsw6WVbCBkGsVL1NDKZu4QAgt5sVJAfcybvMFuGXBPSCsJZsm5J9oK8vufmZHCQwnQJuC9hvY5NmKswvHXAARZfcbRpG9DBB7GvmEYugEGWSwLDFAUai2AeyNkW7cN1GQjaNN4XuEXVNvG7UkAfH2XdeNAjevKYxFSpZm2AH7ZoK4r51HFwsJuPD3L92jzTQ6JzUPaJ3",
        {
            "skipPreflight": true
        }
    ]
}'

Last updated