Solana-Native
Compat. No paid assumptions.
Unified SDK for the fragmented Solana mobile client layer: solana-kmp, Sol4k, mobile-wallet-adapter-clientlib-ktx, seedvault-wallet-sdk, and Metaplex KMM. MWA and Seed Vault remain the underlying Solana Mobile primitives.
Unified. Modern. Coroutine-first.
One SDK for the fragmented Kotlin/Android Solana client layer. Source-compatible migration modules preserve existing imports, plus a first-class Artemis-native surface for new code.
Unified Kotlin SDK
Consolidates solana-kmp, Sol4k, mobile-wallet-adapter-clientlib-ktx, seedvault-wallet-sdk, and Metaplex KMM client code into one modern SDK. Source-compatible shims keep existing imports working.
MWA 2.0 & Seed Vault
Android Mobile Wallet Adapter 2.0 dApp client with P-256 association, AES-128-GCM session cipher, HKDF-SHA256, and Sign-In With Solana. Seed Vault stays the device custody boundary; Artemis provides the client integration.
Token-2022 & cNFTs
Token-2022 tooling with TLV decoding for supported extensions, plus Bubblegum compressed-NFT transfers, marketplace preflight, and failover DAS routing (Helius primary, RPC fallback).
Versioned Transactions
v0 versioned transaction support with Address Lookup Tables, priority fees, durable nonce, dynamic compute-budget planning, and a TxEngine pipeline with blockhash cache and retries.
React Native Bridge
React Native bindings expose the shared TypeScript surface while keeping Solana Mobile primitives Android-only: MWA and Seed Vault run on Android, with iOS routed through explicit fallback hooks.
Reliability layer
WS auto-reconnect with deterministic resubscribe, circuit-breaker RPC endpoint pool, per-transaction batch results, priority-fee oracle, and a framework event bus.
Migrating Solana Mobile client code?
Keep MWA and Seed Vault as the underlying primitives. Swap Maven coordinates to the Artemis compat artifacts underinterop/artemis-*-compatand keep your existing imports. See the migration guide.
Unified client layer for Solana Mobile apps
Artemis consolidates fragmented client SDK code while staying compatible with MWA and Seed Vault. It keeps upstream Java/Kotlin import names working through dedicatedinterop/artemis-*-compatmodules while exposing a first-class native surface for new code. Fewer dependencies, per-transaction batch results, real reconnect logic, and CI-enforced coverage.
Before: Current Stack
// Current Solana Mobile approach (3+ dependencies)
implementation("com.solanamobile:mobile-wallet-adapter-clientlib-ktx:2.1.0")
implementation("com.solanamobile:seedvault-wallet-sdk:0.4.0")
implementation("foundation.metaplex:solana-kmp:0.3.0")
// Imports scattered across packages
import com.solana.publickey.SolanaPublicKey
import com.solana.rpc.SolanaRpcClient
import com.solana.networking.KtorNetworkDriver
import com.solana.mobilewalletadapter.clientlib.*After: Artemis
// Artemis-native: two dependencies, more features
implementation("xyz.selenus:artemis-core:2.3.1")
implementation("xyz.selenus:artemis-wallet-mwa-android:2.3.1")
// Unified imports on the com.selenus.artemis namespace
import com.selenus.artemis.runtime.Pubkey
import com.selenus.artemis.rpc.JsonRpcClient
import com.selenus.artemis.rpc.RpcApi
import com.selenus.artemis.wallet.mwa.MwaWalletAdapter
// HTTP client + blockhash cache + retries are built in.Import Mapping (Zero Code Changes)
Modular by design
Pick only what you need. Modules are optional and tested, with strict ring dependencies enforced by CI.
// Add to build.gradle.kts
implementation("xyz.selenus:artemis-core:2.3.1")
Foundation
artemis-core2.3.1Pubkey, Keypair, Base58, PDA derivation, Ed25519, SHA-256, event bus
artemis-rpc2.3.180+ JSON-RPC methods, typed results, batch DSL, blockhash cache, endpoint pool, circuit breaker
artemis-ws2.3.1WebSocket subscriptions with reconnect, deterministic resubscribe, polling fallback
artemis-tx2.3.1Legacy transaction construction, serialization, signing, durable nonce
artemis-vtx2.3.1v0 versioned transactions, ALT, TxEngine pipeline, priority fees
artemis-programs2.3.1System, Token, ATA, Compute Budget, Stake instruction builders
artemis-compute2.3.1Compute unit estimation and priority fee helpers
artemis-errors2.3.1Structured Solana error types and on-chain error decoding
artemis-logging2.3.1Structured SDK logging
Mobile
artemis-wallet2.3.1WalletAdapter, WalletSession, WalletSessionManager with lifecycle callbacks
artemis-wallet-mwa-android2.3.1Native MWA 2.0 client. P-256 association, AES-128-GCM, HKDF-SHA256, SIWS, ArtemisMobile.create()
artemis-seed-vault2.3.1Saga Seed Vault integration with contract/provider split and deterministic binder-death handling
Ecosystem
artemis-token20222.3.1Token-2022 mint and account extensions with TLV decoding
artemis-metaplex2.3.1Token Metadata: metadata account, master edition, collection
artemis-mplcore2.3.1MPL Core asset program flows and plugins
artemis-cnft2.3.1Bubblegum compressed NFTs, ArtemisDas, HeliusDas, RpcFallbackDas, CompositeDas, MarketplaceEngine
artemis-candy-machine2.3.1Candy Machine v3 mintV2 builder and guard planner
artemis-solana-pay2.3.1Solana Pay URL parsing and SolanaPayManager
artemis-anchor2.3.1Anchor IDL parsing, Borsh serializer, typed AnchorProgram client
artemis-jupiter2.3.1JupiterClient quote and swap route building
artemis-actions2.3.1Solana Actions and Blinks fetch and execute
Advanced
artemis-privacy2.3.1StealthAddress, EncryptedMemo, ConfidentialTransfer, Light Protocol, Shamir
artemis-portfolio2.3.1Portfolio fetcher, snapshot, balance providers
artemis-offline2.3.1Offline transaction queue, persistent store, durable-nonce retry
artemis-gaming2.3.1Session keys, VRF wrappers, priority-fee oracle, state proof helpers
artemis-intent2.3.1Per-program intent decoders
artemis-streaming2.3.1ZeroCopyAccountStream with a pluggable WebSocketClient
artemis-simulation2.3.1PredictiveSimulator with a caller-provided RpcAdapter
artemis-batch2.3.1Transaction batching engine that groups instructions into compute-budget-optimized txs
artemis-scheduler2.3.1Predictive submission scheduler driven by block production and fee pressure
artemis-replay2.3.1Transaction replay primitives
artemis-depin2.3.1Device attestation primitives
artemis-nlp2.3.1Token and instruction entity resolver
artemis-universal2.3.1IDL-less program discovery
artemis-preview2.3.1Transaction preview rendering
Compat
artemis-discriminators2.3.1Anchor program discriminator utilities
artemis-nft-compat2.3.1Cross-standard NFT compatibility helpers
artemis-tx-presets2.3.1Pre-built transaction patterns
artemis-candy-machine-presets2.3.1Pre-built Candy Machine configurations
artemis-presets2.3.1High-level SDK presets and configuration
Interop
artemis-mwa-compat2.3.1Source-compatible MWA clientlib-ktx migration shim
artemis-mwa-clientlib-compat2.3.1Source-compatible MWA clientlib migration shim
artemis-mwa-common-compat2.3.1Source-compatible MWA common protocol types
artemis-seedvault-compat2.3.1Source-compatible Seed Vault client-library shim
artemis-sol4k-compat2.3.1Source-compatible shim for org.sol4k
artemis-solana-kmp-compat2.3.1Source-compatible shim for foundation.metaplex.solana-kmp
artemis-metaplex-android-compat2.3.1Source-compatible shim for Metaplex Android SDK
artemis-rpc-core-compat2.3.1Source-compatible RPC core types from the Funkatronics family
artemis-web3-solana-compat2.3.1Kotlin-side shim for @solana/web3.js call shapes
Code that makes sense
Every snippet below targets the real Artemis 2.3.1 modules. Small surface, explicit boundaries, coroutine-first APIs.
import com.selenus.artemis.wallet.mwa.ArtemisMobile
val artemis = ArtemisMobile.create(
activity = this,
identityUri = Uri.parse("https://myapp.example.com"),
iconPath = "https://myapp.example.com/favicon.ico",
identityName = "My App",
rpcUrl = "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY",
wsUrl = "wss://atlas-mainnet.helius-rpc.com/?api-key=YOUR_KEY",
dasUrl = "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY"
)
// Every wallet op goes through the session manager. It connects
// lazily, caches the auth token, retries on session expiration,
// and fires lifecycle events.
val sig = artemis.sessionManager.withWallet { session ->
session.sendSol(recipient, 1_000_000_000L)
}