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

# Trace

> Fluent builder for constructing traces

**Web Client SDK:**

```typescript theme={null}
import { Trace } from '@miradorlabs/web-sdk';
```

**Node.js SDK:**

```typescript theme={null}
import { Trace } from '@miradorlabs/nodejs-sdk';
```

<Note>
  You typically don't instantiate `Trace` directly. Use `client.trace()` instead.
</Note>

## Methods

### addAttribute()

Add a single attribute to the trace.

```typescript theme={null}
addAttribute(key: string, value: string | number | boolean | object): Trace
```

#### Parameters

| Parameter | Type                                    | Description                                    |
| --------- | --------------------------------------- | ---------------------------------------------- |
| `key`     | `string`                                | Attribute key                                  |
| `value`   | `string \| number \| boolean \| object` | Attribute value (objects are JSON stringified) |

#### Examples

```typescript theme={null}
trace.addAttribute('userId', 'user-123')
     .addAttribute('amount', 1.5)
     .addAttribute('config', { slippage: 0.5 });  // Stringified
```

***

### addAttributes()

Add multiple attributes at once.

```typescript theme={null}
addAttributes(attrs: Record<string, string | number | boolean | object>): Trace
```

#### Parameters

| Parameter | Type                  | Description               |
| --------- | --------------------- | ------------------------- |
| `attrs`   | `Record<string, any>` | Object of key-value pairs |

#### Examples

```typescript theme={null}
trace.addAttributes({
  from: '0xabc...',
  to: '0xdef...',
  value: 1.0,
  metadata: { source: 'web' }
});
```

***

### addTag()

Add a single tag to the trace.

```typescript theme={null}
addTag(tag: string): Trace
```

#### Parameters

| Parameter | Type     | Description |
| --------- | -------- | ----------- |
| `tag`     | `string` | Tag to add  |

#### Examples

```typescript theme={null}
trace.addTag('ethereum')
     .addTag('swap');
```

***

### addTags()

Add multiple tags at once.

```typescript theme={null}
addTags(tags: string[]): Trace
```

#### Parameters

| Parameter | Type       | Description   |
| --------- | ---------- | ------------- |
| `tags`    | `string[]` | Array of tags |

#### Examples

```typescript theme={null}
trace.addTags(['dex', 'uniswap', 'v3']);
```

***

### addEvent()

Add a timestamped event to the trace.

```typescript theme={null}
addEvent(
  name: string,
  details?: string | object,
  options?: AddEventOptions
): Trace
```

#### Parameters

| Parameter | Type               | Required | Description                                         |
| --------- | ------------------ | -------- | --------------------------------------------------- |
| `name`    | `string`           | Yes      | Event name                                          |
| `details` | `string \| object` | No       | Event details (objects are stringified)             |
| `options` | `AddEventOptions`  | No       | Options with `captureStackTrace` and/or `timestamp` |

#### AddEventOptions

| Option              | Type       | Default | Description                                      |
| ------------------- | ---------- | ------- | ------------------------------------------------ |
| `captureStackTrace` | `boolean`  | `false` | Capture stack trace at event location            |
| `timestamp`         | `Date`     | `now`   | Custom timestamp for the event                   |
| `severity`          | `Severity` | —       | Event severity level: `info`, `warn`, or `error` |

#### Examples

```typescript theme={null}
// Simple event
trace.addEvent('started');

// With string details
trace.addEvent('error', 'Connection timeout');

// With object details
trace.addEvent('transaction_sent', {
  txHash: '0x123...',
  gasUsed: 21000
});

// With stack trace capture
trace.addEvent('error_occurred', { code: 500 }, { captureStackTrace: true });

// With custom timestamp
trace.addEvent('operation_started', null, { timestamp: new Date('2024-01-01') });
```

<Note>
  **Convenience methods:** `trace.info()`, `trace.warn()`, and `trace.error()` are shortcuts for `addEvent()` with a severity field. See below.
</Note>

***

### info() / warn() / error()

Convenience methods for adding events with severity. These are shortcuts for `addEvent()` that include a `severity` field in the event details.

```typescript theme={null}
info(name: string, details?: string | object, options?: Omit<AddEventOptions, 'severity'>): Trace
warn(name: string, details?: string | object, options?: Omit<AddEventOptions, 'severity'>): Trace
error(name: string, details?: string | object, options?: Omit<AddEventOptions, 'severity'>): Trace
```

#### Examples

