@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
package/dist/errors.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { MAX_STATEMENT_SIZE } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Base class for all statement store errors.
|
|
4
|
+
*
|
|
5
|
+
* Use `instanceof StatementStoreError` to catch any error originating
|
|
6
|
+
* from the statement store package.
|
|
7
|
+
*/
|
|
8
|
+
export class StatementStoreError extends Error {
|
|
9
|
+
constructor(message, options) {
|
|
10
|
+
super(message, options);
|
|
11
|
+
this.name = "StatementStoreError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A SCALE encoding or decoding operation failed.
|
|
16
|
+
*
|
|
17
|
+
* Thrown when statement bytes cannot be parsed (corrupt data, unknown field tags)
|
|
18
|
+
* or when encoding produces invalid output.
|
|
19
|
+
*/
|
|
20
|
+
export class StatementEncodingError extends StatementStoreError {
|
|
21
|
+
constructor(message, options) {
|
|
22
|
+
super(`Encoding error: ${message}`, options);
|
|
23
|
+
this.name = "StatementEncodingError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The statement store node rejected a submitted statement.
|
|
28
|
+
*
|
|
29
|
+
* Carries the raw RPC response detail for programmatic inspection.
|
|
30
|
+
*/
|
|
31
|
+
export class StatementSubmitError extends StatementStoreError {
|
|
32
|
+
/** The raw response from the RPC call. */
|
|
33
|
+
detail;
|
|
34
|
+
constructor(detail) {
|
|
35
|
+
super(`Statement submission rejected: ${JSON.stringify(detail)}`);
|
|
36
|
+
this.name = "StatementSubmitError";
|
|
37
|
+
this.detail = detail;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Failed to set up or maintain a statement subscription.
|
|
42
|
+
*
|
|
43
|
+
* This is a non-fatal error — the client falls back to polling
|
|
44
|
+
* when subscriptions are unavailable.
|
|
45
|
+
*/
|
|
46
|
+
export class StatementSubscriptionError extends StatementStoreError {
|
|
47
|
+
constructor(message, options) {
|
|
48
|
+
super(`Subscription error: ${message}`, options);
|
|
49
|
+
this.name = "StatementSubscriptionError";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Failed to connect to the statement store transport.
|
|
54
|
+
*
|
|
55
|
+
* Thrown when the WebSocket connection cannot be established
|
|
56
|
+
* or the chain-client's bulletin chain is not connected.
|
|
57
|
+
*/
|
|
58
|
+
export class StatementConnectionError extends StatementStoreError {
|
|
59
|
+
constructor(message, options) {
|
|
60
|
+
super(`Connection error: ${message}`, options);
|
|
61
|
+
this.name = "StatementConnectionError";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The statement data payload exceeds the maximum allowed size.
|
|
66
|
+
*
|
|
67
|
+
* The statement store protocol limits individual statement data
|
|
68
|
+
* to {@link MAX_STATEMENT_SIZE} bytes (512 bytes).
|
|
69
|
+
*/
|
|
70
|
+
export class StatementDataTooLargeError extends StatementStoreError {
|
|
71
|
+
/** The actual size of the data in bytes. */
|
|
72
|
+
actualSize;
|
|
73
|
+
/** The maximum allowed size in bytes. */
|
|
74
|
+
maxSize;
|
|
75
|
+
constructor(actualSize, maxSize = MAX_STATEMENT_SIZE) {
|
|
76
|
+
super(`Statement data too large: ${actualSize} bytes exceeds maximum of ${maxSize} bytes`);
|
|
77
|
+
this.name = "StatementDataTooLargeError";
|
|
78
|
+
this.actualSize = actualSize;
|
|
79
|
+
this.maxSize = maxSize;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (import.meta.vitest) {
|
|
83
|
+
const { describe, test, expect } = import.meta.vitest;
|
|
84
|
+
describe("StatementStoreError hierarchy", () => {
|
|
85
|
+
test("StatementStoreError is instanceof Error", () => {
|
|
86
|
+
const err = new StatementStoreError("test");
|
|
87
|
+
expect(err).toBeInstanceOf(Error);
|
|
88
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
89
|
+
expect(err.name).toBe("StatementStoreError");
|
|
90
|
+
expect(err.message).toBe("test");
|
|
91
|
+
});
|
|
92
|
+
test("StatementEncodingError", () => {
|
|
93
|
+
const err = new StatementEncodingError("bad field tag");
|
|
94
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
95
|
+
expect(err).toBeInstanceOf(Error);
|
|
96
|
+
expect(err.name).toBe("StatementEncodingError");
|
|
97
|
+
expect(err.message).toContain("bad field tag");
|
|
98
|
+
});
|
|
99
|
+
test("StatementEncodingError preserves cause", () => {
|
|
100
|
+
const cause = new Error("original");
|
|
101
|
+
const err = new StatementEncodingError("wrap", { cause });
|
|
102
|
+
expect(err.cause).toBe(cause);
|
|
103
|
+
});
|
|
104
|
+
test("StatementSubmitError", () => {
|
|
105
|
+
const detail = { status: "rejected", reason: "bad proof" };
|
|
106
|
+
const err = new StatementSubmitError(detail);
|
|
107
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
108
|
+
expect(err.name).toBe("StatementSubmitError");
|
|
109
|
+
expect(err.detail).toBe(detail);
|
|
110
|
+
expect(err.message).toContain("rejected");
|
|
111
|
+
});
|
|
112
|
+
test("StatementSubscriptionError", () => {
|
|
113
|
+
const err = new StatementSubscriptionError("not supported");
|
|
114
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
115
|
+
expect(err.name).toBe("StatementSubscriptionError");
|
|
116
|
+
expect(err.message).toContain("not supported");
|
|
117
|
+
});
|
|
118
|
+
test("StatementConnectionError", () => {
|
|
119
|
+
const err = new StatementConnectionError("timeout");
|
|
120
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
121
|
+
expect(err.name).toBe("StatementConnectionError");
|
|
122
|
+
expect(err.message).toContain("timeout");
|
|
123
|
+
});
|
|
124
|
+
test("StatementDataTooLargeError", () => {
|
|
125
|
+
const err = new StatementDataTooLargeError(600);
|
|
126
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
127
|
+
expect(err.name).toBe("StatementDataTooLargeError");
|
|
128
|
+
expect(err.actualSize).toBe(600);
|
|
129
|
+
expect(err.maxSize).toBe(512);
|
|
130
|
+
expect(err.message).toContain("600");
|
|
131
|
+
expect(err.message).toContain("512");
|
|
132
|
+
});
|
|
133
|
+
test("StatementDataTooLargeError with custom max", () => {
|
|
134
|
+
const err = new StatementDataTooLargeError(2000, 1024);
|
|
135
|
+
expect(err.actualSize).toBe(2000);
|
|
136
|
+
expect(err.maxSize).toBe(1024);
|
|
137
|
+
});
|
|
138
|
+
test("all errors are catchable via base class", () => {
|
|
139
|
+
const errors = [
|
|
140
|
+
new StatementEncodingError("test"),
|
|
141
|
+
new StatementSubmitError("test"),
|
|
142
|
+
new StatementSubscriptionError("test"),
|
|
143
|
+
new StatementConnectionError("test"),
|
|
144
|
+
new StatementDataTooLargeError(600),
|
|
145
|
+
];
|
|
146
|
+
for (const err of errors) {
|
|
147
|
+
expect(err).toBeInstanceOf(StatementStoreError);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { StatementStoreClient } from "./client.js";
|
|
2
|
+
export { ChannelStore } from "./channels.js";
|
|
3
|
+
export { createTopic, createChannel, serializeTopicFilter, topicToHex, topicsEqual, } from "./topics.js";
|
|
4
|
+
export { encodeData, decodeData, encodeStatement, decodeStatement, createSignatureMaterial, toHex, fromHex, } from "./codec.js";
|
|
5
|
+
export { RpcTransport, createTransport } from "./transport.js";
|
|
6
|
+
export type { RpcClient } from "./transport.js";
|
|
7
|
+
export { StatementStoreError, StatementEncodingError, StatementSubmitError, StatementSubscriptionError, StatementConnectionError, StatementDataTooLargeError, } from "./errors.js";
|
|
8
|
+
export type { TopicHash, ChannelHash, StatementFields, DecodedStatement, TopicFilter, SerializedTopicFilter, StatementStoreConfig, PublishOptions, ReceivedStatement, StatementSigner, StatementSignerWithKey, SubmitStatus, StatementTransport, Unsubscribable, StatementEvent, } from "./types.js";
|
|
9
|
+
export { MAX_STATEMENT_SIZE, MAX_USER_TOTAL, DEFAULT_TTL_SECONDS, DEFAULT_POLL_INTERVAL_MS, } from "./types.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EACH,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,WAAW,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EACH,UAAU,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,KAAK,EACL,OAAO,GACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/D,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,EACH,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,GAC7B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACR,SAAS,EACT,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,cAAc,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACH,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,wBAAwB,GAC3B,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Client
|
|
2
|
+
export { StatementStoreClient } from "./client.js";
|
|
3
|
+
export { ChannelStore } from "./channels.js";
|
|
4
|
+
// Topics
|
|
5
|
+
export { createTopic, createChannel, serializeTopicFilter, topicToHex, topicsEqual, } from "./topics.js";
|
|
6
|
+
// Codec (advanced use — for consumers that need direct SCALE access)
|
|
7
|
+
export { encodeData, decodeData, encodeStatement, decodeStatement, createSignatureMaterial, toHex, fromHex, } from "./codec.js";
|
|
8
|
+
// Transport (advanced use — for consumers that need custom transport implementations)
|
|
9
|
+
export { RpcTransport, createTransport } from "./transport.js";
|
|
10
|
+
// Errors
|
|
11
|
+
export { StatementStoreError, StatementEncodingError, StatementSubmitError, StatementSubscriptionError, StatementConnectionError, StatementDataTooLargeError, } from "./errors.js";
|
|
12
|
+
// Constants
|
|
13
|
+
export { MAX_STATEMENT_SIZE, MAX_USER_TOTAL, DEFAULT_TTL_SECONDS, DEFAULT_POLL_INTERVAL_MS, } from "./types.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,SAAS;AACT,OAAO,EACH,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,UAAU,EACV,WAAW,GACd,MAAM,aAAa,CAAC;AAErB,qEAAqE;AACrE,OAAO,EACH,UAAU,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,KAAK,EACL,OAAO,GACV,MAAM,YAAY,CAAC;AAEpB,sFAAsF;AACtF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG/D,SAAS;AACT,OAAO,EACH,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,GAC7B,MAAM,aAAa,CAAC;AAqBrB,YAAY;AACZ,OAAO,EACH,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,wBAAwB,GAC3B,MAAM,YAAY,CAAC"}
|
package/dist/topics.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ChannelHash, SerializedTopicFilter, TopicFilter, TopicHash } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a 32-byte topic hash from a human-readable string.
|
|
4
|
+
*
|
|
5
|
+
* Uses blake2b-256 to hash the UTF-8 encoded string into a deterministic
|
|
6
|
+
* 32-byte topic identifier. Statements are tagged with topics so subscribers
|
|
7
|
+
* can filter efficiently on the network.
|
|
8
|
+
*
|
|
9
|
+
* @param name - A human-readable topic name (e.g., "ss-webrtc", "my-app").
|
|
10
|
+
* @returns A branded 32-byte topic hash.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const topic = createTopic("ss-webrtc");
|
|
15
|
+
* // Use in subscriptions and publish options
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function createTopic(name: string): TopicHash;
|
|
19
|
+
/**
|
|
20
|
+
* Create a 32-byte channel hash from a human-readable channel name.
|
|
21
|
+
*
|
|
22
|
+
* Channels enable last-write-wins semantics: for a given channel,
|
|
23
|
+
* only the most recent statement (by timestamp) is retained.
|
|
24
|
+
*
|
|
25
|
+
* @param name - A human-readable channel name (e.g., "presence/peer-abc").
|
|
26
|
+
* @returns A branded 32-byte channel hash.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const channel = createChannel("presence/peer-abc123");
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createChannel(name: string): ChannelHash;
|
|
34
|
+
/**
|
|
35
|
+
* Convert a topic or channel hash to a hex string (with 0x prefix).
|
|
36
|
+
*
|
|
37
|
+
* @param hash - A 32-byte topic or channel hash.
|
|
38
|
+
* @returns Hex string with "0x" prefix.
|
|
39
|
+
*/
|
|
40
|
+
export declare function topicToHex(hash: Uint8Array): string;
|
|
41
|
+
/**
|
|
42
|
+
* Compare two topic or channel hashes for byte equality.
|
|
43
|
+
*
|
|
44
|
+
* @param a - First hash.
|
|
45
|
+
* @param b - Second hash.
|
|
46
|
+
* @returns True if the hashes are identical.
|
|
47
|
+
*/
|
|
48
|
+
export declare function topicsEqual(a: Uint8Array, b: Uint8Array): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Serialize a {@link TopicFilter} into the JSON-RPC format expected by statement store nodes.
|
|
51
|
+
*
|
|
52
|
+
* - `"any"` is passed through as the string `"any"`.
|
|
53
|
+
* - `{ matchAll: [...] }` becomes `{ matchAll: ["0x...", ...] }` with hex-encoded topics.
|
|
54
|
+
* - `{ matchAny: [...] }` becomes `{ matchAny: ["0x...", ...] }` with hex-encoded topics.
|
|
55
|
+
*
|
|
56
|
+
* @param filter - The topic filter to serialize.
|
|
57
|
+
* @returns A JSON-RPC compatible filter value.
|
|
58
|
+
*/
|
|
59
|
+
export declare function serializeTopicFilter(filter: TopicFilter): SerializedTopicFilter;
|
|
60
|
+
//# sourceMappingURL=topics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topics.d.ts","sourceRoot":"","sources":["../src/topics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAGnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMnD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAMjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,qBAAqB,CAQ/E"}
|
package/dist/topics.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { blake2b } from "@noble/hashes/blake2.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a 32-byte topic hash from a human-readable string.
|
|
4
|
+
*
|
|
5
|
+
* Uses blake2b-256 to hash the UTF-8 encoded string into a deterministic
|
|
6
|
+
* 32-byte topic identifier. Statements are tagged with topics so subscribers
|
|
7
|
+
* can filter efficiently on the network.
|
|
8
|
+
*
|
|
9
|
+
* @param name - A human-readable topic name (e.g., "ss-webrtc", "my-app").
|
|
10
|
+
* @returns A branded 32-byte topic hash.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const topic = createTopic("ss-webrtc");
|
|
15
|
+
* // Use in subscriptions and publish options
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function createTopic(name) {
|
|
19
|
+
const bytes = new TextEncoder().encode(name);
|
|
20
|
+
return blake2b(bytes, { dkLen: 32 });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a 32-byte channel hash from a human-readable channel name.
|
|
24
|
+
*
|
|
25
|
+
* Channels enable last-write-wins semantics: for a given channel,
|
|
26
|
+
* only the most recent statement (by timestamp) is retained.
|
|
27
|
+
*
|
|
28
|
+
* @param name - A human-readable channel name (e.g., "presence/peer-abc").
|
|
29
|
+
* @returns A branded 32-byte channel hash.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const channel = createChannel("presence/peer-abc123");
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function createChannel(name) {
|
|
37
|
+
const bytes = new TextEncoder().encode(name);
|
|
38
|
+
return blake2b(bytes, { dkLen: 32 });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Convert a topic or channel hash to a hex string (with 0x prefix).
|
|
42
|
+
*
|
|
43
|
+
* @param hash - A 32-byte topic or channel hash.
|
|
44
|
+
* @returns Hex string with "0x" prefix.
|
|
45
|
+
*/
|
|
46
|
+
export function topicToHex(hash) {
|
|
47
|
+
let hex = "0x";
|
|
48
|
+
for (let i = 0; i < hash.length; i++) {
|
|
49
|
+
hex += hash[i].toString(16).padStart(2, "0");
|
|
50
|
+
}
|
|
51
|
+
return hex;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Compare two topic or channel hashes for byte equality.
|
|
55
|
+
*
|
|
56
|
+
* @param a - First hash.
|
|
57
|
+
* @param b - Second hash.
|
|
58
|
+
* @returns True if the hashes are identical.
|
|
59
|
+
*/
|
|
60
|
+
export function topicsEqual(a, b) {
|
|
61
|
+
if (a.length !== b.length)
|
|
62
|
+
return false;
|
|
63
|
+
for (let i = 0; i < a.length; i++) {
|
|
64
|
+
if (a[i] !== b[i])
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Serialize a {@link TopicFilter} into the JSON-RPC format expected by statement store nodes.
|
|
71
|
+
*
|
|
72
|
+
* - `"any"` is passed through as the string `"any"`.
|
|
73
|
+
* - `{ matchAll: [...] }` becomes `{ matchAll: ["0x...", ...] }` with hex-encoded topics.
|
|
74
|
+
* - `{ matchAny: [...] }` becomes `{ matchAny: ["0x...", ...] }` with hex-encoded topics.
|
|
75
|
+
*
|
|
76
|
+
* @param filter - The topic filter to serialize.
|
|
77
|
+
* @returns A JSON-RPC compatible filter value.
|
|
78
|
+
*/
|
|
79
|
+
export function serializeTopicFilter(filter) {
|
|
80
|
+
if (filter === "any")
|
|
81
|
+
return "any";
|
|
82
|
+
if ("matchAll" in filter) {
|
|
83
|
+
return { matchAll: filter.matchAll.map(topicToHex) };
|
|
84
|
+
}
|
|
85
|
+
return { matchAny: filter.matchAny.map(topicToHex) };
|
|
86
|
+
}
|
|
87
|
+
if (import.meta.vitest) {
|
|
88
|
+
const { describe, test, expect } = import.meta.vitest;
|
|
89
|
+
describe("createTopic", () => {
|
|
90
|
+
test("produces a 32-byte hash", () => {
|
|
91
|
+
const topic = createTopic("test");
|
|
92
|
+
expect(topic).toBeInstanceOf(Uint8Array);
|
|
93
|
+
expect(topic.length).toBe(32);
|
|
94
|
+
});
|
|
95
|
+
test("is deterministic (same input = same hash)", () => {
|
|
96
|
+
const a = createTopic("ss-webrtc");
|
|
97
|
+
const b = createTopic("ss-webrtc");
|
|
98
|
+
expect(topicsEqual(a, b)).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
test("different inputs produce different hashes", () => {
|
|
101
|
+
const a = createTopic("topic-a");
|
|
102
|
+
const b = createTopic("topic-b");
|
|
103
|
+
expect(topicsEqual(a, b)).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
test("empty string produces a valid hash", () => {
|
|
106
|
+
const topic = createTopic("");
|
|
107
|
+
expect(topic.length).toBe(32);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe("createChannel", () => {
|
|
111
|
+
test("produces a 32-byte hash", () => {
|
|
112
|
+
const channel = createChannel("presence/peer-abc");
|
|
113
|
+
expect(channel).toBeInstanceOf(Uint8Array);
|
|
114
|
+
expect(channel.length).toBe(32);
|
|
115
|
+
});
|
|
116
|
+
test("same input as createTopic produces same bytes", () => {
|
|
117
|
+
const topic = createTopic("test-name");
|
|
118
|
+
const channel = createChannel("test-name");
|
|
119
|
+
expect(topicsEqual(topic, channel)).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe("topicToHex", () => {
|
|
123
|
+
test("converts to hex with 0x prefix", () => {
|
|
124
|
+
const hash = new Uint8Array(32);
|
|
125
|
+
hash[0] = 0xab;
|
|
126
|
+
hash[1] = 0xcd;
|
|
127
|
+
const hex = topicToHex(hash);
|
|
128
|
+
expect(hex).toMatch(/^0x/);
|
|
129
|
+
expect(hex).toBe("0x" + "abcd" + "00".repeat(30));
|
|
130
|
+
});
|
|
131
|
+
test("round-trips through hex encoding", () => {
|
|
132
|
+
const topic = createTopic("round-trip-test");
|
|
133
|
+
const hex = topicToHex(topic);
|
|
134
|
+
expect(hex.length).toBe(2 + 64); // "0x" + 64 hex chars
|
|
135
|
+
});
|
|
136
|
+
test("pads single-digit bytes with leading zero", () => {
|
|
137
|
+
const hash = new Uint8Array([0x0a]);
|
|
138
|
+
expect(topicToHex(hash)).toBe("0x0a");
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("topicsEqual", () => {
|
|
142
|
+
test("returns true for identical hashes", () => {
|
|
143
|
+
const a = createTopic("same");
|
|
144
|
+
const b = createTopic("same");
|
|
145
|
+
expect(topicsEqual(a, b)).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
test("returns false for different hashes", () => {
|
|
148
|
+
const a = createTopic("alpha");
|
|
149
|
+
const b = createTopic("beta");
|
|
150
|
+
expect(topicsEqual(a, b)).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
test("returns false for different lengths", () => {
|
|
153
|
+
const a = new Uint8Array(32);
|
|
154
|
+
const b = new Uint8Array(16);
|
|
155
|
+
expect(topicsEqual(a, b)).toBe(false);
|
|
156
|
+
});
|
|
157
|
+
test("returns true for empty arrays", () => {
|
|
158
|
+
expect(topicsEqual(new Uint8Array(0), new Uint8Array(0))).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe("serializeTopicFilter", () => {
|
|
162
|
+
test("serializes 'any' as string", () => {
|
|
163
|
+
expect(serializeTopicFilter("any")).toBe("any");
|
|
164
|
+
});
|
|
165
|
+
test("serializes matchAll with hex topics", () => {
|
|
166
|
+
const topics = [createTopic("a"), createTopic("b")];
|
|
167
|
+
const result = serializeTopicFilter({ matchAll: topics });
|
|
168
|
+
expect(result.matchAll).toHaveLength(2);
|
|
169
|
+
expect(result.matchAll[0]).toMatch(/^0x[0-9a-f]{64}$/);
|
|
170
|
+
expect(result.matchAll[1]).toMatch(/^0x[0-9a-f]{64}$/);
|
|
171
|
+
});
|
|
172
|
+
test("serializes matchAny with hex topics", () => {
|
|
173
|
+
const topics = [createTopic("x")];
|
|
174
|
+
const result = serializeTopicFilter({ matchAny: topics });
|
|
175
|
+
expect(result.matchAny).toHaveLength(1);
|
|
176
|
+
expect(result.matchAny[0]).toMatch(/^0x[0-9a-f]{64}$/);
|
|
177
|
+
});
|
|
178
|
+
test("matchAll preserves order", () => {
|
|
179
|
+
const topicA = createTopic("first");
|
|
180
|
+
const topicB = createTopic("second");
|
|
181
|
+
const result = serializeTopicFilter({ matchAll: [topicA, topicB] });
|
|
182
|
+
expect(result.matchAll[0]).toBe(topicToHex(topicA));
|
|
183
|
+
expect(result.matchAll[1]).toBe(topicToHex(topicB));
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=topics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topics.js","sourceRoot":"","sources":["../src/topics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { StatementTransport, SubmitStatus, TopicFilter, TopicHash, Unsubscribable } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* A PolkadotClient-compatible interface for raw RPC operations.
|
|
4
|
+
*
|
|
5
|
+
* This matches the subset of `PolkadotClient` methods we need.
|
|
6
|
+
* Using an interface allows easy mocking in tests.
|
|
7
|
+
*/
|
|
8
|
+
export interface RpcClient {
|
|
9
|
+
/** Make a one-shot RPC request. */
|
|
10
|
+
request: (method: string, params: unknown[]) => Promise<unknown>;
|
|
11
|
+
/** Start a subscription. Returns an unsubscribe function. */
|
|
12
|
+
_request: <T, S>(method: string, params: unknown[], callbacks: {
|
|
13
|
+
onSuccess: (subscriptionId: T, followSubscription: (id: T, handlers: {
|
|
14
|
+
next: (event: S) => void;
|
|
15
|
+
error: (e: Error) => void;
|
|
16
|
+
}) => void) => void;
|
|
17
|
+
onError: (error: Error) => void;
|
|
18
|
+
}) => () => void;
|
|
19
|
+
/** Destroy the client and close the connection. */
|
|
20
|
+
destroy: () => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Statement store transport using JSON-RPC over WebSocket.
|
|
24
|
+
*
|
|
25
|
+
* Communicates with a statement store node via the standard `statement_*` RPC methods.
|
|
26
|
+
* Supports both subscription-based real-time delivery and polling-based queries
|
|
27
|
+
* with graceful fallback across multiple RPC methods.
|
|
28
|
+
*/
|
|
29
|
+
export declare class RpcTransport implements StatementTransport {
|
|
30
|
+
private readonly client;
|
|
31
|
+
private readonly ownsClient;
|
|
32
|
+
/**
|
|
33
|
+
* @param client - The RPC client to use for communication.
|
|
34
|
+
* @param ownsClient - If true, `destroy()` will also destroy the client.
|
|
35
|
+
* Set to false when sharing a client from chain-client.
|
|
36
|
+
*/
|
|
37
|
+
constructor(client: RpcClient, ownsClient: boolean);
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to statements matching a topic filter.
|
|
40
|
+
*
|
|
41
|
+
* Uses the `statement_subscribeStatement` RPC method which returns
|
|
42
|
+
* batched events via a subscription stream. Handles all three event formats
|
|
43
|
+
* (raw hex, StatementEvent, nested wrappers) for cross-node compatibility.
|
|
44
|
+
*
|
|
45
|
+
* If the node does not support subscriptions, `onError` is called
|
|
46
|
+
* and the caller should fall back to polling.
|
|
47
|
+
*/
|
|
48
|
+
subscribe(filter: TopicFilter, onStatement: (statementHex: string) => void, onError: (error: Error) => void): Unsubscribable;
|
|
49
|
+
/**
|
|
50
|
+
* Submit a signed statement via the `statement_submit` RPC method.
|
|
51
|
+
*
|
|
52
|
+
* @returns The submission status extracted from the RPC response.
|
|
53
|
+
*/
|
|
54
|
+
submit(statementHex: string): Promise<SubmitStatus>;
|
|
55
|
+
/**
|
|
56
|
+
* Query existing statements from the store.
|
|
57
|
+
*
|
|
58
|
+
* Tries multiple RPC methods with graceful fallback:
|
|
59
|
+
* 1. `statement_posted` — filtered by topics + decryptionKey (most efficient)
|
|
60
|
+
* 2. `statement_broadcasts` — filtered by topics only
|
|
61
|
+
* 3. `statement_dump` — unfiltered, returns all statements
|
|
62
|
+
*
|
|
63
|
+
* Each method returns hex-encoded statements. If a method is not supported
|
|
64
|
+
* by the node, the next one is tried.
|
|
65
|
+
*/
|
|
66
|
+
query(topics: TopicHash[], decryptionKey?: string): Promise<string[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Destroy the transport and release resources.
|
|
69
|
+
*
|
|
70
|
+
* If this transport owns the RPC client (created via `endpoint` config),
|
|
71
|
+
* the client is also destroyed. If the client is shared from chain-client,
|
|
72
|
+
* only the transport's state is cleaned up.
|
|
73
|
+
*/
|
|
74
|
+
destroy(): void;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a statement store transport.
|
|
78
|
+
*
|
|
79
|
+
* Strategy (Host API first):
|
|
80
|
+
* 1. Try chain-client's bulletin chain connection — this uses product-sdk's
|
|
81
|
+
* `createPapiProvider` which routes through the Host API when inside a container,
|
|
82
|
+
* falling back to direct RPC outside.
|
|
83
|
+
* 2. If chain-client is unavailable (not initialized, not installed), fall back
|
|
84
|
+
* to a direct WebSocket connection using the provided `endpoint`.
|
|
85
|
+
* 3. If neither works, throw {@link StatementConnectionError}.
|
|
86
|
+
*
|
|
87
|
+
* @param config - Configuration with an optional fallback `endpoint`.
|
|
88
|
+
* @returns A configured {@link StatementTransport}.
|
|
89
|
+
* @throws {StatementConnectionError} If no connection method is available.
|
|
90
|
+
*/
|
|
91
|
+
export declare function createTransport(config: {
|
|
92
|
+
endpoint?: string;
|
|
93
|
+
}): Promise<StatementTransport>;
|
|
94
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAER,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,SAAS,EACT,cAAc,EACjB,MAAM,YAAY,CAAC;AAoDpB;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACtB,mCAAmC;IACnC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,6DAA6D;IAC7D,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,EACjB,SAAS,EAAE;QACP,SAAS,EAAE,CACP,cAAc,EAAE,CAAC,EACjB,kBAAkB,EAAE,CAChB,EAAE,EAAE,CAAC,EACL,QAAQ,EAAE;YAAE,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;YAAC,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;SAAE,KAChE,IAAI,KACR,IAAI,CAAC;QACV,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACnC,KACA,MAAM,IAAI,CAAC;IAChB,mDAAmD;IACnD,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,kBAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IAErC;;;;OAIG;gBACS,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO;IAKlD;;;;;;;;;OASG;IACH,SAAS,CACL,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,EAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAChC,cAAc;IAoDjB;;;;OAIG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAQzD;;;;;;;;;;OAUG;IACG,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAyC3E;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;CAKlB;AA8BD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsB9B"}
|