Shield Transaction Policies

Yellowstone Shield

Learn more about Shield in our blog post introducing it: Introducing Yellowstone Shield 🚫🛡️

Overview

Yellowstone Shield is a project that provides ways for managing transaction deliveries - allowing the user to allow or deny specific validators for downstream forwarding.

It's currently integrated with Yellowstone Jet and if you're using Cascade to send, you already have support for it in your infrastructure for sending transactions.

Important: Shield policies are only enforced by RPC providers that have integrated Yellowstone Shield support (such as Triton RPC). Standard Solana RPC nodes will not enforce these policies.

Quick Start

At its simplest, you'd need to provide either a HTTP header or an additional parameter to your sendTransaction calls when using a Shield-enabled RPC endpoint.

RPC Method Parameter

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "sendTransaction",
  "params": [
    "<base64_encoded_transaction>",
    {
      "encoding": "base64",
      "skipPreflight": true,
      "forwardingPolicies": ["<your_policy_pda>"]
    }
  ]
}

HTTP Header

Solana-ForwardingPolicies: "<your_policy_pda>,<your_policy_pda2>"

Integration with Other Infrastructure

If you're using another transaction sending software or infrastructure, Shield provides a ready set of APIs for anyone to integrate with to apply shield policies before sending transactions out to leaders on the Solana network.

On-Chain Policies

Shield policies live on chain, so they are always accessible to everybody and do not depend on a central agency to maintain and update.

Policy Explorer Web Interface

Shield policies can be explored through the Validators.app web interface at validators.app/yellowstone-shield.

CLI Tools

There is tooling available to create and maintain Shield policies here: yellowstone-shield/cli

Installation

git clone https://github.com/rpcpool/yellowstone-shield
cd yellowstone-shield
cargo build --release --bin yellowstone-shield-cli

Creating a Policy

Before creating a policy, prepare a metadata JSON file with this format:

{
  "name": "Your Policy Name",
  "symbol": "SYMBOL",
  "description": "A description of your Shield policy",
  "image": "https://your-image-url.com/image.png",
  "external_url": "https://your-website.com",
  "attributes": []
}

Upload this metadata to a publicly accessible URI (e.g., IPFS, Arweave), then create the policy:

# Create an allowlist policy
yellowstone-shield-cli policy create \
  --strategy allow \
  --name "Your Policy Name" \
  --symbol "SYMBOL" \
  --uri "https://your-metadata-uri.json"

# Create a blocklist policy  
yellowstone-shield-cli policy create \
  --strategy deny \
  --name "Your Policy Name" \
  --symbol "SYMBOL" \
  --uri "https://your-metadata-uri.json"

Managing Identities

Create a text file with validator pubkeys (one per line), then use these commands:

# Add validators to a policy
yellowstone-shield-cli identities add \
  --mint <mint_address> \
  --identities-path validators.txt

# Update/replace all validators in a policy
yellowstone-shield-cli identities update \
  --mint <mint_address> \
  --identities-path validators.txt

# Remove specific validators from a policy
yellowstone-shield-cli identities remove \
  --mint <mint_address> \
  --identities-path validators_to_remove.txt

View Policy Details

yellowstone-shield-cli policy show --mint <mint_address>

Delete a Policy

yellowstone-shield-cli policy delete --mint <mint_address>

Note: The CLI uses your Solana CLI configuration for RPC endpoint and keypair. You can override these with --rpc and --keypair flags.

Example Implementation

The Ping Thing client demonstrates how to use Shield policies in production. The client cycles through different Shield policies to test transaction routing and validator behavior.

Key implementation details from Ping Thing:

  • Uses the forwardingPolicies parameter in sendTransaction calls

  • Logs which validator (slot leader) processed each transaction

  • Helps verify that Shield policies are working correctly

View the implementation: ping-thing-client-custom-sendTx-shield.ts

SDK Integration

TypeScript/JavaScript

The standard @solana/web3.js library does not natively support Shield policies. To use Shield, you need to make direct JSON-RPC calls to an RPC endpoint that supports forwarding policies (like Triton RPC with Yellowstone Jet).

Direct JSON-RPC Method:

// Prepare your transaction as usual
import { Transaction } from '@solana/web3.js';
import bs58 from 'bs58';

const transaction = new Transaction().add(/* your instructions */);
// Sign the transaction
const signedTx = await wallet.signTransaction(transaction);
const serializedTx = bs58.encode(signedTx.serialize());

// Send with Shield policies using direct RPC call
const response = await fetch('https://your-rpc-endpoint.com', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'sendTransaction',
    params: [
      serializedTx,
      {
        encoding: 'base58',
        skipPreflight: true,
        forwardingPolicies: ['<your_policy_pda>']
      }
    ]
  })
});

const result = await response.json();
const signature = result.result;

Using HTTP Headers:

// Alternative: Use HTTP headers for legacy compatibility
const response = await fetch('https://your-rpc-endpoint.com', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Solana-ForwardingPolicies': '<policy_pda_1>,<policy_pda_2>'
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'sendTransaction',
    params: [serializedTx, { encoding: 'base58', skipPreflight: true }]
  })
});

Note: Shield policies are only enforced by RPC providers that have integrated Yellowstone Shield (like Triton RPC). Standard Solana RPC nodes will ignore the forwardingPolicies parameter.

Available Policy Types

The Shield ecosystem includes various community-maintained policies. Common types include:

Allow Lists

  • Top validators by stake - Include only the largest, most established validators

  • Geographic distribution - Include validators from specific regions

  • Performance-based - Include validators meeting certain performance criteria

Deny Lists (Blocklists)

  • MEV protection - Exclude validators known for sandwich attacks or other MEV extraction

  • Poor performance - Exclude validators with high skip rates or slow block production

  • Community-curated - Exclude validators flagged by various protocols and communities

To find current policies and their pubkeys, visit the Policy Explorer where you can browse all available policies and copy their addresses for use in your transactions.

How It Works

Shield policies work by:

  1. Policy Creation - Users create on-chain policies specifying allowed or denied validators

  2. Transaction Submission - When sending a transaction, include the policy PDA(s) you want to enforce

  3. Leader Validation - The RPC checks the current leader against your policy

  4. Smart Routing - If the current leader doesn't meet criteria, the transaction is either:

    • Skipped - Not sent to the current leader

    • Dropped - Rejected if no eligible leaders are available

    • Forwarded - Sent to the next eligible leader in the schedule

Important: Shield does not hold or queue transactions. If the current leader is not on your allowlist or is on your blocklist, the transaction won't be sent to that validator. The system will either wait for an eligible leader or drop the transaction based on the implementation.

This ensures your transactions are only processed by validators you trust, providing protection against MEV and other validator-level exploits.

Resources

Last updated

Was this helpful?