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

# Run a Gateway: Quickstart Guide

> Get a Livepeer dual AI / video Gateway node up and running locally or on the Livepeer network.

export const Subtitle = ({style = {}, text, children, variant = 'default', fontSize = '', fontWeight = '', fontStyle = '', marginTop = '', marginBottom = '', color = '', className = '', ...rest}) => {
  const renderInlineCode = (value, keyPrefix) => {
    return value.split(/(`[^`]+`)/g).map((segment, index) => {
      if (segment.startsWith('`') && segment.endsWith('`')) {
        return <code key={`${keyPrefix}-code-${index}`}>{segment.slice(1, -1)}</code>;
      }
      return segment;
    });
  };
  const renderInlineMarkup = (value, keyPrefix = 'subtitle') => {
    if (typeof value !== 'string') {
      return value;
    }
    return value.split(/(\*\*[\s\S]+?\*\*)/g).map((segment, index) => {
      if (segment.startsWith('**') && segment.endsWith('**')) {
        const inner = segment.slice(2, -2);
        return <strong key={`${keyPrefix}-strong-${index}`}>
            {renderInlineCode(inner, `${keyPrefix}-strong-${index}`)}
          </strong>;
      }
      return renderInlineCode(segment, `${keyPrefix}-${index}`);
    });
  };
  const renderContent = (value, keyPrefix) => {
    if (Array.isArray(value)) {
      return value.map((item, index) => renderContent(item, `${keyPrefix}-${index}`));
    }
    return renderInlineMarkup(value, keyPrefix);
  };
  const variants = {
    default: {
      fontSize: '1rem',
      fontStyle: 'italic',
      color: 'var(--lp-color-accent)',
      marginBottom: 0
    },
    changelog: {
      fontSize: '0.8rem',
      fontStyle: 'normal',
      fontWeight: 700,
      color: 'var(--lp-color-text-primary)',
      marginBottom: 0
    }
  };
  const base = variants[variant] || variants.default;
  return <span className={className} style={{
    ...base,
    ...fontSize ? {
      fontSize
    } : {},
    ...fontWeight ? {
      fontWeight
    } : {},
    ...fontStyle ? {
      fontStyle
    } : {},
    ...marginTop ? {
      marginTop
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...color ? {
      color
    } : {},
    ...style
  }} {...rest}>
      {renderContent(text, 'text')}
      {renderContent(children, 'children')}
    </span>;
};

export const LinuxOffChainTab = ({latestVersion, latestReleasePageUrl, GatewayOffChainWarning, CustomCodeBlock}) => <Tab title="Off-Chain Gateway" icon="floppy-disk">
    <GatewayOffChainWarning />
    <Steps titleSize="h3">
      <Step title="Install Gateway Software">
        <Subtitle style={{
  fontSize: '1.0rem'
}}>
          <span>
            Latest <a href={latestReleasePageUrl}>go-livepeer</a>
            version:<Badge color="green">{latestVersion} </Badge>
          </span>
        </Subtitle>
        <br />
        <CustomCodeBlock {...LINUX_CODE.downloadBinary} placeholderValue={latestVersion} />
        <CustomCodeBlock {...LINUX_CODE.extractBinary} />
      </Step>
      <Step title="Configure Gateway">
      </Step>
      <Step title="Run Gateway">
      </Step>
      <Step title="Test Gateway">
      </Step>
      <Step title="Monitor Gateway">
      </Step>
      <Step title="Gateway Tips">
      </Step>
    </Steps>
  </Tab>;

export const WidthCard = ({width = '80%', children, cardProps, className = "", style = {}, ...rest}) => {
  return <div className={className} style={{
    display: 'flex',
    justifyContent: 'center',
    minWidth: 'fit-content',
    ...style
  }} {...rest}>
      <div style={{
    width: width
  }}>
        <Card {...cardProps}>{children}</Card>
      </div>
    </div>;
};

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

export const latestVersion = "v0.8.10";

export const latestReleasePageUrl = "https://github.com/livepeer/go-livepeer/releases/tag/v0.8.10";

export const FlexContainer = ({children, direction = "row", gap = "var(--lp-spacing-4)", align = "flex-start", justify = "flex-start", wrap = false, marginTop = "", marginBottom = "", margin = "", padding = "", style = {}, className = "", ...rest}) => {
  return <div className={className} style={{
    display: "flex",
    flexDirection: direction,
    gap: gap,
    alignItems: align,
    justifyContent: justify,
    flexWrap: wrap ? "wrap" : "nowrap",
    ...margin ? {
      margin
    } : {},
    ...padding ? {
      padding
    } : {},
    ...marginTop ? {
      marginTop
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const DoubleIconLink = ({label = '', labelColor, href = '#', text = '', iconLeft = 'github', iconLeftColor, iconRight = 'arrow-up-right', iconRightColor = 'var(--lp-color-accent)', className = '', style = {}, ...rest}) => {
  return <span className={className} style={{
    whiteSpace: 'nowrap',
    display: 'inline-flex',
    alignItems: 'center',
    gap: "var(--lp-spacing-1)",
    marginLeft: '0.3rem',
    ...style
  }} {...rest}>
      {text && <span style={{
    marginRight: 8
  }}>{text}</span>}
      <Icon icon={iconLeft} color={iconLeftColor} />
      <a href={href} style={{
    color: {
      labelColor
    }
  }}>
        {label}
      </a>
      <div style={{
    marginRight: '0.3rem'
  }}>
        <Icon icon={iconRight} size={12} color={iconRightColor} />
      </div>
    </span>;
};

export const IconCallout = ({children, icon = 'lightbulb', color, iconSize = 16, textSize = '0.875rem', textColor, showArrow = false, arrowIcon = 'arrow-up-right', arrowSize = 16, className = '', style = {}, ...rest}) => {
  const resolvedColor = color || 'var(--lp-color-accent)';
  const resolvedTextColor = textColor || resolvedColor;
  const resolvedIconColor = (/^#[0-9a-f]{6}$/i).test(resolvedColor) ? resolvedColor : '#3cb540';
  const hexToRgba = (hex, alpha) => {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
  };
  const colorWithAlpha = (value, alpha) => {
    if ((/^#[0-9a-f]{6}$/i).test(value)) {
      return hexToRgba(value, alpha);
    }
    return `color-mix(in srgb, ${value} ${Math.round(alpha * 100)}%, transparent)`;
  };
  return <div className={className} style={{
    position: showArrow ? 'relative' : undefined,
    display: 'flex',
    alignItems: 'flex-start',
    gap: "var(--lp-spacing-px-12)",
    padding: '16px 20px',
    ...showArrow && ({
      paddingRight: '48px'
    }),
    borderRadius: '16px',
    border: `1px solid ${colorWithAlpha(resolvedColor, 0.2)}`,
    backgroundColor: colorWithAlpha(resolvedColor, 0.1),
    marginTop: '16px',
    marginBottom: '16px',
    overflow: 'hidden',
    ...style
  }} {...rest}>
      <div style={{
    marginTop: '2px',
    width: iconSize,
    flexShrink: 0
  }}>
        <Icon icon={icon} size={iconSize} color={resolvedIconColor} />
      </div>
      <div style={{
    fontSize: textSize,
    color: resolvedTextColor,
    minWidth: 0,
    width: '100%'
  }}>
        {children}
      </div>
      {showArrow && <div style={{
    position: 'absolute',
    top: '16px',
    right: '16px',
    opacity: 0.6
  }}>
          <Icon icon={arrowIcon} size={arrowSize} color={resolvedIconColor} />
        </div>}
    </div>;
};

export const ComplexCodeBlock = ({filename, icon, language, highlight, codeString = "", placeholderValue = "", wrap = true, lines = true, preNote = null, postNote = null}) => {
  if (!codeString || codeString.trim() === "") {
    return null;
  }
  const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue);
  return <>
      {preNote && <div style={{
    marginBottom: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)"
  }}>
          {preNote}
        </div>}
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight} wrap={wrap} line={lines}>
        {renderedCode}
      </CodeBlock>
      {postNote && <div style={{
    marginTop: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)"
  }}>
          {postNote}
        </div>}
    </>;
};

export const CodeSection = ({fields = {}, className = "", style = {}, ...rest}) => {
  return <ComplexCodeBlock {...fields} className={className} style={style} {...rest} />;
};

export const CustomCodeBlock = ({filename, icon, language, highlight, codeString = "", placeholderValue = "", wrap = true, lines = true, preNote = "", postNote = "", output = ""}) => {
  if (!codeString || codeString.trim() === "") {
    return null;
  }
  const renderedCode = codeString.replace(/\{PLACEHOLDER\}/g, placeholderValue);
  return <>
      {preNote && <div style={{
    marginBottom: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)"
  }}>
          {preNote}
        </div>}
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight} wrap={wrap} line={lines}>
        {renderedCode}
      </CodeBlock>
      {postNote && <div style={{
    marginTop: "var(--lp-spacing-2)",
    fontSize: "0.875rem",
    color: "var(--lp-color-text-muted)",
    fontStyle: "italic"
  }}>
          {postNote}
        </div>}
      {output?.codeString && <>
          <Expandable title={<span style={{
    fontStyle: "italic",
    fontWeight: "bold"
  }}>
                Expected Output
              </span>}>
            <CodeBlock filename={output.filename || "Output Example"} icon={output.icon || "terminal"} language={output.language || "bash"} highlight={output.highlight} wrap={output.wrap || false} line={output.lines || false}>
              {output.codeString}
            </CodeBlock>
          </Expandable>
          <br />
        </>}
    </>;
};

export const ValueResponseField = ({description, post = null, label = "value", line = true, children, className = "", style = {}, ...props}) => {
  const hasDescription = typeof description === "function" || description != null || children != null;
  if (!hasDescription) {
    console.warn("[ValueResponseField] Missing required prop: description");
    return null;
  }
  const value = post ? [<span>
          <span style={{
    color: "gray"
  }}>{label}: </span>
          <span style={{
    color: "var(--lp-color-response-field-value)"
  }}>{post[0]}</span>
        </span>] : null;
  return <div className={[!line ? "vrf-noline" : "", className].filter(Boolean).join(" ") || undefined} style={style}>
      <style>{`
        .vrf-noline > .field {
          border-bottom: none;
          margin-bottom: -0.5rem;
          padding: 0;
        }
      `}</style>
      <ResponseField {...props} post={value}>
        {typeof description === "function" ? description() : description}
        {children}
      </ResponseField>
    </div>;
};

export const CustomResponseField = ({description, className = "", style = {}, ...props}) => {
  const uniqueId = `custom-rf-${Math.random().toString(36).substring(2, 11)}`;
  return <div className={[uniqueId, className].filter(Boolean).join(" ")} style={style}>
      <style>{`
        .${uniqueId} > .field {
          border-bottom: none;
          margin-bottom: -20px;
        }
      `}</style>
      <ResponseField {...props}>{description}</ResponseField>
    </div>;
};

export const ResponseFieldExpandable = ({fields = {}, className = "", style = {}, ...props}) => {
  const fieldsArray = Array.isArray(fields) ? fields : Object.values(fields);
  if (fieldsArray.length === 0) {
    return null;
  }
  return <Expandable className={className} style={style} {...props}>
      {fieldsArray.map((field, index) => <ValueResponseField key={index} {...field} />)}
    </Expandable>;
};

export const ResponseFieldAccordion = ({fields = {}, className = "", style = {}, ...props}) => {
  const fieldsArray = Array.isArray(fields) ? fields : Object.values(fields);
  if (fieldsArray.length === 0) {
    console.warn("[ResponseFieldAccordion] Missing or invalid fields");
    return null;
  }
  return <Accordion className={className} style={style} {...props}>
      {fieldsArray.map((field, index) => <ValueResponseField key={index} {...field} />)}
    </Accordion>;
};

export const FfmpegWarning = () => {
  return <Danger>
      <div style={{
    fontSize: "1.0rem"
  }}>
        IMPORTANT! Do not install with sudo! <br />
        Livepeer uses a <strong> custom build of FFmpeg </strong>that must be
        installed in a specific location.
      </div>
    </Danger>;
};

export const TestVideoDownload = ({children}) => {
  return <Note>
      <div style={{
    marginBottom: "1rem"
  }}>
        You need a video file called <code>test-video.mp4</code> on your
        machine!{" "}
      </div>
      <span>{children}</span>
    </Note>;
};

export const OrchAddrNote = () => {
  return <Note>
      Replace <Badge color="gray">{"<http://ORCHESTRATOR_IP:PORT>"}</Badge> with
      your locally running orchestrator address <br />
    </Note>;
};

export const GatewayOnChainTTestnetNote = () => {
  return <Note>
      While Livepeer contracts are deployed to the Arbitrum Testnet, there is
      currently no freely available Orchestrator services on this chain.
      <br />
      <strong>
        If you would like to use the Aribtum Testnet for your Gateway, you will
        need to run your own Orchestrator node.
      </strong>
      <br />
      There are conversations underway to enable this in the future. Follow &
      contribute to the discussion on:
      <span>
        <Icon icon="arrow-up-right"></Icon>{" "}
        <a href="https://discord.gg/livepeer">Discord</a>
      </span>
      <span>
        <Icon icon="arrow-up-right"></Icon>{" "}
        <a href="https://forum.livepeer.org">Forum</a>
      </span>
    </Note>;
};

export const GatewayOnChainWarning = () => {
  return <Warning>
      <span style={{
    fontSize: "1.0rem"
  }}>
        You will need to{" "}
        <span style={{
    fontWeight: "bold",
    fontStyle: "italic"
  }}>
          fund an Ethereum wallet
        </span>{" "}
        account on Arbitrum One to run an on-chain Gateway.
        <br /> <br /> See{" "}
        <a href="/v2/gateways/guides/payments-and-pricing/fund-gateway">
          <Icon icon="arrow-up-right" color="var(--accent)" />{" "}
          Fund Your Gateway{" "}
        </a>
      </span>
    </Warning>;
};

export const GatewayOffChainWarning = () => {
  return <Warning>
      <span style={{
    fontSize: "1.0rem"
  }}>
        You will need to{" "}
        <span style={{
    fontWeight: "bold",
    fontStyle: "italic"
  }}>
          run your own Orchestrator node
        </span>{" "}
        to test an off-chain (local) Gateway:
      </span>
      <ul>
        <li>
          See{" "}
          <DoubleIconLink label="BYOC Guide" href="/developers/ai-inference-on-livepeer/byoc" iconLeft="link" />{" "}
          to test a local Gateway without a GPU.
        </li>
        <li>
          See{" "}
          <DoubleIconLink label="Orchestrator Guide" href="/orchestrators/guides/get-started" iconLeft="link" />{" "}
          to setup and run an Orchestrator.
        </li>
      </ul>
    </Warning>;
};

export const CONFIG_FLAGS = {
  offchain: {
    required: {
      gateway: {
        name: "-gateway",
        type: "boolean",
        default: "false",
        required: true,
        description: "Enable gateway mode"
      },
      orchAddr: {
        name: "-orchAddr",
        type: "string",
        default: "none",
        required: true,
        description: "Set to <Badge color='gray'> `http://<ORCHESTRATOR_IP>:<PORT>` </Badge> to connect to orchestrators",
        post: "http://<ORCHESTRATOR_IP>:<PORT>"
      }
    },
    optional: {
      monitor: {
        name: "-monitor",
        type: "boolean",
        default: "false",
        description: "Enables metrics collection"
      },
      v: {
        name: "-v",
        type: "number",
        default: "4",
        description: "Verbosity level",
        post: ["6"]
      },
      rtmpAddr: {
        name: "-rtmpAddr",
        type: "string",
        default: "127.0.0.1:1935",
        description: "Set to <Badge color='gray'> `0.0.0.0:1935` </Badge> to allow external RTMP connections",
        post: ["0.0.0.0:1935"]
      },
      httpAddr: {
        name: "-httpAddr",
        type: "string",
        default: "127.0.0.1:8935",
        description: "Set to <Badge color='gray'> `0.0.0.0:8935` </Badge> to allow external HLS/API access",
        post: ["0.0.0.0:8935"]
      },
      httpIngest: {
        name: "-httpIngest",
        type: "boolean",
        default: "false",
        description: "Must be explicitly set when you make `-httpAddr` publicly accessible and do not have -authWebhookUrl set. \n &nspb Enables HTTP video ingest (in addition to RTMP), necessary for AI pipelines and optionally for video ingest",
        required: true,
        post: ["true"]
      },
      cliAddr: {
        name: "-cliAddr",
        type: "string",
        default: "127.0.0.1:7935",
        description: "Set to <Badge color='gray'> `0.0.0.0:5935` </Badge> to expose the CLI API externally",
        post: ["0.0.0.0:5935"]
      },
      transcodingOptions: {
        name: "-transcodingOptions",
        type: "string",
        default: "P240p30fps16x9,P360p30fps16x9",
        description: "Higher quality transcoding options (e.g., P240p30fps16x9,P360p30fps16x9,P720p30fps16x9) or use path/to/transcodingOptions.json",
        post: ["P240p30fps16x9,P360p30fps16x9,P720p30fps16x9"]
      },
      maxSessions: {
        name: "-maxSessions",
        type: "number",
        default: "10",
        description: "Limit concurrent sessions",
        post: ["5"]
      }
    }
  },
  onchain: {
    required: {
      gateway: {
        name: "-gateway",
        type: "boolean",
        default: "false",
        required: true,
        description: "Enable gateway mode (required)"
      },
      network: {
        name: "-network",
        type: "string",
        default: "offchain",
        required: true,
        description: "Network type (offchain, arbitrum-one-mainnet)",
        post: ["arbitrum-one-mainnet"]
      },
      ethUrl: {
        name: "-ethUrl",
        type: "string",
        default: "none",
        required: true,
        description: "Set to <Badge color='gray'> `https://arb1.arbitrum.io/rpc` </Badge> to connect to Arbitrum Mainnet",
        post: ["https://arb1.arbitrum.io/rpc"]
      },
      httpIngest: {
        name: "-httpIngest",
        type: "boolean",
        default: "false",
        required: true,
        description: "Required to enable AI capabilities. Also enables HTTP video ingest (in addition to RTMP)",
        post: ["true"]
      },
      aiServiceRegistry: {
        name: "-aiServiceRegistry",
        type: "boolean",
        default: "false",
        required: true,
        description: "Enables AI on-chain service registry",
        post: ["true"]
      }
    },
    requiredAI: {
      httpIngest: {
        name: "-httpIngest",
        type: "boolean",
        default: "false",
        description: "Enables AI HTTP endpoints"
      },
      aiServiceRegistry: {
        name: "-aiServiceRegistry",
        type: "boolean",
        default: "false",
        description: "Enables AI on-chain service registry"
      }
    },
    optional: {
      monitor: {
        name: "-monitor",
        type: "boolean",
        default: "false",
        description: "Enables metrics collection"
      },
      v: {
        name: "-v",
        type: "number",
        default: "4",
        description: "Verbosity level",
        post: ["6"]
      },
      rtmpAddr: {
        name: "-rtmpAddr",
        type: "string",
        default: "127.0.0.1:1935",
        description: "Set to <Badge color='gray'> `0.0.0.0:1935` </Badge> to allow external RTMP connections",
        post: ["0.0.0.0:1935"]
      },
      httpAddr: {
        name: "-httpAddr",
        type: "string",
        default: "127.0.0.1:8935",
        description: "Set to <Badge color='gray'> `0.0.0.0:8935` </Badge> to allow external HLS/API access",
        post: ["0.0.0.0:8935"]
      },
      cliAddr: {
        name: "-cliAddr",
        type: "string",
        default: "127.0.0.1:7935",
        description: "Set to <Badge color='gray'> `0.0.0.0:5935` </Badge> to expose the CLI API externally",
        post: ["0.0.0.0:5935"]
      },
      transcodingOptions: {
        name: "-transcodingOptions",
        type: "string",
        default: "P240p30fps16x9,P360p30fps16x9",
        description: "Higher quality transcoding options (e.g., P240p30fps16x9,P360p30fps16x9,P720p30fps16x9) or use path/to/transcodingOptions.json",
        post: ["P240p30fps16x9,P360p30fps16x9,P720p30fps16x9"]
      },
      maxSessions: {
        name: "-maxSessions",
        type: "number",
        default: "10",
        description: "Limit concurrent sessions",
        post: ["5"]
      }
    },
    optionalAdvanced: {
      ethAcctAddr: {
        name: "-ethAcctAddr",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `0xYourETHAddress` </Badge> to specify the ETH account address. \n Leave blank to auto-generate a new wallet",
        post: ["0xYourETHAddress"]
      },
      ethKeystorePath: {
        name: "-ethKeystorePath",
        type: "string",
        default: "none",
        description: 'Set to <Badge color="gray"> `/path/to/keystore` </Badge> to specify the ETH keystore directory. \n If blank, a new keystore will be auto-generated in the datadir',
        post: ["/path/to/keystore"]
      },
      ethPassword: {
        name: "-ethPassword",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `/path/to/password.txt` </Badge> to specify the ETH keystore password file. \n If left blank, you will be prompted to enter a password when the gateway starts",
        post: ["/path/to/password.txt"]
      },
      maxPricePerUnit: {
        name: "-maxPricePerUnit",
        type: "number",
        default: "0",
        description: "Maximum price per pixel unit (in wei) for video transcoding services. Defaults to 0 (no limit)",
        post: ["1000000000"]
      },
      maxPricePerCapability: {
        name: "-maxPricePerCapability",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `path/to/pricing.json` </Badge> to specify AI pricing or path/to/aiPricing.json",
        post: ["path/to/aiPricing.json"]
      },
      livePaymentInterval: {
        name: "-livePaymentInterval",
        type: "string",
        default: "5s",
        description: "Payment processing frequency (e.g., 5s, 10s, 300ms) for Live AI Video workflows, where the gateway needs to send periodic payments to the orchestrator. Defaults to 5s",
        post: ["5s"]
      },
      authWebhookUrl: {
        name: "-authWebhookUrl",
        type: "string",
        default: "none",
        description: "The -authWebhookUrl flag enables webhook-based authentication for incoming streams in production Livepeer gateways. It's essential for securing publicly accessible gateways.\n Set to <Badge color='gray'> `https://your-auth-webhook.com` </Badge> to enable stream authentication",
        post: ["https://your-auth-webhook.com"]
      }
    },
    optionalWallet: {
      ethAcctAddr: {
        name: "-ethAcctAddr",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `0xYourETHAddress` </Badge> to specify the ETH account address. \n Leave blank to auto-generate a new wallet",
        post: ["0xYourETHAddress"]
      },
      ethKeystorePath: {
        name: "-ethKeystorePath",
        type: "string",
        default: "none",
        description: 'Set to <Badge color="gray"> `/path/to/keystore` </Badge> to specify the ETH keystore directory. \n If blank, a new keystore will be auto-generated in the datadir',
        post: ["/path/to/keystore"]
      },
      ethPassword: {
        name: "-ethPassword",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `/path/to/password.txt` </Badge> to specify the ETH keystore password file. \n If left blank, you will be prompted to enter a password when the gateway starts",
        post: ["/path/to/password.txt"]
      }
    },
    optionalPricing: {
      maxPricePerUnit: {
        name: "-maxPricePerUnit",
        type: "number",
        default: "0",
        description: "Maximum price per unit (wei) for video transcoding services. Defaults to 0 (no limit)",
        post: ["1000000000"]
      },
      maxPricePerCapability: {
        name: "-maxPricePerCapability",
        type: "string",
        default: "none",
        description: "Set to <Badge color='gray'> `path/to/pricing.json` </Badge> to specify AI pricing or path/to/aiPricing.json",
        post: ["path/to/pricing.json"]
      },
      livePaymentInterval: {
        name: "-livePaymentInterval",
        type: "string",
        default: "5s",
        description: "Payment processing frequency (e.g., 5s, 10s, 300ms) for Live AI Video workflows, where the gateway needs to send periodic payments to the orchestrator. Defaults to 5s",
        post: ["5s"]
      }
    }
  },
  aiEndpoints: {
    textToImage: {
      name: "/text-to-image",
      description: "Generate images from text prompts"
    },
    imageToImage: {
      name: "/image-to-image",
      description: "Transform images with text prompts"
    },
    imageToVideo: {
      name: "/image-to-video",
      description: "Create videos from images"
    },
    upscale: {
      name: "/upscale",
      description: "Increase image resolution"
    },
    audioToText: {
      name: "/audio-to-text",
      description: "Transcribe audio to text"
    },
    llm: {
      name: "/llm",
      description: "Large language model chat"
    },
    segmentAnything2: {
      name: "/segment-anything-2",
      description: "Image segmentation"
    },
    imageToText: {
      name: "/image-to-text",
      description: "Describe images"
    },
    textToSpeech: {
      name: "/text-to-speech",
      description: "Generate audio from text"
    },
    videoToVideo: {
      name: "/video-to-video",
      description: "Live video-to-video AI processing"
    }
  }
};

