> 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/transaction-config.md).

# Transaction Config

`TransactionConfig` is the standard write-transaction configuration used across Colibri pipelines and high-level clients. The same shape supports classic transactions, Soroban invocations, and [delegated authorization](/colibri/colibri-core/signer/delegated-signer.md).

Choose [fee strategies](#fee-strategies) for the envelope bid and [resource overrides or padding](/colibri/colibri-core/transaction-config/resources.md) for Soroban resource declarations. The [external resource calculator](/colibri/colibri-core/transaction-config/resources.md#read-settings-and-calculate-padding-explicitly) can produce padding from explicitly supplied simulation data and network settings.

```ts
type TransactionConfig = {
  fee: BaseFee | TransactionFee;
  source: TransactionSource;
  timeout: number;
  memo?: Memo;
  signers: Signer[];
  extraSigners?: ExtraSignerKey[];
  resources?: TransactionResources;
};

type TransactionSource = Ed25519PublicKey | MuxedAddress;

type TransactionFee =
  | { base: BaseFee }
  | { inclusion: InclusionFee }
  | { max: MaxFee };

type BaseFee = `${number}`;
type InclusionFee = `${number}`;
type MaxFee = `${number}`;
```

## Properties

| Property                                                                                         | Type                                                                                                        | Description                                                            |
| ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| [`fee`](#fee-strategies)                                                                         | `BaseFee \| TransactionFee`                                                                                 | String base fee or one explicit fee strategy                           |
| [`source`](#muxed-sources)                                                                       | `TransactionSource`                                                                                         | Transaction source as a G-address or M-address                         |
| [`timeout`](#timeout)                                                                            | `number`                                                                                                    | Transaction timeout in seconds                                         |
| [`memo`](#memos)                                                                                 | Native SDK `Memo`                                                                                           | Optional transaction memo, forwarded unchanged                         |
| [`signers`](#signers)                                                                            | [`Signer[]`](/colibri/colibri-core/signer.md#signer-capabilities)                                           | Signers used by the selected transaction flow                          |
| [`extraSigners`](#signers)                                                                       | [`ExtraSignerKey[]`](/colibri/colibri-core/strkeys.md)                                                      | Exact `G...`, `X...`, or `P...` signer-key preconditions               |
| [`resources`](/colibri/colibri-core/transaction-config/resources.md#choose-overrides-or-padding) | [`TransactionResources`](/colibri/colibri-core/transaction-config/resources.md#choose-overrides-or-padding) | Optional Soroban resource overrides and padding after final simulation |

### Timeout

`timeout` is forwarded to the builder and preserved through Soroban assembly. Set it to `0` only when you intentionally want no upper time bound.

### Memos

Use the Stellar SDK's `Memo.text(...)`, `Memo.id(...)`, `Memo.hash(...)`, or `Memo.return(...)` directly in `config.memo`. Omission keeps the existing no-memo behavior; `Memo.none()` explicitly selects it. Colibri preserves the native memo through building and assembly, subject to the network's transaction rules. No recipient-specific policy is enabled automatically. Install the opt-in [SEP-29 plugin](/colibri/plugins/sep29.md) to check memo presence for receiving accounts that advertise the requirement.

### Fee Strategies

`fee` accepts the existing string form or an object that selects exactly one strategy:

| Configuration          | Classic transaction                                                                                                                | Soroban transaction                                                   |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `"100"`                | Uses `100` as the per-operation base-fee bid                                                                                       | Uses `100` as the inclusion-fee bid because Soroban has one operation |
| `{ base: "100" }`      | Uses `100` per operation                                                                                                           | Uses `100` as the inclusion-fee bid                                   |
| `{ inclusion: "205" }` | Sets the transaction's total inclusion-fee bid to exactly `205`, including when it cannot be divided evenly by the operation count | Adds exactly `205` of inclusion fee to the simulated resource fee     |
| `{ max: "1000000" }`   | Caps and sets the complete classic transaction fee to `1000000`                                                                    | Caps the complete fee, including simulated resources, at `1000000`    |

Only one of `base`, `inclusion`, or `max` may be present. Colibri enforces the same rule at runtime even when input enters through untyped JavaScript or deserialized data.

For a Soroban `max` strategy, final assembly reads the resource fee from the latest simulation result and uses the remaining capacity as the inclusion fee. The maximum must cover the adjusted resource fee plus at least 100 stroops. Use [`resources.override`](/colibri/colibri-core/transaction-config/resources.md#choose-overrides-or-padding) for absolute declarations or [`resources.padding`](/colibri/colibri-core/transaction-config/resources.md#choose-overrides-or-padding) for fixed/percentage additions. The [external calculator](/colibri/colibri-core/transaction-config/resources.md#read-settings-and-calculate-padding-explicitly) can explicitly price the resource growth. See [transaction resources](/colibri/colibri-core/transaction-config/resources.md) for units, validation, fee semantics and complete examples. The lower-level `resourceFee` assembly argument remains supported, but cannot accompany the new `resources` argument.

String/base and exact-inclusion strategies preserve their inclusion bid when resources change, so the envelope total grows with the resource fee. With `max`, resource growth instead reduces the remaining inclusion bid and fails with [`ASM_013`](/colibri/reference/errors/core-processes-assemble-transaction.md) if fewer than 100 stroops remain. Manual CPU/byte adjustments leave the resource fee unchanged unless the caller also adjusts it. This is intentional direct control; use the [calculator](/colibri/colibri-core/transaction-config/resources.md#read-settings-and-calculate-padding-explicitly) when you want resource growth priced. See the [combined examples](/colibri/colibri-core/transaction-config/resources.md#combining-resources-with-the-transaction-fee).

The fee encoded in the submitted envelope is a bid. Stellar can charge less than that bid when surge pricing does not require the entire amount. A maximum therefore guarantees an upper bound, not the exact amount ultimately charged. This bound applies to the transaction being built. Choosing a [fee-bump wrapper](/colibri/plugins/fee-bump.md) supplies a separate outer inclusion bid, which can intentionally exceed the inner transaction's `max`.

### Muxed Sources

Classic transactions support [G-address and M-address sources](/colibri/colibri-core/address.md). Stellar Core prohibits muxed transaction and operation sources for Soroban `invokeHostFunction` transactions; use a G-address source there. A [fee bump](/colibri/plugins/fee-bump.md#configuration) can still use an M-address outer fee source.

Both `TransactionConfig.source` and [`FeeBumpConfig.source`](/colibri/plugins/fee-bump.md#configuration) accept muxed addresses. Colibri loads sequence state from the M-address's underlying G-account, keeps the M-address in the transaction or fee-bump envelope, and resolves signing requirements against the underlying G-account. The muxed ID is routing information; it is not an independent on-chain signer.

```ts
const classicConfig: TransactionConfig = {
  source: signer.publicKey(),
  fee: { inclusion: "205" },
  timeout: 30,
  signers: [signer],
};

const sorobanConfig: TransactionConfig = {
  source: signer.publicKey(),
  fee: { max: "1000000" },
  timeout: 30,
  signers: [signer],
};
```

## Signers

One list can contain envelope signers, authorization-entry signers such as [`DelegatedSigner`](/colibri/colibri-core/signer/delegated-signer.md), or signers that support both capabilities. The relevant signing process narrows each value with [`isEnvelopeSigner(...)`](/colibri/colibri-core/signer.md#signer-capabilities), [`isPreAuthTransactionSigner(...)`](/colibri/colibri-core/signer.md#signer-capabilities), or [`isAuthEntrySigner(...)`](/colibri/colibri-core/signer.md#signer-capabilities) before invoking the capability.

Native Stellar SDK keypairs can be adapted with [`LocalSigner.fromKeypair()`](/colibri/colibri-core/signer/local-signer.md#from-a-stellar-sdk-keypair). The configuration still contains [`Signer[]`](/colibri/colibri-core/signer.md#signer-capabilities); raw Keypair objects are not accepted. This complete, offline example constructs a configuration using the convenience:

```ts
import { LocalSigner, type TransactionConfig } from "@colibri/core";
import { Keypair } from "npm:@stellar/stellar-sdk@^17.2.1";

const keypair = Keypair.random();
const signer = LocalSigner.fromKeypair(keypair, true);
const config: TransactionConfig = {
  source: signer.publicKey(),
  fee: "100",
  timeout: 30,
  signers: [signer],
};
console.log(config.source);
signer.destroy();
```

The signer targets only its own G-address by default. Configure other targets explicitly, with the required on-chain authority and contract authorization encoding. The adapter borrows the keypair without extracting its secret; `destroy()` invalidates the signer but leaves the original Keypair usable. See [LocalSigner](/colibri/colibri-core/signer/local-signer.md#from-a-stellar-sdk-keypair) for ownership, secret visibility and failure behavior.

`extraSigners` writes Stellar's exact signer-key precondition into the transaction. Colibri later matches each key through `signer.signerKey()`. `T...` pre-authorized transaction keys are excluded because they cannot contain their own transaction hash recursively.

## Usage

```ts
import {
  createInvokeContractPipeline,
  HashXSigner,
  LocalSigner,
  NetworkConfig,
} from "@colibri/core";
import { Operation } from "npm:@stellar/stellar-sdk";

const network = NetworkConfig.TestNet();
const signer = LocalSigner.fromSecret("S...");
const hashXSigner = HashXSigner.generateRandom(true);

const invokeContract = createInvokeContractPipeline({ networkConfig: network });

const result = await invokeContract({
  operations: [
    Operation.invokeContractFunction({
      contract: "CABC...",
      function: "hello",
      args: [],
    }),
  ],
  config: {
    source: signer.publicKey(),
    fee: { max: "1000000" },
    timeout: 30,
    signers: [signer, hashXSigner],
    extraSigners: [hashXSigner.signerKey()],
  },
});
```

High-level clients use the same shape:

```ts
await contract.invoke({
  method: "transfer",
  methodArgs,
  config,
});
```

## Next Steps

* [Signer](/colibri/colibri-core/signer.md) — Signer interface and implementations
* [DelegatedSigner](/colibri/colibri-core/signer/delegated-signer.md) — CAP-71 signer topology
* [Pipelines](/colibri/colibri-core/pipelines.md) — Write flows that accept `TransactionConfig`
