> ## 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.

# Types

> TypeScript type definitions

## Overview

The SDK exports all TypeScript types for full type safety in your application.

## Import

**Web SDK:**

```typescript theme={null}
import type {
  ClientOptions,
  TraceOptions,
  AddEventOptions,
  ChainName,
  Severity,
  Logger,
  ClientMetadata,
  TraceEvent,
  TxHashHint,
  SafeMsgHintData,
  SafeTxHintData,
  TxHintOptions,
  TransactionLike,
  TransactionRequest,
  EIP1193Provider,
  MiradorProviderOptions,
  StackFrame,
  StackTrace,
  TraceCallbacks,
  MiradorPlugin,
  TraceContext,
  PluginSetupResult,
  FlushBuilder,
  Web3Plugin,
  Web3Methods,
  EvmMethods,
  SafeNamespaceMethods,
  NoopTrace,
  HintType,
  SpanStatus,
  SpanOptions,
  SpanEndOptions
} from '@miradorlabs/web-sdk';
```

**Node.js SDK:**

```typescript theme={null}
import type {
  ClientOptions,
  TraceOptions,
  AddEventOptions,
  ChainName,
  Severity,
  Logger,
  TraceEvent,
  TxHashHint,
  SafeMsgHintData,
  SafeTxHintData,
  TxHintOptions,
  TransactionLike,
  TransactionRequest,
  EIP1193Provider,
  MiradorProviderOptions,
  StackFrame,
  StackTrace,
  TraceCallbacks,
  MiradorPlugin,
  TraceContext,
  PluginSetupResult,
  FlushBuilder,
  Web3Plugin,
  Web3Methods,
  EvmMethods,
  SafeNamespaceMethods,
  NoopTrace,
  HintType,
  SpanStatus,
  SpanOptions,
  SpanEndOptions
} from '@miradorlabs/nodejs-sdk';
```

## ClientOptions

Configuration options for the client.

**Web SDK:**

```typescript theme={null}
interface ClientOptions {
  /**
   * Gateway URL for the Mirador Ingest API
   * @default 'ingest.mirador.org:443'
   */
  apiUrl?: string;

  /**
   * Keep-alive ping interval in milliseconds
   * @default 10000
   */
  keepAliveIntervalMs?: number;

  /**
   * Timeout for individual API calls in milliseconds
   * @default 5000
   */
  callTimeoutMs?: number;

  /**
   * Maximum trace lifetime in milliseconds. When exceeded, the trace is automatically closed.
   * Set to 0 to disable.
   * @default 0
   */
  maxTraceLifetimeMs?: number;

  /**
   * Enable debug logging
   * @default false
   */
  debug?: boolean;

  /**
   * Custom logger implementation
   */
  logger?: Logger;

  /**
   * Lifecycle callbacks for all traces created by this client
   */
  callbacks?: TraceCallbacks;

  /**
   * Sample rate for traces (0 to 1). 0 = drop all, 1 = keep all.
   * Unsampled traces return a NoopTrace.
   * @default 1
   */
  sampleRate?: number;

  /**
   * Custom sampler function. Takes precedence over sampleRate.
   * Return true to keep the trace, false to drop it.
   */
  sampler?: (name: string | undefined, options: TraceOptions) => boolean;

  /**
   * Plugins to install on all traces created by this client.
   */
  plugins?: MiradorPlugin[];
}
```

**Node.js SDK:**

