53 lines
1.8 KiB
Python
53 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Auto-top-up (sweep): send BTC to IPRoyal when reseller balance is low.
|
|
|
|
SAFETY: DRY-RUN by default — prints what it *would* do, never moves money.
|
|
To go live you must:
|
|
1. set sweep.iproyal_btc_address in config.json (IPRoyal's BTC deposit address),
|
|
2. wire the send() function to your source wallet (BTCPay hot wallet / Alby),
|
|
3. pass --live, with a hard cap via --cap-sats.
|
|
"""
|
|
import argparse
|
|
import sys
|
|
|
|
import iproyal
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--live", action="store_true", help="actually send (default: dry-run)")
|
|
ap.add_argument("--cap-sats", type=int, default=0, help="hard cap on sats to send")
|
|
args = ap.parse_args()
|
|
|
|
cfg = iproyal.CFG.get("sweep", {})
|
|
float_target = float(cfg.get("float_target", 50.0))
|
|
max_sats = args.cap_sats or int(cfg.get("max_sats", 75000))
|
|
dest = cfg.get("iproyal_btc_address", "")
|
|
|
|
try:
|
|
bal = iproyal.get_balance()
|
|
except Exception as e:
|
|
print(f"balance check failed: {e}")
|
|
sys.exit(1)
|
|
|
|
if bal >= float_target:
|
|
print(f"balance ${bal} >= float target ${float_target} — no top-up needed")
|
|
return
|
|
|
|
shortfall = float_target - bal
|
|
if not dest:
|
|
print(f"LOW: balance ${bal} is below float target ${float_target} (shortfall ${shortfall:.2f}). "
|
|
"Set sweep.iproyal_btc_address in config.json to enable auto-top-up.")
|
|
return
|
|
|
|
if args.live:
|
|
print(f"LIVE: balance ${bal} < ${float_target} — would send {max_sats} sats (~${shortfall:.2f}) to {dest}")
|
|
print("WARNING: send() not yet wired — this is a no-op placeholder.")
|
|
else:
|
|
print(f"DRY-RUN: balance ${bal} < float target ${float_target} (shortfall ${shortfall:.2f}) — "
|
|
f"would top up {max_sats} sats to {dest}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|