@miradorlabs/parallax-web 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,13 @@
9
9
  "Bash(chmod:*)",
10
10
  "Bash(gh pr view:*)",
11
11
  "Bash(gh api:*)",
12
- "Bash(npm run lint:*)"
12
+ "Bash(npm run lint:*)",
13
+ "Bash(gh pr diff:*)",
14
+ "Bash(npm pack:*)"
13
15
  ]
14
- }
16
+ },
17
+ "enableAllProjectMcpServers": true,
18
+ "enabledMcpjsonServers": [
19
+ "playwright"
20
+ ]
15
21
  }
package/CLAUDE.md ADDED
@@ -0,0 +1,56 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ Browser SDK for the Parallax tracing platform using gRPC-Web to communicate with the Parallax Gateway API. Published as `@miradorlabs/parallax-web`.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ npm run build # Build ESM, UMD, and type definitions via Rollup
13
+ npm test # Run Jest tests
14
+ npm run test:watch # Run tests in watch mode
15
+ npm run lint # Lint src/ and tests/
16
+ npm run lint:fix # Lint and auto-fix
17
+ ```
18
+
19
+ ## Architecture
20
+
21
+ ```
22
+ src/
23
+ ├── index.ts # Re-exports from parallax/
24
+ └── parallax/
25
+ ├── index.ts # Public exports
26
+ ├── client.ts # ParallaxClient - main entry point, holds gRPC client
27
+ ├── trace.ts # ParallaxTrace - fluent builder with flush logic
28
+ ├── types.ts # TypeScript interfaces (TraceOptions, ChainName, etc.)
29
+ └── metadata.ts # Browser metadata detection utilities
30
+ ```
31
+
32
+ ### Key Classes
33
+
34
+ **ParallaxClient** (`client.ts`)
35
+ - Creates gRPC-Web client for Parallax Gateway
36
+ - `trace(options?)` returns a `ParallaxTrace` builder
37
+ - `_sendTrace()` / `_updateTrace()` are internal methods called by trace
38
+
39
+ **ParallaxTrace** (`trace.ts`)
40
+ - Fluent builder: `addAttribute()`, `addEvent()`, `addTags()`, `addTxHint()`
41
+ - Manages pending state and flush queue for strict ordering
42
+ - `flush()` sends `CreateTrace` (first call) or `UpdateTrace` (subsequent)
43
+ - Auto-flush mode: debounced timer resets on each SDK call
44
+ - `flushPeriod: 0` means immediate flush on every call
45
+
46
+ ### Proto Dependency
47
+
48
+ The gRPC types come from `mirador-gateway-parallax-web` (private package). Key imports:
49
+ - `CreateTraceRequest`, `UpdateTraceRequest`, `TraceData`
50
+ - `Attributes`, `Tags`, `Event`, `TxHashHint`, `Chain`
51
+
52
+ ## Build Output
53
+
54
+ - `dist/index.esm.js` - ES modules
55
+ - `dist/index.umd.js` - UMD for browsers
56
+ - `dist/index.d.ts` - TypeScript declarations
package/README.md CHANGED
@@ -10,31 +10,69 @@ npm install @miradorlabs/parallax-web
10
10
 
11
11
  ## Features
12
12
 
13
- - **Fluent Builder Pattern** - Method chaining for creating traces
13
+ - **Auto-Flush Mode** - Data automatically batches and sends after a configurable period of inactivity
14
+ - **Fluent Builder Pattern** - Method chaining for building traces
14
15
  - **Browser-optimized** - Automatic client metadata collection (browser, OS, etc.)
15
16
  - **Blockchain Integration** - Built-in support for correlating traces with blockchain transactions
16
17
  - **TypeScript Support** - Full type definitions included
17
- - **Single Request** - All trace data submitted in one efficient gRPC call
18
+ - **Strict Ordering** - Flush calls maintain strict ordering even when async
18
19
 
19
- ## Quick Start
20
+ ## Quick Start (Auto-Flush - Default)
20
21
 
21
22
  ```typescript
22
23
  import { ParallaxClient } from '@miradorlabs/parallax-web';
23
24
 
24
- // API key is required, gateway URL is optional
25
25
  const client = new ParallaxClient('your-api-key');
26
26
 
27
- // Create and submit a trace
28
- const traceId = await client.trace('SwapExecution')
27
+ const trace = client.trace({ name: 'SwapExecution' })
29
28
  .addAttribute('from', '0xabc...')
30
- .addAttribute('slippage', { bps: 50, tolerance: 'auto' }) // objects are stringified
31
29
  .addTags(['dex', 'swap'])