```typescript theme={null}
interface ClientOptions {
  /**
   * Gateway URL for the Mirador Ingest API
   * @default 'ingest.mirador.org:443'
   */
  apiUrl?: string;

  /**
   * Keep-alive ping interval in milliseconds
   * @default 10000
   */
  keepAliveIntervalMs?: number;

  /**
   * Timeout for individual API calls in milliseconds
   * @default 5000
   */
  callTimeoutMs?: number;

  /**
   * Maximum trace lifetime in milliseconds. When exceeded, the trace is automatically closed.
   * Set to 0 to disable.
   * @default 0
   */
  maxTraceLifetimeMs?: number;

  /**
   * Enable debug logging
   * @default false
   */
  debug?: boolean;

  /**
   * Custom logger implementation
   */
  logger?: Logger;

  /**
   * Lifecycle callbacks for all traces created by this client
   */
  callbacks?: TraceCallbacks;

  /**
   * Sample rate for traces (0 to 1). 0 = drop all, 1 = keep all.
   * Unsampled traces return a NoopTrace.
   * @default 1
   */
  sampleRate?: number;

  /**
   * Custom sampler function. Takes precedence over sampleRate.
   * Return true to keep the trace, false to drop it.
   */
  sampler?: (name: string | undefined, options: TraceOptions) => boolean;

  /**
   * Plugins to install on all traces created by this client.
   */
  plugins?: MiradorPlugin[];

  /**
   * Use SSL for the gRPC connection
   * @default true
   */
  useSsl?: boolean;
}
```

### Usage

```typescript theme={null}
const options: ClientOptions = {
  apiUrl: 'https://custom-gateway.example.com:443'
};

const client = new Client('api-key', options);
```

**With Web3Plugin:**

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

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

// All traces created by this client will have web3 methods available
```

**Node.js SDK — local development (no SSL):**

```typescript theme={null}
const client = new Client('api-key', {
  apiUrl: 'localhost:50053',
  useSsl: false
});
```

***

## TraceOptions

Configuration options for individual traces.

**Web SDK:**

```typescript theme={null}
interface TraceOptions {
  /**
   * Name identifying the trace
   */
  name?: string;

  /**
   * Resume an existing trace by ID, or provide a pre-generated W3C Tracing Context
   * compatible ID (32-char hex string).
   * When set, the flush uses the provided ID instead of generating a new one.
   */
  traceId?: string;

  /**
   * Include browser metadata on first flush
   * @default true
   */
  includeUserMeta?: boolean;

  /**
   * Maximum retry attempts on network failure
   * @default 2
   */
  maxRetries?: number;

  /**
   * Base delay in ms for exponential backoff
   * @default 500
   */
  retryBackoff?: number;

  /**
   * Automatically close trace on page unload
   * @default false
   */
  autoClose?: boolean;

  /**
   * Automatically start the keep-alive timer.
   * Defaults to true for new traces, false when traceId is set (resumed traces).
   */
  autoKeepAlive?: boolean;

  /**
   * Maximum number of events/items in the flush queue before dropping.
   * @default 4096
   */
  maxQueueSize?: number;

  /**
   * Lifecycle callbacks for this specific trace (merged with client-level callbacks).
   */
  callbacks?: TraceCallbacks;
}
```

**Node.js SDK:**

```typescript theme={null}
interface TraceOptions {
  /**
   * Name identifying the trace
   */
  name?: string;

  /**
   * Resume an existing trace by ID, or provide a pre-generated W3C Tracing Context
   * compatible ID (32-char hex string).
   * When set, the flush uses the provided ID instead of generating a new one.
   */
  traceId?: string;

  /**
   * Capture stack trace at trace creation point
   * @default true
   */
  captureStackTrace?: boolean;

  /**
   * Maximum retry attempts on network failure
   * @default 2
   */
  maxRetries?: number;

  /**
   * Base delay in ms for exponential backoff
   * @default 500
   */
  retryBackoff?: number;

  /**
   * Automatically start the keep-alive timer.
   * Defaults to true for new traces, false when traceId is set (resumed traces).
   */
  autoKeepAlive?: boolean;

  /**
   * Maximum number of events/items in the flush queue before dropping.
   * @default 4096
   */
  maxQueueSize?: number;

  /**
   * Lifecycle callbacks for this specific trace (merged with client-level callbacks).
   */
  callbacks?: TraceCallbacks;
}
```

### Usage

**Web SDK:**

```typescript theme={null}
const options: TraceOptions = {
  name: 'MyTrace',
  includeUserMeta: true,
  maxRetries: 5,
  retryBackoff: 1000
};

