Skip to main content
Web Client SDK:
import { Trace } from '@miradorlabs/web-sdk';
Node.js SDK:
import { Trace } from '@miradorlabs/nodejs-sdk';
You typically don’t instantiate Trace directly. Use client.trace() instead.

Methods

addAttribute()

Add a single attribute to the trace.
addAttribute(key: string, value: string | number | boolean | object): Trace

Parameters

ParameterTypeDescription
keystringAttribute key
valuestring | number | boolean | objectAttribute value (objects are JSON stringified)

Examples

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

addAttributes()

Add multiple attributes at once.
addAttributes(attrs: Record<string, string | number | boolean | object>): Trace

Parameters

ParameterTypeDescription
attrsRecord<string, any>Object of key-value pairs

Examples

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

addTag()

Add a single tag to the trace.
addTag(tag: string): Trace

Parameters

ParameterTypeDescription
tagstringTag to add

Examples

trace.addTag('ethereum')
     .addTag('swap');

addTags()

Add multiple tags at once.
addTags(tags: string[]): Trace

Parameters

ParameterTypeDescription
tagsstring[]Array of tags

Examples

trace.addTags(['dex', 'uniswap', 'v3']);

addEvent()

Add a timestamped event to the trace.
addEvent(
  name: string,
  details?: string | object,
  options?: AddEventOptions
): Trace

Parameters

ParameterTypeRequiredDescription
namestringYesEvent name
detailsstring | objectNoEvent details (objects are stringified)
optionsAddEventOptionsNoOptions with captureStackTrace and/or timestamp

AddEventOptions

OptionTypeDefaultDescription
captureStackTracebooleanfalseCapture stack trace at event location
timestampDatenowCustom timestamp for the event
severitySeverityEvent severity level: info, warn, or error

Examples

// 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') });
Convenience methods: trace.info(), trace.warn(), and trace.error() are shortcuts for addEvent() with a severity field. See below.

info() / warn() / error()

Convenience methods for adding events with severity. These are shortcuts for addEvent() that include a severity field in the event details.
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

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.
getTraceId(): string

Returns

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

Examples

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:
const trace = client.trace({ traceId: 'your-32-char-hex-id' });
trace.getTraceId(); // 'your-32-char-hex-id'

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.
These methods are only available when Web3Plugin is enabled. See Plugins for setup.

web3.evm.addTxHint()

Add a blockchain transaction hash hint.
trace.web3.evm.addTxHint(
  txHash: string,
  chain: ChainName,
  options?: string | TxHintOptions
): Trace
ParameterTypeRequiredDescription
txHashstringYesTransaction hash
chainChainNameYesBlockchain network
optionsstring | TxHintOptionsNoDescription string or structured options
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.
trace.web3.evm.addTxInputData(inputData: string): Trace
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.
trace.web3.evm.addTx(tx: TransactionLike, chain?: ChainName): Trace
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.
trace.web3.evm.sendTransaction(tx: TransactionRequest): Promise<string>
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 for usage details.
trace.web3.safe.addMsgHint(
  msgHint: string,
  chain: ChainName,
  details?: string
): Trace
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 for usage details.
trace.web3.safe.addTxHint(
  safeTxHash: string,
  chain: ChainName,
  details?: string
): Trace
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.
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.
flush() is fire-and-forget. It returns immediately but maintains strict ordering of requests internally.

Examples

trace.addEvent('important_milestone');
trace.flush();  // Send immediately instead of waiting for microtask

addStackTrace()

Capture and add the current stack trace as an event.
addStackTrace(eventName?: string, additionalDetails?: object): Trace

Parameters

ParameterTypeRequiredDescription
eventNamestringNoEvent name (default: “stack_trace”)
additionalDetailsobjectNoAdditional details to include

Examples

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

addExistingStackTrace()

Add a previously captured stack trace as an event.
addExistingStackTrace(
  stackTrace: StackTrace,
  eventName?: string,
  additionalDetails?: object
): Trace

Parameters

ParameterTypeRequiredDescription
stackTraceStackTraceYesPreviously captured stack trace
eventNamestringNoEvent name (default: “stack_trace”)
additionalDetailsobjectNoAdditional details to include

Examples

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.
startKeepAlive(): void
This method is idempotent — calling it when the timer is already running has no effect.

Examples

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.
stopKeepAlive(): void
This method is idempotent — calling it when the timer is already stopped has no effect.

Examples

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.
close(reason?: string): Promise<void>

Parameters

ParameterTypeRequiredDescription
reasonstringNoReason for closing the trace

Examples

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');
}
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.

isClosed()

Check if the trace has been closed.
isClosed(): boolean

Returns

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

Examples

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

Method Chaining

All builder methods return this, enabling fluent chaining:
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

Types

TypeScript type definitions

Examples

See complete usage examples