```typescript theme={null}
trace.info('User logged in', { userId: 'user-123' });
trace.warn('Rate limit approaching', { remaining: 5 });
trace.error('Payment failed', { code: 'INSUFFICIENT_FUNDS' });
```

***

### getTraceId()

Get the trace ID. In v2, trace IDs are generated client-side at creation time as W3C Tracing Context compatible 32-character hex strings. The ID is available immediately — no need to wait for the server response.

```typescript theme={null}
getTraceId(): string
```

#### Returns

* `string` - The trace ID (always available immediately after trace creation)

#### Examples

```typescript theme={null}
const trace = client.trace({ name: 'MyTrace' });
const traceId = trace.getTraceId(); // Available immediately — 32-char hex string

// Pass to backend via HTTP header
fetch('/api/action', {
  headers: { 'X-Mirador-Trace-Id': traceId }
});
```

**With a pre-set trace ID:**

```typescript theme={null}
const trace = client.trace({ traceId: 'your-32-char-hex-id' });
trace.getTraceId(); // 'your-32-char-hex-id'
```

***

### startSpan()

Open a [span](/concepts/spans) — a timed, nestable unit of work within the trace. Returns a [`Span`](/api-reference/span) handle; call `span.end()` to close it.

```typescript theme={null}
startSpan(name: string, options?: SpanOptions): Span
```

#### Parameters

| Parameter | Type          | Required | Description                                |
| --------- | ------------- | -------- | ------------------------------------------ |
| `name`    | `string`      | Yes      | Span name                                  |
| `options` | `SpanOptions` | No       | `parentSpanId` and/or initial `attributes` |

#### SpanOptions

| Option         | Type                  | Description                                                               |
| -------------- | --------------------- | ------------------------------------------------------------------------- |
| `parentSpanId` | `string`              | Parent span id (defaults to the innermost open span, else the trace root) |
| `attributes`   | `Record<string, any>` | Initial span attributes (objects are stringified)                         |

#### Examples

```typescript theme={null}
const span = trace.startSpan('swap_quote', { attributes: { dex: 'uniswap' } });
span.setAttribute('amountIn', '1.5');
span.info('quote_received');
span.end({ status: 'OK' });
```

Events recorded while the span is open nest under it. See [Spans](/concepts/spans).

***

### span()

Run a function inside a span that ends automatically — status `OK` when it returns, or `ERROR` (plus the error message) when it throws. Works with sync and async functions and returns the function's result. The span is passed to the callback for precise event nesting.

```typescript theme={null}
span<T>(name: string, fn: (span: Span) => T): T
```

#### Parameters

| Parameter | Type                | Required | Description                     |
| --------- | ------------------- | -------- | ------------------------------- |
| `name`    | `string`            | Yes      | Span name                       |
| `fn`      | `(span: Span) => T` | Yes      | Function to run inside the span |

#### Examples

```typescript theme={null}
// Async — awaits the result, ends OK, or ERROR + message on throw
const quote = await trace.span('fetch_quote', async (span) => {
  span.setAttribute('pair', 'ETH/USDC');
  return await getQuote();
});

// Sync
const total = trace.span('compute', (span) => {
  span.addEvent('summing');
  return items.reduce((a, b) => a + b, 0);
});
```

***

### web3 (Plugin Namespace)

When the `Web3Plugin` is enabled, blockchain methods are available under the `web3` namespace. These methods require the plugin to be configured on the client.

<Note>
  These methods are only available when `Web3Plugin` is enabled. See [Plugins](/concepts/plugins) for setup.
</Note>

#### web3.evm.addTxHint()

Add a blockchain transaction hash hint.

```typescript theme={null}
trace.web3.evm.addTxHint(
  txHash: string,
  chain: ChainName,
  options?: string | TxHintOptions
): Trace
```

| Parameter | Type                      | Required | Description                              |
| --------- | ------------------------- | -------- | ---------------------------------------- |
| `txHash`  | `string`                  | Yes      | Transaction hash                         |
| `chain`   | `ChainName`               | Yes      | Blockchain network                       |
| `options` | `string \| TxHintOptions` | No       | Description string or structured options |

```typescript theme={null}
trace.web3.evm.addTxHint('0x123...', 'ethereum');
trace.web3.evm.addTxHint('0x456...', 'polygon', 'Bridge transaction');
trace.web3.evm.addTxHint('0x789...', 'ethereum', {
  input: '0xa9059cbb...',
  details: 'ERC-20 transfer'
});
```