const trace = client.trace(options);
```

**Node.js SDK:**

```typescript theme={null}
const options: TraceOptions = {
  name: 'MyTrace',
  captureStackTrace: false
};

const trace = client.trace(options);
```

**Node.js SDK — Resuming a frontend trace:**

```typescript theme={null}
// Backend receives trace ID from frontend (e.g., via HTTP header)
const trace = client.trace({
  name: 'BackendProcessing',
  traceId: req.headers['x-mirador-trace-id']
});

trace.addEvent('backend:received');
// → FlushTrace sent automatically (uses the provided traceId)
```

***

## TraceCallbacks

Lifecycle callbacks for observing trace events programmatically. See the [Lifecycle Callbacks](/advanced/lifecycle-callbacks) guide for detailed usage patterns.

```typescript theme={null}
interface TraceCallbacks {
  /** Called once when the trace is first created on the server (first successful flush) */
  onCreated?: (traceId: string) => void;

  /** Called after each successful flush */
  onFlushed?: (traceId: string, itemCount: number) => void;

  /** Called when a flush operation fails after retries */
  onFlushError?: (error: Error, operation: string) => void;

  /** Called when the trace is closed */
  onClosed?: (traceId: string, reason?: string) => void;

  /** Called when items are dropped (e.g., queue full) */
  onDropped?: (count: number, reason: string) => void;
}
```

### Usage

```typescript theme={null}
const client = new Client('api-key', {
  callbacks: {
    onCreated: (traceId) => console.log('Trace created:', traceId),
    onFlushed: (traceId, itemCount) => console.log(`Flushed ${itemCount} items`),
    onFlushError: (error, operation) => console.error(`${operation} failed:`, error),
    onClosed: (traceId, reason) => console.log('Closed:', traceId, reason),
    onDropped: (count, reason) => console.warn(`Dropped ${count} items: ${reason}`)
  }
});
```

***

## Logger

Interface for custom logging implementations. See the [Custom Logging](/advanced/logging) guide for integration examples.

```typescript theme={null}
interface Logger {
  debug(...args: unknown[]): void;
  warn(...args: unknown[]): void;
  error(...args: unknown[]): void;
}
```

### Usage

```typescript theme={null}
// Use the built-in console logger
const client = new Client('api-key', { debug: true });

// Or provide a custom logger
const client = new Client('api-key', {
  logger: {
    debug: (...args) => myLogger.debug(args.join(' ')),
    warn:  (...args) => myLogger.warn(args.join(' ')),
    error: (...args) => myLogger.error(args.join(' '))
  }
});
```

***

## Severity

Event severity levels used by convenience methods.

```typescript theme={null}
type Severity = 'info' | 'warn' | 'error';
```

### Usage

```typescript theme={null}
trace.info('User action completed');
trace.warn('Approaching rate limit');
trace.error('Transaction failed', { code: 'REVERT' });
```

***

## MiradorPlugin

Interface for creating plugins that extend trace functionality.

```typescript theme={null}
interface MiradorPlugin {
  /** Unique plugin name — used as the namespace on the trace */
  name: string;

  /** Called when a trace is created. Returns methods and lifecycle hooks. */
  setup(context: TraceContext): PluginSetupResult;
}
```

***

## TraceContext

Read/write access to the trace, passed to plugin `setup()`.

```typescript theme={null}
interface TraceContext {
  /** Add an event to the trace */
  addEvent(name: string, details?: string | object, options?: AddEventOptions): void;
  /** Add a single attribute */
  addAttribute(key: string, value: string | number | boolean | object): void;
  /** Add multiple attributes at once */
  addAttributes(attrs: Record<string, string | number | boolean | object>): void;
  /** Add a single tag */
  addTag(tag: string): void;
  /** Add multiple tags at once */
  addTags(tags: string[]): void;
  /** Get the W3C trace ID */
  getTraceId(): string;
  /** Check if the trace has been closed */
  isClosed(): boolean;
  /** Schedule a flush (batched via microtask) */
  scheduleFlush(): void;
  /** Logger instance respecting client configuration */
  logger: Logger;
}
```

***

## PluginSetupResult

Object returned by a plugin's `setup()` method.

```typescript theme={null}
interface PluginSetupResult<TMethods> {
  /** Methods to merge onto the Trace instance under the plugin's name */
  methods: TMethods;

