> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livepeer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Paths for Gateway Operators

> Choose the right payment path for a Livepeer gateway. Covers on-chain self-managed, remote signer, and clearinghouse options by operational mode and node type.

export const BorderedBox = ({children, variant = "default", padding = "var(--lp-spacing-4)", borderRadius = "var(--lp-spacing-px-8)", margin = "", accentBar = "", style = {}, className = "", ...rest}) => {
  const variants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    accent: {
      border: "1px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    muted: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "transparent"
    }
  };
  const accentBarColors = {
    accent: "var(--lp-color-accent)",
    positive: "var(--green-9)"
  };
  return <div data-docs-bordered-box="" data-accent-bar={accentBarColors[accentBar] ? "" : undefined} className={className} style={{
    ...variants[variant],
    padding: padding,
    borderRadius: borderRadius,
    ...margin ? {
      margin
    } : {},
    ...accentBarColors[accentBar] ? {
      position: "relative",
      '--accent-bar-color': accentBarColors[accentBar]
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const TableCell = ({children, align = "left", header = false, style = {}, className = "", ...rest}) => {
  const Component = header ? "th" : "td";
  return <Component className={className} style={{
    padding: "0.75rem 1rem",
    textAlign: align,
    border: header ? "none" : "1px solid var(--lp-color-border-default)",
    ...style
  }} {...rest}>
      {children}
    </Component>;
};

export const TableRow = ({children, header = false, hover = false, style = {}, className = "", ...rest}) => {
  const rowId = `table-row-${Math.random().toString(36).substr(2, 9)}`;
  return <>
      {hover && <style>{`
          #${rowId}:hover {
            background-color: var(--lp-color-bg-card);
          }
        `}</style>}
      <tr id={rowId} className={className} style={{
    ...header && ({
      backgroundColor: "var(--lp-color-accent-strong)",
      color: "var(--lp-color-on-accent)",
      fontWeight: "bold"
    }),
    ...style
  }} {...rest}>
        {children}
      </tr>
    </>;
};

export const StyledTable = ({children, variant = "default", style = {}, className = "", ...rest}) => {
  const wrapperVariants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)",
      overflow: "hidden"
    },
    bordered: {
      border: "2px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-page)",
      overflow: "hidden"
    },
    minimal: {
      border: "none",
      backgroundColor: "transparent",
      overflow: "visible"
    }
  };
  return <div data-docs-styled-table-shell className={className} style={{
    width: "100%",
    padding: 0,
    margin: 0,
    ...wrapperVariants[variant],
    ...style
  }} {...rest}>
      <table data-docs-styled-table style={{
    width: "100%",
    borderCollapse: "collapse",
    borderSpacing: 0,
    margin: 0,
    backgroundColor: "transparent"
  }}>
        {children}
      </table>
    </div>;
};

export const LinkArrow = ({href, label, description, newline = true, borderColor, className = '', style = {}, ...rest}) => {
  const linkArrowStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: "var(--lp-spacing-1)",
    width: 'fit-content',
    ...borderColor && ({
      borderColor
    })
  };
  return <span className={className} style={style} {...rest}>
      {newline && <br />}
      <span style={linkArrowStyle}>
        <a href={href} target="_blank" rel="noopener noreferrer">
          {label}
        </a>
        <Icon icon="arrow-up-right" size={14} color="var(--lp-color-accent)" />
      </span>
      {description && description}
      {description && <div style={{
    height: "var(--lp-spacing-3)"
  }} />}
    </span>;
};

export const CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

<Note>
  Livepeer fees between Gateways and Orchestrators are settled in **ETH on Arbitrum One** via probabilistic micropayment (PM) tickets. Gateways can configure price caps in wei or in USD (converted at runtime via a Chainlink price feed). LPT is the staking and governance token and plays no role in day-to-day payment flows.
</Note>

<CustomDivider style={{margin: "-1rem 0 -1rem 0"}} />

## Payments Guide

After initial Gateway setup, the next step is configuring how the Gateway pays Orchestrators for compute. The right payment path depends on the Gateway's operational mode and node type.

<AccordionGroup>
  <Accordion title={<span><Badge color="purple">AI</Badge> Off-chain AI Gateway</span>} icon="cloud">
    The Gateway holds no ETH and no Ethereum key. Payments are handled by a connected remote signer or clearinghouse. For testing, use the community signer at `signer.eliteencoder.net`. Once a public clearinghouse reaches GA, this becomes a pure API key sign-up.

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/clearinghouse-guide" label="Clearinghouses" newline={false} />
  </Accordion>

  <Accordion title={<span><Badge color="blue">Video</Badge> On-chain video Gateway</span>} icon="link">
    Video transcoding requires the on-chain self-managed path. The Gateway holds an Ethereum keystore, signs PM tickets directly, and needs a funded deposit and reserve on Arbitrum. Remote signing is not supported for video workloads.

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/funding-guide" label="Funding Guide" newline={false} />
  </Accordion>

  <Accordion title={<span><Badge color="purple">AI</Badge> On-chain AI Gateway</span>} icon="link">
    AI Gateways can also run on-chain, using `-aiServiceRegistry` for automatic Orchestrator discovery and self-managed PM tickets. The Gateway holds an Ethereum keystore and a funded account, same as a video Gateway.

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/funding-guide" label="Funding Guide" newline={false} />
  </Accordion>

  <Accordion title={<span><Badge color="green">Dual</Badge> On-chain dual Gateway</span>} icon="link">
    Because the video component requires on-chain payments, a dual Gateway follows the on-chain self-managed path. The AI component uses the same funded account. Fund the Gateway, then configure pricing for both video (per-pixel) and AI (per-pipeline).

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/funding-guide" label="Funding Guide" newline={false} />
  </Accordion>

  <Accordion title={<span><Badge color="purple">AI</Badge> SDK or non-Go Gateway</span>} icon="code">
    Non-Go Gateways (Python, mobile, browser) use the remote signer path via the Livepeer SDK. The SDK handles PM signing interaction with the remote signer. The Gateway holds no Ethereum dependency.

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/remote-signers" label="Remote Signers" newline={false} />
  </Accordion>

  <Accordion title={<span><Badge color="blue">Video</Badge> <Badge color="purple">AI</Badge> <Badge color="green">Dual</Badge> Gateway-as-a-service operator</span>} icon="building-columns">
    Build or integrate with a clearinghouse. A clearinghouse runs remote signer instances, holds ETH, and adds user management, accounting, and billing. See the Opportunities section for NaaP infrastructure guidance.

    Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/clearinghouse-guide" label="Clearinghouses" newline={false} />
  </Accordion>
