# Transaction Lifecycle

Every action that modifies the state of the blockchain, such as transferring tokens or creating an asset, is executed through a transaction. Understanding the lifecycle of a transaction is fundamental to building applications with the OCAP Client. This process involves four main stages: Preparation, Encoding, Signing, and Sending.

The OCAP Client provides a flexible set of methods that allow you to either perform these steps individually for maximum control or use high-level helpers that combine them for convenience.

This guide breaks down each stage and illustrates both single-signature and multi-signature workflows.


## Lifecycle Overview

The following diagram illustrates the complete journey of a transaction from preparation to its final submission to the blockchain.

<!-- DIAGRAM_IMAGE_START:flowchart:4:3 -->

![Transaction Lifecycle](assets/diagram/core-concepts-transaction-lifecycle-01.jpg)

<!-- DIAGRAM_IMAGE_END -->


## Stage 1: Preparation (Creating the `itx`)

Every transaction begins with an `itx` (inner transaction). This is a plain JavaScript object that contains the specific data for the action you want to perform. For example, a transfer `itx` would include the recipient's address and the amount.

```javascript Preparing the itx icon=logos:javascript
// The core data for our transfer transaction
const itx = {
  to: 'z2C8j81aL2oXpA5t42s2h4g9o8p1k6m3n7b', // Recipient's address
  value: await client.fromTokenToUnit(10),   // Amount to send, converted to the chain's base unit
};
```


## Stage 2: Encoding

Encoding transforms the `itx` and other metadata into a standardized, binary format that can be cryptographically signed. The client provides an `encode{TxType}Tx` method for each transaction type (e.g., `encodeTransferV2Tx`).

During this stage, the client automatically adds essential metadata:

* **`from`**: The sender's address, derived from the provided wallet.
* **`chainId`**: The identifier of the target blockchain, fetched automatically.
* **`nonce`**: A unique number to prevent replay attacks, which defaults to the current timestamp (`Date.now()`).
* **`pk`**: The public key of the sender's wallet.

The encoding function returns both the full transaction object and a `Buffer` of the serialized data, which is used for signing.

```javascript Encoding the Transaction icon=logos:javascript
const { object: encodedTx, buffer: txBuffer } = await client.encodeTransferV2Tx({
  tx: { itx },
  wallet: senderWallet,
});

console.log('Encoded TX Object:', encodedTx);
console.log('Buffer to be signed:', txBuffer);
```


## Stage 3: Signing

Signing proves ownership of the account and authorizes the transaction. The process differs for single-signature and multi-signature workflows.

### Single-Signature Workflow

This is the most common scenario, where a single user signs a transaction. The `sign{TxType}Tx` methods take the encoded transaction, sign the binary buffer with the user's private key, and populate the `signature` field.

```javascript Signing with a Single Signature icon=logos:javascript
const signedTx = await client.signTransferV2Tx({
  tx: encodedTx, // The object from the encoding step
  wallet: senderWallet,
});

console.log('Signature:', signedTx.signature);
```

### Multi-Signature Workflow

Multi-signature (multisig) transactions require approval from multiple parties. This is commonly used for atomic swaps or shared accounts. The process is sequential:

1. **Preparation**: The initial transaction is created with a `signaturesList` that defines all required signers.
2. **Sequential Signing**: The transaction is passed from one signer to the next. Each signer uses the corresponding `multiSign{TxType}Tx` method to add their signature.

Internally, the `multiSign` method ensures that each party signs the exact same transaction digest by temporarily stripping all existing signatures before encoding the transaction for signing.

Here’s an example for an `ExchangeTx`, where two parties swap assets.

```javascript Multi-Signature Signing Example icon=logos:javascript
// Step 1: Alice (the offerer) prepares and signs the exchange transaction.
const txFromAlice = await client.prepareExchange({
  offerToken: 10,
  demandToken: 20,
  receiver: bobWallet.address,
  wallet: aliceWallet,
});

// Step 2: The transaction is sent to Bob.
// Bob (the demander) adds his signature to finalize it.
const txFromBob = await client.finalizeExchange({
  tx: txFromAlice, // Transaction signed by Alice
  wallet: bobWallet,
});

console.log('Alice\'s Signature:', txFromBob.signaturesList[0].signature);
console.log('Bob\'s Signature:', txFromBob.signaturesList[1].signature);
```


## Stage 4: Sending

Once a transaction is fully signed, it can be sent to the blockchain node for processing. The `send{TxType}Tx` methods handle this final step.

For convenience, these methods can also perform the signing step implicitly if you provide a wallet and an unsigned transaction. The method returns a promise that resolves with the transaction hash upon successful submission.

```javascript Sending the Signed Transaction icon=logos:javascript
// Using a pre-signed transaction
const hash = await client.sendTransferV2Tx({ tx: signedTx, wallet: senderWallet });

// Or, letting the send method handle the signing automatically
const hash2 = await client.sendTransferV2Tx({
  tx: { itx }, // Just the inner transaction
  wallet: senderWallet,
});

console.log('Transaction sent! Hash:', hash);
```

You can also include a `commit: true` option to make the client wait until the transaction is fully confirmed and included in a block before resolving the promise.


## Summary

The transaction lifecycle provides a robust and flexible framework for interacting with the blockchain. By breaking the process into distinct stages—Preparation, Encoding, Signing, and Sending—the OCAP Client offers developers granular control over transaction creation while also providing simple, high-level helpers for common use cases.

For more details on how transaction fees are handled, see the [Gas Payment](./core-concepts-gas-payment.md) guide. To understand the different client types available, refer to the [Client Architecture](./core-concepts-client-architecture.md) documentation.