  /** No-op versions of methods for NoopTrace (sampled-out traces).
   *  If not provided, methods default to returning `this` for chaining. */
  noopMethods?: DeepPartial<TMethods>;

  /** Called during flush to contribute data to the payload */
  onFlush?: (builder: FlushBuilder) => void;

  /** Called when the trace is being closed */
  onClose?: () => void;

  /** Return true if this plugin has unflushed data */
  hasPendingData?: () => boolean;
}
```

***

## FlushBuilder

Interface for contributing data to a flush payload from a plugin's `onFlush` hook.

```typescript theme={null}
interface FlushBuilder {
  /** Add a hint (type-safe for known hint types) */
  addHint<T extends HintTypeName>(type: T, data: HintDataMap[T]): void;
  /** Add a hint with a custom type (extensibility fallback) */
  addHint(type: string, data: Record<string, unknown>): void;
  /** Add an event to the flush payload */
  addEvent(event: { name: string; details?: string; timestamp: Date; severity?: Severity }): void;
  /** Add an attribute */
  addAttribute(key: string, value: string): void;
  /** Add a tag */
  addTag(tag: string): void;
}
```

***

## Web3Methods

Methods available on `trace.web3` when using the Web3Plugin.

```typescript theme={null}
interface Web3Methods {
  evm: EvmMethods;
  safe: SafeNamespaceMethods;
}
```

***

## EvmMethods

EVM transaction methods available on `trace.web3.evm`.

```typescript theme={null}
interface EvmMethods {
  addTxHint(txHash: string, chain: ChainName, options?: string | TxHintOptions): Trace;
  addTxInputData(inputData: string): Trace;
  addTx(tx: TransactionLike, chain?: ChainName): Trace;
  sendTransaction(tx: TransactionRequest): Promise<string>;
}
```

***

## SafeNamespaceMethods

Safe multisig methods available on `trace.web3.safe`.

```typescript theme={null}
interface SafeNamespaceMethods {
  addMsgHint(msgHint: string, chain: ChainName, details?: string): Trace;
  addTxHint(safeTxHash: string, chain: ChainName, details?: string): Trace;
}
```

***

## NoopTrace

A trace implementation that silently discards all operations. Returned when a trace is not sampled.

```typescript theme={null}
class NoopTrace {
  // All Trace methods are available but do nothing
  addAttribute(key: string, value: any): NoopTrace;
  addEvent(name: string, details?: any): NoopTrace;
  getTraceId(): string;  // Returns the generated ID
  // ... etc
}
```

### Usage

```typescript theme={null}
const client = new Client('api-key', { sampleRate: 0.5 });
const trace = client.trace({ name: 'MaybeRecorded' });

// Safe to call all methods — if unsampled, they're silently ignored
trace.addEvent('action');
```

***

## HintType

Discriminator for the type of transaction hint.

```typescript theme={null}
type HintType = 'tx' | 'safe_msg' | 'safe_tx';
```

***

## ChainName

Supported blockchain networks for transaction hints.

```typescript theme={null}
type ChainName =
  | 'ethereum'
  | 'polygon'
  | 'arbitrum'
  | 'base'
  | 'optimism'
  | 'bsc';
```

### Usage

```typescript theme={null}
const chain: ChainName = 'ethereum';
trace.web3.evm.addTxHint(txHash, chain);

// Type-safe: only valid chains allowed
trace.web3.evm.addTxHint(hash, 'polygon');   // OK
trace.web3.evm.addTxHint(hash, 'invalid');   // Type error
```

***

## TraceEvent

Structure of events added to traces.

```typescript theme={null}
interface TraceEvent {
  /**
   * Event name
   */
  eventName: string;

