@miradorlabs/parallax-web 1.0.7 → 2.0.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.
- package/.claude/settings.local.json +15 -0
- package/.github/dependabot.yml +39 -0
- package/.github/workflows/pr.yml +33 -0
- package/README.md +145 -280
- package/dist/index.d.ts +56 -214
- package/dist/index.esm.js +760 -1049
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +764 -1054
- package/dist/index.umd.js.map +1 -1
- package/example/proxy-server.js +1 -1
- package/index.ts +2 -5
- package/package.json +4 -2
- package/scripts/release.sh +109 -0
- package/src/index.ts +2 -0
- package/src/parallax/client.ts +66 -0
- package/src/parallax/index.ts +22 -372
- package/src/parallax/metadata.ts +173 -0
- package/src/parallax/trace.ts +209 -0
- package/src/parallax/types.ts +73 -0
- package/tests/parallax.test.ts +395 -372
- package/SETUP.md +0 -220
- package/src/grpc/index.ts +0 -155
- package/src/helpers/index.ts +0 -13
- package/src/parallax/ParallaxService.ts +0 -296
package/SETUP.md
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
# Web Parallax Client Setup Summary
|
|
2
|
-
|
|
3
|
-
This document summarizes the complete configuration and structure of the web-parallax-client SDK.
|
|
4
|
-
|
|
5
|
-
## Directory Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
web-parallax-client/
|
|
9
|
-
├── dist/ # Build output (generated)
|
|
10
|
-
│ ├── index.esm.js # ES Module bundle
|
|
11
|
-
│ ├── index.esm.js.map # ESM source map
|
|
12
|
-
│ ├── index.umd.js # UMD bundle (browser global)
|
|
13
|
-
│ ├── index.umd.js.map # UMD source map
|
|
14
|
-
│ └── index.d.ts # TypeScript declarations
|
|
15
|
-
├── src/
|
|
16
|
-
│ ├── grpc/
|
|
17
|
-
│ │ └── index.ts # GrpcWebRpc adapter (uses Fetch API)
|
|
18
|
-
│ ├── parallax/
|
|
19
|
-
│ │ └── index.ts # ParallaxClient main class
|
|
20
|
-
│ └── helpers/
|
|
21
|
-
│ └── index.ts # Serialization helpers
|
|
22
|
-
├── tests/
|
|
23
|
-
│ └── parallax.test.ts # Jest unit tests
|
|
24
|
-
├── index.ts # Main entry point
|
|
25
|
-
├── package.json # NPM package configuration
|
|
26
|
-
├── tsconfig.json # TypeScript config (dev)
|
|
27
|
-
├── tsconfig.build.json # TypeScript config (build)
|
|
28
|
-
├── rollup.config.mjs # Rollup bundler configuration
|
|
29
|
-
├── jest.config.ts # Jest test configuration
|
|
30
|
-
├── eslint.config.js # ESLint configuration
|
|
31
|
-
├── .prettierrc # Prettier configuration
|
|
32
|
-
├── .nvmrc # Node version (22.13.0)
|
|
33
|
-
├── .gitignore # Git ignore rules
|
|
34
|
-
└── README.md # User documentation
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Key Configuration Files
|
|
38
|
-
|
|
39
|
-
### package.json
|
|
40
|
-
|
|
41
|
-
- **Name**: `@miradorlabs/parallax-web`
|
|
42
|
-
- **Main Entry Points**:
|
|
43
|
-
- `main`: `dist/index.umd.js` (UMD for Node.js/CommonJS)
|
|
44
|
-
- `module`: `dist/index.esm.js` (ES Module for bundlers)
|
|
45
|
-
- `browser`: `dist/index.umd.js` (Browser global)
|
|
46
|
-
- `types`: `dist/index.d.ts` (TypeScript definitions)
|
|
47
|
-
- **Dependencies**:
|
|
48
|
-
- `google-protobuf`: ^4.0.1
|
|
49
|
-
- `mirador-gateway-parallax-web`: grpc-web package from GCS
|
|
50
|
-
- `rxjs`: ^7.8.2
|
|
51
|
-
- **Scripts**:
|
|
52
|
-
- `build`: Build all bundles with Rollup
|
|
53
|
-
- `test`: Run Jest tests
|
|
54
|
-
- `test:watch`: Run Jest in watch mode
|
|
55
|
-
- `test:coverage`: Generate coverage report
|
|
56
|
-
|
|
57
|
-
### rollup.config.mjs
|
|
58
|
-
|
|
59
|
-
Generates three outputs:
|
|
60
|
-
|
|
61
|
-
1. **ESM Bundle** (`dist/index.esm.js`)
|
|
62
|
-
- Format: ES Module
|
|
63
|
-
- For modern bundlers (Webpack, Vite, etc.)
|
|
64
|
-
|
|
65
|
-
2. **UMD Bundle** (`dist/index.umd.js`)
|
|
66
|
-
- Format: UMD
|
|
67
|
-
- Global name: `ParallaxWeb`
|
|
68
|
-
- For browser `<script>` tags
|
|
69
|
-
|
|
70
|
-
3. **Type Definitions** (`dist/index.d.ts`)
|
|
71
|
-
- TypeScript declarations
|
|
72
|
-
|
|
73
|
-
All bundles treat external dependencies as external:
|
|
74
|
-
- `google-protobuf`
|
|
75
|
-
- `mirador-gateway-parallax-web/*`
|
|
76
|
-
- `rxjs/*`
|
|
77
|
-
|
|
78
|
-
### tsconfig.json
|
|
79
|
-
|
|
80
|
-
- Target: ES2020
|
|
81
|
-
- Module: ESNext (for browser)
|
|
82
|
-
- Lib: ES2020, DOM, DOM.Iterable
|
|
83
|
-
- Strict mode enabled
|
|
84
|
-
- Module resolution: bundler
|
|
85
|
-
|
|
86
|
-
### jest.config.ts
|
|
87
|
-
|
|
88
|
-
- Preset: ts-jest
|
|
89
|
-
- Test environment: **jsdom** (browser simulation)
|
|
90
|
-
- Test match: `**/*.test.ts`
|
|
91
|
-
- Coverage from `src/**/*.ts`
|
|
92
|
-
|
|
93
|
-
## Key Differences from nodejs-parallax-client
|
|
94
|
-
|
|
95
|
-
| Feature | nodejs-parallax-client | web-parallax-client |
|
|
96
|
-
|---------|------------------------|---------------------|
|
|
97
|
-
| gRPC Library | `@grpc/grpc-js` | Fetch API (gRPC-Web compatible) |
|
|
98
|
-
| Transport | Native gRPC | HTTP/HTTPS with gRPC-Web protocol |
|
|
99
|
-
| Environment | Node.js | Browser |
|
|
100
|
-
| Module System | CommonJS | ESM + UMD |
|
|
101
|
-
| Test Environment | Node | jsdom (browser) |
|
|
102
|
-
| Connection | Can use insecure | Always uses HTTPS |
|
|
103
|
-
| Default URL | localhost:50053 | https://gateway-parallax-dev... |
|
|
104
|
-
|
|
105
|
-
## Source Files
|
|
106
|
-
|
|
107
|
-
### src/grpc/index.ts - GrpcWebRpc
|
|
108
|
-
|
|
109
|
-
Implements the gRPC-Web RPC adapter using browser Fetch API:
|
|
110
|
-
|
|
111
|
-
- **Unary requests**: Standard HTTP POST with protobuf binary body
|
|
112
|
-
- **Server streaming**: Uses ReadableStream from Response.body
|
|
113
|
-
- **Headers**: Includes `Content-Type: application/grpc-web+proto`
|
|
114
|
-
- **API Key**: Sent as `x-api-key` header
|
|
115
|
-
- **Type casting**: `data.buffer as ArrayBuffer` for Fetch compatibility
|
|
116
|
-
|
|
117
|
-
### src/parallax/index.ts - ParallaxClient
|
|
118
|
-
|
|
119
|
-
Main SDK client with methods:
|
|
120
|
-
- `createTrace()`: Create a new trace
|
|
121
|
-
- `startSpan()`: Start a span within a trace
|
|
122
|
-
- `finishSpan()`: Finish a span
|
|
123
|
-
- `addSpanAttributes()`: Add attributes to a span
|
|
124
|
-
- `addSpanEvent()`: Add an event to a span
|
|
125
|
-
- `addSpanError()`: Add an error to a span
|
|
126
|
-
- `addSpanHint()`: Add a blockchain transaction hint
|
|
127
|
-
|
|
128
|
-
### tests/parallax.test.ts
|
|
129
|
-
|
|
130
|
-
Comprehensive test suite covering:
|
|
131
|
-
- Client instantiation
|
|
132
|
-
- All SDK methods (success and error cases)
|
|
133
|
-
- Integration scenarios
|
|
134
|
-
- API key handling
|
|
135
|
-
- Mock implementation of GrpcWebRpc
|
|
136
|
-
|
|
137
|
-
## Build Process
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
npm run build
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
1. Clears `dist/` directory
|
|
144
|
-
2. Runs Rollup with three configurations in parallel:
|
|
145
|
-
- ESM bundle with source maps
|
|
146
|
-
- UMD bundle with source maps
|
|
147
|
-
- TypeScript declarations
|
|
148
|
-
|
|
149
|
-
Build warnings about `mirador-gateway-parallax-web` imports are **expected** - these are external dependencies resolved at runtime.
|
|
150
|
-
|
|
151
|
-
## Testing
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
npm test # Run all tests
|
|
155
|
-
npm run test:watch # Watch mode
|
|
156
|
-
npm run test:coverage # Generate coverage report
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Tests use:
|
|
160
|
-
- **jsdom**: Simulates browser environment
|
|
161
|
-
- **ts-jest**: TypeScript transformation
|
|
162
|
-
- **Mocking**: GrpcWebRpc is mocked for unit tests
|
|
163
|
-
|
|
164
|
-
## Publishing
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
npm run release:patch # Bump patch version (1.0.0 -> 1.0.1)
|
|
168
|
-
npm run release:minor # Bump minor version (1.0.0 -> 1.1.0)
|
|
169
|
-
npm run release:major # Bump major version (1.0.0 -> 2.0.0)
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
Versioning automatically:
|
|
173
|
-
1. Updates `package.json` version
|
|
174
|
-
2. Creates git tag
|
|
175
|
-
3. Pushes with `--follow-tags`
|
|
176
|
-
|
|
177
|
-
## Browser Compatibility
|
|
178
|
-
|
|
179
|
-
Requires modern browsers supporting:
|
|
180
|
-
- ES2020 features
|
|
181
|
-
- Fetch API
|
|
182
|
-
- Promises
|
|
183
|
-
- ReadableStream
|
|
184
|
-
- Uint8Array
|
|
185
|
-
|
|
186
|
-
For older browsers, polyfills may be needed.
|
|
187
|
-
|
|
188
|
-
## Usage in Browser
|
|
189
|
-
|
|
190
|
-
### Via NPM/Bundler (Recommended)
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
import { ParallaxClient } from '@miradorlabs/parallax-web';
|
|
194
|
-
|
|
195
|
-
const client = new ParallaxClient('your-api-key');
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Via UMD Script Tag
|
|
199
|
-
|
|
200
|
-
```html
|
|
201
|
-
<script src="node_modules/@miradorlabs/parallax-web/dist/index.umd.js"></script>
|
|
202
|
-
<script>
|
|
203
|
-
const client = new ParallaxWeb.ParallaxClient('your-api-key');
|
|
204
|
-
</script>
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Next Steps
|
|
208
|
-
|
|
209
|
-
1. **Install dependencies**: Already done (`npm install`)
|
|
210
|
-
2. **Build**: Already done (`npm run build`)
|
|
211
|
-
3. **Test**: Run `npm test` to verify all tests pass
|
|
212
|
-
4. **Customize**: Update `GRPC_GATEWAY_API_URL` in `src/parallax/index.ts` if needed
|
|
213
|
-
5. **Publish**: When ready, use `npm run release:patch` to version and publish
|
|
214
|
-
|
|
215
|
-
## Notes
|
|
216
|
-
|
|
217
|
-
- The package uses the grpc-web package from GCS: `mirador-gateway-parallax-grpc-web-1.0.9.tgz`
|
|
218
|
-
- Type warnings during build about missing type declarations are expected for external packages
|
|
219
|
-
- All gRPC-Web requests use the browser's Fetch API, making this SDK compatible with modern web applications
|
|
220
|
-
- The SDK maintains the same API surface as the Node.js client for consistency
|
package/src/grpc/index.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { Observable } from "rxjs";
|
|
2
|
-
|
|
3
|
-
interface Metadata {
|
|
4
|
-
[key: string]: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface Rpc {
|
|
8
|
-
request(
|
|
9
|
-
service: string,
|
|
10
|
-
method: string,
|
|
11
|
-
data: Uint8Array,
|
|
12
|
-
metadata?: Metadata
|
|
13
|
-
): Promise<Uint8Array>;
|
|
14
|
-
clientStreamingRequest(
|
|
15
|
-
service: string,
|
|
16
|
-
method: string,
|
|
17
|
-
data: Observable<Uint8Array>
|
|
18
|
-
): Promise<Uint8Array>;
|
|
19
|
-
serverStreamingRequest(
|
|
20
|
-
service: string,
|
|
21
|
-
method: string,
|
|
22
|
-
data: Uint8Array
|
|
23
|
-
): Observable<Uint8Array>;
|
|
24
|
-
bidirectionalStreamingRequest(
|
|
25
|
-
service: string,
|
|
26
|
-
method: string,
|
|
27
|
-
data: Observable<Uint8Array>
|
|
28
|
-
): Observable<Uint8Array>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export class GrpcWebRpc implements Rpc {
|
|
32
|
-
private url: string;
|
|
33
|
-
private apiKey?: string;
|
|
34
|
-
|
|
35
|
-
constructor(url: string, apiKey?: string) {
|
|
36
|
-
this.url = url;
|
|
37
|
-
this.apiKey = apiKey;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async request(
|
|
41
|
-
service: string,
|
|
42
|
-
method: string,
|
|
43
|
-
data: Uint8Array,
|
|
44
|
-
metadata?: Metadata
|
|
45
|
-
): Promise<Uint8Array> {
|
|
46
|
-
console.log(`[gRPC-Web] Making request to ${this.url}/${service}/${method}`);
|
|
47
|
-
|
|
48
|
-
const headers: HeadersInit = {
|
|
49
|
-
'Content-Type': 'application/grpc-web+proto',
|
|
50
|
-
'X-Grpc-Web': '1',
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Add API key to headers if provided
|
|
54
|
-
if (this.apiKey) {
|
|
55
|
-
headers['x-api-key'] = this.apiKey;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Add custom metadata
|
|
59
|
-
if (metadata) {
|
|
60
|
-
Object.entries(metadata).forEach(([key, value]) => {
|
|
61
|
-
headers[key] = value;
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
const response = await fetch(`${this.url}/${service}/${method}`, {
|
|
67
|
-
method: 'POST',
|
|
68
|
-
headers,
|
|
69
|
-
body: data.buffer as ArrayBuffer,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
if (!response.ok) {
|
|
73
|
-
const errorText = await response.text();
|
|
74
|
-
throw new Error(`gRPC-Web error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
78
|
-
console.log(`[gRPC-Web] Success from ${this.url}/${service}/${method}`);
|
|
79
|
-
return new Uint8Array(arrayBuffer);
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.error(
|
|
82
|
-
`[gRPC-Web] Error from ${this.url}/${service}/${method}:`,
|
|
83
|
-
error instanceof Error ? error.message : String(error)
|
|
84
|
-
);
|
|
85
|
-
throw error;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
clientStreamingRequest(): Promise<Uint8Array> {
|
|
90
|
-
throw new Error("Client streaming not yet implemented for gRPC-Web");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
serverStreamingRequest(
|
|
94
|
-
service: string,
|
|
95
|
-
method: string,
|
|
96
|
-
data: Uint8Array
|
|
97
|
-
): Observable<Uint8Array> {
|
|
98
|
-
return new Observable((subscriber) => {
|
|
99
|
-
const headers: HeadersInit = {
|
|
100
|
-
'Content-Type': 'application/grpc-web+proto',
|
|
101
|
-
'X-Grpc-Web': '1',
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// Add API key to headers if provided
|
|
105
|
-
if (this.apiKey) {
|
|
106
|
-
headers['x-api-key'] = this.apiKey;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
fetch(`${this.url}/${service}/${method}`, {
|
|
110
|
-
method: 'POST',
|
|
111
|
-
headers,
|
|
112
|
-
body: data.buffer as ArrayBuffer,
|
|
113
|
-
})
|
|
114
|
-
.then(async (response) => {
|
|
115
|
-
if (!response.ok) {
|
|
116
|
-
throw new Error(`gRPC-Web error: ${response.status} ${response.statusText}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (!response.body) {
|
|
120
|
-
throw new Error('Response body is null');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const reader = response.body.getReader();
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
while (true) {
|
|
127
|
-
const { done, value } = await reader.read();
|
|
128
|
-
|
|
129
|
-
if (done) {
|
|
130
|
-
subscriber.complete();
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (value) {
|
|
135
|
-
subscriber.next(value);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
} catch (error) {
|
|
139
|
-
subscriber.error(error);
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
.catch((error) => {
|
|
143
|
-
subscriber.error(error);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
return () => {
|
|
147
|
-
// Cleanup logic if needed
|
|
148
|
-
};
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
bidirectionalStreamingRequest(): Observable<Uint8Array> {
|
|
153
|
-
throw new Error("Bidirectional streaming not yet implemented for gRPC-Web");
|
|
154
|
-
}
|
|
155
|
-
}
|
package/src/helpers/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Helper serialization functions for browser environment
|
|
2
|
-
function serialize(value: Uint8Array): Uint8Array {
|
|
3
|
-
return value;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
function deserialize(bytes: Uint8Array): Uint8Array {
|
|
7
|
-
return bytes;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
deserialize,
|
|
12
|
-
serialize
|
|
13
|
-
}
|
|
@@ -1,296 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parallax Service - Transaction Tracing for Web Applications
|
|
3
|
-
* Creates individual traces for each transaction and tracks them through their lifecycle
|
|
4
|
-
*
|
|
5
|
-
* This service provides a simplified interface for tracking transactions with automatic
|
|
6
|
-
* client metadata collection and lifecycle management.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { ParallaxClient } from './index';
|
|
10
|
-
import type {
|
|
11
|
-
CreateTraceResponse,
|
|
12
|
-
} from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
|
|
13
|
-
|
|
14
|
-
interface TransactionInfo {
|
|
15
|
-
traceId: string;
|
|
16
|
-
timestamp: string;
|
|
17
|
-
txHash: string | null;
|
|
18
|
-
from?: string;
|
|
19
|
-
to?: string;
|
|
20
|
-
network?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface TransactionData {
|
|
24
|
-
from: string;
|
|
25
|
-
to: string;
|
|
26
|
-
value: string;
|
|
27
|
-
network?: string;
|
|
28
|
-
walletAddress?: string;
|
|
29
|
-
additionalData?: Record<string, any>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface FinishOptions {
|
|
33
|
-
success: boolean;
|
|
34
|
-
error?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class ParallaxService {
|
|
38
|
-
private client: ParallaxClient | null = null;
|
|
39
|
-
private activeTransactions: Map<string, TransactionInfo> = new Map();
|
|
40
|
-
|
|
41
|
-
constructor() {
|
|
42
|
-
// Client will be initialized lazily
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Initialize the Parallax client (lazy initialization)
|
|
47
|
-
* @param apiKey - Optional API key for authentication
|
|
48
|
-
* @param gatewayUrl - Optional custom gateway URL
|
|
49
|
-
*/
|
|
50
|
-
private _ensureClient(apiKey?: string, gatewayUrl?: string): void {
|
|
51
|
-
if (this.client) return;
|
|
52
|
-
|
|
53
|
-
// Determine gateway URL based on environment if not provided
|
|
54
|
-
let url = gatewayUrl;
|
|
55
|
-
if (!url && typeof window !== 'undefined') {
|
|
56
|
-
const isDevelopment =
|
|
57
|
-
window.location.hostname === 'localhost' ||
|
|
58
|
-
window.location.hostname === '127.0.0.1';
|
|
59
|
-
|
|
60
|
-
url = isDevelopment
|
|
61
|
-
? `${window.location.protocol}//${window.location.host}/parallax-gateway`
|
|
62
|
-
: 'https://gateway-parallax-dev.mirador.org';
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
this.client = new ParallaxClient(apiKey || '', url);
|
|
66
|
-
console.log('[ParallaxService] Client initialized with URL:', url);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Start a new transaction trace
|
|
71
|
-
* Called when user initiates a transaction
|
|
72
|
-
*
|
|
73
|
-
* Uses the builder pattern to create a trace with events
|
|
74
|
-
*
|
|
75
|
-
* @param txData - Transaction data
|
|
76
|
-
* @param name - Name for the trace (e.g., 'SendingTrace', 'SwappingTrace')
|
|
77
|
-
* @param options - Optional configuration (apiKey, gatewayUrl, includeClientMeta)
|
|
78
|
-
* @returns Promise with traceId, rootSpanId, and txId
|
|
79
|
-
*/
|
|
80
|
-
async startTransactionTrace(
|
|
81
|
-
txData: TransactionData,
|
|
82
|
-
name: string = 'WalletTransaction',
|
|
83
|
-
options?: { apiKey?: string; gatewayUrl?: string; includeClientMeta?: boolean }
|
|
84
|
-
): Promise<{ traceId: string; rootSpanId: string; txId: string }> {
|
|
85
|
-
this._ensureClient(options?.apiKey, options?.gatewayUrl);
|
|
86
|
-
|
|
87
|
-
if (!this.client) {
|
|
88
|
-
throw new Error('Failed to initialize Parallax client');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
const txId = `tx_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
93
|
-
const timestamp = new Date();
|
|
94
|
-
|
|
95
|
-
// Build the trace using the builder pattern
|
|
96
|
-
const builder = this.client
|
|
97
|
-
.trace(name, options?.includeClientMeta ?? true)
|
|
98
|
-
.addAttribute('transactionId', txId)
|
|
99
|
-
.addAttribute('walletAddress', txData.walletAddress || txData.from)
|
|
100
|
-
.addAttribute('network', txData.network || 'Unknown')
|
|
101
|
-
.addAttribute('transactionStart', timestamp.toISOString())
|
|
102
|
-
.addAttribute('from', txData.from)
|
|
103
|
-
.addAttribute('to', txData.to)
|
|
104
|
-
.addAttribute('value', txData.value)
|
|
105
|
-
.addTags(['transaction', 'wallet', txData.network || 'unknown'])
|
|
106
|
-
.addEvent('transaction_initiated', {
|
|
107
|
-
from: txData.from,
|
|
108
|
-
to: txData.to,
|
|
109
|
-
value: txData.value,
|
|
110
|
-
timestamp: timestamp.toISOString(),
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Add any additional transaction data as attributes
|
|
114
|
-
if (txData.additionalData) {
|
|
115
|
-
Object.entries(txData.additionalData).forEach(([key, value]) => {
|
|
116
|
-
builder.addAttribute(key, typeof value === 'object' ? JSON.stringify(value) : String(value));
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Submit the trace
|
|
121
|
-
const traceResponse: CreateTraceResponse = await builder.submit();
|
|
122
|
-
const traceId = traceResponse.getTraceId();
|
|
123
|
-
|
|
124
|
-
// Store transaction info
|
|
125
|
-
this.activeTransactions.set(txId, {
|
|
126
|
-
traceId,
|
|
127
|
-
timestamp: timestamp.toISOString(),
|
|
128
|
-
txHash: null,
|
|
129
|
-
from: txData.from,
|
|
130
|
-
to: txData.to,
|
|
131
|
-
network: txData.network,
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
console.log('[ParallaxService] Transaction trace started:', {
|
|
135
|
-
txId,
|
|
136
|
-
traceId,
|
|
137
|
-
from: txData.from,
|
|
138
|
-
to: txData.to,
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
return { traceId, rootSpanId: traceId, txId };
|
|
142
|
-
} catch (error) {
|
|
143
|
-
console.error('[ParallaxService] Failed to start transaction trace:', error);
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Associate a transaction hash with an existing trace
|
|
150
|
-
* Called when the transaction hash is available after signing/sending
|
|
151
|
-
*
|
|
152
|
-
* NOTE: This method is deprecated as the new API does not support adding hints to existing traces.
|
|
153
|
-
* Transaction hashes should be provided at trace creation time via the builder's submit(txHash, chainId) method.
|
|
154
|
-
*
|
|
155
|
-
* @param txId - Transaction identifier returned from startTransactionTrace
|
|
156
|
-
* @param txHash - Blockchain transaction hash
|
|
157
|
-
* @param chainId - Chain ID
|
|
158
|
-
* @deprecated Use submit(txHash, chainId) when creating the trace instead
|
|
159
|
-
*/
|
|
160
|
-
async associateTransactionHash(txId: string, txHash: string, chainId: number): Promise<void> {
|
|
161
|
-
const txInfo = this.activeTransactions.get(txId);
|
|
162
|
-
if (!txInfo) {
|
|
163
|
-
console.warn(`[ParallaxService] Transaction ${txId} not found in active transactions`);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Update stored tx info
|
|
168
|
-
txInfo.txHash = txHash;
|
|
169
|
-
this.activeTransactions.set(txId, txInfo);
|
|
170
|
-
|
|
171
|
-
console.warn('[ParallaxService] associateTransactionHash is deprecated. The new API does not support adding transaction hashes after trace creation. Please provide the txHash when creating the trace using submit(txHash, chainId).');
|
|
172
|
-
console.log('[ParallaxService] Transaction hash updated in local cache:', {
|
|
173
|
-
txId,
|
|
174
|
-
txHash,
|
|
175
|
-
traceId: txInfo.traceId,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Add an event to a transaction trace
|
|
181
|
-
*
|
|
182
|
-
* NOTE: This method is deprecated as the new API does not support adding events to existing traces.
|
|
183
|
-
* Events should be added to the trace builder before calling submit().
|
|
184
|
-
*
|
|
185
|
-
* @param txId - Transaction identifier
|
|
186
|
-
* @param eventName - Event name
|
|
187
|
-
* @param attributes - Event attributes
|
|
188
|
-
* @deprecated Use the trace builder's addEvent() method before calling submit() instead
|
|
189
|
-
*/
|
|
190
|
-
async addTransactionEvent(
|
|
191
|
-
txId: string,
|
|
192
|
-
eventName: string,
|
|
193
|
-
attributes: Record<string, any> = {}
|
|
194
|
-
): Promise<void> {
|
|
195
|
-
const txInfo = this.activeTransactions.get(txId);
|
|
196
|
-
if (!txInfo) {
|
|
197
|
-
console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot add event '${eventName}'`);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
console.warn('[ParallaxService] addTransactionEvent is deprecated. The new API does not support adding events after trace creation. Events should be added using the builder pattern before calling submit().');
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Add an error to a transaction trace
|
|
206
|
-
*
|
|
207
|
-
* NOTE: This method is deprecated as the new API does not support adding errors to existing traces.
|
|
208
|
-
* Errors should be added as events to the trace builder before calling submit().
|
|
209
|
-
*
|
|
210
|
-
* @param txId - Transaction identifier
|
|
211
|
-
* @param error - Error object or message
|
|
212
|
-
* @param errorType - Type/category of error (e.g., 'TransactionError', 'NetworkError', 'UserRejection')
|
|
213
|
-
* @deprecated Use the trace builder's addEvent() method to add error events before calling submit() instead
|
|
214
|
-
*/
|
|
215
|
-
async addTransactionError(
|
|
216
|
-
txId: string,
|
|
217
|
-
error: Error | string,
|
|
218
|
-
errorType: string = 'TransactionError'
|
|
219
|
-
): Promise<void> {
|
|
220
|
-
const txInfo = this.activeTransactions.get(txId);
|
|
221
|
-
if (!txInfo) {
|
|
222
|
-
console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot add error.`);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
console.warn('[ParallaxService] addTransactionError is deprecated. The new API does not support adding errors after trace creation. Add error events using the builder pattern before calling submit().');
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Finish a transaction trace
|
|
231
|
-
*
|
|
232
|
-
* NOTE: This method is deprecated as the new API does not support span lifecycle management.
|
|
233
|
-
* Traces are completed when submit() is called on the builder.
|
|
234
|
-
*
|
|
235
|
-
* @param txId - Transaction identifier
|
|
236
|
-
* @param options - Finish options (success, error message)
|
|
237
|
-
* @deprecated Traces are automatically completed when submit() is called
|
|
238
|
-
*/
|
|
239
|
-
async finishTransactionTrace(txId: string, options: FinishOptions = { success: true }): Promise<void> {
|
|
240
|
-
const txInfo = this.activeTransactions.get(txId);
|
|
241
|
-
if (!txInfo) {
|
|
242
|
-
console.warn(`[ParallaxService] Transaction ${txId} not found. Cannot finish.`);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
console.warn('[ParallaxService] finishTransactionTrace is deprecated. The new API does not support span lifecycle. Traces are completed when submit() is called.');
|
|
247
|
-
|
|
248
|
-
console.log('[ParallaxService] Transaction trace marked as finished (local only):', {
|
|
249
|
-
txId,
|
|
250
|
-
traceId: txInfo.traceId,
|
|
251
|
-
success: options.success,
|
|
252
|
-
txHash: txInfo.txHash,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// Remove from active transactions
|
|
256
|
-
this.activeTransactions.delete(txId);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Get info about an active transaction
|
|
261
|
-
*
|
|
262
|
-
* @param txId - Transaction identifier
|
|
263
|
-
* @returns Transaction info or null if not found
|
|
264
|
-
*/
|
|
265
|
-
getTransactionInfo(txId: string): TransactionInfo | null {
|
|
266
|
-
return this.activeTransactions.get(txId) || null;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Get all active transactions
|
|
271
|
-
*
|
|
272
|
-
* @returns Array of active transaction info
|
|
273
|
-
*/
|
|
274
|
-
getAllActiveTransactions(): Array<TransactionInfo & { txId: string }> {
|
|
275
|
-
return Array.from(this.activeTransactions.entries()).map(([txId, info]) => ({
|
|
276
|
-
txId,
|
|
277
|
-
...info,
|
|
278
|
-
}));
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* Get the ParallaxClient instance for advanced usage
|
|
283
|
-
* @param apiKey - Optional API key
|
|
284
|
-
* @param gatewayUrl - Optional gateway URL
|
|
285
|
-
*/
|
|
286
|
-
getClient(apiKey?: string, gatewayUrl?: string): ParallaxClient {
|
|
287
|
-
this._ensureClient(apiKey, gatewayUrl);
|
|
288
|
-
if (!this.client) {
|
|
289
|
-
throw new Error('Failed to initialize Parallax client');
|
|
290
|
-
}
|
|
291
|
-
return this.client;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Export singleton instance
|
|
296
|
-
export const parallaxService = new ParallaxService();
|