Blog

Securing Jupiter: How to write Solana swap policies with Turnkey

Resources
No items found.
·
·

Audience: Developers, protocol teams, and Solana builders integrating Jupiter swaps into wallets, dApps, or trading flows who need stronger guarantees around signing, routing safety, and key custody.

What you’ll learn: How Jupiter’s routing works across Solana liquidity, where swap flows are vulnerable to spoofed tokens or malicious pools, and how Turnkey’s enclave-based signing and intent-level policy controls enforce safe, verifiable, and predictable Jupiter transactions.

Reading time: 13 minutes

In a Medium article titled “I Lost €4,000 on Jupiter Exchange – and Was Told It Was My Fault,” the author describes how a routine swap turned into a loss of several thousand euros after he unknowingly traded it into a counterfeit version of the token MASK.

The author explains that he took every precaution available. He manually pasted the verified contract address for the legitimate MASK token into Jupiter to ensure the swap targeted the correct asset. Nothing about the interface or flow suggested anything was wrong.

But Jupiter aggregates liquidity from dozens of decentralized exchanges, and during this transaction, its routing engine selected a path that included a malicious liquidity pool that advertised the same MASK ticker. The pool spoofed token metadata closely enough to appear legitimate, masking the fact that the output token was a worthless imitation.

This story serves as a warning: attackers exploiting Solana via middleware like Jupiter can sometimes even catch the most cautious traders off guard.

In this article, we’ll explore how developers can reinforce Jupiter swap flows with Turnkey’s security and policy controls, giving users the benefits of Solana’s liquidity without compromise.

What is Jupiter on Solana

Jupiter is the primary liquidity and routing middleware on the Solana network. It connects dozens of decentralized exchanges (DEXs) and liquidity pools through a single interface that developers can access using its API or SDK. Instead of building separate integrations for each DEX, developers can use Jupiter to discover the best trading routes automatically.

When a swap request is made, Jupiter’s backend routing engine evaluates prices, slippage, and liquidity across available markets like Raydium, Orca, and Meteora. It then constructs a complete Solana transaction that achieves the best available price. Developers or wallet providers receive this transaction unsigned, ready for a user or a secure signing system to approve.

In practical terms, Jupiter acts as the middleware layer between decentralized liquidity and the end-user application. It does not custody assets or settle trades itself; it simply identifies the optimal route and builds a transaction that can be executed on Solana. 

This design makes Jupiter one of the most important pieces of infrastructure in the Solana DeFi ecosystem, powering a majority of the network’s swap volume.

KYD Labs Statement

Why combine Jupiter and Turnkey

Jupiter provides access to Solana’s full spectrum of liquidity. It sources pricing and execution routes from a wide network of decentralized exchanges, enabling best-rate swaps, multi-hop routing, and even advanced order types like limit and DCA orders. 

Developers can use Jupiter’s API to retrieve quotes and build transactions that automatically find the most efficient trading path, without managing integrations for every underlying DEX.

Turnkey, on the other hand, provides the secure execution layer. It uses Trusted Execution Environments (TEEs) to protect private keys inside isolated hardware enclaves and applies a programmable policy to every signing request. 

Developers can define detailed constraints, what programs are allowed, which tokens can be swapped, how much can be spent, and what fees are acceptable, so that even if an attacker tampers with the transaction, Turnkey will reject the signature. 

Turnkey also supports embedded wallets, making it easy to integrate secure signing into any Solana application or front end.

By combining these two platforms, developers can let users interact with Solana’s most efficient liquidity layer while maintaining strict control over what gets signed. Jupiter ensures the swap route is optimal. Turnkey ensures it is authentic, policy-compliant, and verifiable.

This integration reduces exposure to malicious pools, token-spoofing scams, and routing exploits, while also giving teams the tools to enforce their own business logic without compromising user experience.

Turnkey and Jupiter high-level swap flow

Here’s how a Jupiter swap secured with Turnkey works from start to finish.

1. User selects token pair and amount
The user chooses which tokens to swap and how much to trade. No signatures or private keys are used at this stage.

2. App calls Jupiter to get a quote and unsigned transaction
The app requests a quote from Jupiter’s API. Jupiter’s routing engine (Juno) scans liquidity across Solana DEXs, finds the best route, and returns a ready-to-sign, unsigned transaction.

3. Unsigned transaction sent to backend
The app sends this unsigned transaction to your backend, where it can be checked for route accuracy, valid mints, and alignment with user intent.

4. Backend submits transaction to Turnkey for signing
Your backend submits the unsigned transaction to Turnkey’s signing API, applying a Solana policy that defines allowed programs, token mints, max spend, and fee limits.

5. Turnkey parses the Solana transaction
Before applying policy rules, Turnkey parses the unsigned Solana transaction into a structured, human-readable form, decoding each instruction, program ID, and account. This prevents malicious behavior from hiding in raw bytecode or large ALT tables and ensures policies evaluate the transaction’s actual intent.

6. Turnkey enforces the policy and signs
Turnkey validates the transaction against any policies before signing. If it passes, the enclave signs and returns the signature; if not, the request is rejected.

7. Broadcast and confirm on Solana
The signed transaction is broadcast to the Solana network via your RPC. The app tracks confirmation, updates the UI, and logs the signature for records.

Jupiter provides routing and liquidity. Turnkey ensures every transaction is verified, policy-compliant, and safely executed.
See Turnkey’s Solana policy examples for more information.

Policy design for Turnkey in a swap integration

Once your application can generate and forward Jupiter transactions to Turnkey for signing, the next step is defining a Solana policy that enforces safe and predictable behavior. Following are some examples. 

Program allowlist