  /**
   * Optional event details (stringified if object)
   */
  details?: string;

  /**
   * Timestamp of the event
   */
  timestamp: Date;

  /**
   * Owning span id ("" / undefined = trace-level). Set automatically when the
   * event is recorded via a span or while a span is open.
   */
  spanId?: string;
}
```

### Usage

```typescript theme={null}
// Events are created internally by addEvent()
trace.addEvent('my_event', { key: 'value' });

// The SDK creates a TraceEvent like:
// {
//   eventName: 'my_event',
//   details: '{"key":"value"}',
//   timestamp: new Date()
// }
```

***

## TxHashHint

Structure of blockchain transaction hints.

```typescript theme={null}
interface TxHashHint {
  /**
   * Transaction hash
   */
  txHash: string;

  /**
   * Blockchain network
   */
  chain: ChainName;

  /**
   * Optional description
   */
  details?: string;

  /**
   * Timestamp of the hint
   */
  timestamp: Date;
}
```

### Usage

```typescript theme={null}
// TxHashHints are created internally by web3.evm.addTxHint()
trace.web3.evm.addTxHint('0x123...', 'ethereum', 'Swap transaction');
```

***

## SafeMsgHintData

Structure of Safe multisig message hints.

```typescript theme={null}
interface SafeMsgHintData {
  /**
   * Safe message hash
   */
  messageHash: string;

  /**
   * Blockchain network the Safe is deployed on
   */
  chain: ChainName;

  /**
   * Optional description
   */
  details?: string;

  /**
   * Timestamp of the hint
   */
  timestamp: Date;
}
```

### Usage

```typescript theme={null}
// SafeMsgHintData is created internally by web3.safe.addMsgHint()
trace.web3.safe.addMsgHint('0xabc...', 'ethereum', 'Multisig approval');
```

***

## SafeTxHintData

Structure of Safe multisig transaction hints.

```typescript theme={null}
interface SafeTxHintData {
  /**
   * Safe transaction hash
   */
  safeTxHash: string;

  /**
   * Blockchain network the Safe is deployed on
   */
  chain: ChainName;

  /**
   * Optional description
   */
  details?: string;

  /**
   * Timestamp of the hint
   */
  timestamp: Date;
}
```

### Usage

```typescript theme={null}
// SafeTxHintData is created internally by web3.safe.addTxHint()
trace.web3.safe.addTxHint('0xdef...', 'ethereum', 'Safe execution');
```

***

## AddEventOptions

Options for the `addEvent()` method.

```typescript theme={null}
interface AddEventOptions {
  /**
   * Capture stack trace at event location
   * @default false
   */
  captureStackTrace?: boolean;

  /**
   * Custom timestamp for the event
   */
  timestamp?: Date;
}
```

### Usage

```typescript theme={null}
// Capture stack trace for debugging
trace.addEvent('error_occurred', { code: 500 }, { captureStackTrace: true });

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

***

## SpanStatus

Terminal status for a span, mirroring the OTLP span status.

```typescript theme={null}
type SpanStatus = 'UNSET' | 'OK' | 'ERROR';
```

### Usage

```typescript theme={null}
span.end({ status: 'OK' });
span.end({ status: 'ERROR', message: 'quote timed out' });
```

***

## SpanOptions

