> For the complete documentation index, see [llms.txt](https://docs.trilobyte.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.trilobyte.finance/technical-documentation/deployment.md).

# Deployment

Trilobyte contracts are deployed to Stellar with a TypeScript script that drives the `stellar` CLI (`@stellar/stellar-sdk` is used for keypair/address handling).

## Full Protocol Deployment

The main deployment script is `scripts/deploy-protocol.ts`. It deploys the four governance/registry contracts and runs post-deploy initialisation. (The **CollateralEscrow** is deployed separately, per RWA-collateral lender — it is not part of the core protocol deploy.)

### Step 1 — Deploy Globals

```
Globals(governor, treasury, security_admin, operations_admin)
```

Globals is deployed first. `governor` becomes the OZ admin; `security_admin` and `operations_admin` are granted their roles in the constructor.

### Step 2 — Deploy Timelock

```
Timelock(min_delay, proposers, executors, admin: None)
```

Self-administered. `min_delay` is in **ledgers**. Proposers are also granted the canceller role; an empty executor list means anyone can execute.

### Step 3 — Upload Vault WASM

The compiled vault WASM is uploaded (`stellar contract upload`), returning a WASM hash used by the Factory to deploy vault instances.

### Step 4 — Deploy Factory

```
Factory(governor, globals_address, vault_wasm_hash)
```

### Step 5 — Register the Factory in Globals (MANDATORY)

```
globals.set_factory(factory_address)
```

{% hint style="danger" %}
**This step is required.** Globals gates `lock_collateral`, `increment_outstanding`, and `register_vault` on the call coming from the registered Factory. Until `set_factory` has been called, `create_vault` fails when it tries those cross-contract calls — no vault can be created. `set_factory` is `#[only_admin]`, so it must run **before** admin is transferred to the Timelock.
{% endhint %}

### Step 6 — Whitelist Assets

```
globals.whitelist_asset(asset)
```

{% hint style="info" %}
Must be done **before** transferring Globals admin to the Timelock, since it requires direct admin access.
{% endhint %}

### Step 7 — Approve Initial Managers

```
globals.approve_pool_manager(manager_address, caller, max_credit)
```

A single call both registers and approves a manager (there is no separate `add_pool_manager`). `caller` must hold the `ops_adm` role.

### Step 8 — Transfer Globals Admin to the Timelock

Globals uses the OZ **two-step** admin transfer:

```
globals.transfer_admin_role(timelock_address, live_until_ledger)   // current admin initiates
globals.accept_admin_transfer()                                     // the Timelock accepts
```

`live_until_ledger` bounds when the pending transfer expires (`0` cancels it). After acceptance, all admin-gated operations on Globals must go through the Timelock's governance process.

{% hint style="warning" %}
**This step is effectively irreversible.** Once admin is the Timelock, direct admin access is gone. Ensure `set_factory`, asset whitelisting, and manager approval are all complete first.
{% endhint %}

{% hint style="danger" %}
**Deploy-script discrepancy (verify before running).** As of this writing `scripts/deploy-protocol.ts` calls a single `transfer_admin` (one-step) for step 8. The deployed Globals contract exposes only the OZ two-step `transfer_admin_role` / `accept_admin_transfer` — there is no `transfer_admin` function. The single call will fail. Use `transfer_admin_role(new_admin, live_until_ledger)` followed by `accept_admin_transfer()`.
{% endhint %}

## Running the Deployment

```bash
# Build all contracts (WASM target wasm32v1-none)
stellar contract build

# Deploy the full protocol
npx ts-node scripts/deploy-protocol.ts
```

## Configuration

All deployment parameters are configured via environment variables. See `.env.example`:

| Variable                   | Description                                               |
| -------------------------- | --------------------------------------------------------- |
| `SOROBAN_NETWORK`          | Network to deploy to (`testnet` / `mainnet`)              |
| `NETWORK_RPC_URL`          | Soroban RPC endpoint                                      |
| `NETWORK_PASSPHRASE`       | Network passphrase                                        |
| `NETWORK_HORIZON_URL`      | Horizon endpoint                                          |
| `WASM_TARGET_DIR`          | Build output dir (default `target/wasm32v1-none/release`) |
| `SOURCE_SECRET_KEY`        | Secret key for the deploying account                      |
| `GOVERNOR_ADDRESS`         | Initial governor (root admin of Globals)                  |
| `TREASURY_ADDRESS`         | Protocol treasury address                                 |
| `SECURITY_ADMIN_ADDRESS`   | Security admin address                                    |
| `OPERATIONS_ADMIN_ADDRESS` | Operations admin address                                  |
| `TIMELOCK_MIN_DELAY`       | Minimum delay for timelocked operations (ledgers)         |
| `TIMELOCK_PROPOSERS`       | Comma-separated proposer addresses (≥ 1 required)         |
| `TIMELOCK_EXECUTORS`       | Comma-separated executor addresses (empty ⇒ anyone)       |
| `WHITELIST_ASSETS`         | Comma-separated asset addresses to whitelist              |
| `INITIAL_MANAGERS`         | Comma-separated manager addresses to approve              |
| `MANAGER_CREDIT_LIMIT`     | Credit limit applied to initial managers (7-decimal)      |
| `STELLAR_CLI_PATH`         | (optional) Absolute path override for the `stellar` CLI   |

{% hint style="info" %}
The deployer secret is passed to the CLI via the `STELLAR_ACCOUNT` / `STELLAR_SIGN_WITH_KEY` environment variables (never on argv), and the `stellar` CLI path is resolved on a sanitised PATH to prevent PATH-hijack.
{% endhint %}

## Output

Deployment results are saved to `.soroban/contract-ids.json`:

```json
{
  "network": "testnet",
  "deployedAt": "2026-02-27T12:00:00Z",
  "contracts": {
    "globals": "CABC...",
    "timelock": "CDEF...",
    "factory": "CGHI..."
  },
  "vaultWasmHash": "abc123..."
}
```


---

# 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 current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.trilobyte.finance/technical-documentation/deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