32
- .addEvent('quote_received', { provider: 'Uniswap' })
33
- .addEvent('transaction_signed')
34
- .setTxHint('0xtxhash...', 'ethereum') // optional
35
- .create();
30
+ .addEvent('quote_received');
31
+ // → CreateTrace sent after 50ms of inactivity
36
32
 
37
- console.log('Trace ID:', traceId);
33
+ trace.addEvent('transaction_signed')
34
+ .addTxHint('0xtxhash...', 'ethereum');
35
+ // → UpdateTrace sent after 50ms of inactivity
36
+
37
+ // You can still call flush() explicitly to send immediately
38
+ trace.addEvent('confirmed');
39
+ trace.flush(); // → UpdateTrace sent immediately
40
+ ```
41
+
42
+ ## Manual Flush Mode
43
+
44
+ ```typescript
45
+ import { ParallaxClient } from '@miradorlabs/parallax-web';
46
+
47
+ const client = new ParallaxClient('your-api-key');
48
+
49
+ const trace = client.trace({ name: 'SwapExecution', autoFlush: false })
50
+ .addAttribute('from', '0xabc...')
51
+ .addTags(['dex', 'swap'])
52
+ .addEvent('quote_received');
53
+
54
+ trace.flush(); // → CreateTrace
55
+
56
+ trace.addEvent('transaction_signed')
57
+ .addTxHint('0xtxhash...', 'ethereum');
58
+
59
+ trace.flush(); // → UpdateTrace
60
+ ```
61
+
62
+ ## Immediate Flush Mode
63
+
64
+ Set `flushPeriodMs: 0` to flush immediately on every SDK call (no batching):
65
+
66
+ ```typescript
67
+ import { ParallaxClient } from '@miradorlabs/parallax-web';
68
+
69
+ const client = new ParallaxClient('your-api-key');
70
+
71
+ const trace = client.trace({ name: 'SwapExecution', flushPeriodMs: 0 })
72
+ .addAttribute('from', '0xabc...'); // → CreateTrace sent immediately
73
+
74
+ trace.addEvent('transaction_signed'); // → UpdateTrace sent immediately
75
+ trace.addTxHint('0x...', 'ethereum'); // → UpdateTrace sent immediately
38
76
  ```
39
77
 
40
78
  ## API Reference
@@ -46,36 +84,48 @@ The main client for interacting with the Parallax Gateway.
46
84
  #### Constructor
47
85
 
48
86
  ```typescript
49
- new ParallaxClient(apiKey: string, apiUrl?: string)
87
+ new ParallaxClient(apiKey: string, options?: ParallaxClientOptions)
50
88
  ```
51
89
 
52
90
  | Parameter | Type | Required | Description |
53
91
  |-----------|------|----------|-------------|
54
92
  | `apiKey` | `string` | Yes | API key for authentication (sent as `x-parallax-api-key` header) |
55
- | `apiUrl` | `string` | No | Gateway URL (defaults to `https://parallax-gateway.dev.mirador.org:443`) |
93
+ | `options` | `ParallaxClientOptions` | No | Configuration options |
94
+
95
+ #### Options
96
+
97
+ ```typescript
98
+ interface ParallaxClientOptions {
99
+ apiUrl?: string; // Gateway URL (defaults to parallax-gateway-dev.mirador.org:443)
100
+ }
101
+ ```
56
102
 
57
103
  #### Methods
58
104
 
59
- ##### `trace(name?, includeClientMeta?)`
105
+ ##### `trace(options?)`
60
106
 
61
107
  Creates a new trace builder.
62
108
 
63
109
  ```typescript
64
- const trace = client.trace('MyTrace'); // client metadata included by default
65
- const trace = client.trace(); // name is optional (defaults to empty string)
66
- // Or explicitly disable client metadata: client.trace('MyTrace', false)
110
+ const trace = client.trace({ name: 'MyTrace' });
111
+ const trace = client.trace({ name: 'MyTrace', autoFlush: false });
112
+ const trace = client.trace({ autoFlush: false, flushPeriodMs: 100 });
67
113
  ```
68
114
 
69
- | Parameter | Type | Default | Description |
70
- |-----------|------|---------|-------------|
71
- | `name` | `string` | `''` | Optional name of the trace |
115
+ | Option | Type | Default | Description |
116
+ |--------|------|---------|-------------|
117
+ | `name` | `string` | `undefined` | Optional name of the trace |
118
+ | `autoFlush` | `boolean` | `true` | Auto-flush after period of inactivity |
119
+ | `flushPeriodMs` | `number` | `50` | Debounce period in ms (0 = immediate flush on every call) |
72
120
  | `includeClientMeta` | `boolean` | `true` | Include browser/OS metadata |
