All articles
candidepaymasterkorasolanausdtgaslesstetherwdkfee-abstraction

Candide Solana Paymaster: pay gas in USDT — zero SOL transfers via Kora

Candide’s Solana Paymaster is a hosted Kora fee-payer endpoint: users transfer SPL with no SOL; fees collected in USDT in the same tx. WDK quickstart, RPC methods, policy limits, roadmap.

Share
devrels.xyz/a/185short link

Candide Solana Paymaster: pay gas in USDT so accounts with zero SOL can still send SPL transfers. It is Candide’s first non-EVM product — a hosted Kora endpoint that cosigns as fee payer, fronts SOL for fees and rent, and collects the equivalent in USDT inside the same transaction.

Announcement: docs.candide.dev/blog/solana-paymaster. Guide: Pay Gas in USDT on Solana. RPC ref: Solana Paymaster RPC methods. Dashboard: dashboard.candide.dev. X: @candidelabs.

The problem

Stablecoin users hold USDT/USDC, not SOL. On Solana an account with balances but no native SOL cannot pay fees or create ATAs — so wallets bounce people to an exchange mid-funnel. EVM teams solved this with ERC-4337 token paymasters; Candide’s Solana answer reuses that product intuition on Foundation’s open fee-payer standard: Kora.

Important distinction: this is not a proprietary proprietary SDK lock-in. Because the service speaks Kora JSON-RPC, any Kora client can target it — including @solana/kora and Tether’s Wallet Development Kit gasless Solana package.

How it works

text
User wallet (may have 0 SOL, has USDT)
   │  builds SPL transfer + USDT fee ix to payment_address
   │  user signs (not as fee payer)
   ▼
Candide Solana Paymaster (hosted Kora)
   │  validates policy
   │  cosigns as fee payer (signer_address)
   │  submits tx
   ▼
Solana
   • fee payer spends SOL (fees + rent)
   • user pays fee_in_token USDT in same tx

Fee is priced from the live SOL cost of the transaction. If the recipient lacks a USDT ATA, rent to create it is folded into the quoted USDT fee.

Endpoint and auth

text
https://api.candide.dev/api/v3/solana/YOUR_API_KEY

# or key in header:
https://api.candide.dev/api/v3/solana
Header: x-api-key: YOUR_API_KEY

# smoke test
curl https://api.candide.dev/api/v3/solana/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getPayerSigner","params":[]}'

Get the key from the Candide dashboard. Keep the URL secret — it embeds the key when using path style.

Fast path: Tether WDK

Packages (versions as verified in Candide’s guide): @tetherto/[email protected], @solana/[email protected].

bash
npm install @tetherto/wdk-wallet-solana-gasless @solana/kora
typescript
import WalletManagerSolanaGasless from "@tetherto/wdk-wallet-solana-gasless"
import { KoraClient } from "@solana/kora"

const nodeUrl = process.env.SOLANA_NODE_URL!
const paymasterUrl = process.env.SOLANA_PAYMASTER_URL! // Candide URL+key
const usdtMint = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"

const kora = new KoraClient({ rpcUrl: paymasterUrl })
const { signer_address: paymasterAddress } = await kora.getPayerSigner()

const wallet = new WalletManagerSolanaGasless(seedPhrase, {
  provider: nodeUrl,
  paymasterUrl,
  paymasterAddress,
  paymasterToken: { address: usdtMint },
  transferMaxFee: 1_000000n, // abort if fee > 1 USDT
})

const account = await wallet.getAccount(0)

// quote (USDT base units, 6 decimals)
const quote = await account.quoteTransfer({
  token: usdtMint,
  recipient,
  amount: 100000n, // 0.1 USDT
})

// send — user never needs SOL
const result = await account.transfer({
  token: usdtMint,
  recipient,
  amount: 100000n,
})
// result.hash, result.fee

Full runnable sample: candidelabs/tether-wdk-candide …/01-usdt-gas.

Raw Kora RPC flow

If you are not on WDK, the documented flow is:

  1. getPayerSigner → set signer_address as fee payer; fee goes to payment_address.
  2. Build the tx (or use paymaster transferTransaction).
  3. estimateTransactionFeefee_in_token.
  4. Append an SPL transfer of fee_in_token to payment_address as the last instruction; re-estimate until stable (usually one iteration).
  5. User signs → signAndSendTransaction (or signTransaction + your RPC).

Conventions differ from Candide’s EVM paymaster: Solana txs are base64 wire format; amounts are decimal base units; request params are named objects; response fields are snake_case.

Note: Kora’s newer getPaymentInstruction is not enabled on this endpoint (returns -32600). Build the fee payment as a plain SPL transfer.

Tokens and sponsorship modes

Mode / tokenStatus
USDT fee payments (mainnet mint Es9v…wNYB)Default on every endpoint
USDC (EPjF…Dt1v) and other SPLOn request per API key
Full gas sponsorship (user pays 0)On request (EVM InstaGas analogue)

Live allowlist: getSupportedTokens. Default mode is token gas payment inside the same transaction — not free gas unless sponsorship is enabled for your key.

Policy limits (read before you integrate)

From the RPC reference “Current Policy” (as documented — re-check getConfig in production):

  • Only tokens enabled for your endpoint (as fee mint and transfer mint).
  • Fee payment must be present and sufficient or sign/send rejects.
  • Only five programs may be invoked: System, SPL Token, ATA, Compute Budget, Address Lookup Table. Token-2022 is not allowed yet.
  • Fee payer spends at most 9,000,000 lamports per tx (fees + rent).
  • Max 10 signatures; durable nonce txs rejected.

That program allowlist means this is a stablecoin transfer paymaster today, not a general “sponsor any dapp ix” relayer. Complex DeFi menus still need a custom Kora operator or self-hosted policy.

Where it sits vs Kora DIY

Candide Solana PaymasterSelf-host Kora
OpsHosted endpoint + dashboard keyYou run signer, inventory SOL, policies
ProtocolKora JSON-RPC (compatible clients)Same standard
Best forUSDT (and requested tokens) transfers fastCustom fees, Token-2022, app-wide policies

Read the Foundation-side design in Kora: fee abstraction so users never need SOL for gas.

Roadmap signal

Candide’s post: mainnet USDT is the only fee token by default today; sponsored transactions (app pays, user pays nothing) are next — mirroring their EVM InstaGas product. Contact for USDC/other tokens and sponsorship enablement.

Builder checklist

  1. Create Candide dashboard key; store paymaster URL server-side.
  2. Decide WDK transfer() vs raw Kora client.
  3. Enforce transferMaxFee / quote ceilings in UX.
  4. Confirm recipient ATA creation rent is acceptable in the USDT fee.
  5. Do not promise Token-2022 or arbitrary program calls until policy expands.
  6. Production RPC: paid Solana provider; poll signatures if you need confirmed finality beyond submit.

Resources

Bottom line

Candide Solana Paymaster is the practical “pay gas in USDT” button for Solana stablecoin UX: hosted Kora, standard clients, WDK one-call transfers. Scope it correctly — SPL Token path, USDT default, strict program allowlist — and it removes the SOL chicken-and-egg for the most common wallet action. For custom fee tokens or broader ix sets, run your own Kora policy or wait for Candide’s sponsorship/token expansions.

Keep reading

Get new articles in your inbox

Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.

Candide Solana Paymaster: pay gas in USDT — zero SOL transfers via Kora | devrels.xyz