Skip to main content
POST
/
transactions
/
eoa
/
gas-abstraction
Abstract gas fees for EOA transactions
curl --request POST \
  --url https://grid.squads.xyz/api/v0/grid/transactions/eoa/gas-abstraction \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'X-Grid-Environment: <x-grid-environment>' \
  --data '{
  "transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABBDZi..."
}'
{
"transaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABBDZi...",
"fee": {
"amount": "22390",
"amount_decimal": "0.002239",
"currency": "USDC",
"sol_equivalent": {
"amount": "895880",
"amount_decimal": "0.00089588"
}
}
}
The Gas Abstraction endpoint enables fee sponsorship for standard Solana wallet transactions through the Grid paymaster system. This service removes the requirement for users to hold SOL tokens for transaction fees, creating a seamless user experience.
This endpoint is exclusively for standard Solana wallets (keypair-based accounts). For Squads smart accounts with built-in gas abstraction, see Grid v1 Cost Efficiency.

How It Works

The gas abstraction process follows these steps:
  1. Transaction Submission: Send your unsigned, base64-encoded transaction to the endpoint
  2. Fee Calculation: The paymaster computes the required fees in your specified currency (defaults to USDC)
  3. Paymaster Signing: The paymaster adds its signature to sponsor the fees
  4. User Signing: Add the user’s signature to the paymaster-signed transaction
  5. Blockchain Submission: Submit the fully signed transaction to Solana

Implementation Guide

1

Prepare Your Unsigned Transaction

Create your versioned transaction without signing it:
import {
  VersionedTransaction,
  TransactionMessage,
  SystemProgram,
  PublicKey,
  Connection,
  LAMPORTS_PER_SOL,
} from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com");

// Create transaction instructions (example: SOL transfer)
const transferInstruction = SystemProgram.transfer({
  fromPubkey: senderPublicKey,
  toPubkey: recipientPublicKey,
  lamports: 0.1 * LAMPORTS_PER_SOL,
});

// Get recent blockhash and build transaction message
const { blockhash } = await connection.getLatestBlockhash();
const messageV0 = new TransactionMessage({
  payerKey: senderPublicKey,
  recentBlockhash: blockhash,
  instructions: [transferInstruction],
}).compileToV0Message();

// Create versioned transaction (unsigned)
const transaction = new VersionedTransaction(messageV0);

// Serialize to base64
const serializedTransaction = Buffer.from(
  transaction.serialize()
).toString("base64");
2

Submit to Gas Abstraction API

Send your unsigned transaction to the endpoint:
const response = await fetch(
  "https://grid.squads.xyz/api/v0/grid/transactions/eoa/gas-abstraction",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "X-Grid-Environment": "production", // or 'sandbox' for devnet
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      transaction: serializedTransaction,
    }),
  }
);

const result = await response.json();

// Review fee information
console.log(`Fee: ${result.fee.amount_decimal} ${result.fee.currency}`);
console.log(
  `SOL equivalent: ${result.fee.sol_equivalent.amount_decimal} SOL`
);
3

Sign and Submit to Blockchain

Deserialize the paymaster-signed transaction, add the user’s signature, and submit:
import { VersionedTransaction } from "@solana/web3.js";

// Decode the paymaster-signed transaction
const signedTransactionBuffer = Buffer.from(result.transaction, "base64");
const transaction = VersionedTransaction.deserialize(
  signedTransactionBuffer
);

// Add user's signature
transaction.sign([userKeypair]);

// Submit to blockchain
const signature = await connection.sendTransaction(transaction);
console.log("Transaction signature:", signature);

// Confirm transaction
const confirmation = await connection.confirmTransaction(signature);
console.log(
  "Status:",
  confirmation.value.err ? "Failed" : "Confirmed"
);

Fee Structure

Fee Calculation

The total fee consists of:
  • Compute Units: Based on transaction complexity and computational requirements
  • Rent Fees: For account creation or rent-exempt balance requirements
  • Currency Conversion: Fees quoted in your specified currency (default: USDC)

Billing Details

  • Sandbox Environment: Devnet transactions are processed but not billed
  • Production Environment: Mainnet transactions are recorded and billed according to your Grid API agreement
  • Fee Components: Transaction, priority, and rent fees are included in billing

Custom Identifiers

Use the optional customIdentifier query parameter to group and track related transactions:
const response = await fetch(
  "https://grid.squads.xyz/api/v0/grid/transactions/eoa/gas-abstraction?customIdentifier=user-123-session-abc",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
      "X-Grid-Environment": "production",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      transaction: serializedTransaction,
    }),
  }
);
Custom identifiers enable you to:
  • Group transactions by user, session, or feature
  • Query fee history by identifier
  • Track usage patterns and costs per category

Transaction Validation

Transactions must:
  • Be valid Solana transactions that can be simulated successfully
  • Use versioned transaction format
  • Be properly serialized to base64
  • Not be pre-signed

Error Handling

Common error scenarios:

Invalid Transaction Format

{
  "code": "INVALID_TRANSACTION",
  "message": "tried to parse invalid transaction"
}
Solution: Verify your transaction is properly serialized and base64-encoded.

Invalid Environment Header

{
  "code": "INVALID_ENVIRONMENT",
  "message": "Environment must be either 'sandbox' or 'production'"
}
Solution: Ensure X-Grid-Environment header is set to either sandbox or production.

Service Unavailable

{
  "code": "SERVICE_UNAVAILABLE",
  "message": "The service is temporarily unavailable. Please try again."
}
Solution: Implement retry logic with exponential backoff.

Security Best Practices

  1. API Key Protection: Never expose your Grid API key in client-side code or public repositories
  2. Environment Separation: Use sandbox for testing, production only for live transactions
  3. Transaction Verification: Always validate the returned signed transaction matches your intent
  4. Fee Monitoring: Implement alerts for unexpected fee spikes
  5. Rate Limiting: Implement appropriate rate limiting to avoid overwhelming the API

Authorizations

Authorization
string
header
required

API Key for authentication. Include your Grid API key in the Authorization header.

Headers

X-Grid-Environment
enum<string>
required

The environment you're using. Can be sandbox or production.

Available options:
sandbox,
production

Query Parameters

customIdentifier
string<uuid>

Optional custom identifier for tracking purposes. Used to group and filter transactions.

Body

application/json
transaction
string
required

Base64-encoded unsigned Solana transaction to process for fee abstraction

Example:

"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABBDZi..."

Response

Transaction successfully processed with abstracted fees

transaction
string
required

Base64-encoded signed transaction ready for submission to the blockchain

Example:

"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABBDZi..."

fee
object
required

Detailed fee breakdown for the transaction