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

# Guide to Funding an On-Chain Gateway

> Step-by-step guide to funding an on-chain Livepeer Gateway with ETH on Arbitrum One. Covers bridging, depositing, setting reserve amounts via livepeercli, and monitoring balance.

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>;
};

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

After choosing the on-chain operational mode, the Gateway needs a funded ETH account on Arbitrum One before routing any jobs. This covers acquiring ETH, bridging it to Arbitrum, and depositing it into the `TicketBroker` contract that backs the Gateway's payment tickets.

<Warning>
  **This page applies to Gateways running in on-chain operational mode** (Video, AI, or Dual). Off-chain Gateways and clearinghouse-backed Gateways do not need ETH in the Gateway process and skip this step entirely. Not sure which applies? See <LinkArrow href="/v2/gateways/guides/payments-and-pricing/payment-guide" label="Payments Guide" newline={false} />.
</Warning>

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

## Prerequisites

Confirm the following before starting:

<StyledTable>
  <TableRow>
    <TableCell>**ETH on Arbitrum One**</TableCell>
    <TableCell>Not Ethereum mainnet. The Livepeer Protocol operates on Arbitrum One.</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Gateway ETH address**</TableCell>
    <TableCell>Created automatically on first `go-livepeer` run. Found in the keystore directory.</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Arbitrum RPC endpoint**</TableCell>
    <TableCell>Public endpoints exist; a dedicated endpoint is more reliable for production.</TableCell>
  </TableRow>

  <TableRow>
    <TableCell>**Running Gateway with `livepeer_cli`**</TableCell>
    <TableCell>Default CLI port is `5935`.</TableCell>
  </TableRow>
</StyledTable>

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

## Step 1 - Get ETH

The `TicketBroker` contract lives on Arbitrum One (not Ethereum mainnet). ETH must be on that network specifically.