Options for opening a span via [`trace.startSpan()`](/api-reference/trace#startspan) or `span.startSpan()`.

```typescript theme={null}
interface SpanOptions {
  /**
   * Explicit parent span id. Defaults to the innermost open span, otherwise
   * the span is a root of the trace.
   */
  parentSpanId?: string;

  /**
   * Initial span attributes (objects are stringified).
   */
  attributes?: Record<string, string | number | boolean | object>;
}
```

### Usage

```typescript theme={null}
const span = trace.startSpan('swap', {
  attributes: { dex: 'uniswap' },
  parentSpanId: parent.id
});
```

***

## SpanEndOptions

Options for ending a span via [`span.end()`](/api-reference/span#end).

```typescript theme={null}
interface SpanEndOptions {
  /**
   * OTLP status: 'OK', 'ERROR', or 'UNSET' (default — omitted).
   */
  status?: SpanStatus;

  /**
   * Optional status message, typically an error description.
   */
  message?: string;
}
```

### Usage

```typescript theme={null}
span.end();                                          // UNSET
span.end({ status: 'ERROR', message: err.message });
```

***

## StackFrame

Represents a single frame in a stack trace.

```typescript theme={null}
interface StackFrame {
  /**
   * Function name (or '<anonymous>')
   */
  functionName: string;

  /**
   * File name or URL
   */
  fileName: string;

  /**
   * Line number
   */
  lineNumber: number;

  /**
   * Column number
   */
  columnNumber: number;
}
```

***

## StackTrace

Captured stack trace information.

```typescript theme={null}
interface StackTrace {
  /**
   * Parsed stack frames
   */
  frames: StackFrame[];

  /**
   * Original Error.stack string
   */
  raw: string;
}
```

### Usage

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

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

// Format for storage
const json = formatStackTrace(stack);

// Format for display
const readable = formatStackTraceReadable(stack);
```

***

## ClientMetadata (Web SDK Only)

Browser environment metadata collected automatically.

```typescript theme={null}
interface ClientMetadata {
  // Browser
  browser?: string;
  browserVersion?: string;
  userAgent?: string;

  // Operating System
  os?: string;
  osVersion?: string;
  deviceType?: string;

  // Display
  screenWidth?: string;
  screenHeight?: string;
  viewportWidth?: string;
  viewportHeight?: string;
  colorDepth?: string;
  pixelRatio?: string;

  // Hardware
  cpuCores?: string;
  deviceMemory?: string;
  touchSupport?: string;

  // Network
  connectionType?: string;
  online?: string;

  // Locale
  language?: string;
  languages?: string;
  timezone?: string;
  timezoneOffset?: string;

  // Page Context
  url?: string;
  origin?: string;
  pathname?: string;
  referrer?: string;
  documentVisibility?: string;

  // Privacy
  cookiesEnabled?: string;
  doNotTrack?: string;
}
```

### Usage

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

const metadata: ClientMetadata = getClientMetadata();
console.log(metadata.browser);      // 'Chrome'
console.log(metadata.deviceType);   // 'desktop'
```

***

## EIP1193Provider

Standard [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) provider interface. Compatible with MetaMask, WalletConnect, and any EIP-1193 compliant wallet.

```typescript theme={null}
interface EIP1193Provider {
  request(args: { method: string; params?: unknown[] }): Promise<unknown>;
}
```

### Usage

```typescript theme={null}
// window.ethereum is an EIP1193Provider
const provider: EIP1193Provider = window.ethereum;

// viem walletClient.transport is compatible
// ethers.js BrowserProvider is compatible
```

***

## TxHintOptions

Structured options for `web3.evm.addTxHint()`, extending the simple string details.

```typescript theme={null}
interface TxHintOptions {
  /** Transaction input data / calldata */
  input?: string;
  /** Additional details string */
  details?: string;
}
```

<Note>
  When `input` is provided, it is emitted as a `"Tx input data"` event via `web3.evm.addTxInputData()`. Only `details` is stored in the hint itself.
</Note>

### Usage

```typescript theme={null}
// Simple string details
trace.web3.evm.addTxHint(txHash, 'ethereum', 'Swap transaction');

// Structured options with calldata
trace.web3.evm.addTxHint(txHash, 'ethereum', {
  input: '0xa9059cbb000000000000000000000000...',
  details: 'ERC-20 transfer'
});
```

***

## TransactionLike

A transaction-like object that matches common library shapes (ethers v5/v6, viem, raw RPC).

```typescript theme={null}
interface TransactionLike {
  /** Transaction hash */
  hash: string;
  /** Transaction input data (ethers v5 style) */
  data?: string;
  /** Transaction input data (ethers v6 / viem / raw RPC style) */
  input?: string;
  /** Chain ID */
  chainId?: number | bigint | string;
}
```

### Usage

```typescript theme={null}
// Works with ethers v5 TransactionResponse
const tx = await signer.sendTransaction(txData);
trace.web3.evm.addTx(tx); // tx.hash and tx.data are used

// Works with viem transaction objects
const hash = await walletClient.sendTransaction(request);
trace.web3.evm.addTx({ hash, input: request.data, chainId: request.chain.id });
```

***

## TransactionRequest

Transaction parameters for `web3.evm.sendTransaction()`, matching the EIP-1193 `eth_sendTransaction` format.

```typescript theme={null}
interface TransactionRequest {
  /** Sender address */
  from: string;
  /** Recipient address */
  to?: string;
  /** Transaction input data / calldata */
  data?: string;
  /** Value in wei */
  value?: string | bigint;
  /** Gas limit */
  gas?: string | bigint;
  /** Gas price (legacy) */
  gasPrice?: string | bigint;
  /** Max fee per gas (EIP-1559) */
  maxFeePerGas?: string | bigint;
  /** Max priority fee per gas (EIP-1559) */
  maxPriorityFeePerGas?: string | bigint;
  /** Transaction nonce */
  nonce?: number | string;
  /** Chain ID */
  chainId?: number | string;
}
```

### Usage

```typescript theme={null}
const tx: TransactionRequest = {
  from: '0xabc...',
  to: '0xdef...',
  data: '0xa9059cbb...',
  value: '0x0',
  chainId: 1
};

const txHash = await trace.web3.evm.sendTransaction(tx);
```

***

## MiradorProviderOptions

Configuration for the `MiradorProvider` wrapper.

```typescript theme={null}
interface MiradorProviderOptions {
  /** Bind to an existing trace instead of auto-creating per transaction */
  trace?: Trace;
  /** Trace options for auto-created traces (ignored if trace is provided) */
  traceOptions?: TraceOptions;
}
```

### Usage

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

const client = new Client('api-key');

// Auto-create a new trace per transaction
const provider = new MiradorProvider(window.ethereum, client);

// Or bind to an existing trace
const trace = client.trace({ name: 'MyFlow' });
const provider = new MiradorProvider(window.ethereum, client, { trace });
```

***

## Utility Functions

Both SDKs export utility functions for stack traces and chain ID mapping. The Web SDK additionally exports browser metadata utilities.

**Both SDKs:**

```typescript theme={null}
import {
  captureStackTrace,
  formatStackTrace,
  formatStackTraceReadable,
  chainIdToName
} from '@miradorlabs/web-sdk'; // or '@miradorlabs/nodejs-sdk'

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

// Format for storage (JSON)
const json = formatStackTrace(stack);

// Format for display (human-readable)
const readable = formatStackTraceReadable(stack);

// Convert chain ID to chain name
chainIdToName(1);     // 'ethereum'
chainIdToName(137);   // 'polygon'
chainIdToName(42161); // 'arbitrum'
chainIdToName(8453);  // 'base'
chainIdToName(10);    // 'optimism'
chainIdToName(56);    // 'bsc'
chainIdToName(999);   // undefined
```

**Web SDK only — browser metadata:**

```typescript theme={null}
import {
  getClientMetadata,
  detectBrowser,
  detectOS,
  detectDeviceType,
} from '@miradorlabs/web-sdk';

// Get full metadata object
const metadata = getClientMetadata();

// Individual detection
const browser = detectBrowser();
// { name: 'Chrome', version: '120.0.0' }

const os = detectOS();
// { name: 'macOS', version: '14.0' }

const device = detectDeviceType();
// 'desktop' | 'mobile' | 'tablet'
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Client" icon="plug" href="/api-reference/client">
    Client class reference
  </Card>

  <Card title="Trace" icon="route" href="/api-reference/trace">
    Trace builder reference
  </Card>
</CardGroup>
