jupiter 1.0.1
jupiter: ^1.0.1 copied to clipboard
A robust, type-safe Dart SDK for interacting with the Jupiter Ultra API. Supports Solana transaction signing, order routing, execution, balances, and token shield info.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:jupiter/jupiter.dart';
import 'package:jupiter/ultra_order_request_model.dart';
import 'package:logger/logger.dart';
/// Jupiter Dart SDK Flutter Example App
///
/// This app demonstrates how to use the Jupiter Dart SDK for:
/// - Order and Execute
/// - Fetching Balances
/// - Using the Shield API
///
/// Setup:
/// 1. Set the PRIVATE_KEY environment variable to a valid Solana keypair (base58 encoded)
/// 2. (Optional) Set the JUP_API_KEY environment variable for authenticated endpoints
/// 3. Run: flutter run -d <device> example/jupiter_sdk_example.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: ".env");
runApp(const JupiterSdkExampleApp());
}
class JupiterSdkExampleApp extends StatelessWidget {
const JupiterSdkExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Jupiter Dart SDK Example',
theme: ThemeData(primarySwatch: Colors.indigo),
home: const JupiterExampleHome(),
);
}
}
class JupiterExampleHome extends StatefulWidget {
const JupiterExampleHome({super.key});
@override
State<JupiterExampleHome> createState() => _JupiterExampleHomeState();
}
class _JupiterExampleHomeState extends State<JupiterExampleHome> {
late final String? apiKey;
late final String privateKey;
late final UltraApiClient client;
late final Logger logger;
String? publicKey;
String output = '';
bool loading = false;
@override
Future<void> initState() async {
super.initState();
logger = Logger();
apiKey = dotenv.env['JUP_API_KEY'];
privateKey = dotenv.env['PRIVATE_KEY'] ?? '';
client = UltraApiClient(
apiKey: apiKey,
privateKeyEnvVar: 'PRIVATE_KEY',
privateKeyValue: privateKey,
);
try {
publicKey = await client.getPublicKey();
logger.i('Public key loaded: $publicKey');
} catch (e, st) {
output = 'Error: $e';
logger.e('Error loading public key', error: e, stackTrace: st);
}
}
Future<void> runOrderAndExecute() async {
setState(() {
loading = true;
output = 'Running order and execute...';
});
logger.i('Starting order and execute');
try {
final taker = publicKey;
final request = UltraOrderRequest(
inputMint: 'So11111111111111111111111111111111111111112',
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: 1000000,
taker: taker,
);
logger.d(
'Order request fields: inputMint=${request.inputMint}, outputMint=${request.outputMint}, amount=${request.amount}, taker=${request.taker}',
);
final result = await client.orderAndExecute(request);
logger.i('Order and execute result: $result');
setState(() {
output = 'Order and Execute Result:\n';
output += 'Status: [1m${result['status']}[0m\n';
if (result['status'] == 'Failed') {
output +=
'Code: [31m${result['code']}[0m\nError: ${result['error']}\n';
}
final signature = result['signature']?.toString();
if (signature != null) {
output += 'Signature: $signature\n';
output += 'Solscan: https://solscan.io/tx/$signature\n';
}
});
} catch (e, st) {
setState(() {
output = 'Error: $e\n\nStackTrace:\n$st';
});
logger.e('Order and execute failed', error: e, stackTrace: st);
} finally {
setState(() {
loading = false;
});
}
}
Future<void> runBalances() async {
setState(() {
loading = true;
output = 'Fetching balances...';
});
logger.i('Fetching balances for $publicKey');
try {
final pubkey = publicKey;
final result = await client.balances(pubkey!);
logger.i('Balances result: $result');
if (result.containsKey('balances')) {
final balances = result['balances'] as Map<String, dynamic>;
if (balances.isEmpty) {
setState(() {
output = 'No balances found.';
});
} else {
final buf = StringBuffer('Balances:\n');
balances.forEach((mint, balance) {
buf.writeln(' $mint: $balance');
});
setState(() {
output = buf.toString();
});
}
} else {
setState(() {
output = 'Unexpected response: $result';
});
}
} catch (e, st) {
setState(() {
output = 'Error: $e';
});
logger.e('Fetching balances failed', error: e, stackTrace: st);
} finally {
setState(() {
loading = false;
});
}
}
Future<void> runShield() async {
setState(() {
loading = true;
output = 'Fetching shield info...';
});
logger.i('Fetching shield info');
try {
final mints = [
'So11111111111111111111111111111111111111112',
'USDC111111111111111111111111111111111111111',
];
final result = await client.shield(mints);
logger.i('Shield result: $result');
final buf = StringBuffer('Shield API Response:\n');
if (result.containsKey('tokens')) {
final tokens = result['tokens'] as Map<String, dynamic>;
tokens.forEach((mint, info) {
buf.writeln(' $mint:');
if (info is Map<String, dynamic>) {
info.forEach((k, v) => buf.writeln(' $k: $v'));
} else {
buf.writeln(' $info');
}
});
}
if (result.containsKey('warnings')) {
buf.writeln('Warnings:');
final warnings = result['warnings'] as Map<String, dynamic>;
warnings.forEach((mint, warningList) {
buf.writeln(' $mint:');
if (warningList is List) {
for (final warning in warningList) {
if (warning is Map<String, dynamic>) {
buf.writeln(' Type: ${warning['type']}');
buf.writeln(' Message: ${warning['message']}');
} else {
buf.writeln(' $warning');
}
}
} else {
buf.writeln(' $warningList');
}
});
}
setState(() {
output = buf.toString();
});
} catch (e, st) {
setState(() {
output = 'Error: $e';
});
logger.e('Fetching shield info failed', error: e, stackTrace: st);
} finally {
setState(() {
loading = false;
});
}
}
@override
void dispose() {
client.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Jupiter Dart SDK Example')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (publicKey != null)
Text(
'Public Key: $publicKey',
style: const TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: loading ? null : runOrderAndExecute,
child: const Text('Order and Execute'),
),
ElevatedButton(
onPressed: loading ? null : runBalances,
child: const Text('Fetch Balances'),
),
ElevatedButton(
onPressed: loading ? null : runShield,
child: const Text('Shield Info'),
),
const SizedBox(height: 24),
Expanded(
child: SingleChildScrollView(
child: Text(
output,
style: const TextStyle(fontFamily: 'monospace'),
),
),
),
],
),
),
);
}
}