> For the complete documentation index, see [llms.txt](https://fifo-docs.gitbook.io/colibri/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://fifo-docs.gitbook.io/colibri/colibri-core/pipelines.md).

# Pipelines

Pipelines combine [processes](/colibri/colibri-core/processes.md), step wrappers, and connectors into reusable transaction workflows. They are built on [`convee` 2.4.1](https://jsr.io/@fifo/convee/2.4.1).

Colibri exposes factory functions instead of wrapper objects:

* [`createInvokeContractPipeline(...)`](/colibri/colibri-core/pipelines/invoke-contract.md)
* [`createReadFromContractPipeline(...)`](/colibri/colibri-core/pipelines/read-from-contract.md)
* [`createClassicTransactionPipeline(...)`](/colibri/colibri-core/pipelines/classic-transaction.md)

Each pipeline also exports a stable `*_PIPELINE_ID` constant.

The returned pipeline is callable. Name it after the action and invoke it directly:

```ts
const invokeContract = createInvokeContractPipeline({ networkConfig });
const result = await invokeContract({ operations, config });
```

The callable also exposes methods such as `use(...)` for composition. Calling `.run(...)` is unnecessary in application code.

Write pipelines share [TransactionConfig](/colibri/colibri-core/transaction-config.md). The [read pipeline](/colibri/colibri-core/pipelines/read-from-contract.md) has its own simulation-only input and does not submit a transaction.

## Common Structure

Each built-in pipeline typically includes:

* input connectors that normalize the public input shape
* step wrappers around raw processes such as [`buildTransaction`](/colibri/colibri-core/processes/build-transaction.md) and [`sendTransaction`](/colibri/colibri-core/processes/send-transaction.md)
* shared connectors from `core/pipelines/shared/connectors`
* pipeline-specific connectors beside the owning pipeline

## Plugins

Plugins target a specific step or pipeline ID and are attached with the callable pipeline's `use(...)` method. This fragment uses an application-provided sponsor:

```ts
import { createInvokeContractPipeline, NetworkConfig } from "@colibri/core";
import { createFeeBumpPlugin } from "@colibri/plugin-fee-bump";

const networkConfig = NetworkConfig.TestNet();
const invokeWithSponsor = createInvokeContractPipeline({ networkConfig });

invokeWithSponsor.use(
  createFeeBumpPlugin({
    networkConfig,
    feeBumpConfig: {
      source: sponsorAddress,
      fee: "10000000",
      signers: [sponsorSigner],
    },
  }),
);
```

For available plugins, see [Plugins](/colibri/plugins/plugins.md).

## Convee compatibility

Use [Convee 2.4.1](https://jsr.io/@fifo/convee/2.4.1) when composing custom pipes or plugins with this release, matching Colibri's exact dependency version. Colibri's factory names, callable inputs, step IDs, transaction fees, and signing order remain unchanged. `use(...)` and `remove(...)` return the same callable instance.

Custom integrations should review the [Convee 1.x migration guide](https://github.com/fazzatti/convee/tree/v2.4.1#migrating-from-1x), particularly these upstream rules:

* An array returned by a child is spread into the next child's arguments. To pass one array argument, return an outer one-element tuple, `[array]`.
* Error hooks handle failures from the step or pipeline body. Failures in that unit's input/output hooks propagate; they do not enter its own error hooks. Do not rely on an error hook as an unconditional cleanup/finally handler.
* Use `onFinally` for resource cleanup after execution settles. Finalizers run even when input, output, or error hooks fail, and async cleanup is awaited. A finalizer must tolerate an input hook that never acquired its resource. The [channel-accounts plugin](/colibri/plugins/channel-accounts.md) uses this lifecycle to return pooled channels.
* Context views belong to individual invocations. Share state through a parent run context, and keep output capture enabled when using Colibri connectors that read preceding step outputs.
* Distinct children must not reuse a step ID within a pipe. Update plugins through `use`/`remove`, not by mutating the returned plugin or child lists.

Colibri keeps the original callable binding in its built-in clients; custom consumers may also use Convee 2's callable chaining.