<Tabs>
  <Tab title="ETH on Arbitrum" icon="check">
    Transfer the required amount to the Gateway's ETH address directly. No bridging needed.

    The Gateway address is the public key of the keystore created on first `go-livepeer` run. Check `~/.lpData/keystore` or review the startup logs for the address.
  </Tab>

  <Tab title="ETH on mainnet" icon="bridge">
    Bridge ETH from Ethereum mainnet to Arbitrum One via the official Arbitrum bridge:

    **Bridge:** [bridge.Arbitrum.io](https://bridge.arbitrum.io/)

    The bridging process involves two transactions: an approval and a deposit. Allow 10 to 20 minutes for the deposit to finalise on Arbitrum. If the bridge fails due to gas price volatility, Arbitrum provides a retry panel at [retryable-tx-panel.Arbitrum.io](https://retryable-tx-panel.arbitrum.io/).

    <Note>
      Native ETH bridges straightforwardly. Only ERC-20 tokens like LPT require the token address import step.
    </Note>
  </Tab>

  <Tab title="No ETH yet" icon="cart-shopping">
    Some centralised exchanges support direct withdrawals to Arbitrum One, avoiding the bridging step entirely.

    For a current list of exchanges supporting Arbitrum One, see the [Arbitrum Exchange Reference](/v2/Gateways/resources/compendium/Arbitrum-exchanges) in the Resources section. This list is dynamically sourced from CoinGecko.

    <Note>
      Livepeer does not recommend any specific exchange. Verify network support before initiating a withdrawal.
    </Note>
  </Tab>
</Tabs>

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

## Step 2 - Transfer

Send ETH on Arbitrum One to the Gateway's Ethereum address. This is the keystore account created during Gateway installation.

To find the Gateway address, run `livepeer_cli` and select **Option 1: Get node status**. The address appears under **BROADCASTER STATS** (the CLI uses the legacy term "Broadcaster" for Gateway).

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

## Step 3 - Deposit

The Livepeer payment system splits Gateway funds into two components.

<AccordionGroup>
  <Accordion title="Deposit" icon="coins">
    The **deposit** is the primary balance from which Orchestrators are paid when they redeem winning PM tickets. As the Gateway sends tickets across jobs, winning tickets are redeemed against this deposit. When the deposit runs too low, Orchestrators begin rejecting tickets and jobs fail.

    The deposit functions as a running payment balance: it is depleted by usage and needs to be topped up periodically.
  </Accordion>

  <Accordion title="Reserve" icon="vault">
    The **reserve** is a collateral backstop that protects Orchestrators against Gateway non-payment. It is not consumed directly by ticket redemption under normal operation; rather, it is available as a protection mechanism for Orchestrators with a stake-based relationship to the Gateway.

    The reserve also determines the face value of PM tickets. Tickets are sized as a fraction of the reserve, so a larger reserve allows for higher-value tickets per redemption event.

    <Warning>
      For production environments, a reserve of at least **0.36 ETH** is recommended to prevent service interruptions during gas price spikes. [Issue #3744](https://github.com/livepeer/go-livepeer/issues/3744) tracks work to reduce this requirement.
    </Warning>
  </Accordion>
</AccordionGroup>

<Steps>
  <Step title="Open livepeer_cli">
    On the host running the Gateway:

    ```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    livepeer_cli -host 127.0.0.1 -http 5935
    ```

    The interactive CLI menu appears.
  </Step>

  <Step title="Select Option 11 - Invoke deposit broadcasting funds">
    Type `11` and press Enter. The CLI prompts for two amounts.
  </Step>

  <Step title="Enter deposit and reserve amounts">
    Enter the amounts in ETH when prompted:

    <StyledTable>
      <TableRow header>
        <TableCell header>Purpose</TableCell>
        <TableCell header>Recommended</TableCell>
        <TableCell header>Notes</TableCell>
      </TableRow>

      <TableRow>
        <TableCell>**Testing**</TableCell>
        <TableCell>0.065 ETH deposit + 0.03 ETH reserve</TableCell>
        <TableCell>Minimum functional setup. Not for production.</TableCell>
      </TableRow>

      <TableRow>
        <TableCell>**Production**</TableCell>
        <TableCell>0.1+ ETH deposit + 0.36 ETH reserve</TableCell>
        <TableCell>Reserve covers gas spike scenarios.</TableCell>
      </TableRow>
    </StyledTable>

    The ticket face value is calculated as a fraction of the reserve. In the testing example: `0.03 ETH reserve / 100 = 0.0003 ETH per ticket`.

    <Note>
      These amounts are in ETH, not wei. The CLI accepts decimal ETH values directly.
    </Note>
  </Step>

  <Step title="Confirm the transaction">
    The CLI prompts for confirmation. Review the amounts, then confirm. The transaction is submitted to the `TicketBroker` contract on Arbitrum One. Allow a few seconds for confirmation.
  </Step>

  <Step title="Verify the balance">
    Select **Option 1: Get node status** in `livepeer_cli`. Scroll to the **BROADCASTER STATS** section (the CLI uses the legacy term "Broadcaster" for Gateway). The deposit and reserve amounts should be reflected there.

    The balance can also be verified on-chain via [Livepeer Explorer](https://explorer.livepeer.org) by searching for the Gateway address.
  </Step>
</Steps>

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

## Monitoring

The deposit depletes with every winning ticket redeemed. The reserve normally stays intact unless there is a default event. Monitor and top up the deposit regularly.

<Warning>
  When the deposit falls below a threshold, Orchestrators begin rejecting payment tickets. Jobs silently fail or stall. Monitor the deposit balance proactively.
</Warning>

**Check the balance:**

```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
livepeer_cli -host 127.0.0.1 -http 5935
# Select Option 1 - review BROADCASTER STATS
```

**Top up the deposit:** Invoke Option 11 again at any time and add further ETH.

**Automate monitoring:** For production deployments, monitor the Gateway's ETH balance via the Arbitrum RPC endpoint. Alert when the deposit falls below the minimum operating threshold.

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

## Withdrawals

To withdraw funds from the `TicketBroker` deposit, there is an unlock period. This prevents instantaneous withdrawal attacks.
Use `livepeer_cli` to initiate an unlock request. After the unlock period expires, withdraw the funds to the Gateway's Ethereum address.

<Tip>
  When winding down a Gateway, initiate the unlock well in advance. The unlock period protects Orchestrators who may have pending tickets against the deposit.
</Tip>

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

## Related Pages

<CardGroup cols={2}>
  <Card title="Pricing Strategy" icon="chart-line" href="/v2/gateways/guides/payments-and-pricing/pricing-strategy">
    Set maximum prices the Gateway pays Orchestrators. Configure after funding.
  </Card>

  <Card title="Remote Signers" icon="shield-check" href="/v2/gateways/guides/payments-and-pricing/remote-signers">
    Isolate the signing key from the Gateway process for better security.
  </Card>

  <Card title="Payments Guide" icon="code-branch" href="/v2/gateways/guides/payments-and-pricing/payment-guide">
    Revisit the payment architecture decision guide.
  </Card>

  <Card title="Arbitrum Exchanges" icon="arrow-right-arrow-left" href="/v2/gateways/resources/compendium/arbitrum-exchanges">
    Exchanges that support direct Arbitrum One withdrawals.
  </Card>
</CardGroup>
