{
  "schemaVersion": 1,
  "name": "Orbi node reference",
  "origin": "https://docs.orbi.gg",
  "connectionCaveat": "These lists show compatible node types, not approval of every graph. Branch, position context, subscription, no-cycle and complete-exit rules also apply. A node cannot connect to itself.",
  "graphRules": "https://docs.orbi.gg/guides/graphs",
  "nodes": [
    {
      "id": "sec-filings",
      "title": "SEC reports",
      "category": "Company movement",
      "description": "Tier 1 live SEC 8-K, 10-Q and 10-K reports. Important filters routine-only 8-Ks and weak catalysts. Select Nasdaq-100 or tracked tickers, then connect Telegram or Discord. Importance is a rule-based signal, not a price prediction. Foreign issuers may use other SEC forms.",
      "how": [
        "Receive newly collected SEC 8-K, 10-Q and 10-K reports for the verified Nasdaq-100 snapshot or covered tickers you select.",
        "Important includes medium/high relevance and excludes routine-only 8-K items. Periodic 10-Q and 10-K reports count as medium; High only may therefore exclude them."
      ],
      "notes": [
        "Requires Tier 1 and a healthy configured collector. Historical backfill does not trigger live alerts.",
        "Only connects to Telegram or Discord, never a crypto entry/filter. Rule-based importance is not a price prediction. Foreign issuers may use other forms."
      ],
      "minimumTier": 1,
      "defaults": {
        "universe": "nasdaq100",
        "tickers": "",
        "minimumImportance": "important",
        "maximumAgeMinutes": 1440,
        "forms": "8-K"
      },
      "settings": [
        {
          "key": "universe",
          "label": "Companies",
          "kind": "select",
          "options": [
            {
              "value": "nasdaq100",
              "label": "Nasdaq-100"
            },
            {
              "value": "tickers",
              "label": "Selected tickers"
            }
          ],
          "help": "Tracks the collector’s verified Nasdaq-100 snapshot. Selected tickers must be covered by that collector.",
          "initialDisplayValue": "Nasdaq-100",
          "details": "Tracks the collector’s verified Nasdaq-100 snapshot. Selected tickers must be covered by that collector. Options: Nasdaq-100 (nasdaq100); Selected tickers (tickers)."
        },
        {
          "key": "tickers",
          "label": "Tickers · comma separated",
          "kind": "text",
          "help": "For Selected tickers, e.g. AAPL, NVDA, MSFT. Cannot subscribe outside collector coverage.",
          "initialDisplayValue": "None",
          "details": "For Selected tickers, e.g. AAPL, NVDA, MSFT. Cannot subscribe outside collector coverage."
        },
        {
          "key": "minimumImportance",
          "label": "Importance",
          "kind": "select",
          "options": [
            {
              "value": "important",
              "label": "Important · medium + high"
            },
            {
              "value": "high",
              "label": "High only"
            },
            {
              "value": "all",
              "label": "All collected"
            }
          ],
          "help": "Rule-based catalyst relevance, not guaranteed price movement. Important excludes routine-only 8-Ks. Periodic reports count as medium.",
          "initialDisplayValue": "Important · medium + high",
          "details": "Rule-based catalyst relevance, not guaranteed price movement. Important excludes routine-only 8-Ks. Periodic reports count as medium. Options: Important · medium + high (important); High only (high); All collected (all)."
        },
        {
          "key": "maximumAgeMinutes",
          "label": "Maximum age · minutes",
          "kind": "number",
          "min": 5,
          "max": 1440,
          "sliderMax": 1440,
          "step": 5,
          "help": "Publication age. Only newly collected events are delivered; historical/backfill data never triggers alerts.",
          "initialDisplayValue": "1440",
          "details": "Publication age. Only newly collected events are delivered; historical/backfill data never triggers alerts. Editor range: 5 to 1440."
        },
        {
          "key": "forms",
          "label": "Reports",
          "kind": "select",
          "options": [
            {
              "value": "8-K",
              "label": "8-K · current reports"
            },
            {
              "value": "10-Q",
              "label": "10-Q · quarterly"
            },
            {
              "value": "10-K",
              "label": "10-K · annual"
            },
            {
              "value": "all",
              "label": "All three forms"
            }
          ],
          "initialDisplayValue": "8-K · current reports",
          "details": "Options: 8-K · current reports (8-K); 10-Q · quarterly (10-Q); 10-K · annual (10-K); All three forms (all)."
        }
      ],
      "incoming": [
        "start"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify"
      ],
      "url": "https://docs.orbi.gg/nodes/sec-filings",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/sec-filings"
    },
    {
      "id": "company-news",
      "title": "Company news",
      "category": "Company movement",
      "description": "Tier 1 company headlines and identified press releases from the shared collector. Filter importance and Nasdaq-100 or tracked tickers. Connect Telegram or Discord; this source does not place trades.",
      "how": [
        "Receive newly collected company headlines and identified press releases for the covered universe.",
        "Filter news versus press releases, importance and publication age; connect a notification destination."
      ],
      "notes": [
        "Requires Tier 1 and collector coverage. Only connects to Telegram or Discord; it does not place trades or provide unrestricted web/news access."
      ],
      "minimumTier": 1,
      "defaults": {
        "universe": "nasdaq100",
        "tickers": "",
        "minimumImportance": "important",
        "maximumAgeMinutes": 1440,
        "newsKind": "all"
      },
      "settings": [
        {
          "key": "universe",
          "label": "Companies",
          "kind": "select",
          "options": [
            {
              "value": "nasdaq100",
              "label": "Nasdaq-100"
            },
            {
              "value": "tickers",
              "label": "Selected tickers"
            }
          ],
          "help": "Tracks the collector’s verified Nasdaq-100 snapshot. Selected tickers must be covered by that collector.",
          "initialDisplayValue": "Nasdaq-100",
          "details": "Tracks the collector’s verified Nasdaq-100 snapshot. Selected tickers must be covered by that collector. Options: Nasdaq-100 (nasdaq100); Selected tickers (tickers)."
        },
        {
          "key": "tickers",
          "label": "Tickers · comma separated",
          "kind": "text",
          "help": "For Selected tickers, e.g. AAPL, NVDA, MSFT. Cannot subscribe outside collector coverage.",
          "initialDisplayValue": "None",
          "details": "For Selected tickers, e.g. AAPL, NVDA, MSFT. Cannot subscribe outside collector coverage."
        },
        {
          "key": "minimumImportance",
          "label": "Importance",
          "kind": "select",
          "options": [
            {
              "value": "important",
              "label": "Important · medium + high"
            },
            {
              "value": "high",
              "label": "High only"
            },
            {
              "value": "all",
              "label": "All collected"
            }
          ],
          "help": "Rule-based catalyst relevance, not guaranteed price movement. Important excludes routine-only 8-Ks. Periodic reports count as medium.",
          "initialDisplayValue": "Important · medium + high",
          "details": "Rule-based catalyst relevance, not guaranteed price movement. Important excludes routine-only 8-Ks. Periodic reports count as medium. Options: Important · medium + high (important); High only (high); All collected (all)."
        },
        {
          "key": "maximumAgeMinutes",
          "label": "Maximum age · minutes",
          "kind": "number",
          "min": 5,
          "max": 1440,
          "sliderMax": 1440,
          "step": 5,
          "help": "Publication age. Only newly collected events are delivered; historical/backfill data never triggers alerts.",
          "initialDisplayValue": "1440",
          "details": "Publication age. Only newly collected events are delivered; historical/backfill data never triggers alerts. Editor range: 5 to 1440."
        },
        {
          "key": "newsKind",
          "label": "Content",
          "kind": "select",
          "options": [
            {
              "value": "all",
              "label": "News + press releases"
            },
            {
              "value": "news",
              "label": "News only"
            },
            {
              "value": "press-release",
              "label": "Identified press releases"
            }
          ],
          "initialDisplayValue": "News + press releases",
          "details": "Options: News + press releases (all); News only (news); Identified press releases (press-release)."
        }
      ],
      "incoming": [
        "start"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify"
      ],
      "url": "https://docs.orbi.gg/nodes/company-news",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/company-news"
    },
    {
      "id": "start",
      "title": "Start",
      "category": "Flow",
      "description": "Begins evaluation when a matching signal arrives.",
      "how": [
        "Every graph has exactly one Start. It makes connected paths active; it is not a timer or a trade by itself.",
        "Connect it to a signal source, or to Balance before your wallet signal paths. Completely disconnected draft nodes do not run."
      ],
      "notes": [
        "Graphs run in response to matching source events. Saving a graph does not automatically start it."
      ],
      "minimumTier": 0,
      "defaults": {},
      "settings": [],
      "incoming": [],
      "outgoing": [
        "sec-filings",
        "company-news",
        "aegis-wallet-feed",
        "wallet-signal",
        "runner-potential",
        "balance-check"
      ],
      "url": "https://docs.orbi.gg/nodes/start",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/start"
    },
    {
      "id": "aegis-wallet-feed",
      "title": "Aegis wallet feed",
      "category": "Signals",
      "description": "Starts candidates from the live, point-in-time Aegis notable-wallet feed rather than a fixed wallet list.",
      "how": [
        "Use the shared notable-wallet feed instead of maintaining a fixed watch list.",
        "A candidate must meet the configured evidence score, independently funded group count and freshness limit before downstream filters run."
      ],
      "notes": [
        "Requires Tier 2 and healthy Aegis coverage. Missing or stale data cannot be treated as a qualifying signal."
      ],
      "minimumTier": 2,
      "defaults": {
        "minimumEvidenceScore": 60,
        "minimumWalletGroups": 2,
        "maximumAgeSeconds": 5
      },
      "settings": [
        {
          "key": "minimumEvidenceScore",
          "label": "Minimum Aegis score",
          "kind": "number",
          "min": 0,
          "max": 100,
          "step": 1,
          "help": "Minimum point-in-time wallet and demand evidence score.",
          "initialDisplayValue": "60",
          "details": "Minimum point-in-time wallet and demand evidence score. Editor range: 0 to 100."
        },
        {
          "key": "minimumWalletGroups",
          "label": "Independent wallet groups",
          "kind": "number",
          "min": 1,
          "max": 12,
          "step": 1,
          "help": "Minimum independently funded notable-wallet groups behind the setup.",
          "initialDisplayValue": "2",
          "details": "Minimum independently funded notable-wallet groups behind the setup. Editor range: 1 to 12."
        },
        {
          "key": "maximumAgeSeconds",
          "label": "Maximum signal age",
          "kind": "number",
          "min": 1,
          "max": 30,
          "step": 1,
          "help": "Reject an Aegis signal older than this many seconds.",
          "initialDisplayValue": "5",
          "details": "Reject an Aegis signal older than this many seconds. Editor range: 1 to 30."
        }
      ],
      "incoming": [
        "start"
      ],
      "outgoing": [
        "wallet-confirmation",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/aegis-wallet-feed",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/aegis-wallet-feed"
    },
    {
      "id": "wallet-signal",
      "title": "Wallet signal",
      "category": "Signals",
      "description": "Arms a candidate when one of the selected wallets buys.",
      "how": [
        "Watch selected Solana wallet addresses. Primary wallets begin candidates; Support wallets contribute evidence to confirmation.",
        "Choose buys, sells or both for notification activity. An entry path still needs a buy; a sell-only source cannot authorize a new trade."
      ],
      "notes": [
        "Free graphs follow one Primary wallet with one Wallet signal node. Additional wallets, Support roles and advanced paths require a paid plan.",
        "An observed transaction is not proof of a complete wallet holding balance."
      ],
      "minimumTier": 0,
      "defaults": {
        "wallets": [],
        "role": "primary",
        "side": "buy"
      },
      "settings": [
        {
          "key": "role",
          "label": "Wallet role",
          "kind": "select",
          "options": [
            {
              "value": "primary",
              "label": "Primary"
            },
            {
              "value": "support",
              "label": "Support"
            }
          ],
          "help": "Primary wallets start candidates; support wallets contribute confirmation.",
          "initialDisplayValue": "Primary",
          "details": "Primary wallets start candidates; support wallets contribute confirmation. Options: Primary (primary); Support (support)."
        },
        {
          "key": "side",
          "label": "Wallet activity",
          "kind": "select",
          "options": [
            {
              "value": "buy",
              "label": "Buys"
            },
            {
              "value": "sell",
              "label": "Sells"
            },
            {
              "value": "both",
              "label": "Buys and sells"
            }
          ],
          "help": "Activity sent to notification branches. New trades still require buy confirmation.",
          "initialDisplayValue": "Buys",
          "details": "Activity sent to notification branches. New trades still require buy confirmation. Options: Buys (buy); Sells (sell); Buys and sells (both)."
        },
        {
          "key": "wallets",
          "label": "Wallets",
          "kind": "wallets",
          "help": "These addresses contribute wallet signals.",
          "initialDisplayValue": "None selected",
          "details": "These addresses contribute wallet signals."
        }
      ],
      "incoming": [
        "start",
        "balance-check"
      ],
      "outgoing": [
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/wallet-signal",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/wallet-signal"
    },
    {
      "id": "wallet-confirmation",
      "title": "Wallet confirmation",
      "category": "Logic",
      "description": "Requires distinct wallet buys on the same token within the window. Any observed sell, including a partial sale, cancels that wallet's vote. Checked again before entry; a newer buy can qualify again. This uses observed trades, not a verified holding balance.",
      "how": [
        "Count distinct observed buys of the same token inside the configured time window. Require enough total wallets and, optionally, a minimum from Primary sources.",
        "An observed sell, including a partial sale, cancels that wallet’s vote. A later buy can qualify again. Confirmation is rechecked before entry."
      ],
      "notes": [
        "Primary-wallet requirements cannot exceed the total requirement. Supply Primary wallets or an Aegis feed when requiring Primary confirmation."
      ],
      "minimumTier": 1,
      "defaults": {
        "requiredWallets": 2,
        "requiredPrimaryWallets": 1,
        "windowSeconds": 30
      },
      "settings": [
        {
          "key": "requiredWallets",
          "label": "Distinct wallets",
          "kind": "number",
          "min": 1,
          "max": 12,
          "step": 1,
          "help": "Independent tracked wallets required on the same token.",
          "initialDisplayValue": "2",
          "details": "Independent tracked wallets required on the same token. Editor range: 1 to 12."
        },
        {
          "key": "requiredPrimaryWallets",
          "label": "Primary wallets",
          "kind": "number",
          "min": 0,
          "max": 12,
          "step": 1,
          "help": "How many must come from a Primary wallet node.",
          "zeroMeansOff": true,
          "initialDisplayValue": "1",
          "details": "How many must come from a Primary wallet node. Editor range: 0 to 12. Zero disables this threshold."
        },
        {
          "key": "windowSeconds",
          "label": "Window (seconds)",
          "kind": "number",
          "min": 1,
          "max": 600,
          "step": 1,
          "help": "All confirming wallet buys must arrive inside this window.",
          "initialDisplayValue": "30",
          "details": "All confirming wallet buys must arrive inside this window. Editor range: 1 to 600."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase"
      ],
      "outgoing": [
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/wallet-confirmation",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/wallet-confirmation"
    },
    {
      "id": "wallet-conviction",
      "title": "Wallet conviction",
      "category": "Filters",
      "description": "Compares a wallet's initial buy with its own observed history. A 1.5× minimum means 50% larger than usual, not a win probability. Top-ups and missing or stale history cannot qualify for confirmation.",
      "how": [
        "Compare a watched wallet’s initial buy size with its own rolling observed history. Choose median or average as its normal buy size.",
        "A 1.5× multiplier means the purchase is 50% larger than that baseline; it is not a probability of winning."
      ],
      "notes": [
        "Needs an incoming Wallet signal and enough fresh history. Top-ups, current-token entries, incomplete history and stale samples cannot qualify."
      ],
      "minimumTier": 2,
      "defaults": {
        "lookbackDays": 7,
        "baseline": "median",
        "minimumMultiplier": 1.5,
        "minimumSamples": 20
      },
      "settings": [
        {
          "key": "lookbackDays",
          "label": "Lookback days",
          "kind": "number",
          "min": 1,
          "max": 7,
          "step": 1,
          "help": "Rolling history before the signal. Current-token purchases are excluded.",
          "initialDisplayValue": "7",
          "details": "Rolling history before the signal. Current-token purchases are excluded. Editor range: 1 to 7."
        },
        {
          "key": "baseline",
          "label": "Usual buy size",
          "kind": "select",
          "options": [
            {
              "value": "median",
              "label": "Median"
            },
            {
              "value": "average",
              "label": "Average"
            }
          ],
          "help": "Median resists outliers; average is the arithmetic mean.",
          "initialDisplayValue": "Median",
          "details": "Median resists outliers; average is the arithmetic mean. Options: Median (median); Average (average)."
        },
        {
          "key": "minimumMultiplier",
          "label": "Minimum buy size",
          "kind": "number",
          "min": 0.1,
          "max": 100,
          "sliderMax": 5,
          "step": 0.1,
          "help": "Buy SOL divided by this wallet’s usual initial buy. 1.5× means 50% larger, not a 50% win probability.",
          "initialDisplayValue": "1.5",
          "details": "Buy SOL divided by this wallet’s usual initial buy. 1.5× means 50% larger, not a 50% win probability. Editor range: 0.1 to 100."
        },
        {
          "key": "minimumSamples",
          "label": "Minimum entries",
          "kind": "number",
          "min": 5,
          "max": 1000,
          "sliderMax": 100,
          "step": 1,
          "help": "Minimum observed initial buys required. Missing, stale or truncated history blocks the branch.",
          "initialDisplayValue": "20",
          "details": "Minimum observed initial buys required. Missing, stale or truncated history blocks the branch. Editor range: 5 to 1000."
        }
      ],
      "incoming": [
        "wallet-signal"
      ],
      "outgoing": [
        "wallet-confirmation",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/wallet-conviction",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/wallet-conviction"
    },
    {
      "id": "runner-potential",
      "title": "Runner potential",
      "category": "Signals",
      "description": "Requires an Aegis runner stage or probability.",
      "how": [
        "Accept an Aegis runner candidate only when its stage, incidence estimate and age meet your thresholds.",
        "Use it as a signal source or after a wallet source, then add entry filters or an alert branch."
      ],
      "notes": [
        "The incidence estimate is not your strategy’s win rate. The current shared model caps this value at 42%."
      ],
      "minimumTier": 2,
      "defaults": {
        "minimumStage": 3,
        "minimumProbabilityPct": 25,
        "maximumAgeSeconds": 12
      },
      "settings": [
        {
          "key": "minimumStage",
          "label": "Minimum stage",
          "kind": "number",
          "min": 1,
          "max": 3,
          "step": 1,
          "help": "Highest Aegis confirmation stage required before entry.",
          "initialDisplayValue": "3",
          "details": "Highest Aegis confirmation stage required before entry. Editor range: 1 to 3."
        },
        {
          "key": "minimumProbabilityPct",
          "label": "Minimum probability %",
          "kind": "number",
          "min": 0,
          "max": 42,
          "step": 1,
          "help": "Minimum Aegis incidence estimate, not trade win rate. The current model ceiling is 42%.",
          "zeroMeansOff": true,
          "initialDisplayValue": "25",
          "details": "Minimum Aegis incidence estimate, not trade win rate. The current model ceiling is 42%. Editor range: 0 to 42. Zero disables this threshold."
        },
        {
          "key": "maximumAgeSeconds",
          "label": "Maximum age (seconds)",
          "kind": "number",
          "min": 1,
          "max": 120,
          "step": 1,
          "help": "Reject a runner signal older than this.",
          "initialDisplayValue": "12",
          "details": "Reject a runner signal older than this. Editor range: 1 to 120."
        }
      ],
      "incoming": [
        "start",
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "balance-check",
        "entry-chase"
      ],
      "outgoing": [
        "wallet-confirmation",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/runner-potential",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/runner-potential"
    },
    {
      "id": "twitter-traction",
      "title": "Twitter traction",
      "category": "Filters",
      "description": "Requires fresh exact-contract posts, independent authors and meaningful public engagement from the shared Aegis social feed. Missing coverage is not counted as zero interest.",
      "how": [
        "Evaluate fresh exact-contract posts, distinct sampled authors, public engagement and measured momentum from the shared social feed.",
        "A ticker mention alone is not an exact-contract match. View growth needs repeated samples, not an invented rate from one post."
      ],
      "notes": [
        "Wait-then-block treats missing coverage as unavailable. Neutral lets other filters decide but gives no positive endorsement; observed weak evidence still fails your thresholds."
      ],
      "minimumTier": 2,
      "defaults": {
        "missingCoverage": "block",
        "minimumScore": 55,
        "minimumContractPosts": 2,
        "minimumAuthors": 2,
        "minimumViews": 0,
        "minimumReplies": 0,
        "minimumViewsPerMinute": 0,
        "maximumAgeSeconds": 180,
        "maximumWaitSeconds": 20
      },
      "settings": [
        {
          "key": "missingCoverage",
          "label": "Missing coverage",
          "kind": "select",
          "options": [
            {
              "value": "block",
              "label": "Wait, then block"
            },
            {
              "value": "neutral",
              "label": "Neutral · keep other filters"
            }
          ],
          "help": "Neutral does not endorse the token: missing exact-token coverage contributes no score and does not block. Available weak evidence still fails the configured thresholds.",
          "initialDisplayValue": "Wait, then block",
          "details": "Neutral does not endorse the token: missing exact-token coverage contributes no score and does not block. Available weak evidence still fails the configured thresholds. Options: Wait, then block (block); Neutral · keep other filters (neutral)."
        },
        {
          "key": "minimumScore",
          "label": "Minimum traction score",
          "kind": "number",
          "min": 0,
          "max": 100,
          "step": 1,
          "help": "Combined exact-post, author, view, reply and momentum quality score.",
          "initialDisplayValue": "55",
          "details": "Combined exact-post, author, view, reply and momentum quality score. Editor range: 0 to 100."
        },
        {
          "key": "minimumContractPosts",
          "label": "Exact contract posts",
          "kind": "number",
          "min": 1,
          "max": 1000,
          "sliderMax": 20,
          "step": 1,
          "help": "Posts must reference this token's exact contract, not only its ticker or narrative.",
          "initialDisplayValue": "2",
          "details": "Posts must reference this token's exact contract, not only its ticker or narrative. Editor range: 1 to 1000."
        },
        {
          "key": "minimumAuthors",
          "label": "Independent authors",
          "kind": "number",
          "min": 1,
          "max": 1000,
          "sliderMax": 20,
          "step": 1,
          "help": "Distinct sampled accounts required so one viral account cannot qualify alone.",
          "initialDisplayValue": "2",
          "details": "Distinct sampled accounts required so one viral account cannot qualify alone. Editor range: 1 to 1000."
        },
        {
          "key": "minimumViews",
          "label": "Minimum impressions",
          "kind": "number",
          "min": 0,
          "max": 1000000000,
          "sliderMax": 100000,
          "step": 100,
          "help": "Minimum sampled public views. Set to 0 to let the traction score decide.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Minimum sampled public views. Set to 0 to let the traction score decide. Editor range: 0 to 1000000000. Zero disables this threshold."
        },
        {
          "key": "minimumReplies",
          "label": "Minimum comments",
          "kind": "number",
          "min": 0,
          "max": 1000000000,
          "sliderMax": 1000,
          "step": 1,
          "help": "Minimum sampled replies. Set to 0 to let the traction score decide.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Minimum sampled replies. Set to 0 to let the traction score decide. Editor range: 0 to 1000000000. Zero disables this threshold."
        },
        {
          "key": "minimumViewsPerMinute",
          "label": "Impressions per minute",
          "kind": "number",
          "min": 0,
          "max": 10000000,
          "sliderMax": 10000,
          "step": 10,
          "help": "Requires measured view growth across repeated samples. Set to 0 when a first sample may qualify.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Requires measured view growth across repeated samples. Set to 0 when a first sample may qualify. Editor range: 0 to 10000000. Zero disables this threshold."
        },
        {
          "key": "maximumAgeSeconds",
          "label": "Maximum sample age",
          "kind": "number",
          "min": 15,
          "max": 180,
          "step": 5,
          "help": "Reject social evidence older than this.",
          "initialDisplayValue": "180",
          "details": "Reject social evidence older than this. Editor range: 15 to 180."
        },
        {
          "key": "maximumWaitSeconds",
          "label": "Wait for coverage",
          "kind": "number",
          "min": 0,
          "max": 60,
          "step": 1,
          "help": "How long a candidate may wait for the shared scraper. Missing coverage remains unavailable, never zero.",
          "zeroMeansOff": true,
          "initialDisplayValue": "20",
          "details": "How long a candidate may wait for the shared scraper. Missing coverage remains unavailable, never zero. Editor range: 0 to 60. Zero disables this threshold."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation"
      ],
      "outgoing": [
        "wallet-confirmation",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/twitter-traction",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/twitter-traction"
    },
    {
      "id": "token-filter",
      "title": "Token filter",
      "category": "Filters",
      "description": "Requires the token to remain inside configured market-cap, age, holder and observed Pump global-fee ranges.",
      "how": [
        "Keep a candidate inside configured market-cap, age, holder and observed Pump global-fee limits.",
        "Enable at least one threshold. For paired minimum and maximum limits, an enabled minimum must stay below its enabled maximum."
      ],
      "notes": [
        "Zero disables each optional threshold. Missing required observations block the candidate.",
        "The editor displays token ages in seconds; the internal minimumAgeMinutes and maximumAgeMinutes keys store minutes."
      ],
      "minimumTier": 1,
      "defaults": {
        "minimumMarketCapUsd": 5000,
        "maximumMarketCapUsd": 0,
        "minimumAgeMinutes": 0,
        "maximumAgeMinutes": 0,
        "minimumHolders": 0,
        "maximumHolders": 0,
        "minimumGlobalFeesPaidSol": 0,
        "maximumGlobalFeesPaidSol": 0
      },
      "settings": [
        {
          "key": "minimumMarketCapUsd",
          "label": "Minimum market cap",
          "kind": "number",
          "min": 0,
          "max": 1000000000,
          "sliderMax": 1000000,
          "step": 1000,
          "help": "Require at least this market cap.",
          "zeroMeansOff": true,
          "initialDisplayValue": "5000",
          "details": "Require at least this market cap. Editor range: 0 to 1000000000. Zero disables this threshold."
        },
        {
          "key": "maximumMarketCapUsd",
          "label": "Maximum market cap",
          "kind": "number",
          "min": 0,
          "max": 1000000000,
          "sliderMax": 1000000,
          "step": 1000,
          "help": "Reject tokens above this market cap.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Reject tokens above this market cap. Editor range: 0 to 1000000000. Zero disables this threshold."
        },
        {
          "key": "minimumAgeMinutes",
          "label": "Minimum token age",
          "kind": "number",
          "min": 0,
          "max": 31536000,
          "sliderMax": 3600,
          "step": 1,
          "displayScale": 60,
          "help": "Minimum age in seconds. 60 is one minute; 1800 is thirty minutes.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Minimum age in seconds. 60 is one minute; 1800 is thirty minutes. Editor range: 0 to 31536000. Zero disables this threshold. The editor displays the stored value × 60."
        },
        {
          "key": "maximumAgeMinutes",
          "label": "Maximum token age",
          "kind": "number",
          "min": 0,
          "max": 31536000,
          "sliderMax": 3600,
          "step": 1,
          "displayScale": 60,
          "help": "Maximum age in seconds. 60 is one minute; 1800 is thirty minutes.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Maximum age in seconds. 60 is one minute; 1800 is thirty minutes. Editor range: 0 to 31536000. Zero disables this threshold. The editor displays the stored value × 60."
        },
        {
          "key": "minimumHolders",
          "label": "Minimum holders",
          "kind": "number",
          "min": 0,
          "max": 10000000,
          "sliderMax": 10000,
          "step": 1,
          "help": "Require at least this many observed holders.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Require at least this many observed holders. Editor range: 0 to 10000000. Zero disables this threshold."
        },
        {
          "key": "maximumHolders",
          "label": "Maximum holders",
          "kind": "number",
          "min": 0,
          "max": 10000000,
          "sliderMax": 10000,
          "step": 1,
          "help": "Reject tokens above this holder count.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Reject tokens above this holder count. Editor range: 0 to 10000000. Zero disables this threshold."
        },
        {
          "key": "minimumGlobalFeesPaidSol",
          "label": "Minimum global fees paid",
          "kind": "number",
          "min": 0,
          "max": 1000000,
          "sliderMax": 1000,
          "step": 0.01,
          "help": "Require at least this much decoded Pump global protocol fee activity in SOL. Missing coverage fails closed.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Require at least this much decoded Pump global protocol fee activity in SOL. Missing coverage fails closed. Editor range: 0 to 1000000. Zero disables this threshold."
        },
        {
          "key": "maximumGlobalFeesPaidSol",
          "label": "Maximum global fees paid",
          "kind": "number",
          "min": 0,
          "max": 1000000,
          "sliderMax": 1000,
          "step": 0.01,
          "help": "Reject tokens above this much decoded Pump global protocol fee activity in SOL.",
          "zeroMeansOff": true,
          "initialDisplayValue": "0",
          "details": "Reject tokens above this much decoded Pump global protocol fee activity in SOL. Editor range: 0 to 1000000. Zero disables this threshold."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation"
      ],
      "outgoing": [
        "wallet-confirmation",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/token-filter",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/token-filter"
    },
    {
      "id": "balance-check",
      "title": "Balance",
      "category": "Safety",
      "description": "Passes only while available cash remains above its USD safety floor. Pass can feed several signal branches; Fail must stop the bot.",
      "how": [
        "Check available cash against a USD safety floor before allowing another candidate through.",
        "Pass can feed multiple supported signal/filter paths. Fail must connect to Stop bot; it is not an alternate entry path."
      ],
      "notes": [
        "This reads available funds. It does not deposit money, reset your paper balance or close an open trade."
      ],
      "minimumTier": 1,
      "defaults": {
        "minimumBalanceUsd": 30
      },
      "settings": [
        {
          "key": "minimumBalanceUsd",
          "label": "Balance must exceed",
          "kind": "number",
          "min": 1,
          "max": 10000000,
          "sliderMax": 1000,
          "step": 1,
          "help": "Available cash must remain above this USD floor or the bot pauses.",
          "initialDisplayValue": "30",
          "details": "Available cash must remain above this USD floor or the bot pauses. Editor range: 1 to 10000000."
        }
      ],
      "incoming": [
        "start",
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "entry-chase",
        "demand-confirmation"
      ],
      "outgoing": [
        "wallet-signal",
        "wallet-confirmation",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "entry-chase",
        "open-trade",
        "skip-trade",
        "stop-bot",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/balance-check",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/balance-check"
    },
    {
      "id": "entry-chase",
      "title": "Entry chase",
      "category": "Filters",
      "description": "Limits the rise from the first signal and, optionally, rejects a late entry after a large drop. Wallet strategies anchor to the initial primary buy. Maximum drop 0 disables the decline guard; this does not change open-position exits.",
      "how": [
        "Reject an entry that has risen too far from the first signal. Wallet strategies anchor to the initial Primary buy.",
        "Optionally reject a candidate that has already dropped too far. These limits are checked again during execution."
      ],
      "notes": [
        "Maximum drop 0 disables the decline guard. Neither setting replaces the exits on an already-open position."
      ],
      "minimumTier": 1,
      "defaults": {
        "maximumChasePct": 20
      },
      "settings": [
        {
          "key": "maximumChasePct",
          "label": "Maximum chase %",
          "kind": "number",
          "min": 0,
          "max": 500,
          "step": 0.5,
          "help": "Maximum price rise allowed after the original signal.",
          "initialDisplayValue": "20",
          "details": "Maximum price rise allowed after the original signal. Editor range: 0 to 500."
        },
        {
          "key": "maximumDropPct",
          "label": "Maximum drop %",
          "kind": "number",
          "min": 0,
          "max": 99,
          "step": 0.5,
          "help": "Reject a late entry after this decline from the initial primary signal. Checked again during execution. 0 disables it; existing positions are unaffected.",
          "initialDisplayValue": "0 · disabled",
          "details": "Reject a late entry after this decline from the initial primary signal. Checked again during execution. 0 disables it; existing positions are unaffected. Editor range: 0 to 99."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "demand-confirmation"
      ],
      "outgoing": [
        "wallet-confirmation",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/entry-chase",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/entry-chase"
    },
    {
      "id": "demand-confirmation",
      "title": "Demand confirmation",
      "category": "Filters",
      "description": "Requires positive net buying in two consecutive windows, fresh buyers and retained-buyer growth. These are observed buyers, not a complete holder census. Unknown funding is not verified independence; set a minimum verified-cluster count to require it. Missing or stale flow blocks entry. Wallet retention and original chase limits are rechecked before execution.",
      "how": [
        "Require positive net buying in two consecutive windows, fresh buyers and configured growth in retained observed buyers.",
        "A verified-cluster minimum requires known distinct funding groups. Setting it to zero permits unknown funding without claiming that those buyers are independent."
      ],
      "notes": [
        "Observed retention is not a complete holder census. Missing, truncated or stale flow blocks entry; a confirming wallet’s sale also invalidates demand."
      ],
      "minimumTier": 2,
      "defaults": {
        "windowSeconds": 1,
        "minimumNetBuySol": 0.02,
        "minimumNewBuyers": 1,
        "minimumRetainedGrowth": 1,
        "minimumVerifiedClusters": 0,
        "maximumDataAgeSeconds": 2
      },
      "settings": [
        {
          "key": "windowSeconds",
          "label": "Each window (seconds)",
          "kind": "number",
          "min": 1,
          "max": 10,
          "step": 1,
          "help": "Two consecutive windows must both show net buying. Fresh source signals still expire normally.",
          "initialDisplayValue": "1",
          "details": "Two consecutive windows must both show net buying. Fresh source signals still expire normally. Editor range: 1 to 10."
        },
        {
          "key": "minimumNetBuySol",
          "label": "Net buying per window (SOL)",
          "kind": "number",
          "min": 0,
          "max": 1000000,
          "sliderMax": 5,
          "step": 0.01,
          "help": "Buy SOL minus sell SOL must exceed this in both windows. Creator trades are excluded.",
          "initialDisplayValue": "0.02",
          "details": "Buy SOL minus sell SOL must exceed this in both windows. Creator trades are excluded. Editor range: 0 to 1000000."
        },
        {
          "key": "minimumNewBuyers",
          "label": "Fresh buyers",
          "kind": "number",
          "min": 1,
          "max": 100,
          "step": 1,
          "help": "Buyers arriving in the second window who are not confirming wallets or linked to known first-wave funders.",
          "initialDisplayValue": "1",
          "details": "Buyers arriving in the second window who are not confirming wallets or linked to known first-wave funders. Editor range: 1 to 100."
        },
        {
          "key": "minimumRetainedGrowth",
          "label": "Retained-buyer growth",
          "kind": "number",
          "min": 0,
          "max": 100,
          "step": 1,
          "zeroMeansOff": true,
          "help": "Growth in observed buyers still retaining tokens. This is not a full holder census.",
          "initialDisplayValue": "1",
          "details": "Growth in observed buyers still retaining tokens. This is not a full holder census. Editor range: 0 to 100. Zero disables this threshold."
        },
        {
          "key": "minimumVerifiedClusters",
          "label": "Verified new clusters",
          "kind": "number",
          "min": 0,
          "max": 100,
          "step": 1,
          "zeroMeansOff": true,
          "help": "Known distinct funding clusters among fresh buyers. Zero allows unknown funding, without claiming independence.",
          "initialDisplayValue": "0",
          "details": "Known distinct funding clusters among fresh buyers. Zero allows unknown funding, without claiming independence. Editor range: 0 to 100. Zero disables this threshold."
        },
        {
          "key": "maximumDataAgeSeconds",
          "label": "Maximum data age (seconds)",
          "kind": "number",
          "min": 0.1,
          "max": 5,
          "step": 0.1,
          "help": "Stale or incomplete flow blocks entry.",
          "initialDisplayValue": "2",
          "details": "Stale or incomplete flow blocks entry. Editor range: 0.1 to 5."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "entry-chase"
      ],
      "outgoing": [
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/demand-confirmation",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/demand-confirmation"
    },
    {
      "id": "setup-failed",
      "title": "Setup failed",
      "category": "Exits",
      "description": "Closes the position when buying fades and net selling takes over, optionally requiring an observed sale from a confirming wallet. A price dip, elapsed time or missing data alone cannot trigger this exit. Emergency stop and time exit remain active.",
      "how": [
        "After a minimum hold, compare consecutive buying windows and require net selling in the latest window.",
        "Optionally require an observed sale by a wallet that confirmed the entry. When the setup is demonstrably fading, the connected Close trade closes what remains."
      ],
      "notes": [
        "Attach directly after Open trade, with exactly one Close trade action. A price dip, elapsed time or missing data alone cannot trigger this exit.",
        "Emergency stops and the Time exit remain active independently."
      ],
      "minimumTier": 2,
      "defaults": {
        "minimumHoldSeconds": 10,
        "windowSeconds": 3,
        "maximumBuyRatio": 0.5,
        "minimumNetSellSol": 0.02,
        "requireWalletSell": true,
        "maximumDataAgeSeconds": 2
      },
      "settings": [
        {
          "key": "minimumHoldSeconds",
          "label": "Minimum hold (seconds)",
          "kind": "number",
          "min": 0,
          "max": 3600,
          "sliderMax": 60,
          "step": 1,
          "zeroMeansOff": true,
          "help": "Earliest evaluation of this exit. This does not delay emergency stops.",
          "initialDisplayValue": "10",
          "details": "Earliest evaluation of this exit. This does not delay emergency stops. Editor range: 0 to 3600. Zero disables this threshold."
        },
        {
          "key": "windowSeconds",
          "label": "Each window (seconds)",
          "kind": "number",
          "min": 1,
          "max": 10,
          "step": 1,
          "help": "Compare buying in consecutive windows, and require net selling in the latest.",
          "initialDisplayValue": "3",
          "details": "Compare buying in consecutive windows, and require net selling in the latest. Editor range: 1 to 10."
        },
        {
          "key": "maximumBuyRatio",
          "label": "Buying remaining (ratio)",
          "kind": "number",
          "min": 0,
          "max": 1,
          "step": 0.05,
          "help": "0.5 means current buying is at most half the previous window; zero requires no new buys.",
          "initialDisplayValue": "0.5",
          "details": "0.5 means current buying is at most half the previous window; zero requires no new buys. Editor range: 0 to 1."
        },
        {
          "key": "minimumNetSellSol",
          "label": "Net selling (SOL)",
          "kind": "number",
          "min": 0,
          "max": 1000000,
          "sliderMax": 5,
          "step": 0.01,
          "help": "Sell SOL minus buy SOL must exceed this amount. Missing data is not selling.",
          "initialDisplayValue": "0.02",
          "details": "Sell SOL minus buy SOL must exceed this amount. Missing data is not selling. Editor range: 0 to 1000000."
        },
        {
          "key": "requireWalletSell",
          "label": "Confirming wallet sold",
          "kind": "boolean",
          "options": [
            {
              "value": "true",
              "label": "Required"
            },
            {
              "value": "false",
              "label": "Not required"
            }
          ],
          "help": "Require an observed sale from a wallet that confirmed your entry.",
          "initialDisplayValue": "Enabled",
          "details": "Require an observed sale from a wallet that confirmed your entry. Options: Required (true); Not required (false)."
        },
        {
          "key": "maximumDataAgeSeconds",
          "label": "Maximum data age (seconds)",
          "kind": "number",
          "min": 0.1,
          "max": 5,
          "step": 0.1,
          "help": "Stale or incomplete data cannot trigger this exit.",
          "initialDisplayValue": "2",
          "details": "Stale or incomplete data cannot trigger this exit. Editor range: 0.1 to 5."
        }
      ],
      "incoming": [
        "open-trade"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "close-trade"
      ],
      "url": "https://docs.orbi.gg/nodes/setup-failed",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/setup-failed"
    },
    {
      "id": "open-trade",
      "title": "Open trade",
      "category": "Trade",
      "description": "Sets position size, execution limits and the mandatory emergency stop.",
      "how": [
        "Create a position using its USD amount, slippage limit, simultaneous-position cap and token cooldown.",
        "Choose whether an observed source-wallet sell should close the remaining position. The emergency stop is a fallback safety limit, not a guaranteed execution price."
      ],
      "notes": [
        "Only one active Open trade is allowed per bot. Each needs an exit action, a reachable Close trade, and a direct Time exit → Close trade safety path.",
        "Filled branches can reach exits or alerts. Failed branches cannot reach position exits and cannot send successful-fill notifications.",
        "These settings describe the graph contract, not a promise that live execution is currently enabled or that a token can be sold."
      ],
      "minimumTier": 0,
      "defaults": {
        "amountUsd": 1,
        "maximumSlippagePct": 14,
        "emergencyStopPct": -30,
        "maximumPositions": 1,
        "cooldownMinutes": 15,
        "sourceSellExit": true
      },
      "settings": [
        {
          "key": "amountUsd",
          "label": "Position USD",
          "kind": "number",
          "min": 1,
          "max": 50,
          "step": 0.01,
          "help": "Cash risked on each filled entry; it cannot exceed available funds.",
          "initialDisplayValue": "1",
          "details": "Cash risked on each filled entry; it cannot exceed available funds. Editor range: 1 to 50."
        },
        {
          "key": "maximumSlippagePct",
          "label": "Maximum slippage %",
          "kind": "number",
          "min": 0.1,
          "max": 50,
          "step": 0.1,
          "help": "Reject an execution that lands beyond this price movement.",
          "initialDisplayValue": "14",
          "details": "Reject an execution that lands beyond this price movement. Editor range: 0.1 to 50."
        },
        {
          "key": "emergencyStopPct",
          "label": "Emergency stop %",
          "kind": "number",
          "min": -90,
          "max": -1,
          "step": 1,
          "help": "Fallback loss limit if no earlier stop closes the trade.",
          "initialDisplayValue": "-30",
          "details": "Fallback loss limit if no earlier stop closes the trade. Editor range: -90 to -1."
        },
        {
          "key": "maximumPositions",
          "label": "Maximum positions",
          "kind": "number",
          "min": 1,
          "max": 5,
          "step": 1,
          "help": "Maximum simultaneous active positions for this bot.",
          "initialDisplayValue": "1",
          "details": "Maximum simultaneous active positions for this bot. Editor range: 1 to 5."
        },
        {
          "key": "cooldownMinutes",
          "label": "Token cooldown (minutes)",
          "kind": "number",
          "min": 0,
          "max": 1440,
          "step": 1,
          "help": "Wait before entering the same token again.",
          "zeroMeansOff": true,
          "initialDisplayValue": "15",
          "details": "Wait before entering the same token again. Editor range: 0 to 1440. Zero disables this threshold."
        },
        {
          "key": "sourceSellExit",
          "label": "Exit when source sells",
          "kind": "boolean",
          "options": [
            {
              "value": "true",
              "label": "Enabled"
            },
            {
              "value": "false",
              "label": "Disabled"
            }
          ],
          "help": "Close the remaining position when an observed sell from its source wallet arrives. Disabled leaves exits to the connected exit nodes and emergency stop.",
          "initialDisplayValue": "Enabled",
          "details": "Close the remaining position when an observed sell from its source wallet arrives. Disabled leaves exits to the connected exit nodes and emergency stop. Options: Enabled (true); Disabled (false)."
        }
      ],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation"
      ],
      "outgoing": [
        "setup-failed",
        "telegram-notify",
        "discord-notify",
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit",
        "skip-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/open-trade",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/open-trade"
    },
    {
      "id": "telegram-notify",
      "title": "Telegram notification",
      "category": "Notifications",
      "description": "Ends a notification branch; no End connection is needed. Choose the colour and fields sent to your connected Telegram account. Wallet amount is the watched wallet's trade; My entry is your bot's filled amount, excluding separate fees and rent. Missing fields are omitted. Trade-action alerts wait for confirmed fills.",
      "how": [
        "Send selected event fields to the Telegram account connected in your own Orbi settings.",
        "Choose a colour marker and fields. Wallet amount is the watched wallet’s trade; My entry is your bot’s filled amount, excluding separate fees and rent."
      ],
      "notes": [
        "Terminal alert branch; no End connection is required. Missing fields are omitted and trade-action alerts wait for confirmed fills.",
        "Recipients cannot be inserted as arbitrary graph credentials. Alerts attach to successful events, not no/fail/failed branches.",
        "An End connection is accepted for legacy graphs, but is not required for notification delivery."
      ],
      "minimumTier": 0,
      "defaults": {
        "marker": "",
        "fields": [
          "event",
          "token",
          "token-address",
          "wallet-address",
          "market-cap",
          "price",
          "pnl",
          "reason",
          "jupiter-link",
          "company",
          "headline",
          "filing",
          "importance",
          "summary",
          "source-link",
          "publication-time"
        ]
      },
      "settings": [
        {
          "key": "marker",
          "label": "Message colour",
          "kind": "select",
          "help": "Optional colour marker; None is the legacy default.",
          "initialDisplayValue": "None",
          "details": "Optional colour marker; None is the legacy default."
        },
        {
          "key": "fields",
          "label": "Message fields",
          "kind": "fields",
          "help": "Choose at least one field: Bot + event, Token name, Token address, Jupiter link, Wallet address, Wallet amount · SOL, My entry · SOL, My entry · USD, Market cap, Token price, Net P&L, Exit reason, Runner stage, Time · UTC, Company ticker, Headline, Report + items, Importance + bias, Summary, Source link, Published · UTC.",
          "initialDisplayValue": "16 fields selected",
          "details": "Choose at least one field: Bot + event, Token name, Token address, Jupiter link, Wallet address, Wallet amount · SOL, My entry · SOL, My entry · USD, Market cap, Token price, Net P&L, Exit reason, Runner stage, Time · UTC, Company ticker, Headline, Report + items, Importance + bias, Summary, Source link, Published · UTC."
        }
      ],
      "incoming": [
        "sec-filings",
        "company-news",
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "entry-chase",
        "demand-confirmation",
        "setup-failed",
        "open-trade",
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit",
        "sell-position",
        "close-trade"
      ],
      "outgoing": [
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/telegram-notify",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/telegram-notify"
    },
    {
      "id": "discord-notify",
      "title": "Discord notification",
      "category": "Notifications",
      "description": "Tier 1 notification branch. Choose one of your connected Discord servers, a text channel, an embed accent and the event fields to send. No End connection is needed.",
      "how": [
        "Choose one of your connected servers and a text channel, then select an embed colour and event fields.",
        "Attach it to a successful company event, candidate, fill or exit trigger. Trading links and the optional token image use the observed event data."
      ],
      "notes": [
        "Requires Tier 1. Terminal alert branch; no End connection is required. A connected server/channel must be selected before the graph is valid.",
        "Destinations are account-owned and unsuccessful branches cannot masquerade as successful alerts.",
        "An End connection is accepted for legacy graphs, but is not required for notification delivery."
      ],
      "minimumTier": 1,
      "defaults": {
        "colour": "purple",
        "fields": [
          "event",
          "token",
          "token-image",
          "token-address",
          "wallet-address",
          "market-cap",
          "price",
          "pnl",
          "reason",
          "jupiter-link",
          "company",
          "headline",
          "filing",
          "importance",
          "summary",
          "source-link",
          "publication-time"
        ]
      },
      "settings": [
        {
          "key": "guildId",
          "label": "Connected server",
          "kind": "select",
          "help": "Choose a server connected to your account; there is no default destination.",
          "initialDisplayValue": "Choose in the app",
          "details": "Choose a server connected to your account; there is no default destination."
        },
        {
          "key": "channelId",
          "label": "Text channel",
          "kind": "select",
          "help": "Choose an eligible channel in that connected server.",
          "initialDisplayValue": "Choose in the app",
          "details": "Choose an eligible channel in that connected server."
        },
        {
          "key": "colour",
          "label": "Embed colour",
          "kind": "select",
          "help": "Purple, blue, green, red, orange, yellow or white.",
          "initialDisplayValue": "purple",
          "details": "Purple, blue, green, red, orange, yellow or white."
        },
        {
          "key": "fields",
          "label": "Message fields",
          "kind": "fields",
          "help": "Choose at least one field: Bot + event, Token name, Token address, Trading links, Wallet address, Wallet amount · SOL, My entry · SOL, My entry · USD, Market cap, Token price, Net P&L, Exit reason, Runner stage, Time · UTC, Company ticker, Headline, Report + items, Importance + bias, Summary, Source link, Published · UTC, Token image.",
          "initialDisplayValue": "17 fields selected",
          "details": "Choose at least one field: Bot + event, Token name, Token address, Trading links, Wallet address, Wallet amount · SOL, My entry · SOL, My entry · USD, Market cap, Token price, Net P&L, Exit reason, Runner stage, Time · UTC, Company ticker, Headline, Report + items, Importance + bias, Summary, Source link, Published · UTC, Token image."
        }
      ],
      "incoming": [
        "sec-filings",
        "company-news",
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "entry-chase",
        "demand-confirmation",
        "setup-failed",
        "open-trade",
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit",
        "sell-position",
        "close-trade"
      ],
      "outgoing": [
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/discord-notify",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/discord-notify"
    },
    {
      "id": "profit-target",
      "title": "Profit target",
      "category": "Exits",
      "description": "Activates when return reaches the configured profit.",
      "how": [
        "Watch the open position’s return and trigger its connected action once the target is reached.",
        "Connect exactly one Sell position or Close trade. A Telegram or Discord alert can be a separate successful side branch."
      ],
      "notes": [
        "Return thresholds are not a promise of realized net profit. Slippage and costs affect the settled result."
      ],
      "minimumTier": 0,
      "defaults": {
        "returnPct": 50
      },
      "settings": [
        {
          "key": "returnPct",
          "label": "Profit %",
          "kind": "number",
          "min": 1,
          "max": 100000,
          "sliderMax": 1000,
          "step": 0.5,
          "help": "Triggers its connected sell when net market return reaches this gain.",
          "initialDisplayValue": "50",
          "details": "Triggers its connected sell when net market return reaches this gain. Editor range: 1 to 100000."
        }
      ],
      "incoming": [
        "open-trade",
        "sell-position"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "sell-position",
        "close-trade"
      ],
      "url": "https://docs.orbi.gg/nodes/profit-target",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/profit-target"
    },
    {
      "id": "stop-loss",
      "title": "Stop loss",
      "category": "Exits",
      "description": "Activates when return reaches the configured loss.",
      "how": [
        "Trigger a sell or close when the open position reaches the configured negative return.",
        "A 0% stop is active at the entry price; it does not disable this node."
      ],
      "notes": [
        "Fees, liquidity and slippage still apply. Stops do not guarantee the sale price or limit losses during an outage."
      ],
      "minimumTier": 0,
      "defaults": {
        "returnPct": -20
      },
      "settings": [
        {
          "key": "returnPct",
          "label": "Stop %",
          "kind": "number",
          "min": -90,
          "max": 0,
          "step": 0.5,
          "help": "Triggers when price return falls to this level. 0% is an active entry-price stop, not disabled; fees and slippage still apply.",
          "initialDisplayValue": "-20",
          "details": "Triggers when price return falls to this level. 0% is an active entry-price stop, not disabled; fees and slippage still apply. Editor range: -90 to 0."
        }
      ],
      "incoming": [
        "open-trade",
        "sell-position"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "sell-position",
        "close-trade"
      ],
      "url": "https://docs.orbi.gg/nodes/stop-loss",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/stop-loss"
    },
    {
      "id": "trailing-stop",
      "title": "Trailing stop",
      "category": "Exits",
      "description": "Protects a runner after a configured profit is reached.",
      "how": [
        "Activate after a specified peak gain, then watch the allowed drop from the best observed price.",
        "Optionally protect a minimum return floor. Zero means break-even; −100 disables the additional floor for a long position."
      ],
      "notes": [
        "Needs an open position and exactly one connected sell/close action. Its trigger is distinct from realized P&L."
      ],
      "minimumTier": 1,
      "defaults": {
        "activateAfterPct": 50,
        "trailPct": 20,
        "minimumReturnPct": 0
      },
      "settings": [
        {
          "key": "activateAfterPct",
          "label": "Activate after %",
          "kind": "number",
          "min": 0.1,
          "max": 10000,
          "step": 0.5,
          "help": "Peak return required before the trailing exit becomes active.",
          "initialDisplayValue": "50",
          "details": "Peak return required before the trailing exit becomes active. Editor range: 0.1 to 10000."
        },
        {
          "key": "trailPct",
          "label": "Trail from peak %",
          "kind": "number",
          "min": 0.1,
          "max": 99,
          "step": 0.5,
          "help": "Allowed drop from the best observed price after activation.",
          "initialDisplayValue": "20",
          "details": "Allowed drop from the best observed price after activation. Editor range: 0.1 to 99."
        },
        {
          "key": "minimumReturnPct",
          "label": "Minimum locked return %",
          "kind": "number",
          "min": -100,
          "max": 10000,
          "step": 0.5,
          "help": "Lowest return the trailing exit may protect; zero means break-even. −100 disables this extra floor.",
          "initialDisplayValue": "0",
          "details": "Lowest return the trailing exit may protect; zero means break-even. −100 disables this extra floor. Editor range: -100 to 10000."
        }
      ],
      "incoming": [
        "open-trade",
        "sell-position"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "sell-position",
        "close-trade"
      ],
      "url": "https://docs.orbi.gg/nodes/trailing-stop",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/trailing-stop"
    },
    {
      "id": "time-exit",
      "title": "Time exit",
      "category": "Exits",
      "description": "Activates after the position has remained open for the configured duration.",
      "how": [
        "Trigger after the position has remained open for the configured number of minutes.",
        "Use a direct Open trade → Time exit → Close trade path so remaining tokens have a complete time-based exit."
      ],
      "notes": [
        "A Time exit that only partially sells does not satisfy the graph’s mandatory remaining-position safety path."
      ],
      "minimumTier": 0,
      "defaults": {
        "minutes": 5
      },
      "settings": [
        {
          "key": "minutes",
          "label": "Minutes",
          "kind": "number",
          "min": 0.1,
          "max": 10080,
          "step": 0.1,
          "help": "Closes through the connected action after this hold time.",
          "initialDisplayValue": "5",
          "details": "Closes through the connected action after this hold time. Editor range: 0.1 to 10080."
        }
      ],
      "incoming": [
        "open-trade",
        "sell-position"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "sell-position",
        "close-trade"
      ],
      "url": "https://docs.orbi.gg/nodes/time-exit",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/time-exit"
    },
    {
      "id": "sell-position",
      "title": "Sell position",
      "category": "Trade",
      "description": "Sells 25%, 50%, 75% or 100% of what remains.",
      "how": [
        "Sell the configured percentage of the tokens that remain, rather than a percentage of the original entry.",
        "After a partial sell, connect further exits, Close trade or End as appropriate. Preserve a separate Time exit → Close trade path from Open trade."
      ],
      "notes": [
        "A 50% sell followed by another 50% sell leaves 25% of the original amount. End alone is not a full-liquidation action."
      ],
      "minimumTier": 1,
      "defaults": {
        "sellPercent": 50
      },
      "settings": [
        {
          "key": "sellPercent",
          "label": "Sell remaining %",
          "kind": "number",
          "min": 1,
          "max": 100,
          "step": 1,
          "help": "Percentage of the currently remaining tokens to sell.",
          "initialDisplayValue": "50",
          "details": "Percentage of the currently remaining tokens to sell. Editor range: 1 to 100."
        }
      ],
      "incoming": [
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit",
        "close-trade",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/sell-position",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/sell-position"
    },
    {
      "id": "close-trade",
      "title": "Close trade",
      "category": "Trade",
      "description": "Closes everything remaining. Auto rent returns empty token-account rent to your live wallet after confirmed settlement. It never burns tokens or closes accounts another position uses. Refunds are not profit; network fees still count.",
      "how": [
        "Sell everything remaining and connect to End to finish the position path.",
        "Auto rent, when live execution supports it, returns rent from an empty token account after confirmed settlement. It never burns dust or closes an account used by another position."
      ],
      "notes": [
        "A rent refund is not profit; network fees still count. An unresolved receipt must be reconciled rather than blindly repeated."
      ],
      "minimumTier": 0,
      "defaults": {
        "sellPercent": 100,
        "autoRent": true
      },
      "settings": [
        {
          "key": "autoRent",
          "label": "Auto rent · live only",
          "kind": "boolean",
          "options": [
            {
              "value": "true",
              "label": "Enabled"
            },
            {
              "value": "false",
              "label": "Disabled"
            }
          ],
          "help": "After a confirmed full sale, return empty token-account rent to your own wallet. Never burns dust; retries settlement safely. Refunds are excluded from P&L.",
          "initialDisplayValue": "Enabled",
          "details": "After a confirmed full sale, return empty token-account rent to your own wallet. Never burns dust; retries settlement safely. Refunds are excluded from P&L. Options: Enabled (true); Disabled (false)."
        }
      ],
      "incoming": [
        "setup-failed",
        "profit-target",
        "stop-loss",
        "trailing-stop",
        "time-exit",
        "sell-position"
      ],
      "outgoing": [
        "telegram-notify",
        "discord-notify",
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/close-trade",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/close-trade"
    },
    {
      "id": "skip-trade",
      "title": "Skip trade",
      "category": "Trade",
      "description": "Records a rejected candidate without opening a position.",
      "how": [
        "Record a rejected candidate without opening a position, then connect to End.",
        "Use this to terminate a rejected or failed-entry path rather than routing it into a sell action."
      ],
      "notes": [
        "Skip trade does not sell or close an existing position."
      ],
      "minimumTier": 1,
      "defaults": {},
      "settings": [],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade"
      ],
      "outgoing": [
        "end"
      ],
      "url": "https://docs.orbi.gg/nodes/skip-trade",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/skip-trade"
    },
    {
      "id": "stop-bot",
      "title": "Stop bot",
      "category": "Safety",
      "description": "Pauses new entries until the user manually resumes the bot. Open positions remain managed.",
      "how": [
        "Pause new entries until you resume the bot. It is a terminal node with no outgoing connections.",
        "Use it on Balance’s Fail branch so insufficient available cash cannot start another trade."
      ],
      "notes": [
        "Existing positions retain their managed exits while the runtime is available. Pausing is not the same as liquidating."
      ],
      "minimumTier": 1,
      "defaults": {},
      "settings": [],
      "incoming": [
        "balance-check"
      ],
      "outgoing": [],
      "url": "https://docs.orbi.gg/nodes/stop-bot",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/stop-bot"
    },
    {
      "id": "end",
      "title": "End",
      "category": "Flow",
      "description": "Marks a completed entry or exit path.",
      "how": [
        "Mark an entry, exit or signal-only path complete. End has no outgoing connections.",
        "A qualified signal reaching End can be used without creating an order. A trade action must also have a path to End."
      ],
      "notes": [
        "End does not create, sell or close a position. Notification nodes can finish their own branches without End."
      ],
      "minimumTier": 0,
      "defaults": {},
      "settings": [],
      "incoming": [
        "aegis-wallet-feed",
        "wallet-signal",
        "wallet-confirmation",
        "wallet-conviction",
        "runner-potential",
        "twitter-traction",
        "token-filter",
        "balance-check",
        "entry-chase",
        "demand-confirmation",
        "open-trade",
        "telegram-notify",
        "discord-notify",
        "sell-position",
        "close-trade",
        "skip-trade"
      ],
      "outgoing": [],
      "url": "https://docs.orbi.gg/nodes/end",
      "markdownUrl": "https://docs.orbi.gg/markdown/nodes/end"
    }
  ]
}
