From db7b2c5fd4e1e15c37234b0efd4c1949cfe21854 Mon Sep 17 00:00:00 2001 From: qianghan Date: Fri, 17 Jul 2026 21:28:04 -0700 Subject: [PATCH] fix(live-runner): per-signer payment type on the LR path (sibling to #46) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dual-path fix in #46 covers the BYOC payment path (byoc.py). The Live Runner payment path is separate — `_get_runner_payment` in live_runner.py — and it hardcoded `type="live"` for every non-scope runner. The legacy Daydream signer (signer.daydream.live) only accepts `lv2v`, so LR + Daydream returned `400 invalid job type` and payment failed. (The lr-gateway `lv2v` patch only fixed the isolated sidecar, not the gateway itself.) - Move the per-signer helper to `remote_signer.py` as the canonical `_payment_type_for_signer` (the module that owns LivePaymentSession — shared by both payment paths; LR does not depend on the soon-deprecated byoc.py). - `_get_runner_payment`: Scope/LV2V stays "lv2v"; every other runner uses the per-signer dual-path (Daydream → "lv2v", modern → "byoc"). Verified on-chain (via the lr-gateway lv2v patch this generalizes): LR single-shot + Daydream signer → ticket redeems on Arbitrum. Once #46 merges, byoc.py's local copy should import this canonical helper (trivial dedup follow-up). Co-Authored-By: Claude Opus 4.8 --- src/livepeer_gateway/live_runner.py | 12 +++++++++++- src/livepeer_gateway/remote_signer.py | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/livepeer_gateway/live_runner.py b/src/livepeer_gateway/live_runner.py index 2c53543..b965a3e 100644 --- a/src/livepeer_gateway/live_runner.py +++ b/src/livepeer_gateway/live_runner.py @@ -21,6 +21,7 @@ GetPaymentResponse, LivePaymentSession, _freeze_headers, + _payment_type_for_signer, get_signer_info, ) @@ -737,10 +738,19 @@ async def _get_runner_payment( signer_url: str, signer_headers: Optional[dict[str, str]], ) -> tuple[LivePaymentSession, GetPaymentResponse]: + # Scope/LV2V is a live-video job → always "lv2v". Every other runner (single-shot + # fal/tool caps) pays via the per-signer dual-path: legacy Daydream → "lv2v", + # modern signers → "byoc". The old hardcoded "live" was rejected by the Daydream + # signer ("invalid job type"), breaking LR payment on the default signer. + payment_type = ( + "lv2v" + if runner is not None and runner.app == "live-video-to-video/scope" + else _payment_type_for_signer(signer_url) + ) session = LivePaymentSession( signer_url=signer_url, signer_headers=signer_headers, - type="lv2v" if runner is not None and runner.app == "live-video-to-video/scope" else "live", + type=payment_type, payment_params=challenge.payment_params, manifest_id=challenge.manifest_id, orchestrator_url=challenge.orchestrator_url, diff --git a/src/livepeer_gateway/remote_signer.py b/src/livepeer_gateway/remote_signer.py index fc94463..a90575a 100644 --- a/src/livepeer_gateway/remote_signer.py +++ b/src/livepeer_gateway/remote_signer.py @@ -8,8 +8,9 @@ import ssl from dataclasses import dataclass from functools import lru_cache -from typing import Any, Optional +from typing import Any, Literal, Optional from urllib.error import HTTPError, URLError +from urllib.parse import urlparse from urllib.request import Request, urlopen import aiohttp @@ -19,6 +20,21 @@ from .errors import LivepeerGatewayError, PaymentError, SignerRefreshRequired _LOG = logging.getLogger(__name__) +_LEGACY_DAYDREAM_SIGNER_HOST = "signer.daydream.live" + + +def _payment_type_for_signer(signer_url: str) -> Literal["byoc", "lv2v"]: + """Select the payment payload shape for the target signer. + + Legacy Daydream signer (signer.daydream.live) accepts only type:"lv2v"; + modern signers (pymthouse DMZ, …) accept type:"byoc". Shared by the BYOC and + Live Runner payment paths so both speak the dialect their signer understands. + """ + hostname = (urlparse(signer_url).hostname or "").lower() + if hostname == _LEGACY_DAYDREAM_SIGNER_HOST: + return "lv2v" + return "byoc" + @dataclass(frozen=True) class GetPaymentResponse: payment: str