Updated 21 Aug 2026 · Follows the xrpl-py getting started guide
Keep the job small
XRPL was comfortable for automation long before most chains were. Settlement in seconds. Fees that stay tiny. JSON you can print. A script that checks a balance or sends a drop of Testnet XRP can stay under forty lines and still be honest.
Do not start on Mainnet. Do not put a seed in the repo. One process, one purpose.
Watch new ledgers
Poll validated every few seconds. When the index changes, a ledger closed. That is your cron.
import time
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import Ledger
client = JsonRpcClient("https://s.altnet.rippletest.net:51234/")
last = None
while True:
result = client.request(Ledger(ledger_index="validated")).result
idx = result["ledger_index"]
if idx != last:
print("closed", idx)
last = idx
time.sleep(4)
Four seconds is slightly slower than a typical close. You will not miss a ledger for a balance job; you might skip one index if you sleep too long, so store last and catch up if you care about every sequence.
Watch one account
Same idea: read the account on each new ledger. Useful for “did my mint / payment land?” without sitting in an explorer.
from xrpl.account import get_balance
from xrpl.utils import drops_to_xrp
ADDRESS = "rYourTestnetAddress"
while True:
result = client.request(Ledger(ledger_index="validated")).result
idx = result["ledger_index"]
if idx != last:
drops = get_balance(ADDRESS, client)
print(idx, drops_to_xrp(drops), "XRP")
last = idx
time.sleep(4)
Send 1 XRP on Testnet
Two faucet wallets, one payment, wait until it is validated. submit_and_wait fills sequence and fee, signs locally, submits, and blocks until the result is final.
from xrpl.models.transactions import Payment
from xrpl.transaction import submit_and_wait
from xrpl.utils import xrp_to_drops
from xrpl.wallet import generate_faucet_wallet
sender = generate_faucet_wallet(client, debug=True)
receiver = generate_faucet_wallet(client, debug=True)
payment = Payment(
account=sender.address,
destination=receiver.address,
amount=xrp_to_drops(1),
)
response = submit_and_wait(payment, client, sender)
print(response.result.get("hash"))
print("validated", response.result.get("validated"))
Look up the hash on testnet.xrpl.org. If you see tesSUCCESS and validated: true, it happened.
Mainnet habits
- Load the seed from the environment, never from a file you commit:
Wallet.from_seed(os.environ["XRPL_SEED"]). - Start with a tiny amount. Confirm the destination address on an explorer first.
- Exchanges need a destination tag. A normal r-address in Xaman does not.
- Same code path as Testnet — only the URL and the money change.
import os
from xrpl.wallet import Wallet
# Mainnet read/write only after Testnet is boring
client = JsonRpcClient("https://s2.ripple.com:51234/")
wallet = Wallet.from_seed(os.environ["XRPL_SEED"])
print(wallet.address)
When to use WebSockets
If you outgrow polling, subscribe to the ledger stream with WebsocketClient. Most Pixelverse-style jobs never need it. JSON-RPC stays easier to log, retry, and run under Windows Task Scheduler or cron.
Holders who want a quieter node can swap the URL for the Pixelverse rippled endpoint after login.
Automation is how XRPL stays calm. A wallet is how you hold what you made.