</AccordionGroup>

<CustomDivider style={{margin: "0 0 -2rem 0"}} />

## Operational Modes

The Gateway's operational mode determines whether the Gateway process itself handles Ethereum interactions or delegates them to a remote signer or clearinghouse.

<StyledTable variant="accent">
  <TableRow header>
    <TableCell header>Function</TableCell>

    <TableCell header>
      {<span><Icon icon="link" size={16}/> On-chain <br/><Badge color="gray">Processes</Badge></span>}
    </TableCell>

    <TableCell header>
      {<span><Icon icon="cloud" size={16}/> Off-chain <br/><Badge color="gray">Delegates</Badge></span>}
    </TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Protocol integration**</TableCell>
    <TableCell>Connects to Livepeer Protocol on Arbitrum</TableCell>
    <TableCell>None - no blockchain interaction at the Gateway</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Orchestrator discovery**</TableCell>
    <TableCell>Automatic via protocol</TableCell>
    <TableCell>Manual (`-orchAddr`) or via discovery endpoint</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Payment signing**</TableCell>
    <TableCell>Gateway signs PM tickets directly</TableCell>
    <TableCell>Remote signer or clearinghouse signs tickets</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**ETH required in Gateway**</TableCell>
    <TableCell>Yes - deposit + reserve on Arbitrum</TableCell>
    <TableCell>No - held by signer or clearinghouse</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Private key in Gateway**</TableCell>
    <TableCell>Yes</TableCell>
    <TableCell>No</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Video transcoding**</TableCell>
    <TableCell>Supported</TableCell>
    <TableCell>Not supported (requires on-chain)</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**AI inference**</TableCell>
    <TableCell>Supported</TableCell>
    <TableCell>Supported (Live AI via remote signer)</TableCell>
  </TableRow>
</StyledTable>

<Note>
  **Off-chain does not mean free.** Off-chain Gateways still pay Orchestrators via PM tickets - the signing and ETH custody are handled by a remote signer or clearinghouse instead of the Gateway process itself.
</Note>

<CustomDivider style={{margin: "-1rem 0 -2rem 0"}} />

## Payment Setup

Three payment architectures exist. Each downstream page covers setup in full.

<BorderedBox variant="accent">
  <Tabs>
    <Tab title="Self-managed" icon="key">
      The Gateway holds an Ethereum keystore with a funded account on Arbitrum. It signs PM tickets directly. Required for video transcoding and dual Gateways.

      Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/funding-guide" label="Funding Guide" newline={false} />
    </Tab>

    <Tab title="Remote signer" icon="shield-check">
      A separate `go-livepeer` service holds the key and signs tickets. The Gateway is keyless. Supported for Live AI workloads and SDK-based Gateways. Not supported for video transcoding.

      Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/remote-signers" label="Remote Signers" newline={false} />
    </Tab>

    <Tab title="Clearinghouse" icon="building-columns">
      A third-party service manages ETH custody, PM signing, and Orchestrator settlement. The Gateway gets an API key. No public clearinghouse is at general availability as of early 2026.

      Next step: <LinkArrow href="/v2/gateways/guides/payments-and-pricing/clearinghouse-guide" label="Clearinghouses" newline={false} />
    </Tab>
  </Tabs>
</BorderedBox>

<CustomDivider style={{margin: "0 0 -2rem 0"}} />

## Related Pages

<CardGroup cols={2}>
  <Card title="Funding Guide" icon="coins" href="/v2/gateways/guides/payments-and-pricing/funding-guide">
    Deposit ETH into the TicketBroker contract and set the reserve. Required for on-chain Gateways.
  </Card>

  <Card title="Pricing Strategy" icon="chart-line" href="/v2/gateways/guides/payments-and-pricing/pricing-strategy">
    Set maximum prices per pipeline and model. Controls which Orchestrators the Gateway can access.
  </Card>

  <Card title="Remote Signers" icon="shield-check" href="/v2/gateways/guides/payments-and-pricing/remote-signers">
    Isolate the Ethereum key into a separate signing service. Required for keyless Live AI Gateways.
  </Card>

  <Card title="Clearinghouses" icon="building-columns" href="/v2/gateways/guides/payments-and-pricing/clearinghouse-guide">
    Delegate all ETH management to a third-party clearinghouse.
  </Card>
</CardGroup>
