This repo uses nx for monorepo management and change-detection.
- With the exception of
libs, each package in the root folder creates a binary that instantiates a capability set when added to the node through atype="standardcapabilities"job spec (capability spec). A capability set contains one or more capabilities that are centered around some functionality or shared resource, e.g., EVM chain, CRON, etc. libsfolder contains packages that are shared across capabilities. You should only create a package there if two or more capability sets need to share a dependency.
Each new capability must have a proto in chainlink-protos/cre annotated with cre metadata
See Cron as the simplest example of how to generate a capability from the code generator.
Each new capability requires a corresponding SDK to be generated for it. This SDK can be used by workflow authors to write workflows using that capability in Go.
The process for generating the SDK is:
- Define the inputs and outputs of the calls that can be made to the capability set in JSON schema. This JSON schema should be located in the same directory as the relevant capability set. To ensure that any WASM binaries that depend on these SDKs remain small, we recommend placing this in a subdirectory which just contains the generated types. So, assuming a capability set in the
crondirectory, we recommend putting the JSON schema incron/croncapfor example. - Using the JSON schema, generate some native Go types. This is automated by means of a "gen file", and is described more below.
The files must follow the regex CapabilitySchemaFilePattern.
If you expose one function to users, your schema should follow:
<capability name>_type-schema.json, like cron_trigger-schema.json.
The method on the config file will then be named Config that users interact with.
If you have multiple capabilities in a capability set, you can use the following naming schema:
<capability set prefix>_<capability>_<type>-schema.json
For example:
kv_write_target-schema.json
would define the JSON schema for the KV Write Target that is part of the KV capability set.
This JSON schema file would generate a WriteTargetConfig inside a kv package.
Additional files like kv_read_action-schema.json, kv_batch_read_action-schema.json, etc., could be used to
generate more types in the same namespace.
Common methods may live in:
<capability set>_common-schema.json, eg. kv_common-schema.json using the previous example.
All schemas must have a $id, the id must match the package that the folder it is in will resolve to, followed by either the capability's name and version or an interface name.
For example, the cron trigger is
"$id": "https://github.com/smartcontractkit/capabilities/cron/croncap/cron-trigger@1.0.0",
whereas the common type for a chain reader would be similar to
"$id": "https://github.com/smartcontractkit/capabilities/chain/chaincap/reader",
The former will not require a user to specify which capability to bind to at runtime, whereas the latter will.
Triggers must contain an output and config types.
If you wish for the output to have a better name than the default, create it in $defs and refer to that.
Actions must contain input, output, and config types.
If you wish for the input and output to have a better name than the default, create them in $defs and refer to those.
Note: At the time of writing this, it has been decided that targets will likely go away in favour of becoming actions.
Until that happens, targets must contain input and config types.
Common schemas only generate helper types for capabilities and should only be used for their $defs section.
Each binary can pull the dependencies it needs without adding them to all the other binaries. If some shared dependencies emerge, e.g., input and output types, then those should be extracted to a separate lib in the libs folder and referenced from there (project.json files should be updated accordingly).
This allows capabilities to evolve independently of each other. It is encouraged to have a separate README.md file for each capability.
There should be no imports from the chainlink repository which hosts the node, because this creates a risk for circular dependencies.
For dependency graph run:
./nx dep-graphcapabilities repo also depends on the platform (chainlink) repo. The
platform defines and operates on the interfaces.
Run a task for all projects:
./nx run-many -t testRun a task for the affected projects only:
./nx affected -t testUpdate libs for chain capabilities:
nx run-many -t update-libs -p aptos,solana,evm,stellar --args='--version=v1.2.3' && nx run integration_tests:tidy