121
+ | `maxRetries` | `number` | `3` | Maximum retry attempts on network failure |
122
+ | `retryBackoff` | `number` | `1000` | Base delay in ms for exponential backoff (doubles each retry) |
73
123
 
74
124
  Returns: `ParallaxTrace` builder instance
75
125
 
76
126
  ### ParallaxTrace (Builder)
77
127
 
78
- Fluent builder for constructing traces. All methods return `this` for chaining.
128
+ Fluent builder for constructing traces. All builder methods return `this` for chaining.
79
129
 
80
130
  #### `addAttribute(key, value)`
81
131
 
@@ -109,7 +159,7 @@ trace.addTag('transaction')
109
159
  .addTags(['ethereum', 'send'])
110
160
  ```
111
161
 
112
- #### `addEvent(name, details?)`
162
+ #### `addEvent(name, details?, timestamp?)`
113
163
 
114
164
  Add an event with optional details (string or object).
115
165
 
@@ -119,12 +169,13 @@ trace.addEvent('wallet_connected', { wallet: 'MetaMask' })
119
169
  .addEvent('transaction_confirmed', { blockNumber: 12345 })
120
170
  ```
121
171
 
122
- #### `setTxHint(txHash, chain, details?)`
172
+ #### `addTxHint(txHash, chain, details?)`
123
173
 
124
- Set the transaction hash hint for blockchain correlation.
174
+ Add a transaction hash hint for blockchain correlation. Multiple hints can be added.
125
175
 
126
176
  ```typescript
127
- trace.setTxHint('0x123...', 'ethereum', 'Main transaction')
177
+ trace.addTxHint('0x123...', 'ethereum', 'Main transaction')
178
+ .addTxHint('0x456...', 'polygon', 'Bridge transaction')
128
179
  ```
129
180
 
130
181
  | Parameter | Type | Description |
@@ -133,15 +184,26 @@ trace.setTxHint('0x123...', 'ethereum', 'Main transaction')
133
184
  | `chain` | `ChainName` | Chain name: 'ethereum' \| 'polygon' \| 'arbitrum' \| 'base' \| 'optimism' \| 'bsc' |
134
185
  | `details` | `string` | Optional details about the transaction |
135
186
 
136
- #### `create()`
187
+ #### `flush()`
137
188
 
138
- Submit the trace to the gateway.
189
+ Flush pending data to the gateway. Fire-and-forget - returns immediately but maintains strict ordering.
190
+
191
+ - First flush calls `CreateTrace`
192
+ - Subsequent flushes call `UpdateTrace`
139
193
 
140
194
  ```typescript
141
- const traceId = await trace.create();
195
+ trace.flush();
142
196
  ```
143
197
 
144
- Returns: `Promise<string | undefined>` - The trace ID if successful, undefined if failed
198
+ Returns: `void`
199
+
200
+ #### `getTraceId()`
201
+
202
+ Get the trace ID (available after first flush completes).
203
+
204
+ ```typescript
205
+ const traceId = trace.getTraceId(); // string | null
206
+ ```
145
207
 
146
208
  ## Complete Example: Transaction Tracking
147
209
 
@@ -151,34 +213,27 @@ import { ParallaxClient } from '@miradorlabs/parallax-web';
151
213
  const client = new ParallaxClient('your-api-key');
152
214
 
153
215
  async function handleWalletTransaction(userAddress: string, recipientAddress: string, amount: string) {
154
- // Build trace with all transaction details (client metadata included by default)
155
- const traceId = await client.trace('SendETH')
216
+ const trace = client.trace({ name: 'SendETH' })
156
217
  .addAttribute('from', userAddress)
157
218
  .addAttribute('to', recipientAddress)
158
219
  .addAttribute('value', amount)
159
- .addAttribute('network', 'ethereum')
160
220
  .addTags(['transaction', 'send', 'ethereum'])
161
- .addEvent('wallet_connected', { wallet: 'MetaMask' })
162
- .addEvent('transaction_initiated')
163
- .addEvent('user_signed')
164
- .addEvent('transaction_sent', {
165
- txHash: receipt.hash,
166
- blockNumber: receipt.blockNumber,
167
- gasUsed: receipt.gasUsed,
168
- success: true
169
- })
170
- .setTxHint(receipt.hash, 'ethereum')
171
- .create();
172
-
173
- if (traceId) {
174
- console.log('Trace ID:', traceId);
175
- }
221
+ .addEvent('wallet_connected', { wallet: 'MetaMask' });
222
+ // → CreateTrace sent automatically
223
+
224
+ trace.addEvent('user_signed');
225
+
226
+ const receipt = await sendTransaction();
227
+
228
+ trace.addEvent('transaction_sent', { txHash: receipt.hash })
229
+ .addTxHint(receipt.hash, 'ethereum');
230
+ // → UpdateTrace sent automatically
176
231
  }
