> ## 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.

# Local Gateway

> Running a go-livepeer broadcaster gateway locally: Ethereum keystore setup, deposit funding, and connecting to mainnet orchestrators.

export const StyledStep = ({title, icon, titleSize = 'h3', iconColor = null, titleColor = null, children, className = '', style = {}, ...rest}) => {
  const styledTitle = titleColor ? <span style={{
    color: titleColor
  }}>{title}</span> : title;
  return <Step title={styledTitle} icon={icon} iconColor={iconColor || undefined} titleSize={titleSize} className={className} style={style} {...rest}>
      {children}
    </Step>;
};

export const StyledSteps = ({children, iconColor, titleColor, lineColor, iconSize = '24px', className = '', style = {}, ...rest}) => {
  const resolvedIconColor = iconColor || 'var(--accent-dark, #18794E)';
  const resolvedTitleColor = titleColor || 'var(--lp-color-accent)';
  const resolvedLineColor = lineColor || 'var(--lp-color-accent)';
  return <div className={['docs-styled-steps', className].filter(Boolean).join(' ')} style={style} {...rest}>
      <style>{`
        .docs-styled-steps .steps > div > div.absolute > div {
          background-color: ${resolvedIconColor};
        }
        .docs-styled-steps .steps > div > div.w-full > p {
          color: ${resolvedTitleColor};
        }
        .docs-styled-steps .steps > div > div.absolute.w-px {
          background-color: ${resolvedLineColor};
        }
        .docs-styled-steps .steps > div:last-child > div.absolute.w-px::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 50%;
          transform: translateX(-50%);
          width: 6px;
          height: 6px;
          background-color: ${resolvedLineColor};
          transform: translateX(-50%) rotate(45deg);
        }
      `}</style>
      <div>
        <Steps>{children}</Steps>
      </div>
    </div>;
};

export const CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </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>;
};

<CenteredContainer preset="readable90">
  <Tip>A local Gateway in broadcaster mode needs ETH on Arbitrum One in its keystore before it can send jobs to the network. Fund the TicketBroker deposit after the node starts; the node will not route jobs with an unfunded deposit.</Tip>
</CenteredContainer>

***

Running a local go-livepeer broadcaster connects your development environment directly to the Livepeer Network, bypassing managed API infrastructure. Use this when you need to test RTMP ingest, custom Orchestrator selection, or payment flows with full network access.

<CustomDivider />

## Prerequisites

* go-livepeer installed (see <LinkArrow href="/v2/developers/guides/local-development/overview" label="Local Development Overview" newline={false} />)
* An Arbitrum One RPC endpoint (Alchemy, Infura, or any Arbitrum RPC provider)
* An Ethereum keystore file with ETH on Arbitrum One for payment deposits

<CustomDivider />

<StyledSteps iconColor="#2d9a67" titleColor="var(--accent)">
  <StyledStep title="Create or import a keystore" icon="key">
    go-livepeer generates a keystore on first run if none exists. Alternatively, import an existing Ethereum keystore file.

    To create a new keystore, run go-livepeer once with no flags and let it generate one:

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    livepeer
    ```

    The keystore is stored at `~/.lpData/arbitrum-one-mainnet/keystore/` by default. Note the generated Ethereum address.
  </StyledStep>

  <StyledStep title="Fund the account with ETH on Arbitrum One" icon="coin">
    The Gateway address needs ETH on Arbitrum One (not Ethereum mainnet). Bridge ETH from L1 or buy ETH directly on Arbitrum via a centralised exchange.

    The amount needed depends on your expected usage. For development, 0.01-0.1 ETH covers typical testing; for production workloads, scale up based on expected ticket face values and session volumes.
  </StyledStep>

  <StyledStep title="Start the broadcaster" icon="play">
    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    livepeer \
      -broadcaster \
      -network arbitrum-one-mainnet \
      -ethUrl <YOUR_ARBITRUM_RPC_URL> \
      -ethKeystorePath ~/.lpData/arbitrum-one-mainnet/keystore \
      -maxPricePerUnit 0 \
      -rtmpAddr 127.0.0.1:1935 \
      -httpAddr 127.0.0.1:8935 \
      -metrics
    ```

    `-maxPricePerUnit 0` disables price filtering. Set a positive value to limit which Orchestrators the Gateway routes to.
  </StyledStep>

  <StyledStep title="Fund the TicketBroker deposit" icon="lock">
    With the node running, use `livepeer_cli` to fund the sender deposit and penalty reserve:

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    livepeer_cli -sender-deposit 0.05
    livepeer_cli -sender-reserve 0.02
    ```

    Amounts are in ETH. Once funded, the node will route jobs to the active Orchestrator set.
  </StyledStep>

  <StyledStep title="Test with a stream" icon="video">
    Push a test stream via FFmpeg:

    ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    ffmpeg -re -f lavfi -i testsrc=size=640x360:rate=30 \
      -f lavfi -i sine=frequency=440 \
      -c:v libx264 -b:v 1000k -c:a aac \
      -f flv rtmp://127.0.0.1:1935/stream/test
    ```

    The HLS manifest appears at `http://127.0.0.1:8935/stream/test.m3u8` once the first segment is transcoded.
  </StyledStep>
</StyledSteps>

<CustomDivider />

Once the deposit is funded and a test stream completes successfully, the Gateway is ready for development workloads. See the [production checklist](/v2/developers/guides/production-hardening-checklist) before moving to real traffic.

## Related Pages

<CardGroup cols={2}>
  <Card title="ETH Escrow and Deposits" icon="lock" href="/v2/developers/guides/payments/eth-escrow-and-deposits" arrow horizontal>
    Managing TicketBroker deposits including withdrawal.
  </Card>

  <Card title="Transcoding" icon="cpu" href="/v2/developers/build/video/transcoding-direct-quickstart" arrow horizontal>
    The segment submission API the local broadcaster uses.
  </Card>

  <Card title="Local Development Overview" icon="grid" href="/v2/developers/guides/local-development/overview" arrow horizontal>
    Choosing the right local setup for your development scenario.
  </Card>
</CardGroup>