export const CLI_CODE = {
  cliOptions: {
    filename: "CLI Options",
    icon: "terminal",
    language: "bash",
    codeString: `
# Get current status  
curl http://localhost:5935/status  
  
# Get broadcast config  
curl http://localhost:5935/getBroadcastConfig  
  
# Get orchestrator info  
curl http://localhost:5935/getOrchestrators`
  },
  status: {
    filename: "Current Status",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/status`
  },
  broadcastConfig: {
    filename: "Broadcast Configuration",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/getBroadcastConfig`
  },
  orchestrators: {
    filename: "Orchestrator Information",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/getOrchestrators`
  }
};

export const CONFIG_FILES = {
  video: {
    transcodingOptionsJson: `[
  {
    "name": "240p",
    "width": 426,
    "height": 240,
    "bitrate": 250000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  },
  {
    "name": "360p",
    "width": 640,
    "height": 360,
    "bitrate": 500000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  },
  {
    "name": "720p",
    "width": 1280,
    "height": 720,
    "bitrate": 3000000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  }
]`
  },
  ai: {
    aiModelsJson: `[
  {
    "pipeline": "text-to-image",
    "model_id": "stabilityai/sd-turbo",
    "warm": true
  }
]`,
    aiPricingJsonMinimal: `{
  "capabilities_prices": [
    {
      "pipeline": "text-to-image",
      "model_id": "stabilityai/sd-turbo",
      "price_per_unit": 1000
    }
  ]
}`,
    aiPricingJson: `{
  "capabilities_prices": [
    {
      "pipeline": "text-to-image",
      "model_id": "stabilityai/sd-turbo",
      "price_per_unit": 1000,
      "pixels_per_unit": 1,
      "currency": "WEI"
    },
    {
      "pipeline": "image-to-video",
      "model_id": "default",
      "price_per_unit": 2000,
      "pixels_per_unit": 3,
      "currency": "WEI"
    },
    {
      "pipeline": "upscale",
      "model_id": "default",
      "price_per_unit": 1200,
      "pixels_per_unit": 1,
      "currency": "WEI"
    }
  ]
}`
  },
  dual: {
    transcodingOptionsJson: `[
  {
    "name": "240p",
    "width": 426,
    "height": 240,
    "bitrate": 250000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  },
  {
    "name": "360p",
    "width": 640,
    "height": 360,
    "bitrate": 500000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  },
  {
    "name": "720p",
    "width": 1280,
    "height": 720,
    "bitrate": 3000000,
    "fps": 30,
    "profile": "h264constrainedhigh"
  }
]`,
    aiModelsJson: `[
  {
    "pipeline": "text-to-image",
    "model_id": "stabilityai/sd-turbo",
    "warm": true
  }
]`,
    aiPricingJsonMinimal: `{
  "capabilities_prices": [
    {
      "pipeline": "text-to-image",
      "model_id": "stabilityai/sd-turbo",
      "price_per_unit": 1000
    }
  ]
}`,
    aiPricingJson: `{
  "capabilities_prices": [
    {
      "pipeline": "text-to-image",
      "model_id": "stabilityai/sd-turbo",
      "price_per_unit": 1000,
      "pixels_per_unit": 1,
      "currency": "WEI"
    },
    {
      "pipeline": "image-to-video",
      "model_id": "default",
      "price_per_unit": 2000,
      "pixels_per_unit": 3,
      "currency": "WEI"
    },
    {
      "pipeline": "upscale",
      "model_id": "default",
      "price_per_unit": 1200,
      "pixels_per_unit": 1,
      "currency": "WEI"
    }
  ]
}`
  },
  onchain: {
    keyStoreJson: `{
  "address": "0x1234567890123456789012345678901234567890",
  "crypto": {
    "cipher": "aes-128-ctr",
    "ciphertext": "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
    "cipherparams": {
      "iv": "0x12345678901234567890123456789012"
    },
    "kdf": "scrypt",
    "kdfparams": {
      "dklen": 32,
      "n": 262144,
      "p": 1,
      "r": 8,
      "salt": "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
    },
    "mac": "0x123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
  },
  "id": "unique-id",
  "version": 3
}`
  }
};

export const AI_TEST_COMMANDS = {
  textToImage: {
    filename: "Text-to-Image",
    icon: "terminal",
    language: "bash",
    wrap: true,
    codeString: `curl -X POST http://localhost:8935/text-to-image \  
        -H "Content-Type: application/json" \  
        -d '{  
          "prompt": "A beautiful sunset over mountains",  
          "model_id": "stabilityai/sdxl-turbo"  
        }'`,
    preNote: "Test Text-to-Image:"
  },
  imageToImage: {
    filename: "Image-to-Image",
    icon: "terminal",
    language: "bash",
    wrap: true,
    codeString: `curl -X POST http://localhost:8935/image-to-image \  
      -F "prompt=Turn this into a watercolor painting" \  
      -F "model_id=stabilityai/sdxl-turbo" \  
      -F "image=@input.jpg"`,
    preNote: "Test Image-to-Image:"
  },
  LLM: {
    filename: "LLM",
    icon: "terminal",
    language: "bash",
    wrap: true,
    codeString: `curl -X POST http://localhost:8935/llm \  
        -H "Content-Type: application/json" \  
        -d '{  
          "model": "meta-llama/llama-3.1-8B-Instruct",  
          "messages": [  
            {"role": "user", "content": "What is Livepeer?"}  
          ]  
        }'`,
    preNote: "Test LLM:"
  },
  liveVideoAI: {
    filename: "Live Video AI",
    icon: "terminal",
    language: "bash",
    wrap: true,
    codeString: `# Start a live AI video session  
      curl -X POST http://localhost:8935/live/video-to-video/mystream/start \  
        -H "Content-Type: application/json" \  
        -d '{  
          "model_id": "your-live-model"  
        }'`,
    preNote: "For live video-to-vdieo AI processing:"
  }
};

