Quick Start

import 'package:para/para.dart';

// Sign a Cosmos transaction
final para = Para(apiKey: 'your-api-key');
final wallet = (await para.fetchWallets()).firstWhere((w) => w.type == 'COSMOS');

final transaction = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000', // 1 ATOM in micro-units
  chainId: 'theta-testnet-001', // Cosmos Hub testnet (use 'cosmoshub-4' for mainnet)
  format: 'proto',
);

final result = await para.signTransaction(
  walletId: wallet.id!,
  transaction: transaction.toJson(),
  chainId: 'theta-testnet-001',
);
print('Transaction signed: ${result.signature}');

Common Operations

Sign Transactions for Different Chains

// Sign ATOM transaction on Cosmos Hub testnet
final atomTx = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000', // 1 ATOM
  denom: 'uatom',
  chainId: 'theta-testnet-001', // Testnet
  format: 'proto',
);

// Sign OSMO transaction on Osmosis testnet
final osmoTx = CosmosTransaction(
  to: 'osmo1recipient...',
  amount: '1000000', // 1 OSMO
  denom: 'uosmo',
  chainId: 'osmo-test-5', // Testnet
  format: 'proto',
);

// Sign JUNO transaction on Juno mainnet
final junoTx = CosmosTransaction(
  to: 'juno1recipient...',
  amount: '1000000', // 1 JUNO
  denom: 'ujuno',
  chainId: 'juno-1',
  format: 'proto',
);

Sign Transaction

final transaction = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000', // 1 ATOM
  denom: 'uatom',
  memo: 'Transfer via Para',
  chainId: 'theta-testnet-001', // Testnet
  format: 'proto', // or 'amino' for legacy
);

final result = await para.signTransaction(
  walletId: wallet.id!,
  transaction: transaction.toJson(),
  chainId: 'theta-testnet-001',
  rpcUrl: 'https://rpc.sentry-01.theta-testnet.polypore.xyz',
);
// Cosmos returns: { signBytes, signDoc, format }
print('Signed: ${result.signature}');

Check Balance

final balance = await para.getBalance(
  walletId: wallet.id!,
  rpcUrl: 'https://cosmos-rpc.publicnode.com',
  chainPrefix: 'cosmos',
  denom: 'uatom',
);
print('Balance: $balance uatom');

// Different chain
final osmoBalance = await para.getBalance(
  walletId: wallet.id!,
  rpcUrl: 'https://osmosis-rpc.publicnode.com',
  chainPrefix: 'osmo',
  denom: 'uosmo',
);

Sign Message

final message = 'Hello, Cosmos!';
final result = await para.signMessage(
  walletId: wallet.id!,
  message: message,
);
print('Signature: ${result.signature}');

Supported Networks

Testnets

NetworkChain IDPrefixNative TokenRPC URL
Cosmos Hub Testnettheta-testnet-001cosmosuatomhttps://rpc.sentry-01.theta-testnet.polypore.xyz
Osmosis Testnetosmo-test-5osmouosmohttps://rpc.osmotest5.osmosis.zone

Mainnets

NetworkChain IDPrefixNative TokenDecimalsRPC URL
Cosmos Hubcosmoshub-4cosmosuatom6https://cosmos-rpc.publicnode.com
Osmosisosmosis-1osmouosmo6https://osmosis-rpc.publicnode.com
Junojuno-1junoujuno6https://rpc-juno.itastakers.com
Stargazestargaze-1starsustars6https://rpc.stargaze-apis.com
Akashakashnet-2akashuakt6https://rpc.akash.forbole.com
Celestiacelestiacelestiautia6https://rpc.celestia.pops.one
dYdXdydx-mainnet-1dydxadydx18https://dydx-dao-api.polkachu.com
Injectiveinjective-1injinj18https://injective-rpc.publicnode.com

Complete Example

import 'package:flutter/material.dart';
import 'package:para/para.dart';

class CosmosWalletView extends StatefulWidget {
  final Para para;
  final Wallet wallet;
  
  const CosmosWalletView({required this.para, required this.wallet});
  
  @override
  State<CosmosWalletView> createState() => _CosmosWalletViewState();
}

class _CosmosWalletViewState extends State<CosmosWalletView> {
  String _selectedChain = 'theta-testnet-001';
  bool _isLoading = false;
  String? _result;
  
  final chains = {
    'theta-testnet-001': {'name': 'Cosmos Hub Testnet', 'rpc': 'https://rpc.sentry-01.theta-testnet.polypore.xyz', 'denom': 'uatom', 'prefix': 'cosmos'},
    'osmo-test-5': {'name': 'Osmosis Testnet', 'rpc': 'https://rpc.osmotest5.osmosis.zone', 'denom': 'uosmo', 'prefix': 'osmo'},
  };
  
  @override
  Widget build(BuildContext context) {
    final chain = chains[_selectedChain]!;
    
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        children: [
          DropdownButton<String>(
            value: _selectedChain,
            items: chains.entries.map((e) => 
              DropdownMenuItem(value: e.key, child: Text(e.value['name']!))
            ).toList(),
            onChanged: (value) => setState(() => _selectedChain = value!),
          ),
          SizedBox(height: 20),
          Text(
            widget.wallet.address ?? 'No address',
            style: TextStyle(fontFamily: 'monospace', fontSize: 12),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _isLoading ? null : _signTransaction,
            child: Text(_isLoading ? 'Signing...' : 'Sign Transaction for ${chain['name']}'),
          ),
          if (_result != null)
            Padding(
              padding: const EdgeInsets.only(top: 20),
              child: Text(_result!, style: TextStyle(fontSize: 12)),
            ),
        ],
      ),
    );
  }
  
  Future<void> _signTransaction() async {
    setState(() => _isLoading = true);
    final chain = chains[_selectedChain]!;
    
    try {
      final transaction = CosmosTransaction(
        to: '${chain['prefix']}1recipient...', // Uses chain prefix
        amount: '1000000', // 1 token in micro-units
        denom: chain['denom']!,
        memo: 'Test transaction from Flutter',
        chainId: _selectedChain,
        format: 'proto',
      );
      
      final result = await widget.para.signTransaction(
        walletId: widget.wallet.id!,
        transaction: transaction.toJson(),
        chainId: _selectedChain,
        rpcUrl: chain['rpc']!,
      );
      setState(() => _result = 'Signed! Signature: ${result.signature}');
    } catch (e) {
      setState(() => _result = 'Error: $e');
    } finally {
      setState(() => _isLoading = false);
    }
  }
}

Proto vs Amino Formats

// Modern Proto format (recommended)
final protoTx = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000',
  format: 'proto',
  chainId: 'cosmoshub-4',
);

// Legacy Amino format (compatibility)
final aminoTx = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000',
  format: 'amino',
  chainId: 'cosmoshub-4',
);

// Use convenience constructor
final simpleTx = CosmosTransaction(
  to: 'cosmos1recipient...',
  amount: '1000000',
  denom: 'uatom',
  chainId: 'theta-testnet-001',
);