CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-xrpl-py

A complete Python library for interacting with the XRP Ledger blockchain, providing transaction creation, account management, and comprehensive XRPL protocol support

Overview
Eval results
Files

wallets.mddocs/

Wallet Operations

Create, manage, and operate XRPL wallets including key generation, address derivation, and testnet funding. The wallet module provides comprehensive cryptographic wallet functionality for XRPL applications.

Capabilities

Wallet Class

Complete wallet implementation with cryptographic key management and address operations.

from xrpl.wallet import Wallet
from xrpl import CryptoAlgorithm

class Wallet:
    """XRPL wallet containing cryptographic keys and address information."""
    
    def __init__(
        self,
        public_key: str,
        private_key: str,
        classic_address: str = None,
        seed: str = None
    ):
        """
        Initialize wallet with key material.
        
        Args:
            public_key: Hex-encoded public key
            private_key: Hex-encoded private key  
            classic_address: XRPL classic address (derived if not provided)
            seed: Original seed used to generate keys (optional)
        """
        self.public_key = public_key
        self.private_key = private_key
        self.classic_address = classic_address
        self.seed = seed
    
    @property
    def address(self) -> str:
        """Get the classic address (alias for classic_address)."""
        return self.classic_address
    
    @classmethod
    def create(cls, algorithm: CryptoAlgorithm = CryptoAlgorithm.ED25519) -> "Wallet":
        """
        Create a new wallet with randomly generated keys.
        
        Args:
            algorithm: Cryptographic algorithm to use (ED25519 or SECP256K1)
            
        Returns:
            New Wallet instance with generated keys
        """
    
    @classmethod
    def from_seed(
        cls, 
        seed: str, 
        algorithm: CryptoAlgorithm = None
    ) -> "Wallet":
        """
        Create wallet from existing seed.
        
        Args:
            seed: Base58-encoded seed string
            algorithm: Algorithm to use (inferred from seed if not provided)
            
        Returns:
            Wallet instance derived from seed
        """
    
    @classmethod  
    def from_secret(cls, seed: str) -> "Wallet":
        """
        Create wallet from secret (alias for from_seed).
        
        Args:
            seed: Base58-encoded seed/secret string
            
        Returns:
            Wallet instance derived from secret
        """
    
    def get_xaddress(self, tag: int = None, is_test: bool = False) -> str:
        """
        Get X-address format of wallet address.
        
        Args:
            tag: Optional destination tag to encode
            is_test: Whether this is for test network
            
        Returns:
            X-address string with optional tag encoded
        """

Wallet Funding

Generate wallets funded by testnet faucets for development and testing.

from xrpl.wallet import generate_faucet_wallet

def generate_faucet_wallet(
    client, 
    wallet: Wallet = None, 
    usage_context: str = None
) -> Wallet:
    """
    Generate a wallet funded by testnet faucet.
    
    Args:
        client: XRPL client connected to testnet
        wallet: Existing wallet to fund (creates new if None)
        usage_context: Usage context string for faucet request
        
    Returns:
        Funded wallet ready for testnet use
        
    Raises:
        XRPLFaucetException: If faucet funding fails
    """

Usage Examples

Creating New Wallets

from xrpl.wallet import Wallet
from xrpl import CryptoAlgorithm

# Create wallet with default Ed25519 algorithm
wallet1 = Wallet.create()
print(f"Address: {wallet1.address}")
print(f"Public key: {wallet1.public_key}")
print(f"Seed: {wallet1.seed}")

# Create wallet with secp256k1 algorithm
wallet2 = Wallet.create(CryptoAlgorithm.SECP256K1)
print(f"Address: {wallet2.address}")
print(f"Algorithm: secp256k1")

# Create wallet from existing seed
existing_seed = "sEdTM1uX8pu2do5XvTnutH6HsouMaM2"
wallet3 = Wallet.from_seed(existing_seed)
print(f"Restored address: {wallet3.address}")

# Alternative method using from_secret
wallet4 = Wallet.from_secret(existing_seed)
print(f"Same address: {wallet4.address == wallet3.address}")

Wallet Information and Address Formats

from xrpl.wallet import Wallet

# Create a wallet
wallet = Wallet.create()

# Display wallet information
print("=== Wallet Information ===")
print(f"Classic Address: {wallet.address}")
print(f"Classic Address (property): {wallet.classic_address}")
print(f"Public Key: {wallet.public_key}")
print(f"Private Key: {wallet.private_key}")
print(f"Seed: {wallet.seed}")