export const BASH_CODE = {
  sendVideo: {
    filename: "Send a Video Stream",
    icon: "terminal",
    language: "bash",
    codeString: `ffmpeg -re -i test-video.mp4 -c copy -f flv rtmp://localhost:1935/stream/test-key`,
    wrap: true,
    preNote: ""
  },
  testRTMPingest: {
    filename: "Test RTMP Ingest",
    icon: "terminal",
    language: "bash",
    codeString: `ffmpeg -re -i test-video.mp4 -c copy -f flv rtmp://localhost:1935/stream/test-key`,
    preNote: "Send a Video Stream using FFmpeg:"
  },
  testHTTPingest: {
    filename: "Test HTTP Ingest",
    icon: "terminal",
    language: "bash",
    codeString: `curl -X PUT http://localhost:8935/live/test/0.ts --data-binary @test-segment.ts`,
    preNote: "Test your HTTP Ingest Stream by pushing a segment:"
  },
  testHLS: {
    filename: "Access HLS Stream",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:8935/hls/test-key/index.m3u8`,
    preNote: "Test playback by accessing the HLS stream:"
  },
  scriptVerify: {
    filename: "Use the build-in test stream to verify",
    icon: "terminal",
    language: "bash",
    codeString: `# Generate a test pattern and stream  
        ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30,format=yuv420p \  
        -c:v libx264 -b:v 1000k -f flv rtmp://localhost:1935/stream/test-key`
  },
  checkStatus: {
    filename: "Check Gateway Status",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/status`,
    preNote: "Check if your Gateway node is running:",
    description: "The status endpoint returns a json with node information including type, addresses, and balances.",
    output: `
    {  
      "availability": 100,  
      "broadcaster": {  
        "address": "0x...",  
        "deposit": "1000000000000000000",  
        "withdrawRound": "0"  
      },  
      "eth": {  
        "accountAddr": "0x...",  
        "balance": "1000000000000000000"  
      },  
      "nodeType": "BroadcasterNode",  
      "version": "0.5.32"  
    }
    `
  },
  checkAvailableOrchestrators: {
    filename: "Check Available Orchestrators",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/getOrchestrators`,
    preNote: "Check available orchestrators:"
  },
  aiCapabilities: {
    filename: "Check Orchestrator's available capabilities",
    icon: "terminal",
    language: "bash",
    codeString: `curl http://localhost:5935/getOrchestrators`,
    preNote: "Check Orchestrator's available AI capabilities:",
    postNote: "◆ Make sure your Orchestrator's AI models directory is properly mounted and accessible"
  },
  onchain: {
    checkAccountAddress: {
      filename: "Check Your Account Address",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/status | jq '.eth.accountAddr'`,
      preNote: "Check your account address:",
      description: "The gateway must have an active Ethereum connection and valid account.",
      output: `  
      {  
        "address": "0x...",  
        "deposit": "1000000000000000000",  
        "withdrawRound": "0"  
      }  
      `
    },
    checkCurrentRound: {
      filename: "Check Current Round",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/getCurrentRound`,
      preNote: "Check the current payment round:",
      description: "Check the current payment round",
      output: `  
      {  
        "currentRound": 1,  
        "roundLength": 100,  
        "roundNumber": 1  
      }  
      `
    },
    checkDepositAndReserve: {
      filename: "Check Your Deposit and Reserve",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/getBroadcasterInfo`,
      preNote: "Check your Deposit and Reserve:",
      description: "Check your Deposit and Reserve:",
      output: `  
      {  
        "address": "0x...",  
        "deposit": "1000000000000000000",  
        "withdrawRound": "0"  
      }  
      `
    },
    depositFunds: {
      filename: "Deposit Funds",
      icon: "terminal",
      language: "bash",
      codeString: `curl -X POST http://localhost:5935/depositFunds \  
      -d "amount=1000000000000000000"  # 1 ETH in wei  `,
      preNote: "Deposit ETH funds into your Gateway (if needed):",
      description: "Deposit ETH funds into your Gateway. 1 ETH in wei is 1000000000000000000",
      output: `  
      {  
        "success": true  
      }  
      `
    },
    checkDeposit: {
      filename: "Verify Deposit",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/status | jq '.broadcaster.deposit'`,
      preNote: "Veirfy your Deposit:",
      description: "Check your Deposit:",
      output: `  
      {  
        "deposit": "1000000000000000000"  
      }  
      `
    },
    depositFundsAndReserve: {
      filename: "Deposit Funds",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/fundDepositAndReserve -X POST -d '{"deposit": "100000000000000000", "reserve": "100000000000000000"}' -H "Content-Type: application/json"`,
      preNote: "Deposit funds into your Gateway:",
      description: "Deposit funds into your Gateway:",
      output: `  
      {  
        "success": true  
      }  
      `
    },
    checkTicketParams: {
      filename: "Check Ticket Parameters",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/getOrchestrators | jq '.[].ticketParams'`,
      preNote: "Check ticket parameters:",
      description: "Check ticket parameters:",
      output: `  
      {  
        "ticketParams": {  
          "expiration": 100,  
          "fee": 0,  
          "maxPrice": 1000,  
          "minPrice": 100  
        }  
      }  
      `
    },
    checkPriceInfo: {
      filename: "Check Price Info",
      icon: "terminal",
      language: "bash",
      codeString: `curl http://localhost:5935/getOrchestrators | jq '.[].priceInfo'`,
      preNote: "Verify price information:",
      description: "Check price info:",
      output: `  
      {  
        "priceInfo": {  
          "pricePerUnit": 100,  
          "pixelsPerUnit": 1  
        }  
      }  
      `
    },
    withdrawFunds: {
      filename: "Withdraw Funds",
      icon: "terminal",
      language: "bash",
      codeString: `curl -X POST http://localhost:5935/withdrawFunds`,
      preNote: "Test withdrawal (if funds are unlocked):",
      description: "Withdraw funds from your Gateway:",
      output: `  
      {  
        "success": true  
      }  
      `
    }
  },
  test: {
    basic: {
      checkStatus: {
        filename: "Check Gateway Status",
        icon: "terminal",
        language: "bash",
        codeString: `curl http://localhost:5935/status`,
        preNote: "Check if your Gateway node is running:",
        description: "The status endpoint returns a json with node information including type, addresses, and balances.",
        output: {
          language: "json",
          icon: "curly-braces",
          codeString: `
        {  
          "availability": 100,  
          "broadcaster": {  
            "address": "0x...",  
            "deposit": "1000000000000000000",  
            "withdrawRound": "0"  
          },  
          "eth": {  
            "accountAddr": "0x...",  
            "balance": "1000000000000000000"  
          },  
          "nodeType": "BroadcasterNode",  
          "version": "0.5.32"  
        }
      `
        }
      },
      checkAvailableOrchestrators: {
        filename: "Check Available Orchestrators",
        icon: "terminal",
        language: "bash",
        codeString: `curl http://localhost:5935/getOrchestrators`,
        preNote: "Check available orchestrators:"
      },
      verifyEthConnection: {
        filename: "Verify ETH Connection",
        icon: "terminal",
        language: "bash",
        codeString: `curl http://localhost:5935/status | jq '.eth'`,
        preNote: "Verify your Gateway has an active Ethereum connection:",
        description: "The ETH section should show your account address and balance. If it shows default values, your ETH connection is not active.",
        output: `
        {  
          "accountAddr": "0x...",  
          "balance": "1000000000000000000"  
        }  
        `
      }
    },
    video: {
      sendVideo: {
        filename: "Send a Video Stream",
        icon: "terminal",
        language: "bash",
        codeString: `ffmpeg -re -i test-video.mp4 -c copy -f flv rtmp://localhost:1935/stream/test-key`,
        wrap: true,
        preNote: ""
      },
      testRTMPingest: {
        filename: "Test RTMP Ingest",
        icon: "terminal",
        language: "bash",
        codeString: `ffmpeg -re -i test-video.mp4 -c copy -f flv rtmp://localhost:1935/stream/test-key`,
        preNote: "Send a Video Stream using FFmpeg:"
      },
      testHTTPingest: {
        filename: "Test HTTP Ingest",
        icon: "terminal",
        language: "bash",
        codeString: `curl -X PUT http://localhost:8935/live/test/0.ts --data-binary @test-segment.ts`,
        preNote: "Test your HTTP Ingest Stream by pushing a segment:"
      },
      testHLS: {
        filename: "Access HLS Stream",
        icon: "terminal",
        language: "bash",
        codeString: `curl http://localhost:8935/hls/test-key/index.m3u8`,
        preNote: "Test playback by accessing the HLS stream:"
      },
      scriptVerify: {
        filename: "Use the build-in test stream to verify",
        icon: "terminal",
        language: "bash",
        codeString: `# Generate a test pattern and stream  
        ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30,format=yuv420p \  
        -c:v libx264 -b:v 1000k -f flv rtmp://localhost:1935/stream/test-key`
      }
    },
    ai: {
      textToImage: {
        filename: "Text-to-Image",
        icon: "terminal",
        language: "bash",
        codeString: `curl -X POST http://localhost:8935/text-to-image \  
        -H "Content-Type: application/json" \  
        -d '{  
          "prompt": "A beautiful sunset over mountains",  
          "model_id": "stabilityai/sdxl-turbo"  
        }'`,
        preNote: "Test Text-to-Image:",
        description: "Test Text-to-Image:",
        output: `  
        {  
          "image": "base64-encoded-image-data"  
        }  
        `
      },
      imageToImage: {
        filename: "Image-to-Image",
        icon: "terminal",
        language: "bash",
        codeString: `curl -X POST http://localhost:8935/image-to-image \  
        -F "prompt=Turn this into a watercolor painting" \  
        -F "model_id=stabilityai/sdxl-turbo" \  
        -F "image=@input.jpg"`,
        preNote: "Test Image-to-Image:",
        description: "Test Image-to-Image:",
        output: `  
        {  
          "image": "base64-encoded-image-data"  
        }  
        `
      },
      LLM: {
        filename: "LLM",
        icon: "terminal",
        language: "bash",
        codeString: `curl -X POST http://localhost:8935/llm \  
        -H "Content-Type: application/json" \  
        -d '{  
          "model": "meta-llama/llama-3.1-8B-Instruct",  
          "messages": [  
            {"role": "user", "content": "Hello"}  
          ]  
        }'`,
        preNote: "Test LLM:",
        description: "Test LLM:",
        output: `  
        {  
          "choices": [  
            {"message": {"role": "assistant", "content": "Hello! How can I help you today?"}}  
          ]  
        }  
        `
      }
    }
  }
};