Start by specifying the core Solana programs your app needs to interact with. This should include Jupiter’s swap program along with the base programs that appear in nearly every transaction (according to your needs):

  • Jupiter swap program

  • System Program

  • ComputeBudget Program

  • SPL Token or Token-2022 Program

  • Associated Token Account Program

Everything else should be blocked. This prevents any unapproved DEX, pool, or malicious program from being added to the route.

Input/output mint allowlist and max amount per token

Specify which tokens users can trade and how much they can send in one transaction. This prevents accidental swaps with unsupported tokens or malicious mints impersonating legitimate assets.

Here’s a sample Turnkey policy fragment that combines some of these ideas into a flexible, enforceable structure:

Swap only Solana policy example

{
  "policyName": "swap_only_policy",
  "effect": "EFFECT_ALLOW",
  "consensus": "approvers.any(user, user.id == '')",
  "condition": " \
    solana.tx.program_keys.all(p, \
      p == 'JUPITER_SWAP_PROGRAM_ID' || \
      p == 'SYSTEM_PROGRAM_ID' || \
      p == 'COMPUTE_BUDGET_PROGRAM_ID' || \
      p == 'SPL_TOKEN_PROGRAM_ID' || \
      p == 'ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID' \
    ) && \
    solana.tx.spl_transfers.all(transfer, \
      transfer.token_mint == 'INPUT_TOKEN_MINT' || \
      transfer.token_mint == 'OUTPUT_TOKEN_MINT' \
    ) && \
    solana.tx.spl_transfers.all(transfer, \
      transfer.token_mint != 'INPUT_TOKEN_MINT' || \
      transfer.amount <=  \
    ) \
}

Turkey’s policies ensure that only programs from the approved list can appear, only specific tokens can be traded, and all resource use stays within defined limits.

Dealing with Jupiter routing variability

Every Jupiter transaction looks slightly different because its routing engine builds each swap dynamically. The engine selects the most efficient path across Solana’s decentralized exchanges, which means the set of instructions inside the transaction can vary from swap to swap.

Because of this variability, it’s impossible to design a Turnkey policy that depends on a fixed instruction sequence. A single route could contain entirely different program calls or account structures than another, even for the same token pair. A strict pattern-based policy would fail on legitimate swaps simply because Jupiter chose a different DEX or multi-hop path.

Instead, Turnkey’s policy engine lets developers focus on invariants, the properties that remain true for all Jupiter swaps or limit orders, regardless of route. Rather than trying to match byte-level instruction data, the goal is to validate the intent of the transaction: that it’s a genuine Jupiter limit order or swap within safe parameters.

For things like Solana limit orders, this means building policies at the program level combined with transfer constraints. Developers can allow Jupiter’s program while restricting how many and what type of token transfers can occur in a single transaction.

These approaches combine program allowlisting with token and transfer constraints, providing flexibility without overfitting to a specific route structure.

This is the essence of Turnkey’s intent-based policy model. It ensures the transaction’s purpose is legitimate, matching the developer’s defined parameters, while remaining flexible enough to account for Jupiter’s dynamic routing. 

Turkey’s policies ensure that only programs from the approved list can appear, only specific tokens can be traded, and all resource use stays within defined limits.

Moonshot Statement

Security, operational, and governance consideration

Building a secure Jupiter integration with Turnkey involves more than just enforcing swap-level policies. It requires thinking holistically about how keys are managed, how routing complexity introduces new risks, and how your system evolves as Solana’s ecosystem changes.

Key custody and signing assurance

Turnkey’s enclave-based architecture provides a strong separation between your users’ private keys and your dApp logic. All signing occurs inside Trusted Execution Environments (TEEs), meaning private material never touches your backend or client code. 

For developers, this custody model eliminates the need to manage key storage or encryption directly. Instead, the security boundary is enforced at the hardware level, and the policy engine ensures that every signature aligns with your application’s intent.

Managing the expanded risk surface

When integrating Jupiter, your dApp interacts with a wide variety of Solana programs and liquidity sources. That flexibility increases the potential risk surface. Misconfigured routing, malicious pools, or hidden compute-heavy instructions can all introduce new vulnerabilities.

A well-designed Turnkey policy helps mitigate these risks by enforcing predictable transaction behavior and further reduces the chance of an attacker exploiting route complexity or inflating transaction costs.

Governance and ongoing maintenance

Policies are not static. As your token list, liquidity sources, or Jupiter’s program IDs evolve, you’ll need a governance process to keep your configuration current. Regularly review and update your mint allowlists, especially when supporting new tokens or removing deprecated ones.

Monitor Jupiter’s documentation and changelogs for any new program IDs or route behaviors that might need to be reflected in your allowlist. Version your policies so that older transactions can still be verified against the correct ruleset.

Finally, establish a clear ownership model within your team for who approves, updates, and audits these policies. Treat policy management as part of your security lifecycle so that your Jupiter integration remains secure, compliant, and aligned with user expectations over time.

Building secure swap experiences on Solana

Integrating Jupiter with Turnkey gives developers the foundation for fast, policy-driven swap flows on Solana. Instead of managing private keys or building your own signing infrastructure, you can rely on Turnkey’s infrastructure to perform all signature operations inside a verifiably isolated environment, while your application handles transaction construction and RPC interactions.

Build your first swap flow today. Deploy a policy, simulate different route scenarios, and audit your logs to see every authorization in action. You’ll end up with a swap experience that’s not only efficient and composable, but provably secure.

Get started with Turnkey. 

Related articles

Turnkey for Agent Identity (ERC-8004, SIW, and empowering trustless AI)

Turnkey is helping to operationalize ERC-8004 by supporting the infrastructure needed for agents to register identities and operate securely across services.

20+ skills and MCP servers bridging AI and blockchain development

Here we highlight twenty plus MCP servers and skills for developers to explore.