solana_kit_mobile_wallet_adapter_protocol 0.2.0 copy "solana_kit_mobile_wallet_adapter_protocol: ^0.2.0" to clipboard
solana_kit_mobile_wallet_adapter_protocol: ^0.2.0 copied to clipboard

Pure Dart implementation of the Solana Mobile Wallet Adapter protocol v2.0. Provides cryptography, message framing, JSON-RPC types, and session management without Flutter dependencies.

solana_kit_mobile_wallet_adapter_protocol #

pub package docs CI coverage

Pure Dart implementation of the Solana Mobile Wallet Adapter v2.0 protocol. Handles P-256 cryptography, session handshakes, encrypted message framing, JSON-RPC request/response encoding, association URI building/parsing, and protocol version negotiation.

This package has zero Flutter dependency and can be used in server-side Dart, CLI tools, or any Dart environment.

Features #

  • P-256 ECDSA/ECDH cryptography via pointycastle (pure Dart, cross-platform)
  • AES-128-GCM encryption with sequence number AAD for replay attack prevention
  • HKDF-SHA256 key derivation with association public key as salt
  • HELLO_REQ / HELLO_RSP handshake for session establishment
  • JSON-RPC 2.0 message encryption/decryption
  • Association URI building and parsing (local + remote)
  • Wallet proxy with v1/legacy backwards compatibility
  • Sign In With Solana (SIWS) message builder following EIP-4361
  • JWS ES256 compact serialization for attestation
  • Central error codes integrated with solana_kit_errors

Installation #

dart pub add solana_kit_mobile_wallet_adapter_protocol

If you're working inside the solana_kit monorepo, workspace resolution uses local packages automatically.

Documentation #

Usage #

Association keypair generation #

import 'package:solana_kit_mobile_wallet_adapter_protocol/solana_kit_mobile_wallet_adapter_protocol.dart';

// Generate keypairs for a new session.
final associationKeypair = generateAssociationKeypair();
final ecdhKeypair = generateEcdhKeypair();

// Get the association token (base64url-encoded public key).
final token = getAssociationToken(associationKeypair);

Building association URIs #

// Local association (same-device).
final uri = buildLocalAssociationUri(
  associationKeypair.publicKey,
  55123,
);
// -> solana-wallet:/v1/associate/local?association=...&port=55123

// Remote association (via reflector).
final remoteUri = buildRemoteAssociationUri(
  associationKeypair.publicKey,
  'reflect.example.com',
  reflectorId,
);

HELLO handshake #

// Create HELLO_REQ (129 bytes: 65B ECDH pubkey + 64B ECDSA signature).
final helloReq = createHelloReq(ecdhKeypair, associationKeypair);

// Parse HELLO_RSP from the wallet.
final result = parseHelloRsp(helloRspBytes, associationKeypair, ecdhKeypair);
final sharedSecret = result.sharedSecret; // 16-byte AES key

Encrypted messaging #

// Encrypt a JSON-RPC request.
final encrypted = encryptJsonRpcRequest(
  1, // sequence number
  'authorize',
  {'chain': 'solana:mainnet'},
  sharedSecret,
);

// Decrypt a JSON-RPC response.
final response = decryptJsonRpcResponse(encryptedBytes, sharedSecret);

Wallet proxy #

// Create a wallet proxy that handles v1/legacy compatibility.
final wallet = createMobileWalletProxy(sendRequest, sessionProps);

final authResult = await wallet.authorize({
  'identity': {'name': 'My dApp'},
  'chain': 'solana:mainnet',
});

Protocol details #

Wire format #

Each encrypted message follows this binary format:

[4B sequence number (big-endian)] [12B random IV] [ciphertext + 16B GCM tag]

The 4-byte sequence number is also used as AAD (Additional Authenticated Data) for AES-GCM, preventing replay attacks.

Handshake flow #

  1. dApp generates association keypair (P-256 ECDSA) and ECDH keypair (P-256)
  2. dApp sends HELLO_REQ: [65B ECDH pubkey][64B ECDSA signature]
  3. Wallet sends HELLO_RSP: [65B wallet ECDH pubkey][optional encrypted session props]
  4. Both sides derive shared secret via ECDH + HKDF-SHA256 -> 16-byte AES key
  5. All subsequent messages use AES-128-GCM with incrementing sequence numbers

Protocol versions #

  • v1: Uses chain identifiers (solana:mainnet, solana:devnet, solana:testnet), feature arrays, and separate reauthorize method
  • legacy: Uses cluster names (mainnet-beta, devnet, testnet), boolean feature flags (supports_sign_and_send_transactions), and authorize with auth_token for reauthorization

Example #

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

  • Import path: package:solana_kit_mobile_wallet_adapter_protocol/solana_kit_mobile_wallet_adapter_protocol.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.
0
likes
150
points
65
downloads

Publisher

unverified uploader

Weekly Downloads

Pure Dart implementation of the Solana Mobile Wallet Adapter protocol v2.0. Provides cryptography, message framing, JSON-RPC types, and session management without Flutter dependencies.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

pointycastle, solana_kit_codecs_strings, solana_kit_errors

More

Packages that depend on solana_kit_mobile_wallet_adapter_protocol