export const DOCKER_YML = {
  offChain: {
    videoMin: `
services:
  video-gateway:
    image: livepeer/go-livepeer:master
    container_name: gateway
    hostname: gateway
    ports:
      # RTMP for video ingest
      - 1935:1935
      # HTTP API (optional)
      - 8935:8935
    volumes:
      - gateway-lpData:/root/.lpData
    command:
      # REQUIRED
      - -gateway
      # Connects to your orchestrator(s)
      - -orchAddr=<ORCHESTRATOR_ADDRESSES>
      # Optional. Defaults to localhost
      - -httpAddr=0.0.0.0:8935

volumes:
  gateway-lpData:
    external: true
`,
    video: `
  services:  
    video-gateway:  
        image: livepeer/go-livepeer:master  
        container_name: 'gateway'  
        hostname: 'gateway'  
        ports:  
          - 1935:1935  # Required. RTMP for video ingest  
          - 8935:8935  # HTTP API for both video and AI  
          - 5935:5935  # CLI port (optional - exposes CLI API, defaults to localhost)  
        volumes:  
          - gateway-lpData:/root/.lpData  
        command: 
                    # REQUIRED
                    -gateway
                    -orchAddr=<ORCHESTRATOR_ADDRESSES> # Connects to your orchestrator(s)

                    # OPTIONAL (Recommended)
                    -httpIngest # Enables HTTP video ingest (in addition to RTMP)
                    -monitor=true # Enables metrics collection
                    -v=6 # Verbosity level
                    -rtmpAddr=0.0.0.0:1935 # Open RTMP port to external RTMP (video) stream connections. Defaults to localhost
                    -httpAddr=0.0.0.0:8935 # Open HTTP port to external connections: HLS playback, HTTP ingest, and API endpoints (default: localhost)
                    -cliAddr=0.0.0.0:5935 # Exposes the CLI API. Defaults to 127.0.0.1:7935 (localhost)
                    -transcodingOptions=P240p30fps16x9,P360p30fps16x9,P720p30fps16x9 # Higher Quality transcoding options. Defaults to P240p30fps16x9,P360p30fps16x9
                    # OR -transcodingOptions=/root/.lpData/transcodingOptions.json (path to local file instead)
                    -maxSessions=5 # Limit Concurrent sessions. Defaults to 10

  volumes:  
    gateway-lpData:  
      external: true
`,
    aiMin: `
services:
  ai-gateway:
    image: livepeer/go-livepeer:master
    container_name: ai-gateway
    hostname: ai-gateway
    ports:
      # HTTP API for AI
      - 8935:8935
    volumes:
      - ai-gateway-lpData:/root/.lpData
    command:
      # REQUIRED
      - -gateway
      # Connects to your orchestrator(s)
      - -orchAddr=<ORCHESTRATOR_ADDRESSES>
      # Enables AI HTTP endpoints
      - -httpIngest

volumes:
  ai-gateway-lpData:
    external: true
`,
    ai: `
services:
  ai-gateway:
    image: livepeer/go-livepeer:master
    container_name: ai-gateway
    hostname: ai-gateway
    ports:
      # HTTP API for AI (required)
      - 8935:8935
      # CLI port (optional)
      - 5935:5935
    volumes:
      - ai-gateway-lpData:/root/.lpData
    command:
      # REQUIRED
      - -gateway
      # Connects to your orchestrator(s)
      - -orchAddr=<ORCHESTRATOR_ADDRESSES>
      # Enables AI HTTP endpoints
      - -httpIngest

      # OPTIONAL (Recommended)
      # Enables metrics collection
      - -monitor=true
      # Verbosity level
      - -v=6
      # Exposes HTTP API externally
      - -httpAddr=0.0.0.0:8935
      # Exposes the CLI API. Defaults to localhost
      - -cliAddr=0.0.0.0:5935

volumes:
  ai-gateway-lpData:
    external: true
`,
    dualMin: `
services:
  dual-gateway:
    image: livepeer/go-livepeer:master
    container_name: dual-gateway
    hostname: dual-gateway
    ports:
      # RTMP for video ingest
      - 1935:1935
      # HTTP API for both video and AI
      - 8935:8935
    volumes:
      - dual-gateway-lpData:/root/.lpData
    command:
      # REQUIRED
      - -gateway
      # Connects to your orchestrator(s)
      - -orchAddr=<ORCHESTRATOR_ADDRESSES>
      # Enables AI HTTP endpoints
      - -httpIngest

volumes:
  dual-gateway-lpData:
    external: true
`,
    dual: `
services:
  dual-gateway:
    image: livepeer/go-livepeer:master
    container_name: dual-gateway
    hostname: dual-gateway
    ports:
      - 1935:1935 # RTMP expose (video)
      - 8935:8935 # HTTP API expose (AI/video)
      - 5935:5935 # CLI port expose (optional)
    volumes:
      - dual-gateway-lpData:/root/.lpData
    command:
      # REQUIRED
      - -gateway
      - -httpIngest
      - -orchAddr=<http://ORCHESTRATOR_IP:PORT>

      # OPTIONAL (Recommended)
      - -monitor=true
      - -v=6
      - -rtmpAddr=0.0.0.0:1935
      - -httpAddr=0.0.0.0:8935
      - -cliAddr=0.0.0.0:5935
      - -transcodingOptions=P240p30fps16x9,P360p30fps16x9,P720p30fps16x9
      - -maxSessions=5

volumes:
  dual-gateway-lpData:
    external: true
`
  },
  onChain: {
    video: `
services:
  video-gateway:
    image: livepeer/go-livepeer:master
    container_name: video-gateway
    hostname: video-gateway
    ports:
      # RTMP for video ingest
      - 1935:1935
      # HTTP API for video (optional)
      - 8935:8935
      # CLI port (optional)
      - 5935:5935
    volumes:
      - video-gateway-lpData:/root/.lpData
      # (optional) Mount your own keystore
      # - ./keystore:/root/.lpData/keystore
    command:
      # REQUIRED
      - -gateway
      # Network to connect to (default: offchain)
      - -network=arbitrum-one-mainnet
      # RPC to interface with Arbitrum Mainnet Blockchain
      - -ethUrl=https://arb1.arbitrum.io/rpc

      # OPTIONAL (Recommended)
      # Enables HTTP video ingest (in addition to RTMP)
      - -httpIngest
      # Enables metrics collection
      - -monitor=true
      # Verbosity level
      - -v=6
      # Open RTMP port externally. Defaults to localhost
      - -rtmpAddr=0.0.0.0:1935
      # Open HTTP port externally. Defaults to localhost
      - -httpAddr=0.0.0.0:8935
      # Exposes the CLI API. Defaults to localhost
      - -cliAddr=0.0.0.0:5935
      # Higher quality transcoding options
      - -transcodingOptions=P240p30fps16x9,P360p30fps16x9,P720p30fps16x9
      # Limit concurrent sessions. Defaults to 10
      - -maxSessions=5

      # OPTIONAL (Advanced: Wallet Options - auto-generated if not provided)
      # Bring your own ETH account address
      # - -ethAcctAddr=<ETH_ACCOUNT_ADDRESS>
      # Path to keystore directory or keyfile
      # - -ethKeystorePath=/root/.lpData/keystore
      # Path to password file
      # - -ethPassword=/root/.lpData/keystore/password.txt

      # OPTIONAL (Advanced: Pricing Options)
      # Max price per pixel in wei (defaults to 0: ANY price)
      # - -maxPricePerUnit=1000000000

volumes:
  video-gateway-lpData:
    external: true
`,
    ai: `
services:
  ai-gateway:
    image: livepeer/go-livepeer:master
    container_name: ai-gateway
    hostname: ai-gateway
    ports:
      # HTTP API for AI
      - 8935:8935
      # CLI port (optional)
      - 5935:5935
    volumes:
      - ai-gateway-lpData:/root/.lpData
      # (optional) Mount your own keystore
      # - ./keystore:/root/.lpData/keystore
    command:
      # REQUIRED
      - -gateway
      # Enables AI HTTP endpoints
      - -httpIngest
      # Enables AI on-chain service registry
      - -aiServiceRegistry
      # Network to connect to (default: offchain)
      - -network=arbitrum-one-mainnet
      # RPC to interface with Arbitrum Mainnet Blockchain
      - -ethUrl=https://arb1.arbitrum.io/rpc

      # OPTIONAL (Recommended)
      # Enables metrics collection
      - -monitor=true
      # Verbosity level
      - -v=6
      # Open HTTP port externally. Defaults to localhost
      - -httpAddr=0.0.0.0:8935
      # Exposes the CLI API. Defaults to localhost
      - -cliAddr=0.0.0.0:5935

      # OPTIONAL (Advanced: Wallet Options - auto-generated if not provided)
      # Bring your own ETH account address
      # - -ethAcctAddr=<ETH_ACCOUNT_ADDRESS>
      # Path to keystore directory or keyfile
      # - -ethKeystorePath=/root/.lpData/keystore
      # Path to password file
      # - -ethPassword=/root/.lpData/keystore/password.txt

      # OPTIONAL (Advanced: Pricing Options)
      # Max price per AI capability (pipeline/model)
      # - -maxPricePerCapability=/path/to/your/config.json
      # Payment processing frequency for Live AI Video workflows
      # - -livePaymentInterval=5s

volumes:
  ai-gateway-lpData:
    external: true
`,
    dual: `
services:
  dual-gateway:
    image: livepeer/go-livepeer:master
    container_name: dual-gateway
    hostname: dual-gateway
    ports:
      - 1935:1935 # RTMP for video ingest
      - 8935:8935 # HTTP API (AI / video)
      - 5935:5935 # CLI port (optional, recommended)
    volumes:
      - dual-gateway-lpData:/root/.lpData
      # - ./keystore:/root/.lpData/keystore  # (optional) Mount your own keystore
    command:
      # REQUIRED
      - -gateway
      - -httpIngest
      - -aiServiceRegistry
      - -network=arbitrum-one-mainnet
      - -ethUrl=https://arb1.arbitrum.io/rpc

      # OPTIONAL (Recommended)
      - -monitor=true
      - -v=6
      - -rtmpAddr=0.0.0.0:1935
      - -httpAddr=0.0.0.0:8935
      - -cliAddr=0.0.0.0:5935
      - -transcodingOptions=P240p30fps16x9,P360p30fps16x9,P720p30fps16x9
      - -maxSessions=5

      # OPTIONAL (Wallet Options, Auto-generated if not provided)
      # - -ethAcctAddr=<ETH_ACCOUNT_ADDRESS>
      # - -ethKeystorePath=/root/.lpData/keystore
      # - -ethPassword=/root/.lpData/keystore/password.txt # !! NOT your private key!

      # OPTIONAL (Recommended: Pricing Options)
      - -maxPricePerUnit=1000000000 # video 
      - -maxPricePerCapability=/path/to/aiPricing.json #ai
      # - -livePaymentInterval=5s

      # OPTIONAL (Advanced Config: Authentication)
      # - -authWebhookUrl=https://your-auth-webhook.com

volumes:
  dual-gateway-lpData:
    external: true
`
  }
};

