> For the complete documentation index, see [llms.txt](https://docs.talus.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.talus.network/guides/getting-started/prepare-onchain-development.md).

# Prepare for On-Chain Development

{% hint style="info" %}
**Audience:** Developers preparing to build a Talus Agent Package (TAP) or an on-chain Tool.

**Goal:** Resolve the public Nexus Move dependencies for one selected network before writing, building, or publishing Move code.
{% endhint %}

Complete this preparation before following [Custom TAP Package Development](/guides/tap-development.md) or [Build an On-Chain Tool](/guides/tool-development/build-onchain-tool.md). Use the Move Registry records for consumer installation, then commit the resolved `Move.lock` and verify every resolved package ID against the network where the package will run.

### Package installation and source references

| Package reference                                         | Move Registry installation                                                                                                                          | Reference source code                                                                                       |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [`nexus_primitives`](/reference/move/nexus_primitives.md) | [@talus/nexus-primitives](https://www.moveregistry.com/package/@talus/nexus-primitives); `nexus_primitives = { r.mvr = "@talus/nexus-primitives" }` | [`packages/primitives`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/primitives) |
| [`nexus_interface`](/reference/move/nexus_interface.md)   | [@talus/nexus-interface](https://www.moveregistry.com/package/@talus/nexus-interface); `nexus_interface = { r.mvr = "@talus/nexus-interface" }`     | [`packages/interface`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/interface)   |
| [`nexus_tool`](/reference/move/nexus_tool.md)             | [@talus/nexus-tool](https://www.moveregistry.com/package/@talus/nexus-tool); `nexus_tool = { r.mvr = "@talus/nexus-tool" }`                         | [`packages/tool`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/tool)             |
| [`nexus_registry`](/reference/move/nexus_registry.md)     | [@talus/nexus-registry](https://www.moveregistry.com/package/@talus/nexus-registry); `nexus_registry = { r.mvr = "@talus/nexus-registry" }`         | [`packages/registry`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/registry)     |
| [`nexus_workflow`](/reference/move/nexus_workflow.md)     | [@talus/nexus-workflow](https://www.moveregistry.com/package/@talus/nexus-workflow); `nexus_workflow = { r.mvr = "@talus/nexus-workflow" }`         | [`packages/workflow`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/workflow)     |
| [`nexus_scheduler`](/reference/move/nexus_scheduler.md)   | [@talus/nexus-scheduler](https://www.moveregistry.com/package/@talus/nexus-scheduler); `nexus_scheduler = { r.mvr = "@talus/nexus-scheduler" }`     | [`packages/scheduler`](https://github.com/Talus-Network/nexus-move-packages/tree/main/packages/scheduler)   |

Use the Move Registry record as the installation authority. Use the public `main` source directories only for inspection and provenance. Do not create direct dependencies for `nexus-policy` or `nexus-kernel`: neither has a Move Registry record, and any required support package belongs to the resolved transitive closure.

### Local Move tests with module extensions

The Nexus Move dependencies are public interface stubs for compiling against packages published on Sui. Their types and public signatures match the supported consumer surface, but their local function bodies deliberately abort with `ELocalExecutionUnavailable`. A Testnet build environment selects Testnet dependencies; it does not make the local Move test VM call Testnet.

Use three layers of evidence:

| Check                                | What it proves                                                                                                                | What it does not prove                                                                                                 |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `sui move build --build-env testnet` | The application compiles against the Testnet interfaces and dependency graph.                                                 | That a transaction succeeds or that selected shared objects are valid.                                                 |
| `sui move test --build-env testnet`  | Application-owned logic works with Nexus value shapes supplied by test-only module extensions, and expected stub calls abort. | Published Nexus validation, authorization, events, payments, scheduling, shared-object behavior, or state transitions. |
| Testnet integration transaction      | The published Nexus packages accept the transaction and produce the expected effects, events, and object state.               | Mainnet configuration unless it is verified separately.                                                                |

#### Enable module extensions only when tests need them

A test-only module extension shares the private scope of the Nexus module it extends. It can add a minimal constructor or observation for a private Nexus value shape without adding a production helper or pretending to implement Nexus behavior. Module extensions require the alpha form of Move 2024, so use it only in a package whose tests contain extensions:

```toml
[package]
name = "my_nexus_app"
edition = "2024.alpha"

[dependencies]
nexus_primitives = { r.mvr = "@talus/nexus-primitives" }

[addresses]
my_nexus_app = "0x0"
```

Put each extension under the consumer package's `tests/` directory. For example, `tests/data_extension.move` can construct and inspect the private `NexusData` shape needed by an application test:

```move
#[test_only]
extend module nexus_primitives::data;

/// Creates one inline value for local application tests.
public fun inline_for_testing(bytes: vector<u8>): NexusData {
    NexusData::One {
        value: NexusValue::InlineData { bytes },
    }
}

/// Returns the inline byte length without calling a Nexus stub.
public fun inline_length_for_testing(self: &NexusData): u64 {
    match (self) {
        NexusData::One {
            value: NexusValue::InlineData { bytes },
        } => bytes.length(),
        _ => 0,
    }
}
```

Call each helper through the module it extends. Keep `_for_testing` in helper names and add only the constructors or observations required by the application test:

```move
#[test_only]
module my_nexus_app::application_tests;

use nexus_primitives::data;
use std::unit_test::assert_eq;

#[test]
fun reads_inline_value_shape() {
    let value = data::inline_for_testing(b"hello");
    assert_eq!(value.inline_length_for_testing(), 5);
}
```

Extensions are additive: they cannot replace an existing Nexus function and do not reproduce its validation, authorization, events, or state changes. A `#[test_only]` extension under `tests/` is excluded from production bytecode. Keep code that invokes Nexus behind a small application boundary, test decisions and transformations on your side of that boundary, and use an expected-failure test when you want to prove that a local test does not cross it:

```move
#[error]
const ELocalExecutionUnavailable: vector<u8> =
    b"Nexus functions require the published Testnet or Mainnet package";

#[test, expected_failure(
    abort_code = ELocalExecutionUnavailable,
    location = nexus_primitives::data,
)]
fun published_constructor_is_not_a_local_mock() {
    nexus_primitives::data::inline_data_value(b"hello");
}
```

Run the suite with the same build environment used for dependency resolution:

```bash
sui move test --build-env testnet
```

Use a real Testnet transaction for anything that calls a Nexus constructor, validator, adapter, or entry function; checks authorization or capability rules; emits or consumes Nexus events; uses shared protocol objects; or executes, schedules, charges, verifies, or settles work. Require successful transaction effects, assert the expected events, and read back affected objects.

#### Local published-bytecode TAP tests

The released 2.1.1 `nexus tap test` command can read published Nexus bytecode for Testnet or Mainnet and runs your local test extensions in a Sui VM; it does not use a wallet, signer, gas, publication, registration, binding, scheduling, settlement, or asset movement.

List available tests first when diagnosing a package, run one named case to isolate the earliest concrete failure, then rerun the complete package suite without a name filter:

```bash
nexus tap test --path <tap-package> --build-env testnet --list
nexus tap test --path <tap-package> <test-name> --threads 1 --build-env testnet
nexus tap test --path <tap-package> --build-env testnet
```

The released CLI/SDK references below remain authoritative for release installation and network operations. A local VM run proves only the exercised published calls and local test extensions; it does not prove package publication, Tool registration, skill binding, scheduling, live execution, payment, or settlement.

### Completion check

Before continuing, confirm that the manifest uses only the required `r.mvr` dependencies, `Move.lock` is committed, and the selected network resolves each direct package to the expected package ID. If local tests use module extensions, confirm that the package uses `edition = "2024.alpha"`, extensions are `#[test_only]` files under `tests/`, and assertions about published Nexus behavior are assigned to Testnet integration transactions. If any record or package ID is unavailable or mismatched, stop before building or signing.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.talus.network/guides/getting-started/prepare-onchain-development.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
