solana_kit_rpc_transport_http

pub package docs website CI coverage

HTTP transport for sending JSON-RPC requests to Solana nodes. Ships two factory functions: createHttpTransport for generic JSON-RPC over HTTP, and createHttpTransportForSolanaRpc for Solana-specific BigInt-aware JSON handling. Most apps use createSolanaRpc from solana_kit_rpc instead of calling these directly.

Installation

Install the package directly:

dependencies:
  "solana_kit_rpc_transport_http": ^0.9.3

If your app uses several Solana Kit packages together, you can also depend on the umbrella package instead:

dart pub add solana_kit

Inside this monorepo, Dart workspace resolution uses the local package automatically.

Documentation

For architecture notes, getting-started guides, and cross-package examples, start with the workspace docs site and then drill down into the package README and API reference.

Usage

Generic HTTP transport

createHttpTransport creates a generic JSON-RPC transport that sends POST requests with JSON payloads.

import 'package:solana_kit_rpc_spec/solana_kit_rpc_spec.dart';
import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

Future<void> main() async {
  final transport = createHttpTransport(
    HttpTransportConfig(url: 'https://api.mainnet-beta.solana.com'),
  );

  final response = await transport(
    RpcTransportConfig(
      payload: {
        'id': '1',
        'jsonrpc': '2.0',
        'method': 'getSlot',
        'params': <Object?>[],
      },
    ),
  );
  print(response);
}

Cancelling requests

Pass a Future<void> as RpcTransportConfig.signal and complete it to abort an in-flight request, including a response body that has stopped streaming. The default HTTP client throws http.RequestAbortedException. Custom clients must support http.AbortableRequest for cancellation to work. Cancelling a request does not undo a transaction the RPC node has already received.

Redirect handling

Redirect responses are returned as rpcTransportHttpError without contacting the redirect destination. This keeps custom authentication headers at the configured endpoint and prevents redirects from bypassing its HTTPS policy. Configure the final RPC URL directly. Connection, cancellation, and response-stream HTTP exceptions omit the endpoint URI and original message because both can contain API keys or other credentials. Cancellation retains its http.RequestAbortedException type.

Custom headers

Pass custom headers through HttpTransportConfig. The accept, content-length, and content-type headers are set automatically and cannot be overridden. Forbidden headers (per the MDN specification) are rejected.

import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  final transport = createHttpTransport(
    HttpTransportConfig(
      url: 'https://api.mainnet-beta.solana.com',
      headers: {
        'x-api-key': 'my-secret-key',
        'authorization': 'Bearer my-token',
      },
    ),
  );
  print(transport);
}

Custom JSON serialization

Provide toJson and fromJson functions to control how payloads are serialized and responses are deserialized.

import 'dart:convert';
import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  final transport = createHttpTransport(
    HttpTransportConfig(
      url: 'https://api.mainnet-beta.solana.com',
      toJson: (payload) => jsonEncode(payload),
      fromJson: (rawResponse, payload) => jsonDecode(rawResponse),
    ),
  );
  print(transport);
}

Solana-specific HTTP transport

createHttpTransportForSolanaRpc creates a transport with BigInt-aware JSON handling. It uses parseJsonWithBigInts and stringifyJsonWithBigInts for Solana RPC requests and standard jsonEncode/jsonDecode for other requests.

import 'package:solana_kit_rpc_spec/solana_kit_rpc_spec.dart';
import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

Future<void> main() async {
  final transport = createHttpTransportForSolanaRpc(
    url: 'https://api.mainnet-beta.solana.com',
  );

  final response = await transport(
    RpcTransportConfig(
      payload: {
        'id': '1',
        'jsonrpc': '2.0',
        'method': 'getBalance',
        'params': ['83astBRguLMdt2h5U1Tbd4hU5SkfAWRkzG2HPM88BREAK'],
      },
    ),
  );
  // Response has BigInt values for large integers.
  final result = response as Map<String, Object?>;
  final value = result['result'] as Map<String, Object?>;
  print(value['value'] is BigInt); // true
}

Pass custom headers and an http.Client for testing:

import 'package:http/http.dart' as http;
import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  final transport = createHttpTransportForSolanaRpc(
    url: 'https://api.devnet.solana.com',
    headers: {'x-api-key': 'my-key'},
    client: http.Client(),
  );
  print(transport);
}

Checking for Solana requests

isSolanaRequest checks whether a payload is a JSON-RPC 2.0 request for a known Solana RPC method. The transport uses this internally to decide whether to apply BigInt-aware JSON handling.

import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  final payload = {
    'jsonrpc': '2.0',
    'method': 'getBalance',
    'params': ['address123'],
    'id': '1',
  };
  print(isSolanaRequest(payload)); // true

  final nonSolana = {
    'jsonrpc': '2.0',
    'method': 'custom_method',
    'params': <Object?>[],
    'id': '1',
  };
  print(isSolanaRequest(nonSolana)); // false
}

Header validation

assertIsAllowedHttpRequestHeaders validates that no forbidden or protocol-reserved headers are included. It is called automatically in every build mode by createHttpTransport.

import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  // These are fine.
  assertIsAllowedHttpRequestHeaders({
    'x-api-key': 'my-key',
    'authorization': 'Bearer token',
  });

  // These throw (forbidden/disallowed headers).
  // assertIsAllowedHttpRequestHeaders({'content-type': 'text/plain'}); // throws
  // assertIsAllowedHttpRequestHeaders({'host': 'example.com'}); // throws
}

Optional Isolate JSON Decoding

For large Solana RPC payloads, you can offload BigInt-aware JSON parsing to a background isolate so the main isolate stays responsive.

import 'package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart';

void main() {
  final transport = createHttpTransportForSolanaRpc(
    url: 'https://api.mainnet-beta.solana.com',
    decodeSolanaJsonInIsolate: true,
    solanaJsonIsolateThreshold: 262144,
  );

  print(transport);
}

For direct parsing, use parseJsonWithBigIntsAsync(...) with runInIsolate: true. Reserve isolate parsing for larger payloads where the extra hop is worth the reduced UI or server-request blocking.

Key APIs

  • createHttpTransport(HttpTransportConfig, {http.Client?}): creates a generic RpcTransport that sends JSON-RPC requests over HTTP POST.
  • createHttpTransportForSolanaRpc({required String url, ...}): creates an RpcTransport with BigInt-aware JSON serialization for Solana RPC.
  • isSolanaRequest(Object?): returns true if the payload is a JSON-RPC 2.0 request for a known Solana method.
  • assertIsAllowedHttpRequestHeaders(Map<String, String>): throws if any forbidden or protocol-reserved headers are present.
  • normalizeHeaders(Map<String, String>): lowercases all header names.
  • HttpTransportConfig: url, headers, toJson, fromJson.

Example

Use example/main.dart as a runnable starting point for solana_kit_rpc_transport_http.

  • Import path: package:solana_kit_rpc_transport_http/solana_kit_rpc_transport_http.dart
  • This section is centrally maintained with mdt to keep package guidance aligned.
  • After updating shared docs templates, run docs:update from the repo root.

Maintenance

  • Validate docs in CI and locally with docs:check.
  • Keep examples focused on one workflow and reference package README sections for deeper API details.

Libraries

solana_kit_rpc_transport_http
HTTP transports for the Solana Kit Dart SDK.