export const DOCKER_CODE = {
  install: {
    filename: "Install go-livepeer",
    icon: "terminal",
    language: "bash",
    codeString: `docker pull livepeer/go-livepeer:stable`
  },
  create: {
    filename: "Create the Gateway Volume",
    icon: "terminal",
    language: "bash",
    codeString: `docker volume create dual-gateway-lpData`,
    description: "Creates a Docker volume with the name `dual-gateway-lpData` for persistent storage.",
    output: ` ✔ Volume dual-gateway-lpData  Created`
  },
  run: {
    filename: "Run the Gateway",
    icon: "terminal",
    language: "bash",
    codeString: `docker-compose up -d`,
    description: "Starts the gateway container in detached mode (-d flag). The volume is created if it doesn't exist.",
    output: `
    [+] Running 2/2  
    ✔ Volume dual-gateway-lpData  Created  
    ✔ Container dual-gateway    Started `
  },
  verify: {
    filename: "Verify Gateway is Running",
    icon: "terminal",
    language: "bash",
    codeString: `docker logs dual-gateway`,
    description: "The logs show the gateway starting up, binding to the configured ports, and connecting to the orchestrator",
    postNote: "Expected Output:",
    output: {
      icon: "docker",
      codeString: `
INFO[0000] Livepeer v0.5.32  
INFO[0000] Starting Livepeer node...  
INFO[0000] Node type: BroadcasterNode  
INFO[0000] RTMP server listening on 0.0.0.0:1935  
INFO[0000] HTTP server listening on 0.0.0.0:8935  
INFO[0000] CLI server listening on 0.0.0.0:5935  
INFO[0000] Connected to orchestrator at <ORCHESTRATOR_IP:PORT>  
INFO[0000] Gateway ready  
    `
    }
  },
  flags: {
    filename: "View all available flags",
    icon: "terminal",
    language: "bash",
    codeString: `docker run --rm livepeer/go-livepeer:master -help`
  },
  sendVideo: {
    filename: "Verify FFmpeg is installed",
    icon: "terminal",
    language: "bash",
    codeString: `docker run --rm -v "$(pwd):/workspace" -w /workspace \  
      jrottenberg/ffmpeg:4.4-alpine \  
      -re -i test-video.mp4 -c copy -f flv rtmp://host.docker.internal:1935/stream/test-key`,
    preNote: "",
    postNote: "Use host.docker.internal instead of localhost when running FFmpeg from a Docker container to connect to services on the host machine."
  },
  verifyEthConnection: {
    filename: "Verify ETH Connection",
    icon: "terminal",
    language: "bash",
    codeString: `docker logs dual-gateway | grep -i "ethereum\|eth\|blockchain"`,
    preNote: "Ensure your Gateway is properly configured by verifying that your Gateway has an active Ethereum connection:",
    description: "The logs should show the ETH account address, balance, and connection status.",
    output: `
    INFO[0000] ETH account address: 0x...  
    INFO[0000] ETH balance: 1000000000000000000  
    INFO[0000] ETH connection active
    `
  },
  verifyOnChainConfig: {
    filename: "Verify On-Chain Configuration",
    icon: "terminal",
    language: "bash",
    codeString: `# Verify Ethereum connection  
docker logs dual-gateway | grep -i "ethereum\|eth\|blockchain"  
    
# Check account address
curl http://localhost:5935/status | jq '.eth.accountAddr'
    `,
    preNote: `
      The gateway must have an active Ethereum connection and valid account.
      
      Before testing, verify your Gateway is properly configured by checking the on-chain settings:
      `,
    postNote: "Expected Output:",
    description: "The logs should show the ETH account address, balance, and connection status.",
    output: {
      icon: "docker",
      codeString: `
INFO[0000] ETH account address: 0x...  
INFO[0000] ETH balance: 1000000000000000000  
INFO[0000] ETH connection active
    `
    }
  }
};

{/* DATA & CODE */}

{/* BANNERS, CALLOUTS, VALUE STRINGS */}

{/* COMPONENTS */}

{/* LAYOUTS & VIEWS */}

<IconCallout showArrow>
  <Subtitle fontSize="1rem"> Use the <Icon icon="circle-chevron-down" /> **Dropdown** at the top-right of this page to view the Quickstart Guide
  for your preferred OS. </Subtitle>
</IconCallout>

<WidthCard title="go-livepeer" href="https://github.com/livepeer/go-livepeer" icon="github" arrow horizontal>
  <span> *Latest Version:* <Badge color="green">{latestVersion}</Badge> </span>
</WidthCard>

<CustomDivider style={{narginTop: "-1rem", marginBottom: "-1rem"}} />

# Let's Go(-Livepeer) ! <Icon icon="face-grin-wink" size={26} />

This page will get you up & running with a Livepeer Gateway Node for <Badge color="blue">Video</Badge> Transcoding & <Badge color="purple">AI</Badge> Pipeline service routing.

*This guide includes:*

* Setup for <span><Icon icon="link" size={20} /> **on-chain *(production)*** and <Icon icon="floppy-disk" size={20} /> **off-chain *(local/dev)*** Livepeer Gateway nodes </span>
* Installation guides for <span><Icon icon="docker" size={20} /> **Docker *(recommended)*** </span> and <span><Icon icon="laptop-code" size={20} /> **Pre-Built Binaries**. </span>

