Skip to content

Automate cross-currency referral payouts (fiat-settled commission paid as BTC) #312

Description

@v0l

Follow-up to #308 / #311. #311 gave a converted payout a record shape (settled/sent/rate); it explicitly left automatic conversion out of scope. This is that other half.

Current state

ReferralPayoutHandler only ever pays BTC-earned commission automatically. Both entry points filter on currency before anything else:

  • process_one (lnvps_api/src/referral/mod.rs:443-460) — usage.iter().filter(|u| u.currency.eq_ignore_ascii_case("BTC")), same filter on existing payouts.
  • process_onchain_batch (mod.rs:421,430) — identical BTC-only filters.

Module doc is explicit about it (mod.rs:8-10): "Non-BTC (fiat) commission is never auto-paid here — Lightning settles in sats — and is left to accrue for manual admin payout."

That manual path is POST /api/admin/v1/referrals/{id}/payouts, which #311 taught to accept a sent_amount/rate pair. Today an admin has to notice the balance and enter the conversion by hand every time.

Wanted

Extend the automated handler to also pay out non-BTC settled balances:

  • Pull a quote from GET /api/v1/exchange-rate (the rate source Referral payouts cannot record a EUR commission settled in BTC #308 named) at send time.
  • Convert the settled (fiat) balance to sats, pay over Lightning/on-chain the same way BTC payouts work today.
  • Record the payout using Record both sides of a converted referral payout #311's shape: amount/currency = settled fiat, sent_amount/sent_currency = BTC actually sent, rate/rate_collected = the quote used.
  • Stay opt-in the same way BTC automation already is — min_payout_msat: Option<u64> gates whether automation runs at all (mod.rs:100-106); fiat should have the same kind of off-switch, not run unconditionally the day this ships.

Not deciding here

Whether the fiat threshold is its own config value or derived through the existing msat minimum via the same exchange rate — implementation call.

Blocked on

#311 merging — needs the settled/sent/rate columns to exist.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpaymentsPayment/invoice logic

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions