@parity/truapi 0.1.0 → 0.3.1

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.
Files changed (38) hide show
  1. package/dist/client.js +5 -2
  2. package/dist/explorer/codegen/types.d.ts +2 -0
  3. package/dist/explorer/codegen/types.js +3610 -0
  4. package/dist/explorer/codegen/versions/0.2.0/services.d.ts +2 -0
  5. package/dist/explorer/codegen/versions/0.2.0/services.js +644 -0
  6. package/dist/explorer/codegen/versions/0.2.0/types.d.ts +2 -0
  7. package/dist/explorer/codegen/versions/0.2.0/types.js +3960 -0
  8. package/dist/explorer/codegen/versions/0.3.0/services.d.ts +2 -0
  9. package/dist/explorer/codegen/versions/0.3.0/services.js +644 -0
  10. package/dist/explorer/codegen/versions/0.3.0/types.d.ts +2 -0
  11. package/dist/explorer/codegen/versions/0.3.0/types.js +3610 -0
  12. package/dist/explorer/codegen/versions/0.3.1/services.d.ts +2 -0
  13. package/dist/explorer/codegen/versions/0.3.1/services.js +644 -0
  14. package/dist/explorer/codegen/versions/0.3.1/types.d.ts +2 -0
  15. package/dist/explorer/codegen/versions/0.3.1/types.js +3610 -0
  16. package/dist/explorer/data-types.d.ts +49 -0
  17. package/dist/explorer/data-types.js +1 -0
  18. package/dist/explorer/versions.d.ts +9 -0
  19. package/dist/explorer/versions.js +21 -0
  20. package/dist/generated/client.d.ts +86 -65
  21. package/dist/generated/client.js +166 -194
  22. package/dist/generated/types.d.ts +442 -232
  23. package/dist/generated/types.js +110 -94
  24. package/dist/generated/wire-table.d.ts +5 -11
  25. package/dist/generated/wire-table.js +5 -11
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +2 -1
  28. package/dist/playground/codegen/services.js +327 -84
  29. package/dist/playground/codegen/truapi-dts.d.ts +1 -0
  30. package/dist/playground/codegen/truapi-dts.js +4310 -0
  31. package/dist/playground/services-types.d.ts +11 -2
  32. package/dist/scale.d.ts +8 -1
  33. package/dist/scale.js +19 -1
  34. package/dist/transport.d.ts +33 -6
  35. package/dist/transport.js +150 -71
  36. package/dist/well-known-chains.d.ts +13 -0
  37. package/dist/well-known-chains.js +7 -0
  38. package/package.json +28 -6
@@ -1,10 +1,19 @@
1
1
  export interface MethodInfo {
2
2
  name: string;
3
3
  type: "unary" | "subscription";
4
+ /** TS-shaped signature for the method (e.g. `getAccount(request: HostAccountGetRequest): Promise<…>`). */
5
+ signature?: string;
6
+ /** Cargo-doc URL fragment for this method (relative to the rustdoc root for the truapi crate). */
7
+ docUrl?: string;
4
8
  description?: string;
5
9
  requestDescription?: string;
6
- defaultRequest?: string;
7
- noParams?: boolean;
10
+ exampleSource?: string;
11
+ /** DataType id (kebab-case) of the method's request payload, when applicable. */
12
+ requestType?: string;
13
+ /** DataType id of the method's response. */
14
+ responseType?: string;
15
+ /** DataType id of the method's error. */
16
+ errorType?: string;
8
17
  }
9
18
  export interface ServiceInfo {
10
19
  name: string;
package/dist/scale.d.ts CHANGED
@@ -7,7 +7,14 @@
7
7
  import { type Codec } from "scale-ts";
8
8
  export type { Codec };
9
9
  export type { ResultPayload } from "scale-ts";
10
- export { Enum, Option, Result, Struct, Tuple, Vector, _void, bool, i8, i16, i32, i64, i128, str, u8, u16, u32, u64, u128, } from "scale-ts";
10
+ export { Enum, Option, Result, Struct, Tuple, Vector, _void, bool, compact, i8, i16, i32, i64, i128, str, u8, u16, u32, u64, u128, } from "scale-ts";
11
+ /**
12
+ * Substrate `OptionBool`: a one-byte `Option<bool>`.
13
+ *
14
+ * Canonical SCALE encoding (matches `parity_scale_codec::OptionBool`):
15
+ * `undefined` → `0`, `true` → `1`, `false` → `2`.
16
+ */
17
+ export declare const OptionBool: Codec<boolean | undefined>;
11
18
  /** Hex-encoded byte string, e.g. `"0xdeadbeef"`. */
12
19
  export type HexString = `0x${string}`;
13
20
  /** Assert that a string is a valid hex string (`0x...`). */
package/dist/scale.js CHANGED
@@ -5,7 +5,25 @@
5
5
  * lazy recursive codecs, and `V<N>`-indexed tagged unions).
6
6
  */
7
7
  import { Bytes, Enum, createCodec, createDecoder, enhanceCodec, u8, } from "scale-ts";
8
- export { Enum, Option, Result, Struct, Tuple, Vector, _void, bool, i8, i16, i32, i64, i128, str, u8, u16, u32, u64, u128, } from "scale-ts";
8
+ export { Enum, Option, Result, Struct, Tuple, Vector, _void, bool, compact, i8, i16, i32, i64, i128, str, u8, u16, u32, u64, u128, } from "scale-ts";
9
+ /**
10
+ * Substrate `OptionBool`: a one-byte `Option<bool>`.
11
+ *
12
+ * Canonical SCALE encoding (matches `parity_scale_codec::OptionBool`):
13
+ * `undefined` → `0`, `true` → `1`, `false` → `2`.
14
+ */
15
+ export const OptionBool = enhanceCodec(u8, (value) => (value === undefined ? 0 : value ? 1 : 2), (byte) => {
16
+ switch (byte) {
17
+ case 0:
18
+ return undefined;
19
+ case 1:
20
+ return true;
21
+ case 2:
22
+ return false;
23
+ default:
24
+ throw new Error(`Unknown OptionBool byte: ${byte}. Expected 0, 1, or 2.`);
25
+ }
26
+ });
9
27
  /** Assert that a string is a valid hex string (`0x...`). */
10
28
  export function toHexString(value) {
11
29
  if (!value.startsWith("0x")) {
@@ -1,4 +1,5 @@
1
- import { type Result } from "neverthrow";
1
+ import { type Result, type ResultAsync } from "neverthrow";
2
+ import { type ResultPayload } from "./scale.js";
2
3
  /**
3
4
  * Handle returned by TrUAPI subscription APIs.
4
5
  **/
@@ -60,14 +61,26 @@ export interface Observer<Item, Reason = never> {
60
61
  **/
61
62
  complete(): void;
62
63
  }
64
+ declare global {
65
+ interface SymbolConstructor {
66
+ readonly observable: unique symbol;
67
+ }
68
+ }
63
69
  /**
64
70
  * Minimal Observable-compatible object returned by generated subscription APIs.
71
+ *
72
+ * Implements the ES Observable interop protocol so that consumers can pass
73
+ * an instance straight to `rxjs.from(...)`.
65
74
  **/
66
75
  export interface ObservableLike<Item, Reason = never> {
67
76
  /**
68
77
  * Start the stream and receive `next`, `error`, and `complete` callbacks.
69
78
  **/
70
79
  subscribe(observer?: Partial<Observer<Item, Reason>>): Subscription;
80
+ /**
81
+ * Observable interop hook. Returns `this`.
82
+ **/
83
+ [Symbol.observable](): ObservableLike<Item, Reason>;
71
84
  }
72
85
  /**
73
86
  * Numeric frame ids for a one-shot request method.
@@ -106,7 +119,7 @@ export interface SubscriptionFrameIds {
106
119
  /**
107
120
  * Options accepted by `TrUApiTransport.request`.
108
121
  **/
109
- export interface RequestParams<Response> {
122
+ export interface RequestParams<Ok, Err> {
110
123
  /**
111
124
  * Wire discriminants for this request method.
112
125
  **/
@@ -116,9 +129,10 @@ export interface RequestParams<Response> {
116
129
  **/
117
130
  payload: Uint8Array;
118
131
  /**
119
- * Decode SCALE response payload bytes into the generated client return type.
132
+ * Decode SCALE response payload bytes into the wire `ResultPayload`
133
+ * envelope. The transport unwraps the envelope into `ResultAsync<Ok, Err>`.
120
134
  **/
121
- decodeResponse: (payload: Uint8Array) => Response;
135
+ decodeResponse: (payload: Uint8Array) => ResultPayload<Ok, Err>;
122
136
  }
123
137
  /**
124
138
  * Options accepted by `TrUApiTransport.subscribeRaw`.
@@ -158,9 +172,9 @@ export interface TrUApiTransport {
158
172
  **/
159
173
  readonly codecVersion: number;
160
174
  /**
161
- * Send a one-shot request and resolve with the decoded response payload.
175
+ * Send a one-shot request and resolve with the typed Ok/Err outcome.
162
176
  **/
163
- request<Response>(params: RequestParams<Response>): Promise<Response>;
177
+ request<Ok, Err>(params: RequestParams<Ok, Err>): ResultAsync<Ok, Err>;
164
178
  /**
165
179
  * Start a subscription and return a handle that can stop it.
166
180
  **/
@@ -231,6 +245,19 @@ export declare function encodeWireMessage(message: ProtocolMessage): Result<Uint
231
245
  * Decode a SCALE wire frame into a `ProtocolMessage`.
232
246
  **/
233
247
  export declare function decodeWireMessage(message: Uint8Array): Result<ProtocolMessage, Error>;
248
+ /**
249
+ * Create a provider for the child side of an iframe `postMessage` channel.
250
+ *
251
+ * `target` is the `Window` the provider posts to (typically `window.parent`);
252
+ * `hostOrigin` is the pinned `targetOrigin` for outbound frames and the
253
+ * required `event.origin` of inbound frames. The provider only delivers
254
+ * frames whose `event.source === target` and `event.origin === hostOrigin`,
255
+ * so it cannot be coerced by an unrelated frame parent.
256
+ **/
257
+ export declare function createIframeProvider(options: {
258
+ target: Window;
259
+ hostOrigin: string;
260
+ }): Provider;
234
261
  /**
235
262
  * Create a provider from a web or Electron `MessagePort`.
236
263
  **/
package/dist/transport.js CHANGED
@@ -1,5 +1,11 @@
1
1
  import { err, ok } from "neverthrow";
2
2
  import { str, u8 } from "./scale.js";
3
+ /**
4
+ * Coerce an unknown thrown value into an `Error` instance.
5
+ */
6
+ function toError(error) {
7
+ return error instanceof Error ? error : new Error(String(error));
8
+ }
3
9
  /**
4
10
  * Terminal error delivered through `Observer.error` for every non-normal
5
11
  * subscription end. When the peer interrupted the stream with a typed payload,
@@ -118,32 +124,137 @@ function scanStrEnd(bytes) {
118
124
  }
119
125
  return ok(total);
120
126
  }
127
+ /**
128
+ * Internal listener bookkeeping and close-once state machine shared by the
129
+ * built-in `Provider` implementations. Transport-specific code wires its
130
+ * inbound source to `deliver`, registers cleanup via `onClose`, and exposes
131
+ * `subscribe`/`subscribeClose` to callers.
132
+ **/
133
+ function createBaseProvider() {
134
+ const listeners = new Set();
135
+ const closeListeners = new Set();
136
+ const onCloseCleanup = new Set();
137
+ let closedError = null;
138
+ return {
139
+ /** Current close error, or `null` while the provider is open. */
140
+ closed: () => closedError,
141
+ /** Dispatch an inbound frame to every active subscriber. */
142
+ deliver(message) {
143
+ if (closedError)
144
+ return;
145
+ for (const listener of [...listeners])
146
+ listener(message);
147
+ },
148
+ /** Transition to the closed state. Idempotent. */
149
+ close(error) {
150
+ if (closedError)
151
+ return;
152
+ closedError = toError(error);
153
+ for (const fn of [...onCloseCleanup]) {
154
+ try {
155
+ fn();
156
+ }
157
+ catch {
158
+ // ignore cleanup failure
159
+ }
160
+ }
161
+ onCloseCleanup.clear();
162
+ for (const listener of [...closeListeners])
163
+ listener(closedError);
164
+ listeners.clear();
165
+ closeListeners.clear();
166
+ },
167
+ /** Register a cleanup function to run exactly once when `close` fires. */
168
+ onClose(fn) {
169
+ if (closedError) {
170
+ try {
171
+ fn();
172
+ }
173
+ catch {
174
+ // ignore cleanup failure
175
+ }
176
+ return;
177
+ }
178
+ onCloseCleanup.add(fn);
179
+ },
180
+ /** Register an inbound message listener. No-op after close. */
181
+ subscribe(callback) {
182
+ if (closedError)
183
+ return () => { };
184
+ listeners.add(callback);
185
+ return () => {
186
+ listeners.delete(callback);
187
+ };
188
+ },
189
+ /**
190
+ * Register a close listener. If the provider is already closed, the
191
+ * callback fires immediately with the stored error.
192
+ **/
193
+ subscribeClose(callback) {
194
+ if (closedError) {
195
+ callback(closedError);
196
+ return () => { };
197
+ }
198
+ closeListeners.add(callback);
199
+ return () => {
200
+ closeListeners.delete(callback);
201
+ };
202
+ },
203
+ };
204
+ }
205
+ /**
206
+ * Create a provider for the child side of an iframe `postMessage` channel.
207
+ *
208
+ * `target` is the `Window` the provider posts to (typically `window.parent`);
209
+ * `hostOrigin` is the pinned `targetOrigin` for outbound frames and the
210
+ * required `event.origin` of inbound frames. The provider only delivers
211
+ * frames whose `event.source === target` and `event.origin === hostOrigin`,
212
+ * so it cannot be coerced by an unrelated frame parent.
213
+ **/
214
+ export function createIframeProvider(options) {
215
+ const base = createBaseProvider();
216
+ const { target, hostOrigin } = options;
217
+ const onMessage = (event) => {
218
+ if (event.source !== target)
219
+ return;
220
+ if (event.origin !== hostOrigin)
221
+ return;
222
+ if (!(event.data instanceof Uint8Array))
223
+ return;
224
+ base.deliver(event.data);
225
+ };
226
+ window.addEventListener("message", onMessage);
227
+ base.onClose(() => window.removeEventListener("message", onMessage));
228
+ return {
229
+ postMessage(message) {
230
+ const error = base.closed();
231
+ if (error)
232
+ throw error;
233
+ try {
234
+ target.postMessage(message, hostOrigin);
235
+ }
236
+ catch (error) {
237
+ base.close(error);
238
+ throw toError(error);
239
+ }
240
+ },
241
+ subscribe: base.subscribe,
242
+ subscribeClose: base.subscribeClose,
243
+ dispose() {
244
+ base.close(new Error("iframe provider disposed"));
245
+ },
246
+ };
247
+ }
121
248
  /**
122
249
  * Create a provider from a web or Electron `MessagePort`.
123
250
  **/
124
251
  export function createMessagePortProvider(port) {
252
+ const base = createBaseProvider();
125
253
  let resolvedPort = null;
126
- let closedError = null;
127
254
  const pending = [];
128
- const listeners = [];
129
- const closeListeners = [];
130
- /**
131
- * Notify close listeners once and drop queued outbound messages.
132
- **/
133
- function notifyClose(error) {
134
- const nextError = error instanceof Error ? error : new Error(String(error));
135
- if (closedError) {
136
- return;
137
- }
138
- closedError = nextError;
139
- pending.length = 0;
140
- for (const listener of [...closeListeners]) {
141
- listener(nextError);
142
- }
143
- }
144
255
  void Promise.resolve(port)
145
256
  .then((p) => {
146
- if (closedError) {
257
+ if (base.closed()) {
147
258
  try {
148
259
  p.close();
149
260
  }
@@ -154,85 +265,53 @@ export function createMessagePortProvider(port) {
154
265
  }
155
266
  resolvedPort = p;
156
267
  p.onmessage = (event) => {
157
- const data = event.data;
158
- if (!(data instanceof Uint8Array))
159
- return;
160
- for (const listener of [...listeners])
161
- listener(data);
268
+ if (event.data instanceof Uint8Array)
269
+ base.deliver(event.data);
162
270
  };
163
271
  if ("onmessageerror" in p) {
164
272
  p.onmessageerror = () => {
165
- notifyClose(new Error("message port closed unexpectedly"));
273
+ base.close(new Error("message port closed unexpectedly"));
166
274
  };
167
275
  }
168
276
  p.start();
169
277
  for (const msg of pending)
170
278
  p.postMessage(msg);
171
279
  pending.length = 0;
280
+ base.onClose(() => {
281
+ try {
282
+ p.close();
283
+ }
284
+ catch {
285
+ // ignore duplicate close during shutdown
286
+ }
287
+ });
172
288
  })
173
289
  .catch((error) => {
174
- notifyClose(error);
290
+ base.close(error);
175
291
  });
176
292
  return {
177
- /**
178
- * Send bytes through the resolved port or queue them until it resolves.
179
- **/
180
293
  postMessage(message) {
181
- if (closedError) {
182
- throw closedError;
183
- }
294
+ const error = base.closed();
295
+ if (error)
296
+ throw error;
184
297
  if (resolvedPort) {
185
298
  try {
186
299
  resolvedPort.postMessage(message);
187
300
  }
188
301
  catch (error) {
189
- notifyClose(error);
190
- throw error instanceof Error ? error : new Error(String(error));
302
+ base.close(error);
303
+ throw toError(error);
191
304
  }
192
305
  }
193
306
  else {
194
307
  pending.push(message);
195
308
  }
196
309
  },
197
- /**
198
- * Register an inbound message listener.
199
- **/
200
- subscribe(callback) {
201
- listeners.push(callback);
202
- return () => {
203
- const idx = listeners.indexOf(callback);
204
- if (idx >= 0)
205
- listeners.splice(idx, 1);
206
- };
207
- },
208
- /**
209
- * Register a close listener.
210
- **/
211
- subscribeClose(callback) {
212
- if (closedError) {
213
- callback(closedError);
214
- return () => { };
215
- }
216
- closeListeners.push(callback);
217
- return () => {
218
- const idx = closeListeners.indexOf(callback);
219
- if (idx >= 0)
220
- closeListeners.splice(idx, 1);
221
- };
222
- },
223
- /**
224
- * Dispose the provider and close the port if it has resolved.
225
- **/
310
+ subscribe: base.subscribe,
311
+ subscribeClose: base.subscribeClose,
226
312
  dispose() {
227
- notifyClose(new Error("message port provider disposed"));
228
- try {
229
- resolvedPort?.close();
230
- }
231
- catch {
232
- // ignore duplicate close during shutdown
233
- }
234
- listeners.length = 0;
235
- closeListeners.length = 0;
313
+ base.close(new Error("message port provider disposed"));
314
+ pending.length = 0;
236
315
  },
237
316
  };
238
317
  }
@@ -0,0 +1,13 @@
1
+ /** Well-known chain descriptors. Each chain is its own `export const` so that
2
+ * bundlers can tree-shake the ones a consumer does not import. */
3
+ import type { HexString } from "./scale.js";
4
+ export interface WellKnownChain {
5
+ readonly name: string;
6
+ readonly network: "Mainnet" | "Testnet";
7
+ readonly genesis: HexString;
8
+ }
9
+ export declare const PASEO_NEXT_V2_ASSET_HUB: {
10
+ readonly name: "Paseo Next v2 Hub";
11
+ readonly network: "Testnet";
12
+ readonly genesis: "0xbf0488dbe9daa1de1c08c5f743e26fdc2a4ecd74cf87dd1b4b1eeb99ae4ef19f";
13
+ };
@@ -0,0 +1,7 @@
1
+ /** Well-known chain descriptors. Each chain is its own `export const` so that
2
+ * bundlers can tree-shake the ones a consumer does not import. */
3
+ export const PASEO_NEXT_V2_ASSET_HUB = {
4
+ name: "Paseo Next v2 Hub",
5
+ network: "Testnet",
6
+ genesis: "0xbf0488dbe9daa1de1c08c5f743e26fdc2a4ecd74cf87dd1b4b1eeb99ae4ef19f",
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parity/truapi",
3
- "version": "0.1.0",
3
+ "version": "0.3.1",
4
4
  "description": "TrUAPI TypeScript transport, SCALE codecs, and generated API client",
5
5
  "license": "MIT",
6
6
  "author": "Parity Technologies <admin@parity.io>",
@@ -19,6 +19,7 @@
19
19
  "LICENSE"
20
20
  ],
21
21
  "type": "module",
22
+ "sideEffects": false,
22
23
  "main": "dist/index.js",
23
24
  "types": "dist/index.d.ts",
24
25
  "exports": {
@@ -26,6 +27,14 @@
26
27
  "types": "./dist/index.d.ts",
27
28
  "import": "./dist/index.js"
28
29
  },
30
+ "./scale": {
31
+ "types": "./dist/scale.d.ts",
32
+ "import": "./dist/scale.js"
33
+ },
34
+ "./wire-table": {
35
+ "types": "./dist/generated/wire-table.d.ts",
36
+ "import": "./dist/generated/wire-table.js"
37
+ },
29
38
  "./playground/services": {
30
39
  "types": "./dist/playground/codegen/services.d.ts",
31
40
  "import": "./dist/playground/codegen/services.js"
@@ -33,17 +42,30 @@
33
42
  "./playground/services-types": {
34
43
  "types": "./dist/playground/services-types.d.ts",
35
44
  "import": "./dist/playground/services-types.js"
45
+ },
46
+ "./playground/codegen/truapi-dts": {
47
+ "types": "./dist/playground/codegen/truapi-dts.d.ts",
48
+ "import": "./dist/playground/codegen/truapi-dts.js"
49
+ },
50
+ "./explorer/data-types": {
51
+ "types": "./dist/explorer/data-types.d.ts",
52
+ "import": "./dist/explorer/data-types.js"
53
+ },
54
+ "./explorer/types": {
55
+ "types": "./dist/explorer/codegen/types.d.ts",
56
+ "import": "./dist/explorer/codegen/types.js"
57
+ },
58
+ "./explorer/versions": {
59
+ "types": "./dist/explorer/versions.d.ts",
60
+ "import": "./dist/explorer/versions.js"
36
61
  }
37
62
  },
38
63
  "scripts": {
39
64
  "ensure-generated": "./scripts/ensure-generated.sh",
40
65
  "build": "tsc",
41
66
  "prebuild": "npm run ensure-generated",
42
- "prepare": "npm run build",
43
- "codegen": "cargo run -p truapi-codegen -- --input ../../../target/doc/truapi.json --output src/generated --playground-output src/playground --client-examples-output test/generated/examples",
44
- "typecheck": "npm run build && npm run typecheck:examples",
45
- "pretypecheck:examples": "npm run ensure-generated",
46
- "typecheck:examples": "tsc -p tsconfig.examples.json",
67
+ "codegen": "cargo run -p truapi-codegen -- --input ../../../target/doc/truapi.json --output src/generated --playground-output src/playground --explorer-output src/explorer",
68
+ "typecheck": "npm run build",
47
69
  "pretest": "npm run ensure-generated",
48
70
  "test": "for f in test/*.test.mjs; do echo \"=== $f ===\" && bun \"$f\" || exit 1; done"
49
71
  },