<Note>
  <Subtitle fontSize="1rem"><Icon icon="docker" size={20} /> [Docker](https://docs.docker.com/get-docker/) is the recommended way to install and run a Livepeer Gateway Node.</Subtitle>

  <br />

  <br /><Subtitle fontSize="1rem"><Icon icon="linux" size={20} /> [Linux OS](https://linux.org) is recommended for production use.</Subtitle>
</Note>

<br />

<View title=" Docker" icon="docker" iconType="solid">
  ## <Icon icon="docker" iconType="solid" size={32} /> Docker Quickstart Guide

  <FlexContainer gap="1rem" wrap>
    <FlexContainer direction="row" gap="0.2rem" align="flex-start">
      <Icon icon="linux" color="var(--lp-color-brand-linux)" size={22} />

      <Badge> Linux </Badge>
    </FlexContainer>

    <FlexContainer direction="row" gap="0.2rem" align="flex-start">
      <Icon icon="windows" color="var(--lp-color-brand-windows)" size={22} />

      <Badge> Windows <Icon icon="warning" size={12} /></Badge>
    </FlexContainer>

    <FlexContainer direction="row" align="flex-start">
      <Icon icon="apple" color="var(--lp-color-brand-macos)" size={22} />

      <Badge> MacOS <Icon icon="warning" size={12} /></Badge>
    </FlexContainer>
  </FlexContainer>

  <br />

  <Accordion title="Docker Supported Hosts Details" icon="warning">
    ## Docker OS Support for Livepeer Gateway

    Docker supports running Livepeer Gateway nodes on <Badge stroke color="yellow" icon="linux" size="sm"> **Linux**</Badge>, <Badge stroke color="green" icon="apple" size="sm"> **macOS**</Badge>, and <Badge stroke color="blue" icon="windows" size="sm"> **Windows**</Badge> with different architecture support and feature limitations.

    <br />

    <br />

    **Supported Platforms**

    | OS                                                                      | Architectures | GPU Compute Support         | Notes                    |
    | ----------------------------------------------------------------------- | ------------- | --------------------------- | ------------------------ |
    | <Badge stroke color="yellow" icon="linux" size="sm">**Linux**</Badge>   | amd64, arm64  | NVIDIA (GPU workloads only) | Full feature support     |
    | <Badge stroke color="green" icon="apple" size="sm">**macOS**</Badge>    | amd64, arm64  | No                          | **CPU-only transcoding** |
    | <Badge stroke color="blue" icon="windows" size="sm">**Windows**</Badge> | amd64         | No                          | **CPU-only transcoding** |

    <Note>
      NVIDIA drivers are not a baseline requirement for a Gateway. They are only
      required when the same host is also running GPU workloads such as an
      Orchestrator or AI worker.
    </Note>

    ## Implementation Details

    #### Docker Build Configuration

    The Dockerfile uses a multi-stage build with CUDA base images for GPU support. The build process supports cross-compilation for multiple architectures.

    #### Build Matrix

    The CI/CD pipeline builds for:

    * <Badge stroke color="yellow" icon="linux" size="sm">**Linux** </Badge> amd64/arm64 (CPU and GPU variants)
    * <Badge stroke color="green" icon="apple" size="sm">**macOS** </Badge> amd64/arm64 (CPU only)
    * <Badge stroke color="blue" icon="windows" size="sm">**Windows** </Badge> amd64 (CPU only)

    #### Cross-Compilation Support

    The Makefile includes cross-compilation configuration for different platforms:

    * <Badge stroke color="green" icon="apple" size="sm"> Darwin (macOS)</Badge> with Intel and Apple Silicon
    * <Badge stroke color="yellow" icon="linux" size="sm"> Linux </Badge> with x86\_64 and ARM64
    * <Badge stroke color="blue" icon="windows" size="sm"> Windows</Badge> x86\_64

    ### GPU Limitations

    GPU transcoding is <Badge stroke color="yellow" icon="linux"> **Linux only** </Badge>.
    The Docker images include NVIDIA CUDA support but *this only works on **Linux hosts.***

    ### Notes

    * ARM64 Docker images are built but note that **ARM64 support is still experimental**
    * For production use, **Linux is recommended for full feature support**
    * *macOS and Windows support is primarily for **development and testing***
    * The box development environment supports both Linux and macOS: <br />

    <Icon icon="github" size={20} /> [Box Example Gateway](https://github.com/livepeer/go-livepeer/blob/master/box/box.md) <Icon icon="arrow-up-right" color="var(--lp-color-accent)" size={10} />
  </Accordion>

  This guide will install and configure a Gateway to run video & AI workloads.

  <Tip>
    Docker is the recommended install method for most users.
  </Tip>

  ***Choose your Gateway Mode:***

  <Tabs>
    <Tab title="Off-Chain Gateway" icon="floppy-disk">
      <GatewayOffChainWarning />

      <Steps titleSize="h3">
        <Step title="Install Gateway Software">
          Pull the Docker image from <Icon icon="arrow-up-right" color="var(--accent)" /> [Livepeer Docker Hub]("https://hub.docker.com/r/livepeer/go-livepeer")

          <CustomCodeBlock {...DOCKER_CODE.install} wrap />
        </Step>

        <Step title="Configure Gateway">
          <Badge color="blue">Video</Badge> {" "} <Badge color="purple">AI</Badge>

          Create the `docker-compose.yml` file that defines the <Badge color="green">dual</Badge> Gateway service.

          <OrchAddrNote />

          <CustomCodeBlock codeString={DOCKER_YML.offChain.dual} language="yaml" icon="docker" filename="docker-compose.yml" highlight="[18]" expandable={true} wrap={false} />

          <Danger> fix me </Danger>
          *See flag details below:*

          <AccordionGroup>
            <ResponseFieldAccordion title="Required Flags" icon="file-circle-exclamation" fields={CONFIG_FLAGS.offchain.required} />

            <ResponseFieldAccordion title="Recommended Flags" icon="file-circle-info" fields={CONFIG_FLAGS.offchain.optional} />
          </AccordionGroup>

          *See Example transcoding options json below:*

          <Accordion title="Transcoding Options Example" icon="brackets-curly">
            <CustomCodeBlock codeString={CONFIG_FILES.video.transcodingOptionsJson} language="json" icon="brackets-curly" filename="Example transcodingOptions.json" />
          </Accordion>
        </Step>

        <Step title="Run Gateway">
          <CustomCodeBlock {...DOCKER_CODE.create} />

          <CustomCodeBlock {...DOCKER_CODE.run} />

          <CustomCodeBlock {...DOCKER_CODE.verify} />
        </Step>

        <Step title="Test Gateway">
          <Danger> Fix me (onchain nicer) </Danger>

          <Tabs>
            <Tab title="Video" icon="camera-movie">
              Send a video stream to the Gateway:

              <TestVideoDownload>
                <DownloadButton label="test-video.mp4" downloadLink="https://raw.githubusercontent.com/livepeer/docs/docs-v2-assets/snippets/assets/domain/04_GATEWAYS/test-video.mp4" />
              </TestVideoDownload>

              From a host terminal (not in Docker or Volume), run this command:

              <CustomCodeBlock {...BASH_CODE.testRTMPingest} />

              After streaming, check the HLS playback output:

              <CustomCodeBlock {...BASH_CODE.testHLS} wrap />

              Tips:

              * Replace localhost with your Gateway's IP if running remotely
              * The stream name (test) becomes part of the HLS playback URL
            </Tab>

            <Tab title="AI" icon="user-robot">
              To test AI functionality in Livepeer, you can make HTTP requests to the AI endpoints exposed by your Gateway.
              The Gateway routes these requests to Orchestrators with AI workers for processing.

              <CustomCodeBlock {...BASH_CODE.testHTTPingest} wrap />

              <CustomCodeBlock {...BASH_CODE.checkStatus} wrap />

              <CustomCodeBlock {...BASH_CODE.aiCapabilities} wrap />

              Use the AI API to test functionality of available models.

              <Expandable title="AI API Example Commands">
                <Danger> Fix code formatting </Danger>

                <br />

                <CustomCodeBlock {...AI_TEST_COMMANDS.textToImage} wrap />

                <CustomCodeBlock {...AI_TEST_COMMANDS.LLM} wrap />

                <CustomCodeBlock {...AI_TEST_COMMANDS.liveVideoAI} wrap />
              </Expandable>

              <Card title="AI API" href="/v2/gateways/resources/reference/technical/api-reference/AI-API/ai" icon="books" arrow horizontal>
                View AI API Full Reference here
              </Card>
            </Tab>
          </Tabs>
        </Step>

        <Step title="Monitor Gateway">
          <Danger> Needs Review </Danger>
          The `-monitor=true` flag in the docker-compose.yml already has basic monitoring enabled which exposes metrics in Prometheus format at `http://localhost:8935/metrics`.

          Metrics collected include:

          * Stream metrics (created, started, ended)
          * Transcoding metrics (success rate, latency)
          * Payment metrics (tickets sent, deposits)
          * AI-specific metrics (attempts, Orchestrators available)

          *See More Metrics Options Below:*

          <Accordion title="Prometheus Metrics" icon="monitor-waveform">
            Access Prometheus metrics at:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:8935/metrics
            ```

            Key metrics include:

            * `livepeer_stream_created_total` - Total streams created
            * `livepeer_current_sessions_total` - Active transcoding sessions
            * `livepeer_success_rate` - Transcoding success rate
            * `livepeer_ai_live_attempts` - AI processing attempts
            * `livepeer_gateway_deposit` - Current ETH deposit
          </Accordion>

          <Accordion title="CLI Monitoring Commands" icon="terminal">
            *CLI Monitoring Commands*

            Check Gateway status:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:5935/status
            ```

            Monitor available Orchestrators:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:5935/getOrchestrators
            ```

            See all CLI options:

            <CustomCodeBlock {...DOCKER_CODE.flags} />

            ```bash Run Livepeer CLI theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              livepeer_cli # livepeer_cli --host=localhost --http=5935
            ```

            ```bash Livepeer CLI Output theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            +-----------------------------------------------------------+
            | Welcome to livepeer-cli, your Livepeer command line tool  |
            +-----------------------------------------------------------+

            What would you like to do? (default = stats)
            1. Get node status
            2. View protocol parameters
            3. List registered orchestrators
            4. Invoke "initialize round"
            5. Invoke "bond"
            ...
            ```
          </Accordion>

          <Accordion title="AI-Specific Monitoring" icon="user-robot">
            *AI-Specific Monitoring*

            For AI workflows, the Gateway sends detailed events including:

            * Stream request events
            * Orchestrator selection info
            * Ingest metrics
            * Error events
          </Accordion>

          <Accordion title="Enhanced Monitoring Options" icon="chart-line">
            *Enhanced Monitoring Options*

            Add to your Docker Compose for more monitoring:

            ```yaml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            # Enable per-stream metrics
            - -metricsPerStream=true

            # Expose client IPs in metrics
            - -metricsClientIP=true

            # Kafka integration (requires setup)
            - -kafkaBootstrapServers=kafka:9092
            - -kafkaUser=username
            - -kafkaPassword=password
            - -kafkaGatewayTopic=livepeer-gateway
            ```
          </Accordion>

          <Accordion title="Log Monitoring" icon="file-lines">
            *Log Monitoring*

            Monitor logs in real-time:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            docker logs -f dual-gateway
            ```

            Look for key events:

            * "Received live video AI request"
            * "Orchestrator selected"
            * "Transcoding completed"
            * Payment processing events
          </Accordion>
        </Step>

        <Step title="Gateway Tips">
          See all available config flags:

          <CustomCodeBlock {...DOCKER_CODE.flags} />

          {/* The -orchAddr flag is required and must point to a running orchestrator */}

          Useful [CLI Commands](/v2/Gateways/resources/reference/technical/cli-commands) <Icon icon="arrow-up-right" />

          <CustomCodeBlock {...CLI_CODE.cliOptions} />
        </Step>
      </Steps>
    </Tab>

    { /* Needs to be further destructured */}

    {/* #### Quick Summary: Off-Chain vs On-Chain Gateway Differences

        | Aspect | Off-Chain Gateway | On-Chain Gateway |
        |--------|------------------|------------------|
        | **Ethereum** | No RPC needed | Requires `-ethUrl` and wallet |
        | **Network** | Default: offchain | Specify network (e.g., arbitrum-one-mainnet) |
        | **Payments** | No blockchain payments | Ticket-based micropayments |
        | **Verification** | Disabled by default | Enabled by default |
        */}

    {/* - You have ETH on Arbitrum L2 Network (or can get it from a faucet) */}

    <Tab title="On-Chain Gateway" icon="link">
      This guide will set up a Livepeer Gateway on the [Arbitrum One Mainnet](https://arbitrum.io/).

      <Accordion title="Looking for a 'testnet'?" icon="info-circle">
        While Livepeer contracts are deployed to Arbitrum Testnet, there is currently no reliable Orchestrator services on this chain.

        <Note>
          If you would like to use the [Aribtum Testnet](#Arbitrum-testnet) for testing, you will need to run your own Orchestrator node there to connect to.
        </Note>

        There are conversations underway to enable a public "testnet" in the future.

        Follow & contribute to the discussion on the
        <Icon icon="arrow-up-right" color="var(--lp-color-accent)" /> [Discord](https://discord.gg/livepeer) and
        <Icon icon="arrow-up-right" color="var(--lp-color-accent)" /> [Forum](https://forum.livepeer.org)
      </Accordion>

      <GatewayOnChainWarning />

      <Steps titleSize="h3">
        <Step title="Install Gateway Software">
          Pull the Docker image from <Icon icon="arrow-up-right" color="var(--lp-color-accent)" /> [Livepeer Docker Hub]("https://hub.docker.com/r/livepeer/go-livepeer")

          <CustomCodeBlock {...DOCKER_CODE.install} wrap />
        </Step>

        <Step title="Configure Gateway">
          <Badge color="blue">Video</Badge> {" "} <Badge color="purple">AI</Badge>

          Create the `docker-compose.yml` file that defines the <Badge color="green">dual</Badge> Gateway service.

          <CustomCodeBlock codeString={DOCKER_YML.onChain.dual} language="yaml" icon="docker" filename="docker-compose.yml" expandable={true} wrap={false} />

          <Danger> Needs edit, better explanation & format </Danger>
          *See flag details below:*

          <AccordionGroup>
            <ResponseFieldAccordion title="Required Flags" icon="file-circle-exclamation" fields={CONFIG_FLAGS.onchain.required} />

            <ResponseFieldAccordion title="Recommended Flags" icon="file-circle-info" fields={CONFIG_FLAGS.onchain.optional} />

            <ResponseFieldAccordion title="Wallet, Pricing & Auth Flag Options" icon="file-circle-info" fields={CONFIG_FLAGS.onchain.optionalAdvanced} />
          </AccordionGroup>

          *See Configuration File Examples below:*

          <AccordionGroup>
            <Accordion title="Transcoding Options Example" icon="brackets-curly">
              <CustomCodeBlock codeString={CONFIG_FILES.video.transcodingOptionsJson} language="json" icon="brackets-curly" filename="Example transcodingOptions.json" />
            </Accordion>

            <Accordion title="AI Capability Pricing Example" icon="brackets-curly">
              <CustomCodeBlock codeString={CONFIG_FILES.ai.aiPricingJson} language="json" icon="brackets-curly" filename="Example aiPricing.json" />
            </Accordion>
          </AccordionGroup>
        </Step>

        <Step title="Run Gateway">
          <CustomCodeBlock {...DOCKER_CODE.create} />

          <CustomCodeBlock {...DOCKER_CODE.run} />

          <CustomCodeBlock {...DOCKER_CODE.verify} />

          <CustomCodeBlock {...DOCKER_CODE.verifyOnChainConfig} />
        </Step>

        <Step title="Connect Gateway">
          For on-chain mode, Orchestrator discovery happens automatically.

          <CustomCodeBlock {...BASH_CODE.checkAvailableOrchestrators} preNote="Verify Orchestrator discovery:" />

          <Note>
            * On-chain discovery requires ETH in your Gateway account for transactions
            * The Gateway will show "No Orchestrator specified; transcoding will not happen" if discovery fails
          </Note>

          The [Livepeer Explorer Orchestrator Performance Leaderboard](https://explorer.livepeer.org/leaderboard) can also show you a list of all available Orchestrators & their capabilities & services.
        </Step>

        <Step title="Test Gateway">
          <Accordion title="Verify Configuration" icon="tools">
            \*Verify Ethereum connection
            Docker logs dual-Gateway | grep -i "Ethereum|ETH|blockchain"

            Check account address
            curl [http://localhost:5935/status](http://localhost:5935/status) | jq '.ETH.accountAddr'
          </Accordion>

          <Accordion title="Basic Connectivity Tests" icon="wifi">
            *Basic Connectivity Tests:*

            <CustomCodeBlock {...DOCKER_CODE.verifyEthConnection} />

            These tests verify the Gateway is running and can discover Orchestrators:

            <CustomCodeBlock {...BASH_CODE.checkStatus} />

            <CustomCodeBlock {...BASH_CODE.checkAvailableOrchestrators} />
          </Accordion>

          <Accordion title="On-Chain Specific Tests" icon="chain">
            *On-Chain Specific Tests:*

            Before testing, ensure your on-chain Gateway is properly configured.
            The Gateway must have an active Ethereum connection and valid account:

            <CustomCodeBlock {...BASH_CODE.onchain.checkAccountAddress} />

            <CustomCodeBlock {...DOCKER_CODE.verifyEthConnection} />
          </Accordion>

          <Accordion title="Payment Tests" icon="hand-holding-dollar">
            *Payment Tests:*

            For on-chain Gateways, test the payment system:

            {/* The payment system uses probabilistic micropayments with tickets. */}

            <CustomCodeBlock {...BASH_CODE.onchain.checkCurrentRound} />

            <CustomCodeBlock {...BASH_CODE.onchain.depositFunds} />

            <CustomCodeBlock {...BASH_CODE.onchain.checkDeposit} />
          </Accordion>

          <Accordion title="Advanced On-Chain Tests" icon="ethereum">
            *Advanced On-Chain Tests*

            Test smart contract interactions:

            <CustomCodeBlock {...BASH_CODE.onchain.checkTicketParams} />

            <CustomCodeBlock {...BASH_CODE.onchain.checkPriceInfo} />

            <CustomCodeBlock {...BASH_CODE.onchain.checkWithdrawal} />
          </Accordion>

          <Accordion title="Video Ingest Tests" icon="camera-movie">
            *Video Tests:*

            {/*
                        Video Transcoding Tests
                        Test both RTMP and HTTP ingest methods:
                                      # RTMP stream (requires FFmpeg)
                        ffmpeg -re -i test-video.mp4 -c copy -f flv rtmp://localhost:1935/stream/test-key

                                      # HTTP segment push
                        curl -X PUT http://localhost:8935/live/test/0.ts --data-binary @test-segment.ts

                                      # Verify HLS output
                        curl http://localhost:8935/hls/test-key/index.m3u8 */}

            <TestVideoDownload>
              <DownloadButton label="test-video.mp4" downloadLink="https://raw.githubusercontent.com/livepeer/docs/docs-v2-assets/snippets/assets/domain/04_GATEWAYS/test-video.mp4" />
            </TestVideoDownload>

            <CustomCodeBlock {...BASH_CODE.testRTMPingest} />

            <CustomCodeBlock {...BASH_CODE.testHLS} wrap />

            <CustomCodeBlock {...BASH_CODE.testHTTPingest} />

            {/* 7.
                        Test Stream Verification
                        Use the built-in test pattern for verification:

                                      # Generate test pattern
                        ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30,format=yuv420p \
                        -c:v libx264 -b:v 1000k -f flv rtmp://localhost:1935/stream/test-key

                                      # Monitor transcoding
                        curl http://localhost:8935/hls/test-key/index.m3u8 */}
          </Accordion>

          <Accordion title="AI Tests" icon="user-robot">
            *AI Tests:*

            <CustomCodeBlock {...BASH_CODE.testHTTPingest} />

            *AI Capability Tests:*

            <CustomCodeBlock {...BASH_CODE.test.ai.textToImage} />

            <CustomCodeBlock {...BASH_CODE.test.ai.LLM} />
          </Accordion>

          <Accordion title="Expected Results" icon="check-circle">
            **Expected Results**

            Successful Test Indicators

            * Status endpoint returns valid Ethereum address
            * Orchestrators list shows pricing and ticket parameters
            * Video streams generate HLS playlists
            * AI endpoints return processed results
            * Payment operations complete without errors

            **Common Issues**

            * No Orchestrators found: Check `-orchAddr` configuration
            * Payment errors: Verify ETH balance and gas settings
            * AI failures: Ensure `-aiServiceRegistry` is set for on-chain AI
            * Connection timeouts: Check firewall and network settings

            **Notes**

            * On-chain tests require ETH in the Gateway account for transactions
            * Test on a testnet first (e.g., Arbitrum-one-goerli) before using mainnet
            * Monitor gas costs during testing
            * The test suite includes on-chain validation tests [test\_args.sh](https://github.com/livepeer/go-livepeer/blob/master/test_args.sh)
            * Use `-localVerify=false` to skip local verification if needed
          </Accordion>
        </Step>

        <Step title="Monitor Gateway">
          The `-monitor=true` flag in the docker-compose.yml already has basic monitoring enabled which exposes metrics in Prometheus format at `http://localhost:8935/metrics`.

          Metrics collected include:

          * Stream metrics (created, started, ended)
          * Transcoding metrics (success rate, latency)
          * Payment metrics (tickets sent, deposits)
          * AI-specific metrics (attempts, Orchestrators available)

          *See More Metrics Options Below:*

          <Accordion title="Prometheus Metrics" icon="monitor-waveform">
            Access Prometheus metrics at:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:8935/metrics
            ```

            Key metrics include:

            * `livepeer_stream_created_total` - Total streams created
            * `livepeer_current_sessions_total` - Active transcoding sessions
            * `livepeer_success_rate` - Transcoding success rate
            * `livepeer_ai_live_attempts` - AI processing attempts
            * `livepeer_gateway_deposit` - Current ETH deposit
          </Accordion>

          <Accordion title="CLI Monitoring Commands" icon="terminal">
            *CLI Monitoring Commands*

            Check Gateway status:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:5935/status
            ```

            Monitor available Orchestrators:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            curl http://localhost:5935/getOrchestrators
            ```

            See all CLI options:

            <CustomCodeBlock {...DOCKER_CODE.flags} />

            ```bash Run Livepeer CLI theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              livepeer_cli # livepeer_cli --host=localhost --http=5935
            ```

            ```bash Livepeer CLI Output theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            +-----------------------------------------------------------+
            | Welcome to livepeer-cli, your Livepeer command line tool  |
            +-----------------------------------------------------------+

            What would you like to do? (default = stats)
            1. Get node status
            2. View protocol parameters
            3. List registered orchestrators
            4. Invoke "initialize round"
            5. Invoke "bond"
            ...
            ```
          </Accordion>

          <Accordion title="AI-Specific Monitoring" icon="user-robot">
            *AI-Specific Monitoring*

            For AI workflows, the Gateway sends detailed events including:

            * Stream request events
            * Orchestrator selection info
            * Ingest metrics
            * Error events
          </Accordion>

          <Accordion title="Enhanced Monitoring Options" icon="chart-line">
            *Enhanced Monitoring Options*

            Add to your Docker Compose for more monitoring:

            ```yaml theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            # Enable per-stream metrics
            - -metricsPerStream=true

            # Expose client IPs in metrics
            - -metricsClientIP=true

            # Kafka integration (requires setup)
            - -kafkaBootstrapServers=kafka:9092
            - -kafkaUser=username
            - -kafkaPassword=password
            - -kafkaGatewayTopic=livepeer-gateway
            ```
          </Accordion>

          <Accordion title="Log Monitoring" icon="file-lines">
            *Log Monitoring*

            Monitor logs in real-time:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            docker logs -f dual-gateway
            ```

            Look for key events:

            * "Received live video AI request"
            * "Orchestrator selected"
            * "Transcoding completed"
            * Payment processing events
          </Accordion>
        </Step>

        <Step title="Gateway Tips">
          <Expandable title="Connecting to Orchestrators">
            The Gateway needs to connect to at least one Orchestrator for services.

            If you're running your own Orchestrator, you can use this by setting the `-orchAddr` flag.
            For on-chain mode, Orchestrator discovery happens automatically but you need to ensure your Gateway has ETH for transactions.
          </Expandable>

          <Expandable title="See More Explorer Information">
            The [Livepeer Explorer Orchestrator Performance Leaderboard](https://explorer.livepeer.org/leaderboard) can also show you a list of all available Orchestrators & their capabilities & services.
            The Performance Leaderboard is provides real-time operational metrics that directly impact Gateway performance, while the main Orchestrators page helps with understanding the economic landscape and potential delegation opportunities.
          </Expandable>

          <Expandable title="Automatic Orchestrator Discovery System">
            When you start an on-chain Gateway (`-network arbitrum-one-mainnet`), it automatically creates a `DBOrchestratorPoolCache` that polls the blockchain for registered Orchestrators.

            Unlike off-chain mode where you specify `-orchAddr`, on-chain Gateways:

            * Discover all public Orchestrators automatically
            * Update the list periodically (every 25 minutes)
            * Handle failures by trying alternative Orchestrators

            *Orchestrator Discovery Initialisation*
            The discovery process queries the BondingManager smart contract to get all registered Orchestrators with different validation rules
            for different node types - transcoders require explicit Orchestrator addresses while Gateways can operate with or without them.

            *The discovery system fetches:*

            * All registered Orchestrators from the BondingManager contract
            * Their capabilities (video transcoding profiles, AI models)
            * Pricing information for each capability
            * Performance metrics and capacity

            *Capability Matching*

            When processing requests, the Gateway:

            * Queries discovered Orchestrators for required capabilities discovery.go:160-174
            * Filters by price limits (-maxPricePerUnit for video, -maxPricePerCapability for AI)
            * Selects based on performance and availability

            {/* 2. Blockchain Orchestrator Pool Query

                                         3. Error Handling and Validation */}
          </Expandable>

          <CustomCodeBlock {...DOCKER_CODE.connect} />
        </Step>
      </Steps>
    </Tab>
  </Tabs>

  <Accordion title="Docker Tips & Tricks" icon="magic-wand-sparkles">
    <Danger> Verify these </Danger>
    If you wanted to build a `go-livepeer` Docker image, you can do so from the root of the repository using this:

    <CustomCodeBlock codeString="docker build -t livepeer/go-livepeer:alpha-build -f docker/Dockerfile ../" language="bash" icon="terminal" filename="Build Docker Image from Source" />
  </Accordion>

  ## Reference Pages

  <Columns cols={2}>
    <Card title="Docker Installation Guide" href="/v2/gateways/setup/install/docker-install" arrow horizontal>
      View Full Installation Guide
    </Card>

    <Card title="Configuration Flags Reference" href="/v2/gateways/resources/reference/technical/configuration-flags" arrow horizontal>
      Gateway Configuration Flag Guide
    </Card>
  </Columns>
</View>

<View title="Linux" icon="linux" iconType="solid">
  ## <Icon icon="linux" iconType="solid" size={32} /> Linux Quickstart Guide

  building from source on Linux (Ubuntu/Debian)

  <Accordion title="Linux Supported Distributions & Required Packages" icon="info-circle">
    ### Supported Distributions

    Livepeer supports building from source on these Linux distributions:

    * \*\*Ubuntu 20.04+ (\*\*tested in CI)
    * **Debian** and derivatives
    * **CentOS/RHEL** (with adjustments)
    * **Arch Linux** (community supported)

    Architectures supported:

    * **x86\_64/amd64** - Primary platform
    * **ARM64/aarch64** - For ARM servers

    ### System Requirements & Packages

    * **Go 1.21+** (as specified in go.mod)
    * <Icon icon="warning" color="orange" /> **FFmpeg** (required for video transcoding)
    * Build tools: **make**, **gcc/clang**, **pkg-config**
    * **Git** for version control

    <Warning>
      **FFmpeg** is a common cause of errors when building from source.

      It **must be installed in a specific location** and not conflict with any existing FFmpeg installations.

      **Livepeer uses a custom build of `ffmpeg`** that is installed as part of the build process.

      If you have `ffmpeg` installed already, it is recommended to remove it before building Livepeer.
    </Warning>

    {/* <Danger> Verify below installs are correct </Danger>
        ```bash ffmpeg install icon="warning" lines
        export ROOT=$HOME/buildoutput
        export LD_LIBRARY_PATH=$ROOT/compiled/lib/ export
        PKG_CONFIG_PATH=$ROOT/compiled/lib/pkgconfig
        export PATH=$ROOT/compiled/bin/:$PATH

        ./install_ffmpeg.sh $ROOT
        ``` */}

    {/* eliteproxy */}

    {/* ```bash lines icon="warning" Linux Dependencies for Livepeer
        sudo apt-get update && sudo apt-get -y install build-essential pkg-config autoconf git curl wget
        sudo apt-get -y install protobuf-compiler-grpc golang-goprotobuf-dev
        sudo apt-get -y install clang-tools
        ``` */}

    ```bash Install Dependencies icon="terminal" lines theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    # Update package lists
    sudo apt update

    # Install build essentials
    sudo apt install -y build-essential make git

    # Install FFmpeg dependencies
    sudo apt install -y software-properties-common curl apt-transport-https lsb-release

    # Add LLVM repository for clang
    curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
    sudo add-apt-repository "deb https://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-14 main"

    # Install remaining dependencies
    sudo apt update
    sudo apt install -y clang-14 clang-tools-14 lld-14 pkg-config autoconf python3 \
     protobuf-compiler libx11-dev libbz2-dev libbzip3-dev

    # Set clang as default
    sudo update-alternatives --install /usr/bin/clang /usr/bin/clang-14 30
    sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 30
    sudo update-alternatives --install /usr/bin/ld /usr/bin/lld-14 30
    ```
  </Accordion>

  It's possible to use this guide for <Icon icon="apple" size={20} /> MacOS also, with some caveats:

  <Accordion title="MacOS Important Notes" icon="warning">
    <Warning> This section is a work in progress. </Warning>
  </Accordion>

  <br />

  ***Choose your Gateway Mode:***

  <Tabs>
    <LinuxOffChainTab latestVersion={latestVersion} latestReleasePageUrl={latestReleasePageUrl} GatewayOffChainWarning={GatewayOffChainWarning} CustomCodeBlock={CustomCodeBlock} />

    {/* Imports only used in this file should be here */}

    <Tab title="On-Chain Gateway" icon="link">
      <GatewayOnChainWarning />

      <Steps>
        <Step title="Install Gateway Software" />

        <Step title="Configure Gateway" />

        <Step title="Run Gateway" />

        <Step title="Connect Gateway" />

        <Step title="Test Gateway" />

        <Step title="Monitor Gateway" />

        <Step title="Gateway Tips" />
      </Steps>
    </Tab>
  </Tabs>

  ## Reference Pages

  <Columns cols={2}>
    <Card title="Linux Installation Guide" href="/v2/gateways/setup/install/linux-install" arrow horizontal>
      View Full Installation Guide
    </Card>

    <Card title="Configuration Flags Reference" href="/v2/gateways/resources/reference/technical/configuration-flags" arrow horizontal>
      Gateway Configuration Flag Guide
    </Card>
  </Columns>
</View>

<View title="Windows" icon="windows" iconType="solid">
  ## <Icon icon="windows" iconType="solid" size={32} /> Windows Quickstart Guide

  <Tabs>
    {/* Imports only used in this file should be here */}

    <Tab title="Off-Chain Gateway" icon="floppy-disk">
      <GatewayOffChainWarning />

      <Steps>
        <Step title="Install Gateway Software" />

        <Step title="Configure Gateway" />

        <Step title="Run Gateway" />

        <Step title="Test Gateway" />

        <Step title="Monitor Gateway" />

        <Step title="Gateway Tips" />
      </Steps>
    </Tab>

    {/* Imports only used in this file should be here */}

    <Tab title="On-Chain Gateway" icon="link">
      <GatewayOnChainWarning />

      <Steps>
        <Step title="Install Gateway Software" />

        <Step title="Configure Gateway" />

        <Step title="Run Gateway" />

        <Step title="Connect Gateway" />

        <Step title="Test Gateway" />

        <Step title="Monitor Gateway" />

        <Step title="Gateway Tips" />
      </Steps>
    </Tab>
  </Tabs>

  ## Reference Pages

  <Columns cols={2}>
    <Card title="Windows Installation Guide" href="/v2/gateways/setup/install/windows-install" arrow horizontal>
      View Full Installation Guide
    </Card>

    <Card title="Configuration Flags Reference" href="/v2/gateways/resources/reference/technical/configuration-flags" arrow horizontal>
      Gateway Configuration Flag Guide
    </Card>
  </Columns>
</View>

## End-to-end test loop with an Orchestrator

Use this loop after both your Gateway and Orchestrator are online.

<Steps>
  <Step title="Confirm orchestrator endpoint and capabilities">
    Verify your Orchestrator is reachable on `:8935` and advertises transcoding
    support.
  </Step>

  <Step title="Configure gateway routing to that orchestrator">
    In off-chain mode, point the Gateway directly with:

    ```bash icon="terminal" theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    -orchAddr=https://your-orchestrator.example.com:8935
    ```
  </Step>

  <Step title="Ingest a test stream through the gateway">
    Use the quickstart ingest flow (FFmpeg or OBS), then fetch the generated HLS
    manifest from the Gateway.
  </Step>

  <Step title="Validate logs on both nodes">
    Confirm the Gateway logs show route selection and the Orchestrator logs show
    session creation/completion for the same stream.
  </Step>
</Steps>

<Card title="Transcoding Orchestrator Quickstart" href="/v2/orchestrators/quickstart/guide" icon="microchip" arrow horizontal>
  Use this guide for Orchestrator-side setup, registration, and verification.
</Card>

## Troubleshooting

<Card title="Common Issues" href="/v2/gateways/resources/reference/faq" icon="triangle-exclamation" iconType="solid" arrow horizontal>
  Review common troubleshooting issues and fixes.
</Card>

## Related Pages

<Columns cols={2}>
  <Card title="Setup Checklist" href="/v2/gateways/setup/requirements/setup" arrow horizontal>
    {' '}

    See Prerequisites & Requirements.{' '}
  </Card>

  <Card title="On-Chain Setup" href="/v2/gateways/setup/requirements/on-chain-setup/on-chain" arrow horizontal>
    See on-chain Setup Checklist.
  </Card>

  <Card title="Run a Gateway" href="/v2/gateways/setup/guide" arrow horizontal>
    See full Gateway Setup Guide.
  </Card>

  <Card title="Orchestrator Guide" href="/v2/orchestrators/portal" arrow horizontal>
    Setup an Orchestrator.
  </Card>
</Columns>
