@teneo-protocol/sdk 3.1.2 → 3.1.4
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/README.md +11 -14
- package/dist/core/websocket-client.d.ts +1 -1
- package/dist/core/websocket-client.js +2 -2
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/managers/message-router.js +1 -1
- package/dist/managers/message-router.js.map +1 -1
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js +27 -5
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/teneo-sdk.d.ts +8 -4
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +25 -6
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/events.d.ts +1 -0
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts +7 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +36 -58
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -3
- package/src/core/websocket-client.ts +3 -3
- package/src/managers/message-router.ts +1 -1
- package/src/managers/room-manager.ts +32 -5
- package/src/teneo-sdk.ts +28 -7
- package/src/types/events.ts +1 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/logger.ts +35 -53
- package/tests/unit/sdk-new-methods.test.ts +42 -0
package/src/teneo-sdk.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type HealthStatus
|
|
23
23
|
} from "./types";
|
|
24
24
|
import { SDKEvents, SDKError } from "./types/events";
|
|
25
|
+
import { CHAIN_ID_TO_NETWORK } from "./payments/networks";
|
|
25
26
|
import { ErrorCode } from "./types/error-codes";
|
|
26
27
|
import { WebSocketClient } from "./core/websocket-client";
|
|
27
28
|
import { WebhookHandler } from "./handlers/webhook-handler";
|
|
@@ -46,7 +47,7 @@ import {
|
|
|
46
47
|
ListAvailableAgentsOptions,
|
|
47
48
|
PaginatedAgentsResult
|
|
48
49
|
} from "./managers";
|
|
49
|
-
import {
|
|
50
|
+
import { createConsoleLogger } from "./utils/logger";
|
|
50
51
|
import { RoomIdSchema, AgentIdSchema, AgentCommandContentSchema } from "./types/validation";
|
|
51
52
|
import { SecurePrivateKey } from "./utils/secure-private-key";
|
|
52
53
|
import { setNetworkConfigUrl, initializeNetworks } from "./payments";
|
|
@@ -1339,11 +1340,15 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
1339
1340
|
* Used in response to a "wallet:tx_requested" event after the user
|
|
1340
1341
|
* has confirmed, rejected, or encountered a failure with the transaction.
|
|
1341
1342
|
*
|
|
1343
|
+
* The txHash is automatically formatted with the network name (e.g., `0xabc...|base`)
|
|
1344
|
+
* when a chainId is provided, matching the format the UI uses.
|
|
1345
|
+
*
|
|
1342
1346
|
* @param taskId - The task ID from the wallet:tx_requested event
|
|
1343
1347
|
* @param status - Transaction result: "confirmed", "rejected", or "failed"
|
|
1344
1348
|
* @param txHash - The on-chain transaction hash (required for "confirmed" status)
|
|
1345
1349
|
* @param error - Error message (optional, for "failed" status)
|
|
1346
1350
|
* @param room - The room ID from the wallet:tx_requested event (required for routing)
|
|
1351
|
+
* @param chainId - The chain ID from data.tx.chainId (used to format txHash with network name)
|
|
1347
1352
|
* @throws {SDKError} If the SDK has been destroyed or not connected
|
|
1348
1353
|
*
|
|
1349
1354
|
* @example
|
|
@@ -1351,9 +1356,9 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
1351
1356
|
* sdk.on("wallet:tx_requested", async (data) => {
|
|
1352
1357
|
* try {
|
|
1353
1358
|
* const txHash = await wallet.sendTransaction(data.tx);
|
|
1354
|
-
* await sdk.sendTxResult(data.taskId, "confirmed", txHash, undefined, data.room);
|
|
1359
|
+
* await sdk.sendTxResult(data.taskId, "confirmed", txHash, undefined, data.room, data.tx.chainId);
|
|
1355
1360
|
* } catch (err) {
|
|
1356
|
-
* await sdk.sendTxResult(data.taskId, "failed", undefined, err.message, data.room);
|
|
1361
|
+
* await sdk.sendTxResult(data.taskId, "failed", undefined, err.message, data.room, data.tx.chainId);
|
|
1357
1362
|
* }
|
|
1358
1363
|
* });
|
|
1359
1364
|
* ```
|
|
@@ -1363,7 +1368,8 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
1363
1368
|
status: "confirmed" | "rejected" | "failed",
|
|
1364
1369
|
txHash?: string,
|
|
1365
1370
|
error?: string,
|
|
1366
|
-
room?: string
|
|
1371
|
+
room?: string,
|
|
1372
|
+
chainId?: number
|
|
1367
1373
|
): Promise<void> {
|
|
1368
1374
|
if (this.isDestroyed) {
|
|
1369
1375
|
throw new SDKError("SDK has been destroyed", ErrorCode.SDK_DESTROYED, null, false);
|
|
@@ -1373,6 +1379,15 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
1373
1379
|
throw new SDKError("Not connected to Teneo Protocol", ErrorCode.NOT_CONNECTED);
|
|
1374
1380
|
}
|
|
1375
1381
|
|
|
1382
|
+
// Format txHash with network name (e.g., "0xabc...|base") to match UI format
|
|
1383
|
+
let formattedTxHash = txHash;
|
|
1384
|
+
if (txHash && chainId) {
|
|
1385
|
+
const networkName = CHAIN_ID_TO_NETWORK[chainId];
|
|
1386
|
+
if (networkName) {
|
|
1387
|
+
formattedTxHash = `${txHash}|${networkName}`;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1376
1391
|
const message = {
|
|
1377
1392
|
type: "tx_result" as const,
|
|
1378
1393
|
...(room && { room }),
|
|
@@ -1380,7 +1395,7 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
1380
1395
|
data: {
|
|
1381
1396
|
task_id: taskId,
|
|
1382
1397
|
status,
|
|
1383
|
-
...(
|
|
1398
|
+
...(formattedTxHash && { tx_hash: formattedTxHash }),
|
|
1384
1399
|
...(error && { error })
|
|
1385
1400
|
}
|
|
1386
1401
|
};
|
|
@@ -2017,6 +2032,12 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
2017
2032
|
// Emit on SDK for external listeners
|
|
2018
2033
|
this.emit("room:deleted", roomId);
|
|
2019
2034
|
});
|
|
2035
|
+
this.wsClient.on("room:list", (rooms) => {
|
|
2036
|
+
// Emit on RoomManager for promise resolution (see listRooms method)
|
|
2037
|
+
this.rooms.emit("room:list", rooms);
|
|
2038
|
+
// Emit on SDK for external listeners
|
|
2039
|
+
this.emit("room:list", rooms);
|
|
2040
|
+
});
|
|
2020
2041
|
this.wsClient.on("room:create_error", (error) => {
|
|
2021
2042
|
// Emit on RoomManagementManager for promise rejection
|
|
2022
2043
|
this.roomManagement.emit("room:create_error", error);
|
|
@@ -2155,10 +2176,10 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
2155
2176
|
}
|
|
2156
2177
|
|
|
2157
2178
|
/**
|
|
2158
|
-
* Create default logger
|
|
2179
|
+
* Create default console-based logger
|
|
2159
2180
|
*/
|
|
2160
2181
|
private createDefaultLogger(): Logger {
|
|
2161
|
-
return
|
|
2182
|
+
return createConsoleLogger(this.config.logLevel ?? "info", "TeneoSDK");
|
|
2162
2183
|
}
|
|
2163
2184
|
|
|
2164
2185
|
/**
|
package/src/types/events.ts
CHANGED
|
@@ -320,6 +320,7 @@ export interface SDKEvents {
|
|
|
320
320
|
}) => void;
|
|
321
321
|
|
|
322
322
|
// Room events
|
|
323
|
+
"room:list": (rooms: z.infer<typeof RoomInfoSchema>[]) => void;
|
|
323
324
|
"room:subscribed": (data: { roomId: string; subscriptions: string[] }) => void;
|
|
324
325
|
"room:unsubscribed": (data: { roomId: string; subscriptions: string[] }) => void;
|
|
325
326
|
"room:message": (roomId: string, message: z.infer<typeof BaseMessageSchema>) => void;
|
package/src/utils/index.ts
CHANGED
package/src/utils/logger.ts
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Logger utility for Teneo Protocol SDK
|
|
3
|
-
* Provides
|
|
3
|
+
* Provides console-based logging with level filtering
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import pino from "pino";
|
|
7
6
|
import type { Logger, LogLevel } from "../types";
|
|
8
7
|
|
|
8
|
+
const LOG_LEVELS: Record<string, number> = {
|
|
9
|
+
debug: 0,
|
|
10
|
+
info: 1,
|
|
11
|
+
warn: 2,
|
|
12
|
+
error: 3,
|
|
13
|
+
silent: 4
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function formatData(data: unknown): string {
|
|
17
|
+
if (data === undefined || data === null) return "";
|
|
18
|
+
try {
|
|
19
|
+
return " " + JSON.stringify(data, null, 2);
|
|
20
|
+
} catch {
|
|
21
|
+
return " " + String(data);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
9
25
|
/**
|
|
10
|
-
* Creates a
|
|
11
|
-
*
|
|
26
|
+
* Creates a console-based logger that conforms to the SDK Logger interface.
|
|
27
|
+
* Filters messages below the configured log level.
|
|
12
28
|
*
|
|
13
29
|
* @param level - Log level (debug, info, warn, error, silent)
|
|
14
30
|
* @param name - Logger name for identifying log source (e.g., "TeneoSDK", "WebSocketClient")
|
|
@@ -16,72 +32,38 @@ import type { Logger, LogLevel } from "../types";
|
|
|
16
32
|
*
|
|
17
33
|
* @example
|
|
18
34
|
* ```typescript
|
|
19
|
-
* const logger =
|
|
35
|
+
* const logger = createConsoleLogger('info', 'TeneoSDK');
|
|
20
36
|
* logger.info('SDK initialized', { wsUrl: 'wss://example.com' });
|
|
21
37
|
* logger.error('Connection failed', { code: 'CONN_FAILED', attempt: 3 });
|
|
22
38
|
* ```
|
|
23
39
|
*/
|
|
24
|
-
export function
|
|
25
|
-
|
|
26
|
-
const
|
|
40
|
+
export function createConsoleLogger(level: LogLevel, name?: string): Logger {
|
|
41
|
+
const threshold = LOG_LEVELS[level] ?? LOG_LEVELS.info;
|
|
42
|
+
const prefix = name ? `[${name}]` : "";
|
|
27
43
|
|
|
28
|
-
// Create pino logger with optional pretty printing for development
|
|
29
|
-
const pinoLogger = pino({
|
|
30
|
-
level: pinoLevel,
|
|
31
|
-
name: name || "TeneoSDK",
|
|
32
|
-
// Use pino-pretty in development for readable logs
|
|
33
|
-
transport:
|
|
34
|
-
process.env.NODE_ENV !== "production"
|
|
35
|
-
? {
|
|
36
|
-
target: "pino-pretty",
|
|
37
|
-
options: {
|
|
38
|
-
colorize: true,
|
|
39
|
-
ignore: "pid,hostname",
|
|
40
|
-
translateTime: "HH:MM:ss.l",
|
|
41
|
-
singleLine: false
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
: undefined,
|
|
45
|
-
// Production: fast JSON logs
|
|
46
|
-
formatters:
|
|
47
|
-
process.env.NODE_ENV === "production"
|
|
48
|
-
? {
|
|
49
|
-
level: (label) => {
|
|
50
|
-
return { level: label };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
: undefined
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Adapt pino's API to match our Logger interface
|
|
57
44
|
return {
|
|
58
45
|
debug: (message: string, data?: unknown) => {
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
} else {
|
|
62
|
-
pinoLogger.debug(message);
|
|
46
|
+
if (threshold <= LOG_LEVELS.debug) {
|
|
47
|
+
console.debug(`${prefix} ${message}${formatData(data)}`);
|
|
63
48
|
}
|
|
64
49
|
},
|
|
65
50
|
info: (message: string, data?: unknown) => {
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
} else {
|
|
69
|
-
pinoLogger.info(message);
|
|
51
|
+
if (threshold <= LOG_LEVELS.info) {
|
|
52
|
+
console.info(`${prefix} ${message}${formatData(data)}`);
|
|
70
53
|
}
|
|
71
54
|
},
|
|
72
55
|
warn: (message: string, data?: unknown) => {
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
} else {
|
|
76
|
-
pinoLogger.warn(message);
|
|
56
|
+
if (threshold <= LOG_LEVELS.warn) {
|
|
57
|
+
console.warn(`${prefix} ${message}${formatData(data)}`);
|
|
77
58
|
}
|
|
78
59
|
},
|
|
79
60
|
error: (message: string, data?: unknown) => {
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
} else {
|
|
83
|
-
pinoLogger.error(message);
|
|
61
|
+
if (threshold <= LOG_LEVELS.error) {
|
|
62
|
+
console.error(`${prefix} ${message}${formatData(data)}`);
|
|
84
63
|
}
|
|
85
64
|
}
|
|
86
65
|
};
|
|
87
66
|
}
|
|
67
|
+
|
|
68
|
+
/** @deprecated Use createConsoleLogger instead */
|
|
69
|
+
export const createPinoLogger = createConsoleLogger;
|
|
@@ -7,6 +7,17 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
|
7
7
|
import { TeneoSDK } from "../../src/teneo-sdk";
|
|
8
8
|
import { ErrorCode } from "../../src/types/error-codes";
|
|
9
9
|
|
|
10
|
+
// Mock the networks module so we can control CHAIN_ID_TO_NETWORK
|
|
11
|
+
vi.mock("../../src/payments/networks", async (importOriginal) => {
|
|
12
|
+
const actual = await importOriginal<typeof import("../../src/payments/networks")>();
|
|
13
|
+
return {
|
|
14
|
+
...actual,
|
|
15
|
+
CHAIN_ID_TO_NETWORK: {} as Record<number, string>,
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
import { CHAIN_ID_TO_NETWORK } from "../../src/payments/networks";
|
|
20
|
+
|
|
10
21
|
describe("TeneoSDK New Methods", () => {
|
|
11
22
|
let sdk: TeneoSDK;
|
|
12
23
|
let sendMessageSpy: ReturnType<typeof vi.fn>;
|
|
@@ -156,6 +167,37 @@ describe("TeneoSDK New Methods", () => {
|
|
|
156
167
|
});
|
|
157
168
|
});
|
|
158
169
|
|
|
170
|
+
it("should format txHash with network name when chainId is provided", async () => {
|
|
171
|
+
// Populate the chain ID mapping like fetchNetworkConfigs would
|
|
172
|
+
const chainMap = CHAIN_ID_TO_NETWORK as Record<number, string>;
|
|
173
|
+
chainMap[8453] = "base";
|
|
174
|
+
chainMap[43114] = "avalanche";
|
|
175
|
+
|
|
176
|
+
await sdk.sendTxResult("task-100", "confirmed", "0xabc", undefined, "room-abc", 8453);
|
|
177
|
+
|
|
178
|
+
expect(sendMessageSpy).toHaveBeenCalledWith({
|
|
179
|
+
type: "tx_result",
|
|
180
|
+
room: "room-abc",
|
|
181
|
+
timestamp: expect.any(String),
|
|
182
|
+
data: {
|
|
183
|
+
task_id: "task-100",
|
|
184
|
+
status: "confirmed",
|
|
185
|
+
tx_hash: "0xabc|base"
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Cleanup
|
|
190
|
+
delete chainMap[8453];
|
|
191
|
+
delete chainMap[43114];
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("should send raw txHash when chainId is unknown", async () => {
|
|
195
|
+
await sdk.sendTxResult("task-100", "confirmed", "0xabc", undefined, "room-abc", 99999);
|
|
196
|
+
|
|
197
|
+
const sentMessage = sendMessageSpy.mock.calls[0][0];
|
|
198
|
+
expect(sentMessage.data.tx_hash).toBe("0xabc");
|
|
199
|
+
});
|
|
200
|
+
|
|
159
201
|
it("should not include room when not provided", async () => {
|
|
160
202
|
await sdk.sendTxResult("task-100", "rejected");
|
|
161
203
|
|