# X-address formats
print("\n=== Address Formats ===")
print(f"Classic: {wallet.address}")
print(f"X-address (mainnet): {wallet.get_xaddress()}")
print(f"X-address (testnet): {wallet.get_xaddress(is_test=True)}")
print(f"X-address with tag: {wallet.get_xaddress(tag=12345, is_test=True)}")

# Address validation
from xrpl.core.addresscodec import is_valid_classic_address, is_valid_xaddress
classic_addr = wallet.address
x_addr = wallet.get_xaddress(is_test=True)

print(f"\nClassic address valid: {is_valid_classic_address(classic_addr)}")
print(f"X-address valid: {is_valid_xaddress(x_addr)}")

Testnet Wallet Funding

from xrpl.clients import JsonRpcClient
from xrpl.wallet import Wallet, generate_faucet_wallet

# Connect to testnet
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")

# Method 1: Generate and fund new wallet
try:
    funded_wallet = generate_faucet_wallet(client)
    print(f"✅ Created funded wallet: {funded_wallet.address}")
    
    # Check balance
    from xrpl import account
    balance = account.get_balance(funded_wallet.address, client)
    print(f"Balance: {balance} drops ({balance / 1_000_000} XRP)")
    
except Exception as e:
    print(f"❌ Faucet funding failed: {e}")

# Method 2: Fund existing wallet
existing_wallet = Wallet.create()
print(f"Created wallet: {existing_wallet.address}")

try:
    funded_existing = generate_faucet_wallet(client, existing_wallet)
    print(f"✅ Funded existing wallet: {funded_existing.address}")
    
except Exception as e:
    print(f"❌ Failed to fund existing wallet: {e}")

Wallet Persistence and Recovery

import json
from xrpl.wallet import Wallet
from xrpl import CryptoAlgorithm

def save_wallet_safely(wallet: Wallet, filename: str, password: str = None):
    """Save wallet to encrypted file (simplified example)."""
    
    # In production, use proper encryption!
    wallet_data = {
        "seed": wallet.seed,
        "address": wallet.address,
        "public_key": wallet.public_key,
        # Never save private keys in plaintext!
        "algorithm": "ed25519" if "ed25519" in wallet.seed else "secp256k1"
    }
    
    with open(filename, 'w') as f:
        json.dump(wallet_data, f, indent=2)
    
    print(f"⚠️  Wallet saved to {filename}")
    print("⚠️  WARNING: This is a simplified example!")
    print("⚠️  In production, encrypt private keys and use secure storage!")

def load_wallet_safely(filename: str, password: str = None) -> Wallet:
    """Load wallet from file (simplified example)."""
    
    with open(filename, 'r') as f:
        wallet_data = json.load(f)
    
    # Restore wallet from seed
    wallet = Wallet.from_seed(wallet_data["seed"])
    
    # Verify address matches
    if wallet.address != wallet_data["address"]:
        raise ValueError("Address mismatch - corrupted wallet file!")
    
    return wallet

# Example usage
original_wallet = Wallet.create()
print(f"Original wallet: {original_wallet.address}")

# Save wallet (INSECURE - for demo only!)
save_wallet_safely(original_wallet, "demo_wallet.json")

# Load wallet
restored_wallet = load_wallet_safely("demo_wallet.json")
print(f"Restored wallet: {restored_wallet.address}")
print(f"Addresses match: {original_wallet.address == restored_wallet.address}")

Multi-Wallet Management

from xrpl.wallet import Wallet, generate_faucet_wallet
from xrpl.clients import JsonRpcClient
from xrpl import account

class WalletManager:
    """Manage multiple XRPL wallets."""
    
    def __init__(self, client):
        self.client = client
        self.wallets = {}
    
    def create_wallet(self, name: str, algorithm=None) -> Wallet:
        """Create and store a new wallet."""
        if algorithm:
            wallet = Wallet.create(algorithm)
        else:
            wallet = Wallet.create()
        
        self.wallets[name] = wallet
        print(f"Created wallet '{name}': {wallet.address}")
        return wallet
    
    def fund_wallet(self, name: str) -> bool:
        """Fund a wallet using testnet faucet."""
        if name not in self.wallets:
            print(f"Wallet '{name}' not found")
            return False
        
        try:
            funded_wallet = generate_faucet_wallet(self.client, self.wallets[name])
            self.wallets[name] = funded_wallet
            print(f"✅ Funded wallet '{name}'")
            return True
        except Exception as e:
            print(f"❌ Failed to fund wallet '{name}': {e}")
            return False
    
    def get_balances(self) -> dict:
        """Get balances for all wallets."""
        balances = {}
        for name, wallet in self.wallets.items():
            try:
                if account.does_account_exist(wallet.address, self.client):
                    balance = account.get_balance(wallet.address, self.client)
                    balances[name] = {
                        "address": wallet.address,
                        "balance_drops": balance,
                        "balance_xrp": balance / 1_000_000
                    }
                else:
                    balances[name] = {
                        "address": wallet.address,
                        "balance_drops": 0,
                        "balance_xrp": 0.0,
                        "exists": False
                    }
            except Exception as e:
                balances[name] = {
                    "address": wallet.address,
                    "error": str(e)
                }
        return balances
    
    def get_wallet(self, name: str) -> Wallet:
        """Get wallet by name."""
        return self.wallets.get(name)

