> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerzero.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Build User Steps

> Generate fresh transaction data for Solana transfers with up-to-date blockhash.

Generates fresh transaction data for a quote. Required for **Solana transfers** due to short blockhash validity.

***

## Reference

### When to use

| Chain type | When to call                                                                                                                            |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| **EVM**    | Not required. Use `userSteps` directly from quote response.                                                                             |
| **Solana** | **Always required**. Solana transactions have short blockhash validity (\~60 seconds). Call this endpoint immediately before execution. |

### Request body

| Parameter | Type   | Required | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| `quoteId` | string | Yes      | Quote ID from the `/quotes` response |

### Response

Returns a `userSteps` array with fresh transaction data.

#### User step attributes

User steps can be `TRANSACTION` or `SIGNATURE` (same structure as quote response):

**TRANSACTION step:**

| Attribute             | Type   | Description                       |
| --------------------- | ------ | --------------------------------- |
| `type`                | string | `TRANSACTION`                     |
| `description`         | string | Human-readable action description |
| `chainKey`            | string | Chain to execute on               |
| `chainType`           | enum   | `EVM`, `SOLANA`, `STARKNET`       |
| `signerAddress`       | string | Wallet that must sign             |
| `transaction`         | object | Transaction details               |
| `transaction.encoded` | object | Encoded transaction data          |

For Solana, the transaction data is base64-encoded:

```typescript wrap theme={null}
{
  type: "TRANSACTION",
  chainType: "SOLANA",
  transaction: {
    encoded: {
      encoding: "base64",
      data: "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
    }
  }
}
```

## Code examples

<Tabs>
  <Tab title="cURL">
    ```bash wrap theme={null}
    curl -X POST "https://transfer.layerzero-api.com/v1/build-user-steps" \
      -H "Content-Type: application/json" \
      -H "x-api-key: YOUR_API_KEY" \
      -d '{"quoteId": "QUOTE_ID_FROM_SOLANA_QUOTE"}'
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript wrap theme={null}
    const response = await fetch('https://transfer.layerzero-api.com/v1/build-user-steps', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'YOUR_API_KEY',
      },
      body: JSON.stringify({quoteId: quote.id}),
    });

    const {userSteps} = await response.json();
    console.log('User steps:', userSteps);
    ```
  </Tab>

  <Tab title="Python">
    ```python wrap theme={null}
    import requests

    response = requests.post(
      "https://transfer.layerzero-api.com/v1/build-user-steps",
      headers={"x-api-key": "YOUR_API_KEY"},
      json={"quoteId": quote["id"]},
    )

    user_steps = response.json()["userSteps"]
    print("User steps:", user_steps)
    ```
  </Tab>
</Tabs>

### Response

```json wrap theme={null}
{
  "userSteps": [
    {
      "type": "TRANSACTION",
      "description": "bridge",
      "chainKey": "solana",
      "chainType": "SOLANA",
      "signerAddress": "Dz93pUVjXuaMnSsPSn7V99V4cUzhKoQdx9ECwZJZiafG",
      "transaction": {
        "encoded": {
          "encoding": "base64",
          "data": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkT..."
        }
      }
    }
  ]
}
```

## Solana execution

After building user steps, deserialize and sign the transaction:

```typescript wrap theme={null}
import {VersionedTransaction, Connection} from '@solana/web3.js';

// Get fresh user steps
const {userSteps} = await buildUserSteps(quoteId);
const step = userSteps[0];

// Decode base64 transaction
const txBuffer = Buffer.from(step.transaction.encoded.data, 'base64');
const tx = VersionedTransaction.deserialize(txBuffer);

// Sign and send
const signedTx = await wallet.signTransaction(tx);
const signature = await connection.sendRawTransaction(signedTx.serialize());

await connection.confirmTransaction(signature, 'confirmed');
```

## Why Solana needs fresh transactions

Solana transactions include a recent blockhash that expires after \~60 seconds. The `/build-user-steps` endpoint generates transactions with the latest blockhash, ensuring they remain valid during execution.

**Workflow:**

1. Request quote → Receive quote with `quoteId`
2. Call `/build-user-steps` with `quoteId` → Get fresh transaction
3. Sign and submit immediately (within 60 seconds)

## Related endpoints

* [Quotes](./quotes) — Request transfer quotes (includes `userSteps` for EVM)
* [Status](./status) — Track transfer progress after execution

## Examples

* [Solana Example](../examples/solana) — Complete Solana transfer with transaction building


## OpenAPI

````yaml POST /build-user-steps
openapi: 3.0.3
info:
  title: Value Transfer API
  version: 1.0.0
  description: Unified API for cross-chain value transfers across 150+ blockchains
servers:
  - url: https://transfer.layerzero-api.com/v1
security: []
paths:
  /build-user-steps:
    post:
      tags:
        - Transfer
      summary: Build transaction steps
      description: >-
        Rebuild or refresh the user steps for a quote. Use this if the original
        quote's user steps have expired or if you need fresh transaction data
        (required for Solana).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - quoteId
              properties:
                quoteId:
                  type: string
                  description: The quote ID to build steps for
                  example: quote_abc123
      responses:
        '200':
          description: Successfully built user steps
          content:
            application/json:
              schema:
                type: object
                properties:
                  userSteps:
                    type: array
                    items:
                      type: object
                      properties:
                        type:
                          type: string
                        description:
                          type: string
                        chainKey:
                          type: string
                        chainType:
                          type: string
                        signerAddress:
                          type: string
                example:
                  userSteps:
                    - type: TRANSACTION
                      description: bridge
                      chainKey: solana
                      chainType: SOLANA
                      signerAddress: Dz93pUVjXuaMnSsPSn7V99V4cUzhKoQdx9ECwZJZiafG
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      name: x-api-key
      in: header
      description: >-
        API key for authenticating requests. Required for /quotes,
        /build-user-steps, /submit-signature, and /status endpoints.

````