Back to Docs/OpenTool CONFIG Lifecycle

OpenTool CONFIG Lifecycle

Developer guide to authoring templateConfig and OPENTOOL_PUBLIC config flows.

OpenTool CONFIG Lifecycle

This guide is for OpenTool template developers.

Use it when you want your tool to expose editable config in OpenPond UI.

What CONFIG means in OpenTool

In OpenTool, template config has two separate parts:

  • Contract metadata in code: profile.templateConfig
  • Runtime value data: JSON stored in an env var (usually OPENTOOL_PUBLIC_*)

templateConfig tells the platform:

  • which env var to use (envVar)
  • what shape to render/validate (schema)
  • initial field values (defaults)
  • config contract version (version)

Add CONFIG to a tool

Define profile.templateConfig in your tool module:

ts
export const profile = { description: "Example strategy", category: "strategy", schedule: { cron: "0 * * * *", enabled: false }, templateConfig: { version: 2, envVar: "OPENTOOL_PUBLIC_MY_STRATEGY_CONFIG", schema: { type: "object", properties: { environment: { type: "string", enum: ["mainnet", "testnet"], default: "testnet", }, amountUsd: { type: "number", minimum: 1, default: 25, }, }, }, defaults: { environment: "testnet", amountUsd: 25, }, }, };

Required and optional fields

  • Required: templateConfig.version (string or number)
  • Optional: templateConfig.schema (object)
  • Optional: templateConfig.defaults (object)
  • Optional: templateConfig.envVar (non-empty string)

Validation is enforced during opentool validate/build. For current strategy templates, use version >= 2.

Trading fields

For capital-allocating trading templates, use these top-level config fields:

  • allocationMode: "fixed" | "percent_equity" | "target_notional"
  • maxPerRunUsd: positive number

Mode-specific fields:

  • fixed: amountUsd
  • percent_equity: percentOfEquity, optional maxPercentOfEquity
  • target_notional: targetNotionalUsd

These fields give one canonical exposure contract across templates while keeping strategy logic inside template code.

Config popup layout recommendation

Use a two-level layout in the config popup:

  • Primary (always visible): allocationMode, maxPerRunUsd, and the active mode-specific field(s)
  • Advanced (collapsed by default): schedule, indicator tuning, slippage/leverage, optional guardrails, and strategy-specific extras

This keeps risk/budget controls visible first and reduces confusion for end users.

End-to-end lifecycle

  1. You author profile.templateConfig in tool code.
  2. opentool build emits tool profile into dist/tools.json.
  3. OpenPond deployment ingests tools.json.
  4. OpenPond config UI discovers your templateConfig from that manifest.
  5. User edits config and saves.
  6. Saved JSON is written to your configured env var key.
  7. If deploy is triggered, runtime starts using the new env value.

Runtime usage pattern

Read and parse your config env var inside tool code:

ts
type StrategyConfig = { environment: "mainnet" | "testnet"; amountUsd: number; }; function readConfig(): StrategyConfig { const raw = process.env.OPENTOOL_PUBLIC_MY_STRATEGY_CONFIG; if (!raw) throw new Error("Missing OPENTOOL_PUBLIC_MY_STRATEGY_CONFIG"); const parsed = JSON.parse(raw) as StrategyConfig; return parsed; }

Keep parsing strict and fail fast on invalid config.

Naming and versioning recommendations

  • Use stable env var names: OPENTOOL_PUBLIC_<TOOL>_CONFIG.
  • Treat templateConfig.version as a contract version.
  • Increment version when schema shape changes in a breaking way.
  • Keep defaults backward compatible where possible.

Practical rules

  • Keep strategy logic in template code, not in OpenTool core.
  • Use schema + defaults to keep UI and runtime expectations aligned.
  • Assume config saves can happen independently from immediate deploy.
  • Write runtime code that clearly errors when required fields are missing.