#### web3.evm.addTxInputData()

Add transaction input data (calldata) as a trace event.

```typescript theme={null}
trace.web3.evm.addTxInputData(inputData: string): Trace
```

```typescript theme={null}
trace.web3.evm.addTxInputData('0xa9059cbb000000000000000000000000...');
```

#### web3.evm.addTx()

Add a transaction hint from a transaction-like object. Automatically extracts the hash, input data, and chain.

```typescript theme={null}
trace.web3.evm.addTx(tx: TransactionLike, chain?: ChainName): Trace
```

```typescript theme={null}
const tx = await signer.sendTransaction(txData);
trace.web3.evm.addTx(tx);  // Uses tx.hash, tx.data, tx.chainId

// With explicit chain override
trace.web3.evm.addTx(tx, 'polygon');
```

#### web3.evm.sendTransaction()

Send a transaction through the plugin's provider, automatically capturing tx hints and error data.

```typescript theme={null}
trace.web3.evm.sendTransaction(tx: TransactionRequest): Promise<string>
```

```typescript theme={null}
try {
  const txHash = await trace.web3.evm.sendTransaction({
    from: '0xabc...',
    to: '0xdef...',
    data: '0xa9059cbb...',
    value: '0x0',
    chainId: 1
  });
  console.log('Transaction sent:', txHash);
} catch (err) {
  // Error is already captured in the trace
  console.error('Transaction failed:', err);
}
```

#### web3.safe.addMsgHint()

Add a Safe multisig message hint. See [Safe Multisig](/concepts/safe-multisig) for usage details.

```typescript theme={null}
trace.web3.safe.addMsgHint(
  msgHint: string,
  chain: ChainName,
  details?: string
): Trace
```

```typescript theme={null}
trace.web3.safe.addMsgHint('0xabc123...', 'ethereum');
trace.web3.safe.addMsgHint('0xabc123...', 'ethereum', 'Multisig approval');
```

#### web3.safe.addTxHint()

Add a Safe multisig transaction hint. See [Safe Multisig](/concepts/safe-multisig) for usage details.

```typescript theme={null}
trace.web3.safe.addTxHint(
  safeTxHash: string,
  chain: ChainName,
  details?: string
): Trace
```

```typescript theme={null}
trace.web3.safe.addTxHint('0xsafeTxHash...', 'ethereum');
trace.web3.safe.addTxHint('0xsafeTxHash...', 'ethereum', 'Token transfer execution');
```

***

### flush()

Send pending data to the gateway. Available in both the Web SDK and Node.js SDK.

```typescript theme={null}
flush(): void
```

All flushes send `FlushTrace` requests. The gateway handles idempotent upserts — there is no distinction between create and update on the wire.

Builder methods automatically schedule a flush via microtask, batching all synchronous calls within the same JS tick into a single network request. You can also call `flush()` manually to send immediately.

<Note>
  `flush()` is fire-and-forget. It returns immediately but maintains strict ordering of requests internally.
</Note>

#### Examples

```typescript theme={null}
trace.addEvent('important_milestone');
trace.flush();  // Send immediately instead of waiting for microtask
```

***

### addStackTrace()

Capture and add the current stack trace as an event.

```typescript theme={null}
addStackTrace(eventName?: string, additionalDetails?: object): Trace
```

#### Parameters

| Parameter           | Type     | Required | Description                          |
| ------------------- | -------- | -------- | ------------------------------------ |
| `eventName`         | `string` | No       | Event name (default: "stack\_trace") |
| `additionalDetails` | `object` | No       | Additional details to include        |

#### Examples

```typescript theme={null}
trace.addStackTrace();  // Creates event named "stack_trace"
trace.addStackTrace('checkpoint', { stage: 'validation' });
```

***

### addExistingStackTrace()

Add a previously captured stack trace as an event.

```typescript theme={null}
addExistingStackTrace(
  stackTrace: StackTrace,
  eventName?: string,
  additionalDetails?: object
): Trace
```

#### Parameters

| Parameter           | Type         | Required | Description                          |
| ------------------- | ------------ | -------- | ------------------------------------ |
| `stackTrace`        | `StackTrace` | Yes      | Previously captured stack trace      |
| `eventName`         | `string`     | No       | Event name (default: "stack\_trace") |
| `additionalDetails` | `object`     | No       | Additional details to include        |

#### Examples