177
232
  ```
178
233
 
179
234
  ## Automatic Client Metadata Collection
180
235
 
181
- When `includeClientMeta: true` is set, the SDK automatically collects:
236
+ When `includeClientMeta: true` is set (default), the SDK automatically collects:
182
237
 
183
238
  | Metadata | Description |
184
239
  |----------|-------------|
@@ -219,6 +274,8 @@ Full TypeScript support with exported types:
219
274
  import {
220
275
  ParallaxClient,
221
276
  ParallaxTrace,
277
+ ParallaxClientOptions,
278
+ TraceOptions,
222
279
  ChainName, // 'ethereum' | 'polygon' | 'arbitrum' | 'base' | 'optimism' | 'bsc'
223
280
  } from '@miradorlabs/parallax-web';
224
281
  ```
package/dist/index.d.ts CHANGED
@@ -1,7 +1,34 @@
1
1
  import * as mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
2
- import { CreateTraceRequest, CreateTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
2
+ import { CreateTraceRequest, CreateTraceResponse, UpdateTraceRequest, UpdateTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
3
3
  export { CreateTraceRequest, CreateTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
4
4
 
5
+ /**
6
+ * TypeScript interfaces for the Parallax SDK
7
+ */
8
+ /**
9
+ * Options for ParallaxClient constructor
10
+ */
11
+ interface ParallaxClientOptions {
12
+ /** Gateway URL (defaults to parallax-gateway-dev.mirador.org:443) */
13
+ apiUrl?: string;
14
+ }
15
+ /**
16
+ * Options for creating a trace
17
+ */
18
+ interface TraceOptions {
19
+ /** Trace name */
20
+ name?: string;
21
+ /** Enable auto-flush mode (default: true) */
22
+ autoFlush?: boolean;
23
+ /** Debounce period in ms before auto-flush triggers (default: 50) */
24
+ flushPeriodMs?: number;
25
+ /** Include browser/OS metadata in first flush (default: true) */
26
+ includeClientMeta?: boolean;
27
+ /** Maximum number of retry attempts on failure (default: 3) */
28
+ maxRetries?: number;
29
+ /** Base delay in ms for exponential backoff between retries (default: 1000) */
30
+ retryBackoff?: number;
31
+ }
5
32
  /**
6
33
  * Supported chain names (maps to Chain enum in proto)
7
34
  */
@@ -17,20 +44,44 @@ type ChainName = 'ethereum' | 'polygon' | 'arbitrum' | 'base' | 'optimism' | 'bs
17
44
  */
18
45
  interface TraceSubmitter {
19
46
  _sendTrace(request: CreateTraceRequest): Promise<CreateTraceResponse>;
47
+ _updateTrace(request: UpdateTraceRequest): Promise<UpdateTraceResponse>;
48
+ }
49
+ /** Options passed to ParallaxTrace constructor (with defaults applied) */
50
+ interface ResolvedTraceOptions {
51
+ name?: string;
52
+ autoFlush: boolean;
53
+ flushPeriodMs: number;
54
+ includeClientMeta: boolean;
55
+ maxRetries: number;
56
+ retryBackoff: number;
20
57
  }
21
58
  /**
22
- * Builder class for constructing traces with method chaining
23
- * Automatically handles web-specific features like client metadata
59
+ * Builder class for constructing traces with method chaining.
60
+ * Supports auto-flush mode (default) where data is automatically sent after a period of inactivity,
61
+ * or manual flush mode where you explicitly call flush().
24
62
  */
25
63
  declare class ParallaxTrace {
26
- private name;
27
- private attributes;
28
- private tags;
29
- private events;
30
- private txHashHint?;
64
+ private name?;
31
65
  private client;
32
66
  private includeClientMeta;
33
- constructor(client: TraceSubmitter, name?: string, includeClientMeta?: boolean);
67
+ private autoFlush;
68
+ private flushPeriodMs;
69
+ private flushTimer;
70
+ private maxRetries;
71
+ private retryBackoff;
72
+ private traceId;
73
+ private pendingAttributes;
74
+ private pendingTags;
75
+ private pendingEvents;
76
+ private pendingTxHashHints;
77
+ private flushQueue;
78
+ constructor(client: TraceSubmitter, options: ResolvedTraceOptions);
79
+ /**
80
+ * Schedule an auto-flush after the configured period.
81
+ * Resets the timer on each call.
82
+ * If flushPeriodMs is 0, flushes immediately on every call.
83
+ */
84
+ private scheduleFlush;
34
85
  /**
35
86
  * Add an attribute to the trace
36
87
  * @param key Attribute key
@@ -67,18 +118,49 @@ declare class ParallaxTrace {
67
118
  */
68
119
  addEvent(eventName: string, details?: string | object, timestamp?: Date): this;
69
120
  /**
70
- * Set the transaction hash hint for blockchain correlation
121
+ * Add a transaction hash hint for blockchain correlation.
122
+ * Multiple hints can be added to the same trace.
71
123
  * @param txHash Transaction hash
72
124
  * @param chain Chain name (e.g., "ethereum", "polygon", "base")
73
125
  * @param details Optional details about the transaction
74
126
  * @returns This trace builder for chaining
75
127
  */
76
- setTxHint(txHash: string, chain: ChainName, details?: string): this;
128
+ addTxHint(txHash: string, chain: ChainName, details?: string): this;
129
+ /**
130
+ * Flush pending data to the gateway.
131
+ * Fire-and-forget - returns immediately but maintains strict ordering of requests.
132
+ * First flush calls CreateTrace, subsequent flushes call UpdateTrace.
133
+ */
134
+ flush(): void;
135
+ /**
136
+ * Build TraceData from pending state
137
+ */
138
+ private buildTraceData;
139
+ /**
140
+ * Sleep for the specified duration
141
+ */
142
+ private sleep;
143
+ /**
144
+ * Execute an operation with exponential backoff retry
145
+ */
146
+ private retryWithBackoff;
147
+ /**
148
+ * Send CreateTrace request
149
+ */
150
+ private createTrace;
77
151
  /**
78
- * Create and submit the trace to the gateway
79
- * @returns The trace ID if successful, undefined if failed
152
+ * Send UpdateTrace request
80
153
  */
81
- create(): Promise<string | undefined>;
154
+ private updateTrace;
155
+ /**
156
+ * Clear all pending data
157
+ */
158
+ private clearPending;
159
+ /**
160
+ * Get the trace ID (available after first flush completes)
161
+ * @returns The trace ID or null if not yet created
162
+ */
163
+ getTraceId(): string | null;
82
164
  }
83
165
 
84
166
  /**
@@ -91,35 +173,20 @@ declare class ParallaxClient {
91
173
  /**
92
174
  * Create a new ParallaxClient instance
93
175
  * @param apiKey Required API key for authentication (sent as x-parallax-api-key header)
94
- * @param apiUrl Optional gateway URL (defaults to parallax-gateway.dev.mirador.org:443)
95
- */
96
- constructor(apiKey: string, apiUrl?: string);
97
- /**
98
- * Internal method to send trace to gateway
99
- * @internal
176
+ * @param options Optional configuration options
100
177
  */
178
+ constructor(apiKey: string, options?: ParallaxClientOptions);
179
+ /** @internal */
101
180
  _sendTrace(request: CreateTraceRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.CreateTraceResponse>;
181
+ /** @internal */
182
+ _updateTrace(request: UpdateTraceRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.UpdateTraceResponse>;
102
183
  /**
103
184
  * Create a new trace builder
104
185
  *
105
- * Example usage:
106
- * ```typescript
107
- * const response = await client.trace("swap_execution")
108
- * .addAttribute("user", "0xabc...")
109
- * .addAttribute("slippage_bps", 25)
110
- * .addTag("dex")
111
- * .addTag("swap")
112
- * .addEvent("wallet_connected", { wallet: "MetaMask" })
113
- * .addEvent("quote_received")
114
- * .setTxHint("0x123...", "ethereum")
115
- * .create();
116
- * ```
117
- *
118
- * @param name Optional name of the trace (defaults to empty string)
119
- * @param includeClientMeta Optional flag to automatically include client metadata
186
+ * @param options Trace configuration options
120
187
  * @returns A ParallaxTrace builder instance
121
188
  */
122
- trace(name?: string, includeClientMeta?: boolean): ParallaxTrace;
189
+ trace(options?: TraceOptions): ParallaxTrace;
123
190
  }
124
191
 
125
192
  export { ParallaxClient, ParallaxTrace };