# Usage example
client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
manager = WalletManager(client)

# Create multiple wallets
manager.create_wallet("alice")
manager.create_wallet("bob", CryptoAlgorithm.SECP256K1)
manager.create_wallet("charlie")

# Fund wallets
manager.fund_wallet("alice")
manager.fund_wallet("bob")

# Check balances
balances = manager.get_balances()
for name, info in balances.items():
    if "error" in info:
        print(f"{name}: Error - {info['error']}")
    elif info.get("exists", True):
        print(f"{name} ({info['address']}): {info['balance_xrp']:.6f} XRP")
    else:
        print(f"{name} ({info['address']}): Account not funded")

Wallet Security Best Practices

from xrpl.wallet import Wallet
import secrets
import hashlib

def create_secure_wallet():
    """Create wallet with additional entropy."""
    
    # Add extra entropy (optional - Wallet.create() is already secure)
    extra_entropy = secrets.token_bytes(32)
    wallet = Wallet.create()
    
    print("🔐 Wallet Security Checklist:")
    print("✅ Generated with cryptographically secure random number generator")
    print("✅ Private key never transmitted over network")
    print("✅ Seed can regenerate the entire wallet")
    
    return wallet

def verify_wallet_integrity(wallet: Wallet) -> bool:
    """Verify wallet keys are consistent."""
    
    try:
        # Create new wallet from same seed
        verification_wallet = Wallet.from_seed(wallet.seed)
        
        # Check all components match
        checks = [
            wallet.address == verification_wallet.address,
            wallet.public_key == verification_wallet.public_key,
            wallet.private_key == verification_wallet.private_key
        ]
        
        if all(checks):
            print("✅ Wallet integrity verified")
            return True
        else:
            print("❌ Wallet integrity check failed!")
            return False
            
    except Exception as e:
        print(f"❌ Wallet verification error: {e}")
        return False

def wallet_security_audit(wallet: Wallet):
    """Perform basic security audit of wallet."""
    
    print("🔍 Wallet Security Audit")
    print(f"Address: {wallet.address}")
    
    # Check key lengths
    public_key_len = len(wallet.public_key)
    private_key_len = len(wallet.private_key)
    
    print(f"Public key length: {public_key_len} chars")
    print(f"Private key length: {private_key_len} chars")
    
    # Verify integrity
    integrity_ok = verify_wallet_integrity(wallet)
    
    # Check address format
    from xrpl.core.addresscodec import is_valid_classic_address
    address_valid = is_valid_classic_address(wallet.address)
    print(f"Address format valid: {address_valid}")
    
    # Security recommendations
    print("\n🛡️  Security Recommendations:")
    print("- Store seed/private key in encrypted storage")
    print("- Never share private key or seed")
    print("- Use hardware wallets for large amounts")
    print("- Test with small amounts first")
    print("- Keep backups of seed in secure locations")
    print("- Use testnet for development")

# Example usage
wallet = create_secure_wallet()
wallet_security_audit(wallet)

Exceptions

class XRPLFaucetException(XRPLException):
    """Exception raised when faucet operations fail during wallet funding."""

Wallet Properties Summary

# Wallet instance properties
wallet = Wallet.create()

wallet.address          # str: Classic XRPL address (rXXX...)
wallet.classic_address  # str: Same as address
wallet.public_key       # str: Hex-encoded public key
wallet.private_key      # str: Hex-encoded private key  
wallet.seed            # str: Base58-encoded seed for key derivation

# Methods
wallet.get_xaddress(tag=None, is_test=False)  # X-address format

# Class methods
Wallet.create(algorithm=CryptoAlgorithm.ED25519)  # Create new wallet
Wallet.from_seed(seed, algorithm=None)            # From existing seed
Wallet.from_secret(seed)                          # Alias for from_seed

Install with Tessl CLI

npx tessl i tessl/pypi-xrpl-py

docs

accounts.md

clients.md

core.md

index.md

ledger.md

models.md

transactions.md

utils.md

wallets.md

tile.json