```typescript theme={null}
import { captureStackTrace } from '@miradorlabs/web-sdk';

// Capture stack trace now
const stack = captureStackTrace();

// ... later ...
trace.addExistingStackTrace(stack, 'deferred_location', { reason: 'async operation' });
```

***

### startKeepAlive()

Manually start the keep-alive timer. This is useful when you set `autoKeepAlive: false` but later decide the trace needs to stay alive.

```typescript theme={null}
startKeepAlive(): void
```

This method is idempotent — calling it when the timer is already running has no effect.

#### Examples

```typescript theme={null}
const trace = client.trace({ name: 'LongRunning', autoKeepAlive: false });

// Later, start keep-alive manually
trace.startKeepAlive();
```

***

### stopKeepAlive()

Manually stop the keep-alive timer without closing the trace. Useful when you want to pause keep-alive pings but continue adding data to the trace.

```typescript theme={null}
stopKeepAlive(): void
```

This method is idempotent — calling it when the timer is already stopped has no effect.

#### Examples

```typescript theme={null}
const trace = client.trace({ name: 'UserSession' });

// Stop keep-alive during an idle period
trace.stopKeepAlive();

// Restart when activity resumes
trace.startKeepAlive();
```

***

### close()

Close the trace, drain the flush queue, run plugin cleanup, and stop all timers. After calling this method, all subsequent operations will be ignored.

```typescript theme={null}
close(reason?: string): Promise<void>
```

#### Parameters

| Parameter | Type     | Required | Description                  |
| --------- | -------- | -------- | ---------------------------- |
| `reason`  | `string` | No       | Reason for closing the trace |

#### Examples

```typescript theme={null}
await trace.close();
await trace.close('User completed workflow');

// Best practice: use try-catch
const trace = client.trace({ name: 'CheckoutFlow' });

try {
  // ... trace user checkout flow ...
  await trace.close('Checkout completed');
} catch (error) {
  trace.addEvent('error', { message: error.message });
  await trace.close('Checkout failed');
}
```

<Note>
  Once a trace is closed, all method calls will be ignored with a warning. The keep-alive timer will be stopped, plugins will be cleaned up, and a close request will be sent to the server.
</Note>

***

### isClosed()

Check if the trace has been closed.

```typescript theme={null}
isClosed(): boolean
```

#### Returns

* `boolean` - `true` if the trace has been closed, `false` otherwise

#### Examples

```typescript theme={null}
const closed = trace.isClosed();
if (!closed) {
  trace.addEvent('still_active');
}
```

## Method Chaining

All builder methods return `this`, enabling fluent chaining:

```typescript theme={null}
import { Client, Web3Plugin } from '@miradorlabs/web-sdk';

const client = new Client('api-key', {
  plugins: [Web3Plugin({ provider: window.ethereum })]
});

const trace = client.trace({ name: 'CompleteExample' })
  .addAttribute('userId', 'user-123')
  .addAttributes({ token: 'ETH', amount: 1.5 })
  .addTag('swap')
  .addTags(['dex', 'ethereum'])
  .addEvent('initiated')
  .addEvent('processing', { step: 1 });

trace.web3.evm.addTxHint('0x123...', 'ethereum', 'Main transaction');
trace.web3.safe.addMsgHint('0xabc...', 'ethereum', 'Multisig approval');
trace.web3.safe.addTxHint('0xdef...', 'ethereum', 'Safe execution');
```

## Lifecycle

Both SDKs share the same auto-flush pattern: builder methods schedule a microtask that batches and sends data automatically. All flushes use the idempotent `FlushTrace` RPC.

```
client.trace() → Trace instance created (ID generated client-side)
      |
addAttribute/addEvent/etc. → Data buffered
      |
(end of JS tick) → flush() auto-triggered
      |
FlushTrace sent to gateway
      |
addAttribute/addEvent/etc. → More data buffered
      |
(end of JS tick) → flush() auto-triggered
      |
FlushTrace sent to gateway
      |
close() → Drains queue, runs plugin cleanup, sends CloseTrace
```

**Resumed trace (cross-SDK):**

```
client.trace({ traceId: '...' }) → Trace instance with pre-set ID
      |
addAttribute/addEvent/etc. → Data buffered
      |
(auto-flush) → FlushTrace sent (uses provided ID)
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Types" icon="code" href="/api-reference/types">
    TypeScript type definitions
  </Card>

  <Card title="Examples" icon="flask" href="/examples/transaction-tracking">
    See complete usage examples
  </Card>
</CardGroup>
