{ "$defs": { "Adapter": { "description": "Configuration for a custom canister build adapter.", "oneOf": [ { "description": "Command used to build a canister", "properties": { "command": { "type": "string" } }, "required": [ "command" ], "type": "object" }, { "description": "Set of commands used to build a canister", "properties": { "commands": { "items": { "type": "string" }, "type": "array" } }, "required": [ "commands" ], "type": "object" } ], "type": "object" }, "Adapter2": { "anyOf": [ { "$ref": "#/$defs/LocalSource", "description": "Local path on-disk to read a WASM file from" }, { "$ref": "#/$defs/RemoteSource", "description": "Remote url to fetch a WASM file from" } ], "description": "Configuration for a wasm source — used by adapters that load a `.wasm` file\neither from a local path or from a remote URL.", "properties": { "sha256": { "description": "Optional sha256 checksum of the WASM", "type": [ "string", "null" ] } }, "type": "object" }, "Adapter3": { "anyOf": [ { "$ref": "#/$defs/LocalSource", "description": "Local path on-disk to read a WASM file from" }, { "$ref": "#/$defs/RemoteSource", "description": "Remote url to fetch a WASM file from" } ], "description": "Configuration for a sync plugin step.\n\nA sync plugin is a WebAssembly module invoked during `icp sync` for a\nspecific canister. It runs inside a WASI sandbox whose filesystem access\nis limited to the directories listed in `dirs` (preopened read-only) plus\nthe contents of any files listed in `files` (read by the host and passed\ninline to the plugin).\n\nExample (local path):\n```yaml\n- type: plugin\n path: ./plugins/populate-data.wasm\n sha256: e3b0c44298fc1c149afb... # optional for path\n dirs: # directories preopened read-only\n - assets/seed-data\n files: # files read by the host and passed inline\n - config.txt\n```\n\nExample (remote URL — `sha256` is required):\n```yaml\n- type: plugin\n url: https://example.com/plugins/populate-data.wasm\n sha256: e3b0c44298fc1c149afb... # required for url\n```", "properties": { "dirs": { "description": "Directories (relative to canister directory) the plugin may read from.\nEach entry must be a directory; it is preopened via WASI so the plugin\ncan traverse it using standard filesystem APIs.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "files": { "description": "Files (relative to canister directory) the host reads and passes to\nthe plugin as part of `sync-exec-input.files`.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "sha256": { "description": "Optional sha256 checksum of the wasm file.\nOptional for `path`; required for `url`.", "type": [ "string", "null" ] } }, "type": "object" }, "ArgsFormat": { "description": "Format specifier for canister call/install args content.", "oneOf": [ { "const": "hex", "description": "Hex-encoded bytes", "type": "string" }, { "const": "candid", "description": "Candid text format", "type": "string" }, { "const": "bin", "description": "Raw binary (only valid for file references)", "type": "string" } ] }, "BuildStep": { "description": "Identifies the type of adapter used to build the canister,\nalong with its configuration.\n\nThe adapter type is specified via the `type` field in the YAML file.\nFor example:\n\n```yaml\ntype: script\ncommand: do_something.sh\n```", "oneOf": [ { "$ref": "#/$defs/Adapter", "description": "Represents a canister built using a custom script or command.\nThis variant allows for flexible build processes defined by the user.", "properties": { "type": { "const": "script", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "$ref": "#/$defs/Adapter2", "description": "Represents a pre-built canister.\nThis variant allows for retrieving a canister WASM from various sources.", "properties": { "type": { "const": "pre-built", "type": "string" } }, "required": [ "type" ], "type": "object" } ] }, "BuildSteps": { "description": "Describes how the canister should be built into WebAssembly,\nincluding the adapters and build steps responsible for the build.", "properties": { "steps": { "items": { "$ref": "#/$defs/BuildStep" }, "type": "array" } }, "required": [ "steps" ], "type": "object" }, "CanisterManifest": { "anyOf": [ { "properties": { "recipe": { "$ref": "#/$defs/Recipe" } }, "required": [ "recipe" ], "type": "object" }, { "properties": { "build": { "$ref": "#/$defs/BuildSteps", "description": "The build configuration specifying how to compile the canister's source\ncode into a WebAssembly module, including the adapter to use." }, "sync": { "anyOf": [ { "$ref": "#/$defs/SyncSteps" }, { "type": "null" } ], "description": "The configuration specifying how to sync the canister" } }, "required": [ "build" ], "type": "object" } ], "description": "Represents the manifest describing a single canister.\nThis struct is typically loaded from a `canister.yaml` file and defines\nthe canister's name and how it should be built into WebAssembly.", "properties": { "init_args": { "anyOf": [ { "$ref": "#/$defs/ManifestInitArgs" }, { "type": "null" } ], "description": "Initialization arguments passed to the canister during installation." }, "name": { "description": "The unique name of the canister as defined in this manifest.", "type": "string" }, "settings": { "$ref": "#/$defs/Settings", "default": { "controllers": null }, "description": "The configuration specifying the various settings when creating the canister." } }, "required": [ "name" ], "type": "object" }, "Connected": { "anyOf": [ { "properties": { "api-url": { "description": "The URL of the API endpoint. Should support the standard API routes (e.g. /api/v3).", "format": "uri", "type": "string" }, "http-gateway-url": { "description": "The URL of the HTTP gateway endpoint. Should support prefixing canister IDs as subdomains,\notherwise icp-cli will fall back to ?canisterId= query parameters which are frequently brittle in frontend code.\n\nIf no HTTP gateway endpoint is provided, canister URLs will not be printed in deploy operations.", "format": "uri", "type": [ "string", "null" ] } }, "required": [ "api-url" ], "type": "object" }, { "properties": { "url": { "description": "The URL this network can be reached at.\n\nAssumed to be the URL of both the HTTP gateway (canister-id.domain.com) and API (domain.com/api/v3).", "format": "uri", "type": "string" } }, "required": [ "url" ], "type": "object" } ], "properties": { "root-key": { "$ref": "#/$defs/RootKeySpec", "description": "How to obtain the root key used to verify responses from this network.\n\nOne of:\n- `mainnet`: use the canonical IC mainnet root key (e.g. to reach mainnet\n through a non-default boundary node without repeating the key literal).\n- `fetch`: fetch the root key from the network on each use. This is\n trust-on-first-use and does *not* verify the key's provenance; only use it\n for testnets that you (or someone you trust) operate.\n- a 266-character hex-encoded root key (133 bytes)." } }, "required": [ "root-key" ], "type": "object" }, "ControllerRef": { "description": "A controller: either a principal text (e.g. '2vxsx-fae') or a canister name in this project (e.g. 'my_canister')", "type": "string" }, "CyclesAmount": { "anyOf": [ { "format": "uint64", "minimum": 0, "type": "integer" }, { "type": "string" } ], "description": "An amount of cycles.\n\nDeserializes from a number or a string with suffixes (k, m, b, t) and optional underscore separators." }, "DependencyManifest": { "description": "Declares a dependency on another `icp` project vendored into this one\n(typically as a git submodule).\n\nRunning `icp deploy` deploys the dependency's canisters into the parent's\nenvironment and injects the *selected* dependency canisters' IDs into the\nparent's canisters as `PUBLIC_CANISTER_ID::` environment\nvariables.", "properties": { "canisters": { "description": "Which of the dependency's canisters to **expose** to the parent as\n`PUBLIC_CANISTER_ID` environment variables. Defaults to all. This is an\nexposure filter only: the whole dependency is always deployed, because a\ndependency's canisters may call each other.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "name": { "description": "Local alias for the dependency project. Namespaces the dependency's\ncanister IDs when they are exposed to the parent's canisters as\n`PUBLIC_CANISTER_ID::` environment variables. Must be\nunique among dependencies, must not collide with a local canister name,\nand must not contain `:`.", "type": "string" }, "path": { "description": "Path to the directory containing the dependency's `icp.yaml`, resolved\nrelative to this manifest's project directory.", "type": "string" } }, "required": [ "name", "path" ], "type": "object" }, "DurationAmount": { "anyOf": [ { "format": "uint64", "minimum": 0, "type": "integer" }, { "type": "string" } ], "description": "A duration in seconds.\n\nDeserializes from a number (seconds) or a string with duration suffix (s, m, h, d, w)\nand optional underscore separators.\n\nSuffixes (case-insensitive):\n- `s` — seconds\n- `m` — minutes (×60)\n- `h` — hours (×3600)\n- `d` — days (×86400)\n- `w` — weeks (×604800)\n\nA bare number without suffix is treated as seconds." }, "EnvironmentManifest": { "properties": { "canisters": { "description": "An optional list of the canisters to be included in this environments.\nDefaults to all the canisters if not specified.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "init_args": { "additionalProperties": { "$ref": "#/$defs/ManifestInitArgs" }, "description": "Override init args for specific canisters in this environment", "type": [ "object", "null" ] }, "name": { "type": "string" }, "network": { "description": "The target network for canister deployment.\nDefaults to the `local` network if not specified", "type": [ "string", "null" ] }, "settings": { "additionalProperties": { "$ref": "#/$defs/Settings" }, "description": "Override the canister settings for this environment", "type": [ "object", "null" ] } }, "required": [ "name" ], "type": "object" }, "Gateway": { "properties": { "bind": { "description": "Network interface for the gateway. Defaults to 127.0.0.1", "type": [ "string", "null" ] }, "domains": { "description": "Domains the gateway should respond to. Automatically includes localhost if applicable.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "port": { "description": "Port for the gateway to listen on. Defaults to 8000", "format": "uint16", "maximum": 65535, "minimum": 0, "type": [ "integer", "null" ] } }, "type": "object" }, "Item": { "anyOf": [ { "description": "Path to a manifest", "type": "string" }, { "$ref": "#/$defs/CanisterManifest", "description": "The manifest" } ] }, "Item2": { "anyOf": [ { "description": "Path to a manifest", "type": "string" }, { "$ref": "#/$defs/NetworkManifest", "description": "The manifest" } ] }, "Item3": { "anyOf": [ { "description": "Path to a manifest", "type": "string" }, { "$ref": "#/$defs/EnvironmentManifest", "description": "The manifest" } ] }, "LocalSource": { "properties": { "path": { "description": "Local path on-disk to read a WASM file from", "type": "string" } }, "required": [ "path" ], "type": "object" }, "LogVisibility": { "description": "Controls who can read canister logs.", "oneOf": [ { "description": "Simple log visibility: 'controllers' (only controllers can view) or 'public' (anyone can view)", "enum": [ "controllers", "public" ], "type": "string" }, { "additionalProperties": false, "description": "Specific principals that can view logs", "properties": { "allowed_viewers": { "description": "List of principal IDs that can view canister logs", "items": { "description": "A principal ID that can view logs", "type": "string" }, "type": "array" } }, "required": [ "allowed_viewers" ], "type": "object" } ] }, "Managed": { "anyOf": [ { "properties": { "args": { "description": "Command line arguments to pass to the container's entrypoint", "items": { "type": "string" }, "type": [ "array", "null" ] }, "entrypoint": { "description": "Entrypoint to use for the container", "items": { "type": "string" }, "type": [ "array", "null" ] }, "environment": { "description": "Environment variables to set in the container in VAR=VALUE format (or VAR to inherit from host)", "items": { "type": "string" }, "type": [ "array", "null" ] }, "extra-hosts": { "description": "Extra hosts entries for Docker networking (e.g. \"host.docker.internal:host-gateway\")", "items": { "type": "string" }, "type": [ "array", "null" ] }, "image": { "description": "The docker image to use for the network", "type": "string" }, "mounts": { "description": "Bind mounts to add to the container in the format relative_host_path:container_path[:options]", "items": { "type": "string" }, "type": [ "array", "null" ] }, "platform": { "description": "The platform to use for the container (e.g. linux/amd64)", "type": [ "string", "null" ] }, "port-mapping": { "description": "Port mappings in the format \"host_port:container_port\"", "items": { "type": "string" }, "type": "array" }, "rm-on-exit": { "description": "Whether to delete the container when the network stops", "type": [ "boolean", "null" ] }, "shm-size": { "description": "The size of /dev/shm in bytes", "format": "int64", "type": [ "integer", "null" ] }, "status-dir": { "description": "The status directory inside the container. Defaults to /app/status", "type": [ "string", "null" ] }, "user": { "description": "The user to run the container as in the format user[:group]", "type": [ "string", "null" ] }, "volumes": { "description": "Volumes to mount into the container in the format name:container_path[:options]", "items": { "type": "string" }, "type": [ "array", "null" ] } }, "required": [ "image", "port-mapping" ], "type": "object" }, { "properties": { "artificial-delay-ms": { "description": "Artificial delay to add to every update call", "format": "uint64", "minimum": 0, "type": [ "integer", "null" ] }, "bitcoind-addr": { "description": "Bitcoin P2P node addresses to connect to (e.g. \"127.0.0.1:18444\")", "items": { "type": "string" }, "type": [ "array", "null" ] }, "dogecoind-addr": { "description": "Dogecoin P2P node addresses to connect to", "items": { "type": "string" }, "type": [ "array", "null" ] }, "gateway": { "anyOf": [ { "$ref": "#/$defs/Gateway" }, { "type": "null" } ], "description": "HTTP gateway configuration" }, "ii": { "description": "Set up the Internet Identity canister. Makes internet identity available at\nid.ai.localhost:", "type": [ "boolean", "null" ] }, "nns": { "description": "Set up the NNS", "type": [ "boolean", "null" ] }, "subnets": { "description": "Configure the list of subnets (one application subnet by default)", "items": { "$ref": "#/$defs/SubnetKind" }, "type": [ "array", "null" ] }, "version": { "description": "The version of icp-cli-network-launcher to use. Defaults to the latest released version. Launcher versions correspond to published PocketIC or IC-OS releases.", "type": [ "string", "null" ] } }, "type": "object" } ], "type": "object" }, "ManifestInitArgs": { "anyOf": [ { "description": "Plain string shorthand — treated as Candid.", "type": "string" }, { "description": "File reference with explicit format.", "properties": { "format": { "$ref": "#/$defs/ArgsFormat", "default": "candid" }, "path": { "type": "string" } }, "required": [ "path" ], "type": "object" }, { "description": "Inline value with explicit format.", "properties": { "format": { "$ref": "#/$defs/ArgsFormat", "default": "candid" }, "value": { "type": "string" } }, "required": [ "value" ], "type": "object" } ], "description": "Init args as specified in a manifest file (canister.yaml or icp.yaml).\n\nA plain string is shorthand for inline Candid:\n```yaml\ninit_args: \"(42)\"\n```\n\nObject forms with explicit source and format:\n```yaml\ninit_args:\n path: ./args.bin\n format: bin\n```\n```yaml\ninit_args:\n value: \"(42)\"\n format: candid\n```" }, "MemoryAmount": { "anyOf": [ { "format": "uint64", "minimum": 0, "type": "integer" }, { "type": "string" } ], "description": "An amount of memory in bytes.\n\nDeserializes from a number or a string with suffixes (kb, kib, mb, mib, gb, gib),\noptional decimals, and optional underscore separators." }, "NetworkManifest": { "description": "A network definition for the project", "oneOf": [ { "$ref": "#/$defs/Managed", "properties": { "mode": { "const": "managed", "type": "string" } }, "required": [ "mode" ], "type": "object" }, { "$ref": "#/$defs/Connected", "properties": { "mode": { "const": "connected", "type": "string" } }, "required": [ "mode" ], "type": "object" } ], "properties": { "name": { "type": "string" } }, "required": [ "name" ], "type": "object" }, "Recipe": { "properties": { "configuration": { "additionalProperties": true, "type": "object" }, "sha256": { "description": "Optional sha256 checksum for the recipe template.\nIf provided, the integrity of the recipe will be verified against this hash", "type": [ "string", "null" ] }, "type": { "description": "An identifier for a recipe, it can have one of the following formats:\n\n`file://` - point to a local recipe template\n\n`http://` - point to a remote recipe template\n\n`@/@` - Point to a recipe in a known registry.\n\nFor now the only registry is the `dfinity` registry at https://github.com/dfinity/icp-cli-recipes\n\nIt is recommended to also provide a hash in the `sha256` field", "type": "string" } }, "required": [ "type" ], "type": "object" }, "RemoteSource": { "properties": { "url": { "description": "Url to fetch the remote WASM file from", "type": "string" } }, "required": [ "url" ], "type": "object" }, "RootKeySpec": { "anyOf": [ { "enum": [ "mainnet", "fetch" ] }, { "pattern": "^[0-9a-f]{266}$" } ], "description": "Root key: \"mainnet\", \"fetch\", or a 266-character hex-encoded key.", "type": "string" }, "Settings": { "description": "Canister settings, such as compute and memory allocation.", "properties": { "compute_allocation": { "description": "Compute allocation (0 to 100). Represents guaranteed compute capacity.", "format": "uint64", "minimum": 0, "type": [ "integer", "null" ] }, "controllers": { "default": null, "description": "Controllers for this canister. Each entry is either a principal text\n(e.g. \"2vxsx-fae\") or the name of another canister in this project.\nNamed canisters that do not yet exist will be set as controllers once created.", "items": { "$ref": "#/$defs/ControllerRef" }, "type": [ "array", "null" ] }, "environment_variables": { "additionalProperties": { "type": "string" }, "description": "Environment variables for the canister as key-value pairs.\nThese variables are accessible within the canister and can be used to configure\nbehavior without hardcoding values in the WASM module.", "type": [ "object", "null" ] }, "freezing_threshold": { "anyOf": [ { "$ref": "#/$defs/DurationAmount" }, { "type": "null" } ], "description": "Freezing threshold in seconds. Controls how long a canister can be inactive before being frozen.\nSupports duration suffixes in YAML: s, m, h, d, w (e.g. \"30d\" or \"4w\")." }, "log_memory_limit": { "anyOf": [ { "$ref": "#/$defs/MemoryAmount" }, { "type": "null" } ], "description": "Log memory limit in bytes (max 2 MiB). Oldest logs are purged when usage exceeds this value.\nSupports suffixes in YAML: kb, kib, mb, mib (e.g. \"2mib\" or \"256kib\"). Canister default is 4096 bytes." }, "log_visibility": { "anyOf": [ { "$ref": "#/$defs/LogVisibility" }, { "type": "null" } ], "description": "Controls who can read canister logs." }, "memory_allocation": { "anyOf": [ { "$ref": "#/$defs/MemoryAmount" }, { "type": "null" } ], "description": "Memory allocation in bytes. If unset, memory is allocated dynamically.\nSupports suffixes in YAML: kb, kib, mb, mib, gb, gib (e.g. \"4gib\" or \"2.5kb\")." }, "reserved_cycles_limit": { "anyOf": [ { "$ref": "#/$defs/CyclesAmount" }, { "type": "null" } ], "description": "Upper limit on cycles reserved for future resource payments.\nMemory allocations that would push the reserved balance above this limit will fail.\nSupports suffixes in YAML: k, m, b, t (e.g. \"4t\" or \"4.3t\")." }, "wasm_memory_limit": { "anyOf": [ { "$ref": "#/$defs/MemoryAmount" }, { "type": "null" } ], "description": "Wasm memory limit in bytes. Sets an upper bound for Wasm heap growth.\nSupports suffixes in YAML: kb, kib, mb, mib, gb, gib (e.g. \"4gib\" or \"2.5kb\")." }, "wasm_memory_threshold": { "anyOf": [ { "$ref": "#/$defs/MemoryAmount" }, { "type": "null" } ], "description": "Wasm memory threshold in bytes. Triggers a callback when exceeded.\nSupports suffixes in YAML: kb, kib, mb, mib, gb, gib (e.g. \"4gib\" or \"2.5kb\")." } }, "type": "object" }, "SubnetKind": { "enum": [ "application", "system", "verified-application", "bitcoin", "fiduciary", "nns", "sns" ], "type": "string" }, "SyncStep": { "description": "Identifies the type of adapter used to sync the canister,\nalong with its configuration.\n\nThe adapter type is specified via the `type` field in the YAML file.\nFor example:\n\n```yaml\ntype: script\ncommand: echo \"synchronizing canister\"\n```", "oneOf": [ { "$ref": "#/$defs/Adapter", "description": "Represents a canister synced using a custom script or command.\nThis variant allows for flexible sync processes defined by the user.", "properties": { "type": { "const": "script", "type": "string" } }, "required": [ "type" ], "type": "object" }, { "$ref": "#/$defs/Adapter3", "description": "Represents a sync step executed by a WebAssembly plugin running inside\na wasmtime WASI sandbox. The plugin can call canister methods on exactly\nthe canister being synced and read files from the declared `dirs`.", "properties": { "type": { "const": "plugin", "type": "string" } }, "required": [ "type" ], "type": "object" } ] }, "SyncSteps": { "description": "Describes how to synchronize the canister state after deployment.", "properties": { "steps": { "items": { "$ref": "#/$defs/SyncStep" }, "type": "array" } }, "required": [ "steps" ], "type": "object" } }, "$id": "ProjectManifest", "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "description": "Schema for ProjectManifest", "properties": { "canisters": { "default": [], "items": { "$ref": "#/$defs/Item" }, "type": "array" }, "dependencies": { "default": [], "description": "Other `icp` projects this project depends on. Their canisters are\ndeployed into this project's environment and their IDs are injected into\nthis project's canisters as `PUBLIC_CANISTER_ID::`\nenvironment variables.", "items": { "$ref": "#/$defs/DependencyManifest" }, "type": "array" }, "environments": { "default": [], "items": { "$ref": "#/$defs/Item3" }, "type": "array" }, "networks": { "default": [], "items": { "$ref": "#/$defs/Item2" }, "type": "array" } }, "title": "ProjectManifest", "type": "object" }