@polkadot-apps/statement-store 0.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.
- package/dist/channels.d.ts +117 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +422 -0
- package/dist/channels.js.map +1 -0
- package/dist/client.d.ts +133 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +688 -0
- package/dist/client.js.map +1 -0
- package/dist/codec.d.ts +74 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +564 -0
- package/dist/codec.js.map +1 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +152 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/topics.d.ts +60 -0
- package/dist/topics.d.ts.map +1 -0
- package/dist/topics.js +187 -0
- package/dist/topics.js.map +1 -0
- package/dist/transport.d.ts +94 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +590 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +276 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
import { createLogger } from "@polkadot-apps/logger";
|
|
2
|
+
import { StatementConnectionError, StatementSubscriptionError } from "./errors.js";
|
|
3
|
+
import { serializeTopicFilter, topicToHex } from "./topics.js";
|
|
4
|
+
const log = createLogger("statement-store:transport");
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Statement Event Extraction
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Extract a {@link StatementEvent} from the various response formats
|
|
10
|
+
* that different node versions produce.
|
|
11
|
+
*
|
|
12
|
+
* Handles:
|
|
13
|
+
* - Direct: `{ statements: [...] }`
|
|
14
|
+
* - Wrapped: `{ NewStatements: { statements: [...] } }`
|
|
15
|
+
* - Data-wrapped: `{ data: { statements: [...] } }` (most common in practice)
|
|
16
|
+
*/
|
|
17
|
+
function extractStatementEvent(event) {
|
|
18
|
+
if (event == null || typeof event !== "object")
|
|
19
|
+
return null;
|
|
20
|
+
const obj = event;
|
|
21
|
+
// Direct format
|
|
22
|
+
if (Array.isArray(obj.statements)) {
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
// NewStatements wrapped format
|
|
26
|
+
if (obj.NewStatements != null &&
|
|
27
|
+
typeof obj.NewStatements === "object" &&
|
|
28
|
+
Array.isArray(obj.NewStatements.statements)) {
|
|
29
|
+
return obj.NewStatements;
|
|
30
|
+
}
|
|
31
|
+
// Data-wrapped format (what the node actually sends)
|
|
32
|
+
if (obj.data != null &&
|
|
33
|
+
typeof obj.data === "object" &&
|
|
34
|
+
Array.isArray(obj.data.statements)) {
|
|
35
|
+
return obj.data;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Statement store transport using JSON-RPC over WebSocket.
|
|
41
|
+
*
|
|
42
|
+
* Communicates with a statement store node via the standard `statement_*` RPC methods.
|
|
43
|
+
* Supports both subscription-based real-time delivery and polling-based queries
|
|
44
|
+
* with graceful fallback across multiple RPC methods.
|
|
45
|
+
*/
|
|
46
|
+
export class RpcTransport {
|
|
47
|
+
client;
|
|
48
|
+
ownsClient;
|
|
49
|
+
/**
|
|
50
|
+
* @param client - The RPC client to use for communication.
|
|
51
|
+
* @param ownsClient - If true, `destroy()` will also destroy the client.
|
|
52
|
+
* Set to false when sharing a client from chain-client.
|
|
53
|
+
*/
|
|
54
|
+
constructor(client, ownsClient) {
|
|
55
|
+
this.client = client;
|
|
56
|
+
this.ownsClient = ownsClient;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Subscribe to statements matching a topic filter.
|
|
60
|
+
*
|
|
61
|
+
* Uses the `statement_subscribeStatement` RPC method which returns
|
|
62
|
+
* batched events via a subscription stream. Handles all three event formats
|
|
63
|
+
* (raw hex, StatementEvent, nested wrappers) for cross-node compatibility.
|
|
64
|
+
*
|
|
65
|
+
* If the node does not support subscriptions, `onError` is called
|
|
66
|
+
* and the caller should fall back to polling.
|
|
67
|
+
*/
|
|
68
|
+
subscribe(filter, onStatement, onError) {
|
|
69
|
+
const serializedFilter = serializeTopicFilter(filter);
|
|
70
|
+
let unsubFn = null;
|
|
71
|
+
try {
|
|
72
|
+
unsubFn = this.client._request("statement_subscribeStatement", [serializedFilter], {
|
|
73
|
+
onSuccess: (_subscriptionId, followSubscription) => {
|
|
74
|
+
log.info("Subscription active");
|
|
75
|
+
followSubscription(_subscriptionId, {
|
|
76
|
+
next: (event) => {
|
|
77
|
+
// Handle raw hex string (legacy format)
|
|
78
|
+
if (typeof event === "string") {
|
|
79
|
+
onStatement(event);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// Extract batched event from various wrapper formats
|
|
83
|
+
const statementEvent = extractStatementEvent(event);
|
|
84
|
+
if (statementEvent) {
|
|
85
|
+
for (const hex of statementEvent.statements) {
|
|
86
|
+
onStatement(hex);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
error: (e) => {
|
|
91
|
+
log.warn("Subscription stream error", { error: e.message });
|
|
92
|
+
onError(new StatementSubscriptionError(e.message, { cause: e }));
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
onError: (e) => {
|
|
97
|
+
log.warn("Subscription not available", { error: e.message });
|
|
98
|
+
onError(new StatementSubscriptionError(e.message, { cause: e }));
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
104
|
+
log.warn("Failed to start subscription", { error: msg });
|
|
105
|
+
onError(new StatementSubscriptionError(msg));
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
unsubscribe: () => {
|
|
109
|
+
if (unsubFn) {
|
|
110
|
+
unsubFn();
|
|
111
|
+
unsubFn = null;
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Submit a signed statement via the `statement_submit` RPC method.
|
|
118
|
+
*
|
|
119
|
+
* @returns The submission status extracted from the RPC response.
|
|
120
|
+
*/
|
|
121
|
+
async submit(statementHex) {
|
|
122
|
+
const result = await this.client.request("statement_submit", [statementHex]);
|
|
123
|
+
const status = extractSubmitStatus(result);
|
|
124
|
+
log.debug("Statement submitted", { status });
|
|
125
|
+
return status;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Query existing statements from the store.
|
|
129
|
+
*
|
|
130
|
+
* Tries multiple RPC methods with graceful fallback:
|
|
131
|
+
* 1. `statement_posted` — filtered by topics + decryptionKey (most efficient)
|
|
132
|
+
* 2. `statement_broadcasts` — filtered by topics only
|
|
133
|
+
* 3. `statement_dump` — unfiltered, returns all statements
|
|
134
|
+
*
|
|
135
|
+
* Each method returns hex-encoded statements. If a method is not supported
|
|
136
|
+
* by the node, the next one is tried.
|
|
137
|
+
*/
|
|
138
|
+
async query(topics, decryptionKey) {
|
|
139
|
+
const topicHexes = topics.map(topicToHex);
|
|
140
|
+
// Try statement_posted (for statements with decryptionKey)
|
|
141
|
+
if (decryptionKey) {
|
|
142
|
+
try {
|
|
143
|
+
const result = await this.client.request("statement_posted", [
|
|
144
|
+
topicHexes,
|
|
145
|
+
decryptionKey,
|
|
146
|
+
]);
|
|
147
|
+
return asStringArray(result);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
log.debug("statement_posted unavailable", {
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Try statement_broadcasts
|
|
156
|
+
try {
|
|
157
|
+
const result = await this.client.request("statement_broadcasts", [topicHexes]);
|
|
158
|
+
return asStringArray(result);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
log.debug("statement_broadcasts unavailable", {
|
|
162
|
+
error: error instanceof Error ? error.message : String(error),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// Fallback to statement_dump (all statements, unfiltered)
|
|
166
|
+
try {
|
|
167
|
+
const result = await this.client.request("statement_dump", []);
|
|
168
|
+
return asStringArray(result);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
log.debug("statement_dump unavailable", {
|
|
172
|
+
error: error instanceof Error ? error.message : String(error),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Destroy the transport and release resources.
|
|
179
|
+
*
|
|
180
|
+
* If this transport owns the RPC client (created via `endpoint` config),
|
|
181
|
+
* the client is also destroyed. If the client is shared from chain-client,
|
|
182
|
+
* only the transport's state is cleaned up.
|
|
183
|
+
*/
|
|
184
|
+
destroy() {
|
|
185
|
+
if (this.ownsClient) {
|
|
186
|
+
this.client.destroy();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Extract a SubmitStatus from a potentially nested RPC response. */
|
|
191
|
+
function extractSubmitStatus(result) {
|
|
192
|
+
if (result == null)
|
|
193
|
+
return "rejected";
|
|
194
|
+
if (typeof result === "string") {
|
|
195
|
+
const lower = result.toLowerCase();
|
|
196
|
+
if (lower === "new" || lower === "known")
|
|
197
|
+
return lower;
|
|
198
|
+
return "rejected";
|
|
199
|
+
}
|
|
200
|
+
if (typeof result === "object") {
|
|
201
|
+
const obj = result;
|
|
202
|
+
if (typeof obj.status === "string") {
|
|
203
|
+
return extractSubmitStatus(obj.status);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return "rejected";
|
|
207
|
+
}
|
|
208
|
+
/** Safely cast an unknown RPC result to a string array. */
|
|
209
|
+
function asStringArray(value) {
|
|
210
|
+
if (Array.isArray(value)) {
|
|
211
|
+
return value.filter((item) => typeof item === "string");
|
|
212
|
+
}
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Create a statement store transport.
|
|
217
|
+
*
|
|
218
|
+
* Strategy (Host API first):
|
|
219
|
+
* 1. Try chain-client's bulletin chain connection — this uses product-sdk's
|
|
220
|
+
* `createPapiProvider` which routes through the Host API when inside a container,
|
|
221
|
+
* falling back to direct RPC outside.
|
|
222
|
+
* 2. If chain-client is unavailable (not initialized, not installed), fall back
|
|
223
|
+
* to a direct WebSocket connection using the provided `endpoint`.
|
|
224
|
+
* 3. If neither works, throw {@link StatementConnectionError}.
|
|
225
|
+
*
|
|
226
|
+
* @param config - Configuration with an optional fallback `endpoint`.
|
|
227
|
+
* @returns A configured {@link StatementTransport}.
|
|
228
|
+
* @throws {StatementConnectionError} If no connection method is available.
|
|
229
|
+
*/
|
|
230
|
+
export async function createTransport(config) {
|
|
231
|
+
// Always try chain-client first (routes through Host API in containers)
|
|
232
|
+
try {
|
|
233
|
+
return await createChainClientTransport();
|
|
234
|
+
}
|
|
235
|
+
catch (chainClientError) {
|
|
236
|
+
log.debug("Chain-client transport unavailable, trying direct endpoint", {
|
|
237
|
+
error: chainClientError instanceof Error
|
|
238
|
+
? chainClientError.message
|
|
239
|
+
: String(chainClientError),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
// Fall back to direct WebSocket if endpoint is provided
|
|
243
|
+
if (config.endpoint) {
|
|
244
|
+
return createDirectTransport(config.endpoint);
|
|
245
|
+
}
|
|
246
|
+
throw new StatementConnectionError("No connection method available. Either initialize chain-client " +
|
|
247
|
+
"(call getChainAPI() first) or provide an explicit endpoint.");
|
|
248
|
+
}
|
|
249
|
+
/* @integration */
|
|
250
|
+
async function createDirectTransport(endpoint) {
|
|
251
|
+
try {
|
|
252
|
+
const { getWsProvider } = await import("polkadot-api/ws-provider/web");
|
|
253
|
+
const { createClient } = await import("polkadot-api");
|
|
254
|
+
const provider = getWsProvider(endpoint);
|
|
255
|
+
const client = createClient(provider);
|
|
256
|
+
log.info("Connected to statement store via direct endpoint", { endpoint });
|
|
257
|
+
return new RpcTransport(client, true);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
throw new StatementConnectionError(`Failed to connect to ${endpoint}: ${error instanceof Error ? error.message : String(error)}`, { cause: error instanceof Error ? error : undefined });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/* @integration */
|
|
264
|
+
async function createChainClientTransport() {
|
|
265
|
+
try {
|
|
266
|
+
const { getClient } = await import("@polkadot-apps/chain-client");
|
|
267
|
+
const { bulletin } = await import("@polkadot-apps/descriptors");
|
|
268
|
+
const client = getClient(bulletin);
|
|
269
|
+
log.info("Connected to statement store via chain-client bulletin");
|
|
270
|
+
return new RpcTransport(client, false);
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
throw new StatementConnectionError(`Chain-client bulletin not available: ${error instanceof Error ? error.message : String(error)}`, { cause: error instanceof Error ? error : undefined });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (import.meta.vitest) {
|
|
277
|
+
const { describe, test, expect, vi, beforeEach } = import.meta.vitest;
|
|
278
|
+
const { configure } = await import("@polkadot-apps/logger");
|
|
279
|
+
beforeEach(() => {
|
|
280
|
+
configure({ handler: () => { } });
|
|
281
|
+
});
|
|
282
|
+
function createMockClient() {
|
|
283
|
+
const requestCalls = [];
|
|
284
|
+
const _requestCalls = [];
|
|
285
|
+
let destroyCalled = false;
|
|
286
|
+
const client = {
|
|
287
|
+
request: async (method, params) => {
|
|
288
|
+
requestCalls.push([method, params]);
|
|
289
|
+
return { status: "new" };
|
|
290
|
+
},
|
|
291
|
+
_request: (method, params, callbacks) => {
|
|
292
|
+
_requestCalls.push([method, params, callbacks]);
|
|
293
|
+
return () => { };
|
|
294
|
+
},
|
|
295
|
+
destroy: () => {
|
|
296
|
+
destroyCalled = true;
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
client,
|
|
301
|
+
requestCalls,
|
|
302
|
+
_requestCalls,
|
|
303
|
+
get destroyCalled() {
|
|
304
|
+
return destroyCalled;
|
|
305
|
+
},
|
|
306
|
+
/** Replace the request handler for a specific test. */
|
|
307
|
+
setRequest(fn) {
|
|
308
|
+
client.request = fn;
|
|
309
|
+
},
|
|
310
|
+
/** Replace the _request handler for a specific test. */
|
|
311
|
+
set_Request(fn) {
|
|
312
|
+
client._request = fn;
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
describe("RpcTransport", () => {
|
|
317
|
+
describe("subscribe", () => {
|
|
318
|
+
test("calls statement_subscribeStatement with serialized filter", () => {
|
|
319
|
+
const mock = createMockClient();
|
|
320
|
+
const transport = new RpcTransport(mock.client, false);
|
|
321
|
+
transport.subscribe("any", () => { }, () => { });
|
|
322
|
+
expect(mock._requestCalls.length).toBe(1);
|
|
323
|
+
expect(mock._requestCalls[0][0]).toBe("statement_subscribeStatement");
|
|
324
|
+
expect(mock._requestCalls[0][1]).toEqual(["any"]);
|
|
325
|
+
});
|
|
326
|
+
test("returns unsubscribable handle", () => {
|
|
327
|
+
const mock = createMockClient();
|
|
328
|
+
const unsubFn = vi.fn();
|
|
329
|
+
mock.set_Request(() => unsubFn);
|
|
330
|
+
const transport = new RpcTransport(mock.client, false);
|
|
331
|
+
const sub = transport.subscribe("any", () => { }, () => { });
|
|
332
|
+
sub.unsubscribe();
|
|
333
|
+
expect(unsubFn).toHaveBeenCalledOnce();
|
|
334
|
+
});
|
|
335
|
+
test("unsubscribe is idempotent", () => {
|
|
336
|
+
const mock = createMockClient();
|
|
337
|
+
const unsubFn = vi.fn();
|
|
338
|
+
mock.set_Request(() => unsubFn);
|
|
339
|
+
const transport = new RpcTransport(mock.client, false);
|
|
340
|
+
const sub = transport.subscribe("any", () => { }, () => { });
|
|
341
|
+
sub.unsubscribe();
|
|
342
|
+
sub.unsubscribe();
|
|
343
|
+
expect(unsubFn).toHaveBeenCalledOnce();
|
|
344
|
+
});
|
|
345
|
+
test("calls onError when _request throws", () => {
|
|
346
|
+
const mock = createMockClient();
|
|
347
|
+
mock.set_Request(() => {
|
|
348
|
+
throw new Error("not supported");
|
|
349
|
+
});
|
|
350
|
+
const transport = new RpcTransport(mock.client, false);
|
|
351
|
+
const onError = vi.fn();
|
|
352
|
+
transport.subscribe("any", () => { }, onError);
|
|
353
|
+
expect(onError).toHaveBeenCalledOnce();
|
|
354
|
+
expect(onError.mock.calls[0][0]).toBeInstanceOf(StatementSubscriptionError);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
describe("submit", () => {
|
|
358
|
+
test("calls statement_submit and returns status", async () => {
|
|
359
|
+
const mock = createMockClient();
|
|
360
|
+
const transport = new RpcTransport(mock.client, false);
|
|
361
|
+
const status = await transport.submit("0xdeadbeef");
|
|
362
|
+
expect(mock.requestCalls[0][0]).toBe("statement_submit");
|
|
363
|
+
expect(status).toBe("new");
|
|
364
|
+
});
|
|
365
|
+
test("returns 'rejected' for null response", async () => {
|
|
366
|
+
const mock = createMockClient();
|
|
367
|
+
mock.setRequest(async () => null);
|
|
368
|
+
const transport = new RpcTransport(mock.client, false);
|
|
369
|
+
expect(await transport.submit("0x")).toBe("rejected");
|
|
370
|
+
});
|
|
371
|
+
test("returns 'known' for known status", async () => {
|
|
372
|
+
const mock = createMockClient();
|
|
373
|
+
mock.setRequest(async () => ({ status: "known" }));
|
|
374
|
+
const transport = new RpcTransport(mock.client, false);
|
|
375
|
+
expect(await transport.submit("0x")).toBe("known");
|
|
376
|
+
});
|
|
377
|
+
test("returns 'rejected' for unexpected status", async () => {
|
|
378
|
+
const mock = createMockClient();
|
|
379
|
+
mock.setRequest(async () => "unexpected");
|
|
380
|
+
const transport = new RpcTransport(mock.client, false);
|
|
381
|
+
expect(await transport.submit("0x")).toBe("rejected");
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
describe("query", () => {
|
|
385
|
+
test("tries statement_broadcasts when no decryptionKey", async () => {
|
|
386
|
+
const mock = createMockClient();
|
|
387
|
+
mock.setRequest(async (method) => {
|
|
388
|
+
if (method === "statement_broadcasts")
|
|
389
|
+
return ["0xaaa", "0xbbb"];
|
|
390
|
+
throw new Error("not supported");
|
|
391
|
+
});
|
|
392
|
+
const transport = new RpcTransport(mock.client, false);
|
|
393
|
+
const result = await transport.query([]);
|
|
394
|
+
expect(result).toEqual(["0xaaa", "0xbbb"]);
|
|
395
|
+
});
|
|
396
|
+
test("tries statement_posted first when decryptionKey provided", async () => {
|
|
397
|
+
const mock = createMockClient();
|
|
398
|
+
mock.setRequest(async (method) => {
|
|
399
|
+
if (method === "statement_posted")
|
|
400
|
+
return ["0xccc"];
|
|
401
|
+
throw new Error("not supported");
|
|
402
|
+
});
|
|
403
|
+
const transport = new RpcTransport(mock.client, false);
|
|
404
|
+
const result = await transport.query([], "0xkey");
|
|
405
|
+
expect(result).toEqual(["0xccc"]);
|
|
406
|
+
});
|
|
407
|
+
test("falls back through methods gracefully", async () => {
|
|
408
|
+
const mock = createMockClient();
|
|
409
|
+
const calledMethods = [];
|
|
410
|
+
mock.setRequest(async (method) => {
|
|
411
|
+
calledMethods.push(method);
|
|
412
|
+
if (method === "statement_dump")
|
|
413
|
+
return ["0xfallback"];
|
|
414
|
+
throw new Error("not supported");
|
|
415
|
+
});
|
|
416
|
+
const transport = new RpcTransport(mock.client, false);
|
|
417
|
+
const result = await transport.query([], "0xkey");
|
|
418
|
+
expect(calledMethods).toEqual([
|
|
419
|
+
"statement_posted",
|
|
420
|
+
"statement_broadcasts",
|
|
421
|
+
"statement_dump",
|
|
422
|
+
]);
|
|
423
|
+
expect(result).toEqual(["0xfallback"]);
|
|
424
|
+
});
|
|
425
|
+
test("returns empty array when all methods fail", async () => {
|
|
426
|
+
const mock = createMockClient();
|
|
427
|
+
mock.setRequest(async () => {
|
|
428
|
+
throw new Error("not supported");
|
|
429
|
+
});
|
|
430
|
+
const transport = new RpcTransport(mock.client, false);
|
|
431
|
+
const result = await transport.query([]);
|
|
432
|
+
expect(result).toEqual([]);
|
|
433
|
+
});
|
|
434
|
+
test("filters non-string elements from results", async () => {
|
|
435
|
+
const mock = createMockClient();
|
|
436
|
+
mock.setRequest(async () => ["0xvalid", 42, null, "0xalso"]);
|
|
437
|
+
const transport = new RpcTransport(mock.client, false);
|
|
438
|
+
const result = await transport.query([]);
|
|
439
|
+
expect(result).toEqual(["0xvalid", "0xalso"]);
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
describe("destroy", () => {
|
|
443
|
+
test("destroys owned client", () => {
|
|
444
|
+
const mock = createMockClient();
|
|
445
|
+
const transport = new RpcTransport(mock.client, true);
|
|
446
|
+
transport.destroy();
|
|
447
|
+
expect(mock.destroyCalled).toBe(true);
|
|
448
|
+
});
|
|
449
|
+
test("does not destroy shared client", () => {
|
|
450
|
+
const mock = createMockClient();
|
|
451
|
+
const transport = new RpcTransport(mock.client, false);
|
|
452
|
+
transport.destroy();
|
|
453
|
+
expect(mock.destroyCalled).toBe(false);
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
describe("extractStatementEvent", () => {
|
|
458
|
+
test("extracts direct format", () => {
|
|
459
|
+
const event = { statements: ["0xaa", "0xbb"], remaining: 0 };
|
|
460
|
+
const result = extractStatementEvent(event);
|
|
461
|
+
expect(result?.statements).toEqual(["0xaa", "0xbb"]);
|
|
462
|
+
expect(result?.remaining).toBe(0);
|
|
463
|
+
});
|
|
464
|
+
test("extracts NewStatements wrapped format", () => {
|
|
465
|
+
const event = {
|
|
466
|
+
NewStatements: { statements: ["0xcc"], remaining: 5 },
|
|
467
|
+
};
|
|
468
|
+
const result = extractStatementEvent(event);
|
|
469
|
+
expect(result?.statements).toEqual(["0xcc"]);
|
|
470
|
+
});
|
|
471
|
+
test("extracts data-wrapped format", () => {
|
|
472
|
+
const event = { data: { statements: ["0xdd"] } };
|
|
473
|
+
const result = extractStatementEvent(event);
|
|
474
|
+
expect(result?.statements).toEqual(["0xdd"]);
|
|
475
|
+
});
|
|
476
|
+
test("returns null for unrecognized format", () => {
|
|
477
|
+
expect(extractStatementEvent({ foo: "bar" })).toBeNull();
|
|
478
|
+
expect(extractStatementEvent(null)).toBeNull();
|
|
479
|
+
expect(extractStatementEvent("string")).toBeNull();
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
describe("extractSubmitStatus", () => {
|
|
483
|
+
test("extracts 'new' from string", () => {
|
|
484
|
+
expect(extractSubmitStatus("new")).toBe("new");
|
|
485
|
+
});
|
|
486
|
+
test("extracts 'known' from string", () => {
|
|
487
|
+
expect(extractSubmitStatus("known")).toBe("known");
|
|
488
|
+
});
|
|
489
|
+
test("extracts from nested object", () => {
|
|
490
|
+
expect(extractSubmitStatus({ status: "new" })).toBe("new");
|
|
491
|
+
});
|
|
492
|
+
test("returns 'rejected' for null", () => {
|
|
493
|
+
expect(extractSubmitStatus(null)).toBe("rejected");
|
|
494
|
+
});
|
|
495
|
+
test("returns 'rejected' for unknown string", () => {
|
|
496
|
+
expect(extractSubmitStatus("badvalue")).toBe("rejected");
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
describe("RpcTransport subscription delivery", () => {
|
|
500
|
+
test("delivers raw hex string events to onStatement", () => {
|
|
501
|
+
const mock = createMockClient();
|
|
502
|
+
const received = [];
|
|
503
|
+
mock.set_Request(((_method, _params, callbacks) => {
|
|
504
|
+
callbacks.onSuccess("sub-id", (_id, handlers) => {
|
|
505
|
+
handlers.next("0xdeadbeef");
|
|
506
|
+
handlers.next("0xcafebabe");
|
|
507
|
+
});
|
|
508
|
+
return () => { };
|
|
509
|
+
}));
|
|
510
|
+
const transport = new RpcTransport(mock.client, false);
|
|
511
|
+
transport.subscribe("any", (hex) => received.push(hex), () => { });
|
|
512
|
+
expect(received).toEqual(["0xdeadbeef", "0xcafebabe"]);
|
|
513
|
+
});
|
|
514
|
+
test("delivers batched statement events to onStatement", () => {
|
|
515
|
+
const mock = createMockClient();
|
|
516
|
+
const received = [];
|
|
517
|
+
mock.set_Request(((_m, _p, cb) => {
|
|
518
|
+
cb.onSuccess("sub-id", (_id, handlers) => {
|
|
519
|
+
handlers.next({ statements: ["0xaa", "0xbb"], remaining: 0 });
|
|
520
|
+
});
|
|
521
|
+
return () => { };
|
|
522
|
+
}));
|
|
523
|
+
const transport = new RpcTransport(mock.client, false);
|
|
524
|
+
transport.subscribe("any", (hex) => received.push(hex), () => { });
|
|
525
|
+
expect(received).toEqual(["0xaa", "0xbb"]);
|
|
526
|
+
});
|
|
527
|
+
test("delivers data-wrapped events to onStatement", () => {
|
|
528
|
+
const mock = createMockClient();
|
|
529
|
+
const received = [];
|
|
530
|
+
mock.set_Request(((_m, _p, cb) => {
|
|
531
|
+
cb.onSuccess("sub-id", (_id, handlers) => {
|
|
532
|
+
handlers.next({ data: { statements: ["0xcc"] } });
|
|
533
|
+
});
|
|
534
|
+
return () => { };
|
|
535
|
+
}));
|
|
536
|
+
const transport = new RpcTransport(mock.client, false);
|
|
537
|
+
transport.subscribe("any", (hex) => received.push(hex), () => { });
|
|
538
|
+
expect(received).toEqual(["0xcc"]);
|
|
539
|
+
});
|
|
540
|
+
test("calls onError on subscription stream error", () => {
|
|
541
|
+
const mock = createMockClient();
|
|
542
|
+
const errors = [];
|
|
543
|
+
mock.set_Request(((_m, _p, cb) => {
|
|
544
|
+
cb.onSuccess("sub-id", (_id, handlers) => {
|
|
545
|
+
handlers.error(new Error("stream died"));
|
|
546
|
+
});
|
|
547
|
+
return () => { };
|
|
548
|
+
}));
|
|
549
|
+
const transport = new RpcTransport(mock.client, false);
|
|
550
|
+
transport.subscribe("any", () => { }, (e) => errors.push(e));
|
|
551
|
+
expect(errors.length).toBe(1);
|
|
552
|
+
expect(errors[0]).toBeInstanceOf(StatementSubscriptionError);
|
|
553
|
+
});
|
|
554
|
+
test("calls onError when onError callback fires", () => {
|
|
555
|
+
const mock = createMockClient();
|
|
556
|
+
const errors = [];
|
|
557
|
+
mock.set_Request(((_m, _p, cb) => {
|
|
558
|
+
cb.onError(new Error("method not found"));
|
|
559
|
+
return () => { };
|
|
560
|
+
}));
|
|
561
|
+
const transport = new RpcTransport(mock.client, false);
|
|
562
|
+
transport.subscribe("any", () => { }, (e) => errors.push(e));
|
|
563
|
+
expect(errors.length).toBe(1);
|
|
564
|
+
expect(errors[0]).toBeInstanceOf(StatementSubscriptionError);
|
|
565
|
+
});
|
|
566
|
+
test("ignores unrecognized event formats silently", () => {
|
|
567
|
+
const mock = createMockClient();
|
|
568
|
+
const received = [];
|
|
569
|
+
mock.set_Request(((_m, _p, cb) => {
|
|
570
|
+
cb.onSuccess("sub-id", (_id, handlers) => {
|
|
571
|
+
handlers.next({ unrecognized: true });
|
|
572
|
+
handlers.next(42);
|
|
573
|
+
handlers.next("0xvalid");
|
|
574
|
+
});
|
|
575
|
+
return () => { };
|
|
576
|
+
}));
|
|
577
|
+
const transport = new RpcTransport(mock.client, false);
|
|
578
|
+
transport.subscribe("any", (hex) => received.push(hex), () => { });
|
|
579
|
+
// Only the raw string event should be delivered
|
|
580
|
+
expect(received).toEqual(["0xvalid"]);
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
describe("createTransport", () => {
|
|
584
|
+
test("throws StatementConnectionError when no method available", async () => {
|
|
585
|
+
// No endpoint and chain-client will fail (dynamic import)
|
|
586
|
+
await expect(createTransport({})).rejects.toThrow(StatementConnectionError);
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|