> ## Documentation Index
> Fetch the complete documentation index at: https://www.solanagun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QUIC (Recommended)

> Send Solana transactions with the [Solana Gun Rust client](https://github.com/allnodes/solana-gun-quic-client), which handles connection setup and authentication.

export const EndpointsTable = ({protocol} = {}) => {
  const [copied, setCopied] = useState(null);
  const regions = [{
    name: "Frankfurt, Germany",
    code: "FRA1",
    host: "fra1.solanagun.com"
  }, {
    name: "Frankfurt, Germany",
    code: "FRA2",
    host: "fra2.solanagun.com"
  }, {
    name: "Frankfurt, Germany",
    code: "FRA3",
    host: "fra3.solanagun.com"
  }, {
    name: "Amsterdam, Netherlands",
    code: "AMS1",
    host: "ams1.solanagun.com"
  }, {
    name: "London, UK",
    code: "LON1",
    host: "lon1.solanagun.com"
  }, {
    name: "New York, USA",
    code: "NYC1",
    host: "nyc1.solanagun.com"
  }, {
    name: "Ashburn, USA",
    code: "ASH1",
    host: "ash1.solanagun.com"
  }, {
    name: "Tokyo, Japan",
    code: "TYO1",
    host: "tyo1.solanagun.com"
  }];
  const allProtocols = [{
    name: "RPC",
    url: host => `https://${host}:8875`
  }, {
    name: "WebSocket",
    url: host => `wss://${host}:8875`
  }, {
    name: "QUIC",
    url: host => `${host}:7000`
  }];
  const protocols = protocol ? allProtocols.filter(p => p.name === protocol) : allProtocols;
  const showProtocol = protocols.length > 1;
  const copy = value => {
    navigator.clipboard.writeText(value).then(() => {
      setCopied(value);
      setTimeout(() => setCopied(current => current === value ? null : current), 1500);
    });
  };
  const cell = "px-4 py-2 border-b border-white/10 align-middle";
  return <div className="not-prose my-6 overflow-x-auto rounded-xl border border-white/10" style={{
    backgroundColor: "#131313"
  }}>
      <table className="w-full text-sm text-left" style={{
    borderCollapse: "collapse"
  }}>
        <thead>
          <tr className="text-white/70">
            <th className={`${cell} font-semibold`}>Location</th>
            {showProtocol && <th className={`${cell} font-semibold`}>Protocol</th>}
            <th className={`${cell} font-semibold`}>Endpoint</th>
          </tr>
        </thead>
        <tbody className="text-white/90">
          {regions.map(region => protocols.map((proto, i) => {
    const value = proto.url(region.host);
    const isCopied = copied === value;
    return <tr key={value}>
                  {i === 0 && <td rowSpan={protocols.length} className={cell} style={{
      whiteSpace: "nowrap"
    }}>
                      <div className="font-medium">{region.name}</div>
                      <div className="text-xs text-white/50">{region.code}</div>
                    </td>}
                  {showProtocol && <td className={cell} style={{
      whiteSpace: "nowrap"
    }}>{proto.name}</td>}
                  <td className={cell}>
                    <div style={{
      display: "flex",
      alignItems: "center",
      gap: "12px"
    }}>
                      <span className="font-mono text-sm text-white" style={{
      whiteSpace: "nowrap"
    }}>{value}</span>
                      <span style={{
      position: "relative",
      display: "inline-flex",
      flexShrink: 0
    }}>
                        <button type="button" onClick={() => copy(value)} title="Copy" aria-label={`Copy ${value}`} className="pn-copy-button">
                          {isCopied ? <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                              <path d="M20 6 9 17l-5-5" />
                            </svg> : <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                              <rect width="14" height="14" x="8" y="8" rx="2" ry="2" />
                              <path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" />
                            </svg>}
                        </button>
                        {isCopied && <span role="status" className="rounded-md bg-white px-2 py-1 text-xs font-medium text-black shadow" style={{
      position: "absolute",
      bottom: "calc(100% + 6px)",
      left: "50%",
      transform: "translateX(-50%)",
      whiteSpace: "nowrap",
      pointerEvents: "none"
    }}>
                            Copied!
                          </span>}
                      </span>
                    </div>
                  </td>
                </tr>;
  }))}
        </tbody>
      </table>
    </div>;
};

## Before you begin

* Use your Solana Gun endpoint ([see below](#endpoints)). Replace the placeholders with your connection details.
* Have a funded Solana wallet and its local keypair JSON file. The example sends 0.0021 SOL (2,100,000 lamports) to an existing wallet, plus the network fee.
* Use a regular Solana RPC to fetch a recent blockhash. The example uses `https://solana-rpc.publicnode.com`.

<Warning>
  Your network must allow outbound UDP to the QUIC port.
</Warning>

## Endpoints

Choose a host close to your application and copy the endpoint.

<EndpointsTable protocol="QUIC" />

## Send a transaction

<Steps>
  <Step title="Create a Rust project">
    ```bash theme={"system"}
    cargo new solana-gun-quic-example
    cd solana-gun-quic-example
    ```
  </Step>

  <Step title="Add dependencies">
    Replace the `[dependencies]` section in `Cargo.toml` with:

    ```toml Cargo.toml theme={"system"}
    [dependencies]
    anyhow = "1"
    solana-client = "=2.3.13"
    solana-sdk = "=2.3.1"
    tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
    bincode = "1"
    solana-gun-quic-client = { git = "https://github.com/allnodes/solana-gun-quic-client", tag = "v1.0.0" }
    ```
  </Step>

  <Step title="Write the code">
    Save the code as `src/main.rs` and replace the hostname, port, token, keypair path, and recipient address:

    ```rust src/main.rs theme={"system"}
    use solana_client::nonblocking::rpc_client::RpcClient;
    use solana_gun_quic_client::{ClientConfig, SolanaGunQuicClient};
    use solana_sdk::{
        commitment_config::CommitmentConfig,
        pubkey::Pubkey,
        signature::{read_keypair_file, Signer},
        system_instruction,
        transaction::{Transaction, VersionedTransaction},
    };
    use std::time::Duration;

    const KEYPAIR_PATH: &str = "/path/to/keypair.json";
    const RPC_URL: &str = "https://solana-rpc.publicnode.com";
    const GUN_HOST_PORT: &str = "fra1.solanagun.com:7000";
    const GUN_TOKEN: &str = "<TOKEN>";
    const RECIPIENT_ADDRESS: &str = "<RECIPIENT_ADDRESS>";
    const AMOUNT_LAMPORTS: u64 = 1_000_000;

    #[tokio::main]
    async fn main() -> anyhow::Result<()> {
        let payer = read_keypair_file(KEYPAIR_PATH)
            .map_err(|error| anyhow::anyhow!(error.to_string()))?;
        let recipient: Pubkey = RECIPIENT_ADDRESS.parse()?;

        let rpc = RpcClient::new_with_timeout(
            RPC_URL.to_string(),
            Duration::from_secs(30),
        );
        let (blockhash, _) = rpc
            .get_latest_blockhash_with_commitment(CommitmentConfig::confirmed())
            .await?;

        let instruction =
            system_instruction::transfer(&payer.pubkey(), &recipient, AMOUNT_LAMPORTS);
        let transaction = VersionedTransaction::from(Transaction::new_signed_with_payer(
            &[instruction],
            Some(&payer.pubkey()),
            &[&payer],
            blockhash,
        ));

        let gun = SolanaGunQuicClient::connect(
            GUN_HOST_PORT,
            GUN_TOKEN,
            ClientConfig::default(),
        )
        .await?;

        gun.send_transaction_bytes(&bincode::serialize(&transaction)?)
            .await?;

        println!("Sent. Transaction signature: {}", transaction.signatures[0]);

        gun.close().await;
        Ok(())
    }
    ```
  </Step>

  <Step title="Run">
    ```bash theme={"system"}
    cargo run --release
    ```
  </Step>
</Steps>

## Submission response

The example prints the signature from your signed transaction. A successful send means the client wrote the transaction bytes.

<Note>
  It does not guarantee server acceptance or confirmation on Solana.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.