Skip to main content

XRP Testnet Integration

The XRP Transaction Risk AI platform integrates with both the XRP Ledger testnet and production APIs to provide comprehensive wallet analysis and transaction capabilities.

API Endpoints

The platform uses two primary endpoints:

XRPScan API

Production Data
https://api.xrpscan.com/api/v1/account/{address}
Used for account information retrieval

Ripple Testnet

Test Network
https://s.altnet.rippletest.net:51234/
Used for test XRP transactions

Account Information Retrieval

The system retrieves detailed wallet information from the XRPScan API:
def get_xrp_info(address):
    url = f"https://api.xrpscan.com/api/v1/account/{address}"
    
    response = requests.get(url)
    if response.status_code == 200:
        account_info = response.json()
        st.write(account_info)
        if 'accountName' not in account_info or account_info['accountName'] is None:
            return None, None, None, None, None  # No accountName, return early
        
        domain = account_info['accountName'].get('domain', None)
        verified = account_info.get('accountName', {}).get('verified', False)
        twitter = account_info['accountName'].get('twitter', None)
        balance = account_info.get('xrpBalance', None)
        initial_balance = account_info.get('initial_balance', None)
        return verified, domain, twitter, balance, initial_balance
    else:
        st.error(f"Error fetching data: {response.status_code}")
        return None, None, None, None, None
Source location: ripple_challange.py:51-69

Retrieved Data Fields

Returned Values:
FieldTypeDescription
verifiedbooleanWhether the account is verified by XRPScan
domainstringAssociated domain name (for business accounts)
twitterstringLinked Twitter handle
balancestringCurrent XRP balance
initial_balancestringBalance when account was created
Example Response:
{
  "accountName": {
    "domain": "example.com",
    "verified": true,
    "twitter": "@example"
  },
  "xrpBalance": "1000.5",
  "initial_balance": "20.0"
}

User Input Form

The platform collects transaction details through a Streamlit form:
with emp.form("Magic form"):
    # User Inputs
    wallet_address = st.text_input(
        "Enter your destination XRP wallet address", 
        placeholder="e.g., rMdG3ju8pgyVh29ELPWaDuA74CpWW6Fxns"
    )
    amount_xrp = st.number_input(
        "Enter the XRP amount that you would like to send!"
    )
    submitted = st.form_submit_button("Check Destination ✨✨")

    if submitted:
        with st.spinner('Fetching account information...'):
            verified, domain, twitter, balance, initial_balance = get_xrp_info(wallet_address)
The form validates wallet addresses and ensures sufficient account information exists before proceeding with compliance analysis.

Validation Logic

The system performs multiple validation checks:
if not domain:
    st.error("No info")
    return
Purpose: Ensures the wallet has an associated business entity that can be analyzed for compliance.

Sending XRP Testnet Transactions

After compliance approval, users can send test XRP using the testnet:
def send_xrp_test(destination_address, amount_xrp):
    JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
    client = JsonRpcClient(JSON_RPC_URL)
    
    # Create a wallet from the testnet credentials
    test_wallet = Wallet.from_seed(test_wallet_secret)

    # Define the destination address and amount to send (in drops, 1 XRP = 1,000,000 drops)
    destination_address = destination_address
    amount_to_send = amount_xrp  # Example: sending 5 XRP (5,000,000 drops)

    # Check the balance of the sender account before the transaction
    account_info = AccountInfo(
        account=test_wallet.classic_address,
        ledger_index="validated"
    )
    response = client.request(account_info)
    print(f"Balance before transaction: {response.result['account_data']['Balance']} drops")

    # Prepare the payment transaction
    payment_tx = Payment(
        account=test_wallet.classic_address,
        amount=amount_to_send,
        destination=destination_address
    )

    # Sign and autofill the transaction
    signed_tx = autofill_and_sign(payment_tx, client, test_wallet)

    # Submit the transaction
    response = submit_and_wait(signed_tx, client)

    # Check the balance of the sender account after the transaction
    response = client.request(account_info)
Source location: ripple_challange.py:16-49

Transaction Workflow

1

Initialize Client

Connect to the XRP Ledger testnet using JsonRpcClient:
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
client = JsonRpcClient(JSON_RPC_URL)
2

Load Wallet Credentials

Create wallet instance from stored seed:
test_wallet = Wallet.from_seed(test_wallet_secret)
Credentials are stored in Streamlit secrets: TEST_WALLET_ADDRESS and TEST_WALLET_SECRET
3

Check Balance

Verify sufficient funds before transaction:
account_info = AccountInfo(
    account=test_wallet.classic_address,
    ledger_index="validated"
)
response = client.request(account_info)
print(f"Balance before transaction: {response.result['account_data']['Balance']} drops")
4

Create Payment

Construct the payment transaction:
payment_tx = Payment(
    account=test_wallet.classic_address,
    amount=amount_to_send,
    destination=destination_address
)
5

Sign & Submit

Sign with wallet and submit to ledger:
signed_tx = autofill_and_sign(payment_tx, client, test_wallet)
response = submit_and_wait(signed_tx, client)
6

Verify

Check post-transaction balance:
response = client.request(account_info)

XRP Amount Conversion

Important Unit Conversion:The XRP Ledger uses “drops” as its base unit:
  • 1 XRP = 1,000,000 drops
  • Minimum transaction amount: 1 drop
  • Maximum precision: 6 decimal places
# Example conversions
amount_to_send = amount_xrp  # User enters XRP amount
# The xrpl library handles conversion automatically
The xrpl library automatically handles drops conversion when you pass XRP amounts as strings or numbers.

Transaction Button

The send button is displayed after compliance analysis completes:
send_xrp_container = st.container()
with send_xrp_container:
    if st.button("Send the amount"):
        send_xrp_test(wallet_address, amount_xrp)
The button appears regardless of compliance results. In a production environment, you should conditionally enable/disable this based on the risk assessment outcome.

XRPL Python Library Integration

The platform uses the official XRPL Python SDK:
import xrpl
from xrpl.clients import JsonRpcClient
from xrpl.wallet import Wallet
from xrpl.transaction import autofill_and_sign, sign_and_submit, submit_and_wait
from xrpl.models.transactions import Payment
from xrpl.models.requests import AccountInfo
Used Classes and Functions:
  • JsonRpcClient: Connects to XRP Ledger nodes via JSON-RPC
  • Wallet: Manages cryptographic keys and signing
  • Payment: Transaction model for sending XRP
  • AccountInfo: Request model for account data
  • autofill_and_sign: Fills transaction fields and signs
  • submit_and_wait: Submits tx and waits for validation
These provide a high-level interface to the XRP Ledger protocol.

Credential Management

Sensitive credentials are stored in Streamlit secrets:
test_wallet_address = st.secrets["TEST_WALLET_ADDRESS"]
test_wallet_secret = st.secrets["TEST_WALLET_SECRET"]
Security Best Practice:Never hardcode wallet seeds or private keys. Use environment variables or secrets management:
  • Streamlit Cloud: Use secrets management UI
  • Local development: .streamlit/secrets.toml file
  • Production: Vault, AWS Secrets Manager, etc.

Complete User Journey

Error Handling

response = requests.get(url)
if response.status_code == 200:
    # Process data
else:
    st.error(f"Error fetching data: {response.status_code}")
    return None, None, None, None, None

Next Steps

Risk Assessment

Learn about the AI risk analysis workflow

Regulatory Compliance

Understand compliance checking and reporting

Build docs developers (and LLMs) love