@parity/product-sdk-host 0.11.0 → 0.13.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/index.d.ts CHANGED
@@ -1,16 +1,19 @@
1
- import { JsonRpcProvider } from 'polkadot-api';
2
- import * as _novasamatech_host_api from '@novasamatech/host-api';
3
- import { Subscription, Transport, CodecType, AllocatableResource as AllocatableResource$1, AllocationOutcome as AllocationOutcome$1, RemotePermission as RemotePermission$1, DevicePermission, HexString } from '@novasamatech/host-api';
4
- export { HexString, PushNotificationError, assertEnumVariant, enumValue, fromHex, isEnumVariant, resultErr, resultOk, toHex, unwrapResultOrThrow } from '@novasamatech/host-api';
5
- import * as _novasamatech_host_api_wrapper from '@novasamatech/host-api-wrapper';
6
- import { hostLocalStorage, createStatementStore, ProductAccountId as ProductAccountId$1, SignedStatement as SignedStatement$1, Statement as Statement$1, StatementTopicFilter as StatementTopicFilter$1, StatementsPage as StatementsPage$1, Topic as Topic$1, createAccountsProvider, preimageManager, ThemeMode as ThemeMode$1, createThemeProvider, ChatBotRegistrationResult as ChatBotRegistrationResult$1, ChatCustomMessageRenderer as ChatCustomMessageRenderer$1, ChatCustomMessageRendererParams as ChatCustomMessageRendererParams$1, createProductChatManager, ChatMessageContent as ChatMessageContent$1, ChatReceivedAction as ChatReceivedAction$1, ChatRoom as ChatRoom$1, ChatRoomRegistrationResult as ChatRoomRegistrationResult$1, PaymentBalance as PaymentBalance$1, paymentManager, PaymentStatus as PaymentStatus$1, TopUpSource as TopUpSource$1, notificationManager } from '@novasamatech/host-api-wrapper';
1
+ import { JsonRpcProvider, PolkadotSigner } from 'polkadot-api';
2
+ import { Topic, RemoteStatementStoreSubscribeItem, Statement, StatementProof, SignedStatement, HexString, GenericError, TrUApiClient, AllocatableResource, AllocationOutcome, HostGetUserIdError, HostRequestLoginResponse, HostRequestLoginError, ProductAccountId, ProductAccount as ProductAccount$1, HostAccountGetError, HostAccountGetAliasResponse, LegacyAccount, RingLocation, HostAccountCreateProofError, HostAccountConnectionStatusSubscribeItem, HostDevicePermissionRequest, RemotePermission, HostThemeSubscribeItem, ChatBotRegistrationStatus, HostChatCreateRoomRequest, ChatRoomRegistrationStatus, HostChatRegisterBotRequest, ChatMessageContent, ChatRoom, HostChatActionSubscribeItem, HostPaymentBalanceSubscribeItem, PaymentPurseId, Balance, PaymentTopUpSource, HostPaymentStatusSubscribeItem, HostPushNotificationRequest, NotificationId } from '@parity/truapi';
3
+ export { AllocatableResource, AllocationOutcome, ChatMessageContent, ChatRoom, HexString, HostPaymentBalanceSubscribeItem, HostPaymentStatusSubscribeItem, NotificationId, PaymentTopUpSource, ProductAccountId, HostPushNotificationError as PushNotificationError, RemotePermission, RingLocation, SignedStatement, Statement, StatementProof, ThemeName, ThemeVariant, Topic } from '@parity/truapi';
4
+ import { SdkError } from '@parity/product-sdk-errors';
5
+ export { SdkError, isSdkError } from '@parity/product-sdk-errors';
6
+ import { Result } from '@parity/result';
7
+ export { Result, err, ok } from '@parity/result';
8
+ import { ResultAsync as ResultAsync$1 } from 'neverthrow';
9
+ export { i as isInsideContainerSync } from './transport-B0cdhwrp.js';
7
10
 
8
11
  /**
9
12
  * Public types for the host wrappers.
10
13
  *
11
- * These are re-exported from `@novasamatech/host-api-wrapper` (the runtime
12
- * objects the host getters cast to) rather than hand-mirrored, so the
13
- * Parity surface stays in lockstep with the upstream codec types.
14
+ * The statement-store types are re-exported from `@parity/truapi` so the Parity
15
+ * surface stays in lockstep with the in-house protocol codec types. Their fields
16
+ * are `0x`-prefixed hex strings (`HexString`) and their enums are `{ tag }` unions.
14
17
  */
15
18
 
16
19
  /**
@@ -20,59 +23,71 @@ import { hostLocalStorage, createStatementStore, ProductAccountId as ProductAcco
20
23
  * via {@link getHostLocalStorage} when you need raw host storage without the
21
24
  * KV abstraction.
22
25
  *
23
- * Type identical to `hostLocalStorage` from `@novasamatech/host-api-wrapper`.
24
- */
25
- type HostLocalStorage = typeof hostLocalStorage;
26
+ * Backed by `truApi.localStorage.*` (raw `read`/`write`/`clear` over hex bytes);
27
+ * {@link getHostLocalStorage} adapts that into this richer surface. `readString`
28
+ * resolves to `""` for a missing key and `readJSON`/`readBytes` to
29
+ * `null`/`undefined`.
30
+ */
31
+ interface HostLocalStorage {
32
+ /** Read a UTF-8 string value; `""` when the key is absent. */
33
+ readString(key: string): Promise<string>;
34
+ /** Write a UTF-8 string value. */
35
+ writeString(key: string, value: string): Promise<void>;
36
+ /** Read and JSON-parse a value; `null` when the key is absent. */
37
+ readJSON(key: string): Promise<unknown>;
38
+ /** JSON-stringify and write a value. */
39
+ writeJSON(key: string, value: unknown): Promise<void>;
40
+ /** Read raw bytes; `undefined` when the key is absent. */
41
+ readBytes(key: string): Promise<Uint8Array | undefined>;
42
+ /** Write raw bytes. */
43
+ writeBytes(key: string, value: Uint8Array): Promise<void>;
44
+ /** Remove a key. */
45
+ clear(key: string): Promise<void>;
46
+ }
26
47
  /**
27
- * Cryptographic proof attached to a statement before submission, returned by
28
- * {@link HostStatementStore.createProof}. Variants cover the supported
29
- * signature schemes - `Sr25519`, `Ed25519`, `Ecdsa`, and `OnChain` (chain-
30
- * attestation-based proofs).
48
+ * Topic-based subscription filter. The host delivers statements that match
49
+ * either *all* of the listed topics (`matchAll`) or *any* of them (`matchAny`).
31
50
  *
32
- * Inferred from `createStatementStore().createProof`'s return type so codec
33
- * changes surface here as compile errors, not runtime decode failures.
51
+ * This is a field-discriminated form of truapi's `RemoteStatementStoreSubscribeRequest`,
52
+ * which is a tagged union (`{ tag: "MatchAll"; value: Topic[] } | { tag: "MatchAny"; value: Topic[] }`).
53
+ * The transport maps between the two.
34
54
  */
35
- type StatementProof = Awaited<ReturnType<ReturnType<typeof createStatementStore>["createProof"]>>;
36
- /**
37
- * Topic-based subscription filter. The host delivers statements that match
38
- * either *all* of the listed topics (`matchAll`) or *any* of them
39
- * (`matchAny`). Re-exported from `@novasamatech/host-api-wrapper`.
40
- */
41
- type StatementTopicFilter = StatementTopicFilter$1;
42
- /** A single topic value used inside a {@link StatementTopicFilter}. Re-exported from `@novasamatech/host-api-wrapper`. */
43
- type Topic = Topic$1;
44
- /** `[ss58Address, chainPrefix]` tuple identifying a product account at the codec layer. Re-exported from `@novasamatech/host-api-wrapper`. */
45
- type ProductAccountId = ProductAccountId$1;
46
- /** Unsigned statement payload. Re-exported from `@novasamatech/host-api-wrapper`. */
47
- type Statement = Statement$1;
48
- /** Statement bundled with its {@link StatementProof}. Re-exported from `@novasamatech/host-api-wrapper`. */
49
- type SignedStatement = SignedStatement$1;
55
+ type StatementTopicFilter = {
56
+ matchAll: Topic[];
57
+ } | {
58
+ matchAny: Topic[];
59
+ };
50
60
  /**
51
61
  * A page of signed statements delivered by {@link HostStatementStore.subscribe}.
52
62
  *
53
- * Pages arrive sequentially. `isComplete` is `true` on the final page of a
54
- * subscription's initial backfill; subsequent pages contain new statements
55
- * as they appear on chain. `statements` is `SignedStatement[]` (typed,
56
- * not `unknown[]`).
63
+ * truapi's `RemoteStatementStoreSubscribeItem`, re-exported under a friendlier
64
+ * name. Pages arrive sequentially; `isComplete` is `false` while the host
65
+ * streams the historical backfill and `true` once it's done (and on every
66
+ * subsequent live-update page).
57
67
  */
58
- type StatementsPage = StatementsPage$1;
68
+ type StatementsPage = RemoteStatementStoreSubscribeItem;
59
69
  /**
60
- * Subscription handle returned by the host - equivalent to
61
- * `Subscription<void>` from `@novasamatech/host-api`. Exposes
62
- * `unsubscribe()` plus an `onInterrupt` hook that fires if the host
63
- * interrupts the subscription server-side.
70
+ * Subscription handle returned by the host. Exposes `unsubscribe()` plus an
71
+ * `onInterrupt` hook that fires if the host interrupts the subscription
72
+ * server-side; `onInterrupt` returns a function that cancels the hook.
64
73
  */
65
- type HostSubscription = Subscription<void>;
74
+ interface HostSubscription {
75
+ unsubscribe(): void;
76
+ onInterrupt(callback: (reason?: unknown) => void): () => void;
77
+ }
66
78
  /**
67
- * Statement Store handle exposed by the host container. Provides
68
- * `subscribe`, `createProof`, and `submit` operations that go through the
69
- * host's native binary protocol; the `statement-store` package layers a
70
- * higher-level client on top.
71
- *
72
- * Type identical to `createStatementStore()` from
73
- * `@novasamatech/host-api-wrapper`.
74
- */
75
- type HostStatementStore = ReturnType<typeof createStatementStore>;
79
+ * Statement Store handle exposed by the host container, backed by
80
+ * `truApi.statementStore.*`. `subscribe` streams matching statements;
81
+ * `createProofAuthorized` signs a statement with the product's RFC-10 allowance
82
+ * account (the sponsored path — no per-call account id); `submit` publishes a
83
+ * signed statement. The `statement-store` package layers a higher-level client
84
+ * on top.
85
+ */
86
+ interface HostStatementStore {
87
+ subscribe(filter: StatementTopicFilter, callback: (page: StatementsPage) => void): HostSubscription;
88
+ createProofAuthorized(statement: Statement): Promise<StatementProof>;
89
+ submit(signedStatement: SignedStatement): Promise<void>;
90
+ }
76
91
 
77
92
  /**
78
93
  * Thrown by {@link getHostProvider} when the host container is reachable but does
@@ -95,56 +110,42 @@ declare class ChainNotSupportedError extends Error {
95
110
  *
96
111
  * The SDK is designed to run exclusively inside a host container. This function
97
112
  * is primarily useful for early validation or informational purposes.
98
- *
99
- * Uses product-sdk's sandboxProvider as primary detection.
100
- * Falls back to manual signal checks when product-sdk is not installed.
101
113
  */
102
114
  declare function isInsideContainer(): Promise<boolean>;
103
115
  /**
104
116
  * Get the Host API localStorage instance when running inside a container.
105
- * Returns null outside a container or when product-sdk is unavailable.
117
+ * Returns null outside a container or when the host transport is unavailable.
106
118
  */
107
119
  declare function getHostLocalStorage(): Promise<HostLocalStorage | null>;
108
120
  /**
109
- * Construct a fresh host-backed `HostLocalStorage` instance with an optional
110
- * custom transport. Use this when you need a non-default transport (e.g.
111
- * for tests); otherwise prefer {@link getHostLocalStorage}, which returns
112
- * the shared singleton.
113
- *
114
- * Mirrors `createLocalStorage` from `@novasamatech/host-api-wrapper`.
121
+ * Construct a host-backed `HostLocalStorage` instance. Retained for API
122
+ * compatibility; with the single cached TruAPI client this is equivalent to
123
+ * {@link getHostLocalStorage}.
115
124
  *
116
- * @param transport - Optional transport; defaults to the sandbox transport.
117
- * @returns A new `HostLocalStorage` instance, or `null` if unavailable.
125
+ * @returns A `HostLocalStorage` instance, or `null` if unavailable.
118
126
  */
119
- declare function createHostLocalStorage(transport?: Transport): Promise<HostLocalStorage | null>;
127
+ declare function createHostLocalStorage(): Promise<HostLocalStorage | null>;
120
128
  /**
121
129
  * Get a PAPI-compatible JSON-RPC provider that routes through the host connection.
122
130
  *
123
- * When running inside a Polkadot container, this wraps the chain connection via the
124
- * host's `createPapiProvider`, enabling shared connections and efficient routing.
125
- * Returns `null` when `@novasamatech/host-api-wrapper` is unavailable or when not
126
- * running inside a container.
131
+ * When running inside a Polkadot container, this builds a `JsonRpcProvider` over
132
+ * `truApi.chain.*` (see {@link module:papi-provider}), enabling shared
133
+ * connections and efficient routing. Returns `null` when not running inside a
134
+ * container.
127
135
  *
128
136
  * @param genesisHash - Genesis hash of the target chain (`0x`-prefixed hex string).
129
137
  * @returns A host-routed `JsonRpcProvider`, or `null` if unavailable.
130
138
  * @throws {ChainNotSupportedError} When inside a container but the host can't serve
131
139
  * the chain — surfaced instead of returning a provider that would hang forever.
132
140
  */
133
- declare function getHostProvider(genesisHash: `0x${string}`): Promise<JsonRpcProvider | null>;
141
+ declare function getHostProvider(genesisHash: HexString): Promise<JsonRpcProvider | null>;
134
142
  /**
135
- * Synchronous container detection fast heuristic check without product-sdk.
143
+ * Get the host statement store when running inside a container, backed by
144
+ * `truApi.statementStore.*`.
136
145
  *
137
- * Checks for iframe, webview marker, and host message port signals.
138
- * Use this when you need a quick sync check (e.g., in hot code paths).
139
- * For full detection including product-sdk, use {@link isInsideContainer} (async).
140
- */
141
- declare function isInsideContainerSync(): boolean;
142
- /**
143
- * Get the host API statement store when running inside a container.
144
- *
145
- * Returns a statement store with `subscribe`, `createProof`, and `submit` methods
146
- * that communicate through the host's native binary protocol — bypassing JSON-RPC
147
- * entirely. Returns `null` when `@novasamatech/host-api-wrapper` is unavailable.
146
+ * Returns a store with `subscribe`, `createProofAuthorized`, and `submit` that
147
+ * communicate through the host's native binary protocol bypassing JSON-RPC
148
+ * entirely. Returns `null` outside a host container.
148
149
  *
149
150
  * @returns The host statement store, or `null` if unavailable.
150
151
  */
@@ -155,13 +156,14 @@ declare function getStatementStore(): Promise<HostStatementStore | null>;
155
156
  * chain-specific endpoints used by multiple packages.
156
157
  */
157
158
  /**
158
- * Bulletin Chain RPC endpoints per network environment. `paseo` and `summit`
159
- * are populated today; `polkadot` and `kusama` are reserved for when those
160
- * Bulletin deployments go live.
159
+ * Bulletin Chain RPC endpoints per network environment. `paseo` (Paseo Next v2),
160
+ * `summit`, and `devnet` (public Paseo testnet) are populated today; `polkadot`
161
+ * and `kusama` are reserved for when those Bulletin deployments go live.
161
162
  */
162
163
  declare const BULLETIN_RPCS: {
163
164
  readonly paseo: readonly ["wss://paseo-bulletin-next-rpc.polkadot.io"];
164
165
  readonly summit: readonly ["wss://summit-bulletin-rpc.polkadot.io"];
166
+ readonly devnet: readonly ["wss://bulletin-paseo.tservices.es:8443"];
165
167
  readonly polkadot: string[];
166
168
  readonly kusama: string[];
167
169
  };
@@ -169,143 +171,168 @@ declare const BULLETIN_RPCS: {
169
171
  declare const DEFAULT_BULLETIN_ENDPOINT: string;
170
172
 
171
173
  /**
172
- * Extract a human-readable message from a host-side error. Hosts wrap
173
- * errors in versioned envelopes (`{ tag: "v1", value: CodecError }`); this
174
- * helper unwraps the envelope and renders the inner error's `name`/`message`
175
- * so callers see the host's actual diagnostic instead of `"[object Object]"`
176
- * (from `String(err)`) or a JSON-stringified envelope.
174
+ * Typed errors carried on the `err` channel of the host public API's
175
+ * {@link Result} returns.
176
+ *
177
+ * The hierarchy mirrors `@parity/product-sdk-signer`'s error classes
178
+ * (`HostUnavailableError` / `HostRejectedError`), so the two layers share one
179
+ * idiom: branch with `instanceof`, and every error is a real `Error` with a
180
+ * stack trace and `cause`. The structured truapi wire error
181
+ * ({@link HostErrorPayload}) rides along as {@link HostCallFailedError.payload}
182
+ * for callers that want fine-grained tag-level handling.
177
183
  *
178
- * Exported for the higher-level wrappers (`requestPermission`,
179
- * `deriveEntropy`, etc.) that build their `throw new Error(...)` messages.
184
+ * This module also owns {@link HostErrorPayload} (the wire-error shape) and
185
+ * {@link formatHostError} (renders a payload to a message) — co-located with the
186
+ * error classes that consume them so the host error model lives in one place.
187
+ *
188
+ * @module
180
189
  */
181
- declare function formatHostError(err: unknown): string;
182
190
 
183
191
  /**
184
- * The TruApi type - provides low-level methods for communicating with the host.
192
+ * The structured error payload `@parity/truapi` surfaces on the `Err` channel of
193
+ * a host call, once unwrapped from the versioned wire envelope. Every host error
194
+ * union is built from these:
195
+ *
196
+ * - the catch-all {@link GenericError} (`{ reason }`),
197
+ * - a unit tagged variant (`{ tag }`), or
198
+ * - a tagged variant carrying a reason (`{ tag, value: { reason } }`).
199
+ *
200
+ * `GenericError` is imported from `@parity/truapi`; the `{ tag }` members are a
201
+ * deliberate widening of truapi's per-domain named variants (the formatter is
202
+ * tag-agnostic). truapi has no umbrella error union to import today — once it
203
+ * exports a canonical tagged-error union from codegen, replace these local
204
+ * members with that import so the type is protocol-sourced rather than
205
+ * hand-widened.
206
+ *
207
+ * This is the *payload* the host public API carries inside a
208
+ * {@link HostCallFailedError} on the `err` channel of its `Result` returns — not
209
+ * the error type consumers branch on.
210
+ */
211
+ type HostErrorPayload = GenericError | {
212
+ tag: string;
213
+ value?: undefined;
214
+ } | {
215
+ tag: string;
216
+ value: {
217
+ reason: string;
218
+ };
219
+ };
220
+ /**
221
+ * Extract a human-readable message from a host-side error.
185
222
  *
186
- * Methods include:
187
- * - `navigateTo(url)` - Navigate to a URL within the host
188
- * - `permission(permissions)` - Request permissions from the host
189
- * - `localStorageRead/Write/Clear` - Host-backed storage
190
- * - `sign(payload)` - Request transaction signing
191
- * - `deriveEntropy(context)` - Derive deterministic entropy
192
- * - `themeSubscribe()` - Subscribe to host theme changes
193
- * - And many more...
223
+ * Renders the {@link HostErrorPayload} shapes `@parity/truapi` surfaces. Accepts
224
+ * `unknown` because it is also the catch-all formatter for thrown adapter-method
225
+ * `Error` messages, so it falls back to `Error`/string/JSON rendering for
226
+ * anything that isn't a recognized host error payload.
194
227
  *
195
- * Type identical to `hostApi` from `@novasamatech/host-api-wrapper` so that
196
- * `truApi.X(...)` calls keep their full inference (return types, method
197
- * names, parameter shapes) instead of decaying to `any`.
228
+ * Used by {@link HostCallFailedError} to render its message, and by the throwing
229
+ * adapter-method helper `unwrapHostResult`.
198
230
  */
199
- type TruApi = typeof _novasamatech_host_api_wrapper.hostApi;
231
+ declare function formatHostError(error: unknown): string;
232
+ /**
233
+ * Base class for all host errors. Use `instanceof HostError` (or {@link isHostError})
234
+ * to catch any host-related failure. Implements the cross-package
235
+ * {@link SdkError} marker so `isSdkError(e)` also recognizes it.
236
+ */
237
+ declare class HostError extends Error implements SdkError {
238
+ readonly isSdkError: true;
239
+ readonly source = "host";
240
+ constructor(message: string, options?: ErrorOptions);
241
+ }
200
242
  /**
201
- * Get the TruAPI instance for direct low-level access.
243
+ * The host API is not available — the app is running outside a Polkadot host
244
+ * container (no injected TruAPI transport). The dominant case during local
245
+ * development. Branch with `instanceof HostUnavailableError` to surface an
246
+ * "open this app in a Polkadot host" message.
247
+ */
248
+ declare class HostUnavailableError extends HostError {
249
+ constructor(message?: string);
250
+ }
251
+ /**
252
+ * A host call reached the container but failed on the `Err` channel. Wraps the
253
+ * structured truapi {@link HostErrorPayload} as {@link payload} (also preserved
254
+ * as `cause`); the message is rendered via {@link formatHostError}.
255
+ */
256
+ declare class HostCallFailedError extends HostError {
257
+ readonly payload: HostErrorPayload;
258
+ constructor(label: string, payload: HostErrorPayload);
259
+ }
260
+ /** Check whether a value is any {@link HostError}. */
261
+ declare function isHostError(error: unknown): error is HostError;
262
+
263
+ /**
264
+ * TruAPI - the protocol for communicating between apps and the Polkadot host container.
202
265
  *
203
- * Returns the `hostApi` object from `@novasamatech/host-api-wrapper` which provides
204
- * methods for communicating directly with the host container. Returns `null`
205
- * when running outside a container or when the SDK is unavailable.
266
+ * This module centralizes access to the in-house `@parity/truapi` client,
267
+ * allowing other `@parity/product-sdk-*` packages to import from here rather
268
+ * than depending directly on the protocol package. The client is built and
269
+ * cached by {@link module:transport}; this module adds the accessor plus the
270
+ * two helpers the convenience wrappers fold truapi's `ResultAsync` through —
271
+ * {@link mapHostResult} (returns a `Result`, used by the public operations) and
272
+ * {@link unwrapHostResult} (throws, used by the adapter-object methods).
206
273
  *
207
- * For most use cases, prefer the higher-level functions like `getHostLocalStorage()`,
208
- * `getHostProvider()`, etc. Use this when you need direct access to host methods
209
- * like `navigateTo()`, `permission()`, or `deriveEntropy()`.
274
+ * @module
275
+ */
276
+
277
+ /** Convert bytes to a `0x`-prefixed lower-case hex string. */
278
+ declare function toHex(bytes: Uint8Array): HexString;
279
+ /** Convert a hex string (with or without `0x`) to bytes. */
280
+ declare function fromHex(hex: string): Uint8Array;
281
+
282
+ /**
283
+ * The TruApi client — namespaced access to every host protocol domain
284
+ * (`permissions`, `entropy`, `signing`, `statementStore`, `system`,
285
+ * `localStorage`, …). Identical to `TrUApiClient` from `@parity/truapi`.
210
286
  *
211
287
  * @example
212
288
  * ```ts
213
- * import { getTruApi, enumValue } from "@parity/product-sdk-host";
214
- *
215
289
  * const truApi = await getTruApi();
216
290
  * if (truApi) {
217
- * // Request permission
218
- * const result = await truApi.permission([enumValue("ChainSubmit")]);
219
- *
220
- * // Navigate to a URL
221
- * await truApi.navigateTo("polkadot://settings");
222
- *
223
- * // Subscribe to theme changes
224
- * const sub = truApi.themeSubscribe(undefined, (theme) => {
225
- * console.log("Theme changed:", theme);
291
+ * await truApi.permissions.requestRemotePermission({
292
+ * permission: { tag: "ChainSubmit", value: undefined },
226
293
  * });
294
+ * await truApi.system.navigateTo({ url: "polkadot://settings" });
227
295
  * }
228
296
  * ```
229
- *
230
- * @returns The TruAPI instance, or `null` if unavailable.
231
297
  */
232
- declare function getTruApi(): Promise<TruApi | null>;
298
+ type TruApi = TrUApiClient;
233
299
  /**
234
- * Get the preimage manager for bulletin chain operations.
235
- *
236
- * The preimage manager handles uploading and looking up preimages (arbitrary data)
237
- * on the bulletin chain through the host's optimized path.
300
+ * Get the TruAPI client for direct low-level access to host protocol domains.
238
301
  *
239
- * @returns The preimage manager, or `null` if unavailable.
240
- *
241
- * @example
242
- * ```ts
243
- * import { getPreimageManager } from "@parity/product-sdk-host";
302
+ * Returns the cached `@parity/truapi` client once the host transport is built
303
+ * and the handshake has run, or `null` when running outside a container.
244
304
  *
245
- * const manager = await getPreimageManager();
246
- * if (manager) {
247
- * // Submit a preimage
248
- * const key = await manager.submit(new Uint8Array([1, 2, 3]));
305
+ * For most use cases, prefer the higher-level functions like
306
+ * {@link requestPermission}, {@link deriveEntropy}, or `getHostLocalStorage()`.
249
307
  *
250
- * // Look up a preimage
251
- * const sub = manager.lookup(key, (data) => {
252
- * if (data) console.log("Found:", data);
253
- * });
254
- * }
255
- * ```
308
+ * @returns The TruAPI client, or `null` if unavailable.
256
309
  */
257
- declare function getPreimageManager(): Promise<PreimageManager | null>;
310
+ declare function getTruApi(): Promise<TruApi | null>;
258
311
  /**
259
- * Preimage manager handle for bulletin chain operations. `lookup` returns a
260
- * `Subscription<void>` (`unsubscribe` + `onInterrupt`); `submit` returns a
261
- * `0x`-prefixed hex preimage key.
262
- *
263
- * Type identical to `preimageManager` from `@novasamatech/host-api-wrapper`.
312
+ * Preimage manager handle for bulletin chain operations, backed by
313
+ * `truApi.preimage.*`. `lookup` opens a {@link HostSubscription} (`unsubscribe`
314
+ * + `onInterrupt`) that delivers the preimage bytes — or `null` until the host
315
+ * finds them; `submit` uploads a preimage and resolves to its `0x`-prefixed hex
316
+ * key.
264
317
  */
265
- type PreimageManager = typeof preimageManager;
266
- /**
267
- * Construct a fresh `PreimageManager` instance with an optional custom
268
- * transport. Use this when you need a non-default transport; otherwise
269
- * prefer {@link getPreimageManager}, which returns the shared singleton.
270
- *
271
- * Mirrors `createPreimageManager` from `@novasamatech/host-api-wrapper`.
272
- *
273
- * @param transport - Optional transport; defaults to the sandbox transport.
274
- * @returns A new `PreimageManager` instance, or `null` if unavailable.
275
- */
276
- declare function createHostPreimageManager(transport?: _novasamatech_host_api.Transport): Promise<PreimageManager | null>;
318
+ interface PreimageManager {
319
+ lookup(key: HexString, callback: (preimage: Uint8Array | null) => void): HostSubscription;
320
+ submit(value: Uint8Array): Promise<HexString>;
321
+ }
277
322
  /**
278
- * Get the accounts provider for managing host accounts.
323
+ * Get the preimage manager for bulletin chain operations.
279
324
  *
280
- * @returns The accounts provider, or `null` if unavailable.
325
+ * @returns The preimage manager, or `null` if unavailable (outside a container).
281
326
  */
282
- declare function getAccountsProvider(): Promise<AccountsProvider | null>;
283
- /**
284
- * Resource types requestable via {@link requestResourceAllocation}.
285
- * Derived from the upstream codec so variant renames surface as compile
286
- * errors, not runtime failures.
287
- */
288
- type AllocatableResource = CodecType<typeof AllocatableResource$1>;
289
- /** Tag-only view of {@link AllocatableResource} for places that just need the variant name. */
290
- type AllocatableResourceTag = AllocatableResource["tag"];
291
- /**
292
- * Per-resource outcome from {@link requestResourceAllocation}.
293
- * The host strips secret payloads from `Allocated` before returning, so
294
- * `value` is always `undefined` on the product side.
295
- */
296
- type AllocationOutcome = CodecType<typeof AllocationOutcome$1>;
297
- /** Tag-only view of {@link AllocationOutcome} (`"Allocated" | "Rejected" | "NotAvailable"`). */
298
- type AllocationOutcomeTag = AllocationOutcome["tag"];
327
+ declare function getPreimageManager(): Promise<PreimageManager | null>;
299
328
  /**
300
- * Remote permission the dapp can ask the host to grant via
301
- * {@link requestPermission}.
329
+ * Construct a `PreimageManager`. Retained for API compatibility; with the single
330
+ * cached TruAPI client this is equivalent to {@link getPreimageManager}.
302
331
  *
303
- * Derived from the upstream codec so variant renames surface as compile
304
- * errors, not runtime failures.
332
+ * @returns A `PreimageManager` instance, or `null` if unavailable.
305
333
  */
306
- type RemotePermission = CodecType<typeof RemotePermission$1>;
307
- /** Tag-only view of {@link RemotePermission}. */
308
- type RemotePermissionTag = RemotePermission["tag"];
334
+ declare function createHostPreimageManager(): Promise<PreimageManager | null>;
335
+
309
336
  /**
310
337
  * Request the host to pre-allocate one or more resource allowances.
311
338
  *
@@ -313,238 +340,232 @@ type RemotePermissionTag = RemotePermission["tag"];
313
340
  * granted allowance don't re-prompt.
314
341
  *
315
342
  * @param resources - Resources to request.
316
- * @returns Per-resource outcomes in the same order as `resources`.
317
- * @throws If the host is unavailable or the request fails.
343
+ * @returns `ok` with per-resource outcomes in the same order as `resources`, or
344
+ * `err(HostUnavailableError | HostCallFailedError)`.
318
345
  *
319
346
  * @example
320
347
  * ```ts
321
- * const outcomes = await requestResourceAllocation([
348
+ * const r = await requestResourceAllocation([
322
349
  * { tag: "BulletinAllowance", value: undefined },
323
350
  * ]);
324
- * if (outcomes[0].tag === "Allocated") { ... }
351
+ * if (r.ok && r.value[0] === "Allocated") { ... }
325
352
  * ```
326
353
  */
327
- declare function requestResourceAllocation(resources: AllocatableResource[]): Promise<AllocationOutcome[]>;
354
+ declare function requestResourceAllocation(resources: AllocatableResource[]): Promise<Result<AllocationOutcome[], HostError>>;
328
355
  /**
329
- * Have the host sign a Statement using an allowance-bearing account it
330
- * picks internally — RFC-10 §"Statement Store allowance".
331
- *
332
- * The product passes only the Statement payload; the host chooses the
333
- * `//allowance//statement-store//{productId}` account that holds SSS
334
- * allowance and signs with it. Allowance is provisioned implicitly on
335
- * first use if the host hasn't already pre-allocated via
336
- * {@link requestResourceAllocation}; products never see the signing
337
- * account or its key material.
356
+ * Have the host sign a Statement using the product's allowance-bearing account,
357
+ * which it picks internally — RFC-10 §"Statement Store allowance". No per-call
358
+ * account id is needed (this is the sponsored-submission path).
338
359
  *
339
- * Pairs with {@link getStatementStore}'s `submit`: call this to obtain
340
- * a proof, attach it to the Statement, and submit the result.
360
+ * Pairs with {@link getStatementStore}'s `submit`: call this to obtain a proof,
361
+ * attach it to the Statement, and submit the result.
341
362
  *
342
363
  * @param statement - The Statement to be signed.
343
- * @returns The proof to attach before submitting.
344
- * @throws If the host is unavailable or the host-side signing fails.
364
+ * @returns `ok` with the proof to attach before submitting, or
365
+ * `err(HostUnavailableError | HostCallFailedError)`.
366
+ */
367
+ declare function createProofAuthorized(statement: Statement): Promise<Result<StatementProof, HostError>>;
368
+ /**
369
+ * Neverthrow-style ResultAsync returned by product-sdk methods.
345
370
  *
346
- * @example
347
- * ```ts
348
- * import { createProofAuthorized, getStatementStore } from "@parity/product-sdk-host";
349
- *
350
- * const statement = {
351
- * proof: undefined,
352
- * decryptionKey: undefined,
353
- * expiry: undefined,
354
- * channel: undefined,
355
- * topics: [],
356
- * data: payload,
357
- * };
358
- * const proof = await createProofAuthorized(statement);
359
- * const store = await getStatementStore();
360
- * await store?.submit({ ...statement, proof });
361
- * ```
371
+ * Use `.match(onOk, onErr)` to handle success/error cases.
372
+ */
373
+ interface ResultAsync<T, E> {
374
+ match: <A, B = A>(ok: (t: T) => A, err: (e: E) => B) => Promise<A | B>;
375
+ }
376
+
377
+ /**
378
+ * Host wallet accounts, backed by `truApi.account.*` and `truApi.signing.*`.
362
379
  *
363
- * @remarks
364
- * RFC-10 introduces this as a new, strictly additive TruAPI call. The
365
- * pre-existing `HostStatementStore.createProof(accountId, statement)`
366
- * surface stays available for products that own a non-allowance signing
367
- * account; this wrapper is the sponsored-submission path.
380
+ * `getAccountsProvider()` returns the full accounts surface — user identity
381
+ * (`getUserId` / `requestLogin`), the user's existing wallet accounts
382
+ * (`getLegacyAccounts`), app-scoped product accounts (`getProductAccount` /
383
+ * `getProductAccountAlias`), Ring VRF proofs (`createRingVRFProof`), connection
384
+ * status, and PAPI `PolkadotSigner` factories for both product and legacy
385
+ * accounts.
386
+ *
387
+ * The signer factories build a PAPI `PolkadotSigner` directly over
388
+ * `truApi.signing.createTransaction` (product) /
389
+ * `createTransactionWithLegacyAccount` (legacy) — `signTx` derives the
390
+ * metadata-driven `txExtVersion` and maps the signed extensions to the host's
391
+ * wire shape; `signBytes` calls `signing.signRaw(WithLegacyAccount)`. No PJS
392
+ * bridge is involved, so opaque signed extensions (e.g. Paseo Next's `AsPgas`)
393
+ * survive end-to-end.
394
+ *
395
+ * @module
368
396
  */
369
- declare function createProofAuthorized(statement: Statement): Promise<StatementProof>;
397
+
370
398
  /**
371
399
  * One of the user's existing wallet accounts, surfaced through the host and
372
400
  * identified by its public key and an optional name. Contrast with
373
401
  * {@link ProductAccount}, which is also user-controlled but derived by the
374
402
  * host for a specific app rather than picked from the user's existing keys.
403
+ *
404
+ * Derived from `@parity/truapi`'s `LegacyAccount`, with `publicKey` decoded to bytes.
375
405
  */
376
- interface HostAccount {
406
+ type HostAccount = Omit<LegacyAccount, "publicKey"> & {
407
+ /** Raw public key bytes. */
377
408
  publicKey: Uint8Array;
378
- name?: string;
379
- }
409
+ };
380
410
  /**
381
411
  * A product account — an app-scoped derived account managed by the host wallet.
382
412
  *
383
413
  * The host derives a unique keypair for each app (identified by `dotNsIdentifier`)
384
414
  * so apps get their own account that the user controls but is scoped to the app.
415
+ *
416
+ * Combines `@parity/truapi`'s `ProductAccountId` (the `{ dotNsIdentifier,
417
+ * derivationIndex }` lookup key) with the `ProductAccount` payload, with
418
+ * `publicKey` decoded to bytes.
385
419
  */
386
- interface ProductAccount {
387
- /** App identifier (e.g., "mark3t.dot"). */
388
- dotNsIdentifier: string;
389
- /** Derivation index within the app scope. Default: 0 */
390
- derivationIndex: number;
391
- /** Raw public key (32 bytes). */
420
+ type ProductAccount = ProductAccountId & Omit<ProductAccount$1, "publicKey"> & {
421
+ /** Raw public key bytes. */
392
422
  publicKey: Uint8Array;
393
- }
423
+ };
394
424
  /**
395
425
  * A contextual alias obtained from Ring VRF.
396
426
  *
397
427
  * Proves account membership in a ring without revealing which account.
398
- */
399
- interface ContextualAlias {
400
- /** Ring context (32 bytes). */
401
- context: Uint8Array;
402
- /** The Ring VRF alias bytes. */
403
- alias: Uint8Array;
404
- }
405
- /**
406
- * Neverthrow-style ResultAsync returned by product-sdk methods.
407
428
  *
408
- * Use `.match(onOk, onErr)` to handle success/error cases.
429
+ * Derived from `@parity/truapi`'s alias response, with both fields decoded to bytes.
409
430
  */
410
- interface ResultAsync<T, E> {
411
- match: <A, B = A>(ok: (t: T) => A, err: (e: E) => B) => Promise<A | B>;
431
+ type ContextualAlias = {
432
+ [K in keyof HostAccountGetAliasResponse]: Uint8Array;
433
+ };
434
+ /**
435
+ * Accounts provider handle, backed by `truApi.account.*` / `truApi.signing.*`.
436
+ * Surfaces the user's wallet accounts, app-scoped product accounts, Ring VRF,
437
+ * user identity, connection status, and `PolkadotSigner` factories.
438
+ *
439
+ * Lookup methods return a neverthrow `ResultAsync` (use `.match(ok, err)`);
440
+ * the signer factories return a synchronous PAPI `PolkadotSigner`.
441
+ */
442
+ interface AccountsProvider {
443
+ getUserId(): ResultAsync$1<{
444
+ primaryUsername: string;
445
+ }, HostGetUserIdError>;
446
+ requestLogin(reason?: string): ResultAsync$1<HostRequestLoginResponse, HostRequestLoginError>;
447
+ getProductAccount(dotNsIdentifier: string, derivationIndex?: number): ResultAsync$1<ProductAccount, HostAccountGetError>;
448
+ getProductAccountAlias(dotNsIdentifier: string, derivationIndex?: number): ResultAsync$1<ContextualAlias, HostAccountGetError>;
449
+ getLegacyAccounts(): ResultAsync$1<HostAccount[], HostAccountGetError>;
450
+ createRingVRFProof(dotNsIdentifier: string, derivationIndex: number, location: RingLocation, message: Uint8Array): ResultAsync$1<Uint8Array, HostAccountCreateProofError>;
451
+ /**
452
+ * Build a `PolkadotSigner` for a product account. Signing routes through the
453
+ * host's `createTransaction` path: the host decodes the metadata and forwards
454
+ * the opaque signed-extension bytes, so unknown extensions survive end-to-end.
455
+ */
456
+ getProductAccountSigner(account: ProductAccount): PolkadotSigner;
457
+ /**
458
+ * Build a `PolkadotSigner` for one of the user's existing wallet accounts.
459
+ * `name` is accepted for callsite ergonomics but unused — the signer is
460
+ * derived from `publicKey` alone.
461
+ */
462
+ getLegacyAccountSigner(account: {
463
+ publicKey: Uint8Array;
464
+ name?: string;
465
+ }): PolkadotSigner;
466
+ subscribeAccountConnectionStatus(callback: (status: HostAccountConnectionStatusSubscribeItem) => void): HostSubscription;
412
467
  }
413
468
  /**
414
- * Accounts provider handle from `@novasamatech/host-api-wrapper`. Surfaces the
415
- * full upstream API - host wallet accounts, app-scoped product accounts,
416
- * Ring VRF, user identity (`getUserId`, `requestLogin`), and connection
417
- * status subscription.
469
+ * Get the accounts provider for managing host accounts, backed by
470
+ * `truApi.account.*` / `truApi.signing.*`. Returns `null` when running outside
471
+ * a host container.
418
472
  *
419
- * Type identical to `createAccountsProvider()` from
420
- * `@novasamatech/host-api-wrapper`; methods return neverthrow `ResultAsync`
421
- * values with typed `CodecError` variants in the error channel.
473
+ * @returns The accounts provider, or `null` if unavailable.
422
474
  */
423
- type AccountsProvider = ReturnType<typeof createAccountsProvider>;
475
+ declare function getAccountsProvider(): Promise<AccountsProvider | null>;
424
476
 
425
477
  /**
426
478
  * Higher-level wrappers for the host's single-permission flows.
427
479
  *
428
- * `hostApi.permission` / `hostApi.devicePermission` take a versioned
429
- * envelope (`enumValue("v1", ...)`) and return a neverthrow `ResultAsync`
430
- * of an unwrapped versioned response. Consumers rebuild that wrap/unwrap
431
- * dance every time. {@link requestPermission} and
432
- * {@link requestDevicePermission} collapse it to one-liners that match the
433
- * shape of {@link requestResourceAllocation} (throws on error, returns
434
- * the unwrapped payload on success).
480
+ * `truApi.permissions.requestRemotePermission` / `requestDevicePermission`
481
+ * return a neverthrow `ResultAsync` of a `{ granted }` response.
482
+ * {@link requestPermission} and {@link requestDevicePermission} collapse that
483
+ * to one-liners returning a `Result<boolean, HostError>` — the granted flag on
484
+ * success, a typed {@link HostError} on the `err` channel.
435
485
  *
436
486
  * @module
437
487
  */
438
488
 
439
489
  /**
440
490
  * Device permission the dapp can ask the host to grant via
441
- * {@link requestDevicePermission}.
442
- *
443
- * Derived from the upstream codec so variant renames surface as compile
444
- * errors, not runtime failures.
491
+ * {@link requestDevicePermission}. A string union (`"Camera"`, `"Microphone"`,
492
+ * …) re-exported from `@parity/truapi`.
445
493
  */
446
- type DevicePermissionKind = CodecType<typeof DevicePermission>;
494
+ type DevicePermissionKind = HostDevicePermissionRequest;
447
495
  /**
448
- * Alias of {@link RemotePermission} matching the upstream
449
- * `@novasamatech/host-api-wrapper` name. Use either freely.
496
+ * Legacy alias of {@link RemotePermission}, kept for back-compat with code that
497
+ * used the older name. Use either freely.
450
498
  */
451
499
  type RemotePermissionItem = RemotePermission;
452
500
  /**
453
501
  * Request a single remote permission from the host.
454
502
  *
455
- * Builds the `v1` envelope, calls `hostApi.permission`, unwraps the response,
456
- * and returns the host's boolean granted/denied outcome.
503
+ * Calls `truApi.permissions.requestRemotePermission` and returns the host's
504
+ * boolean granted/denied outcome.
457
505
  *
458
506
  * @param permission - The remote permission to request.
459
- * @returns `true` if the host granted the permission, `false` if denied.
460
- * @throws If the host is unavailable or the request fails.
507
+ * @returns `ok(true)` if the host granted the permission, `ok(false)` if denied,
508
+ * or `err(HostUnavailableError | HostCallFailedError)`.
461
509
  *
462
510
  * @example
463
511
  * ```ts
464
- * const granted = await requestPermission({ tag: "ChainSubmit", value: undefined });
465
- * if (!granted) {
512
+ * const r = await requestPermission({ tag: "ChainSubmit", value: undefined });
513
+ * if (!r.ok || !r.value) {
466
514
  * tellUserToReconnect();
467
515
  * }
468
516
  * ```
469
517
  */
470
- declare function requestPermission(permission: RemotePermission): Promise<boolean>;
518
+ declare function requestPermission(permission: RemotePermission): Promise<Result<boolean, HostError>>;
471
519
  /**
472
520
  * Request a single device permission (camera, microphone, etc.) from the
473
521
  * host.
474
522
  *
475
- * Builds the `v1` envelope, calls `hostApi.devicePermission`, unwraps the
476
- * response, and returns the host's boolean granted/denied outcome.
523
+ * Calls `truApi.permissions.requestDevicePermission` and returns the host's
524
+ * boolean granted/denied outcome.
477
525
  *
478
526
  * @param permission - The device permission to request.
479
- * @returns `true` if the host granted the permission, `false` if denied.
480
- * @throws If the host is unavailable or the request fails.
527
+ * @returns `ok(true)` if the host granted the permission, `ok(false)` if denied,
528
+ * or `err(HostUnavailableError | HostCallFailedError)`.
481
529
  *
482
530
  * @example
483
531
  * ```ts
484
- * const granted = await requestDevicePermission("Camera");
485
- * if (!granted) {
532
+ * const r = await requestDevicePermission("Camera");
533
+ * if (!r.ok || !r.value) {
486
534
  * showCameraDeniedMessage();
487
535
  * }
488
536
  * ```
489
537
  */
490
- declare function requestDevicePermission(permission: DevicePermissionKind): Promise<boolean>;
538
+ declare function requestDevicePermission(permission: DevicePermissionKind): Promise<Result<boolean, HostError>>;
491
539
 
492
540
  /**
493
- * Higher-level wrapper for the host's theme subscription.
541
+ * Higher-level wrapper for the host's theme subscription, backed by
542
+ * `truApi.theme.subscribe`.
494
543
  *
495
- * `hostApi.themeSubscribe` is reachable via {@link getTruApi}, but consumers
496
- * have to wire the subscription envelope themselves. `getThemeProvider`
497
- * returns the `@novasamatech/host-api-wrapper` theme provider object directly,
498
- * giving callers a `subscribeTheme(cb)` method that resolves to a typed
499
- * {@link ThemeMode} — a `{ name, variant }` struct where `variant` is
500
- * `"Light" | "Dark"` — and yields a `Subscription<void>` handle.
501
- *
502
- * @remarks
503
- * As of `host-api(-wrapper)` v0.8 the theme payload is a struct, not a flat
504
- * `"light" | "dark"` string: read {@link ThemeMode.variant} for the
505
- * light/dark value (now capitalized) and {@link ThemeMode.name} for the
506
- * active theme name (`Default`, or `Custom` carrying a string id).
544
+ * `getThemeProvider` returns a handle whose `subscribeTheme(cb)` delivers a
545
+ * typed {@link ThemeMode} a `{ name, variant }` struct where `variant` is
546
+ * `"Light" | "Dark"` and `name` is `{ tag: "Default" }` or
547
+ * `{ tag: "Custom", value }` and yields a {@link HostSubscription}
548
+ * (`unsubscribe` + `onInterrupt`).
507
549
  *
508
550
  * @module
509
551
  */
510
552
 
511
553
  /**
512
- * Host theme provider handle. Exposes `subscribeTheme(callback)` which
513
- * receives a typed {@link ThemeMode} struct on every change and returns a
514
- * `Subscription<void>` (`unsubscribe` + `onInterrupt`).
515
- *
516
- * Type identical to `createThemeProvider()` from
517
- * `@novasamatech/host-api-wrapper`.
518
- */
519
- type ThemeProvider = ReturnType<typeof createThemeProvider>;
520
- /**
521
- * Host theme value. Re-exported from `@novasamatech/host-api-wrapper`.
522
- *
523
- * A `{ name, variant }` struct as of v0.8 (previously a flat
524
- * `"light" | "dark"` string).
554
+ * Host theme value. A `{ name, variant }` struct re-exported from
555
+ * `@parity/truapi`.
525
556
  */
526
- type ThemeMode = ThemeMode$1;
527
- /** Light/dark variant of the active theme: `"Light" | "Dark"`. */
528
- type ThemeVariant = ThemeMode["variant"];
557
+ type ThemeMode = HostThemeSubscribeItem;
558
+
529
559
  /**
530
- * Active theme name: `{ tag: "Default" }`, or `{ tag: "Custom", value }`
531
- * carrying the custom theme's string id.
560
+ * Host theme provider handle. `subscribeTheme(callback)` receives a typed
561
+ * {@link ThemeMode} on every change and returns a {@link HostSubscription}.
532
562
  */
533
- type ThemeName = ThemeMode["name"];
563
+ interface ThemeProvider {
564
+ subscribeTheme(callback: (theme: ThemeMode) => void): HostSubscription;
565
+ }
534
566
  /**
535
- * Get the host theme provider.
536
- *
537
- * Returns the theme-subscription handle exported by
538
- * `@novasamatech/host-api-wrapper`, or `null` if the package is unavailable
539
- * (running outside a host container or the optional peer dep isn't
540
- * installed).
541
- *
542
- * Implementation note: upstream `@novasamatech/host-api-wrapper` exports only
543
- * the `createThemeProvider` factory and no `themeProvider` singleton, so
544
- * this getter constructs a fresh instance on each call (unlike
545
- * {@link getPreimageManager} or {@link getHostLocalStorage}, which return
546
- * upstream singletons). The constructed provider is cheap to allocate; it
547
- * only opens a subscription when `subscribeTheme` is called.
567
+ * Get the host theme provider, backed by `truApi.theme.*`. Returns `null` when
568
+ * running outside a host container.
548
569
  *
549
570
  * @returns The theme provider, or `null` if unavailable.
550
571
  *
@@ -567,14 +588,14 @@ declare function getThemeProvider(): Promise<ThemeProvider | null>;
567
588
  /**
568
589
  * Higher-level wrapper for the host's entropy derivation (RFC-0007).
569
590
  *
570
- * `hostApi.deriveEntropy` is reachable via {@link getTruApi}, but consumers
571
- * have to wrap the value in the versioned envelope (`enumValue("v1", ...)`)
572
- * and unwrap the neverthrow `ResultAsync` themselves. `deriveEntropy`
573
- * collapses that to a throw-on-error Promise that matches the shape of
574
- * {@link requestPermission} and {@link requestResourceAllocation}.
591
+ * `truApi.entropy.derive` takes a hex `context` and returns a hex `entropy`
592
+ * payload wrapped in a neverthrow `ResultAsync`. `deriveEntropy` keeps the
593
+ * ergonomic `Uint8Array Result<Uint8Array, HostError>` signature: it
594
+ * hex-encodes the context on the way in and decodes the entropy on the way out.
575
595
  *
576
596
  * @module
577
597
  */
598
+
578
599
  /**
579
600
  * Derive deterministic entropy from a context key (RFC-0007).
580
601
  *
@@ -583,61 +604,50 @@ declare function getThemeProvider(): Promise<ThemeProvider | null>;
583
604
  * different keys (or different wallets) yield uncorrelated entropy.
584
605
  *
585
606
  * @param key - Context key bytes (typically a SCALE-encoded discriminator).
586
- * @returns The derived entropy bytes.
587
- * @throws If the host is unavailable or the host-side derivation fails.
607
+ * @returns `ok` with the derived entropy bytes, or
608
+ * `err(HostUnavailableError | HostCallFailedError)`.
588
609
  *
589
610
  * @example
590
611
  * ```ts
591
612
  * import { deriveEntropy } from "@parity/product-sdk-host";
592
613
  *
593
- * const seed = await deriveEntropy(new TextEncoder().encode("my-app:seed-v1"));
614
+ * const r = await deriveEntropy(new TextEncoder().encode("my-app:seed-v1"));
615
+ * if (r.ok) { const seed = r.value; }
594
616
  * ```
595
617
  */
596
- declare function deriveEntropy(key: Uint8Array): Promise<Uint8Array>;
618
+ declare function deriveEntropy(key: Uint8Array): Promise<Result<Uint8Array, HostError>>;
597
619
 
598
620
  /**
599
- * Wrapper for the host's chat surface (`host_chat_*` family).
621
+ * Wrapper for the host's chat surface, backed by `truApi.chat.*`.
600
622
  *
601
- * Shipped flat-in-host rather than as `getTruApi().chat.*` (the shape
602
- * sketched in issue #93) because the upstream JS `hostApi` is itself a
603
- * flat object - there is no `.chat` accessor to mirror. A flat
604
- * `getChatManager()` matches the pattern already used by
605
- * {@link getThemeProvider}, {@link getAccountsProvider}, and
606
- * {@link getStatementStore}; if a namespaced view is desirable later, it
607
- * can be layered on top without breaking this surface.
623
+ * `getChatManager()` returns a manager for room/bot registration, message
624
+ * sending, and subscription to the room list and incoming actions.
608
625
  *
609
626
  * @module
610
627
  */
611
628
 
612
- /** Chat message payload variants. Re-exported from `@novasamatech/host-api-wrapper`. */
613
- type ChatMessageContent = ChatMessageContent$1;
614
- /** Action received via {@link ChatManager.subscribeAction}. Re-exported from `@novasamatech/host-api-wrapper`. */
615
- type ChatReceivedAction = ChatReceivedAction$1;
616
- /** Room metadata delivered to {@link ChatManager.subscribeChatList}. Re-exported from `@novasamatech/host-api-wrapper`. */
617
- type ChatRoom = ChatRoom$1;
618
- /** Result of registering a chat room (`"New" | "Exists"`). Re-exported from `@novasamatech/host-api-wrapper`. */
619
- type ChatRoomRegistrationResult = ChatRoomRegistrationResult$1;
620
- /** Result of registering a bot (`"New" | "Exists"`). Re-exported from `@novasamatech/host-api-wrapper`. */
621
- type ChatBotRegistrationResult = ChatBotRegistrationResult$1;
622
- /** Renderer callback for custom message types. Re-exported from `@novasamatech/host-api-wrapper`. */
623
- type ChatCustomMessageRenderer = ChatCustomMessageRenderer$1;
624
- /** Parameters passed to a {@link ChatCustomMessageRenderer}. Re-exported from `@novasamatech/host-api-wrapper`. */
625
- type ChatCustomMessageRendererParams<T = Uint8Array> = ChatCustomMessageRendererParams$1<T>;
626
- /**
627
- * Chat manager handle. Exposes room/bot registration, message sending,
628
- * subscription to room list and incoming actions, and custom-renderer
629
- * registration.
630
- *
631
- * Type identical to `createProductChatManager()` from
632
- * `@novasamatech/host-api-wrapper`.
633
- */
634
- type ChatManager = ReturnType<typeof createProductChatManager>;
635
- /**
636
- * Get the host chat manager.
637
- *
638
- * Returns the chat manager from `@novasamatech/host-api-wrapper`, or `null` if
639
- * the package is unavailable (running outside a host container or the
640
- * optional peer dep isn't installed).
629
+ /** Action received via {@link ChatManager.subscribeAction} (`{ roomId, peer, payload }`). Re-exported from `@parity/truapi`. */
630
+ type ChatReceivedAction = HostChatActionSubscribeItem;
631
+ /** Result of registering a chat room (`"New" | "Exists"`). Re-exported from `@parity/truapi`. */
632
+ type ChatRoomRegistrationResult = ChatRoomRegistrationStatus;
633
+ /** Result of registering a bot (`"New" | "Exists"`). Re-exported from `@parity/truapi`. */
634
+ type ChatBotRegistrationResult = ChatBotRegistrationStatus;
635
+ /**
636
+ * Chat manager handle. Exposes room/bot registration, message sending, and
637
+ * subscription to the room list and incoming actions.
638
+ */
639
+ interface ChatManager {
640
+ registerRoom(request: HostChatCreateRoomRequest): Promise<ChatRoomRegistrationResult>;
641
+ registerBot(request: HostChatRegisterBotRequest): Promise<ChatBotRegistrationResult>;
642
+ sendMessage(roomId: string, payload: ChatMessageContent): Promise<{
643
+ messageId: string;
644
+ }>;
645
+ subscribeChatList(callback: (rooms: ChatRoom[]) => void): HostSubscription;
646
+ subscribeAction(callback: (action: ChatReceivedAction) => void): HostSubscription;
647
+ }
648
+ /**
649
+ * Get the host chat manager, backed by `truApi.chat.*`. Returns `null` when
650
+ * running outside a host container.
641
651
  *
642
652
  * @returns The chat manager, or `null` if unavailable.
643
653
  *
@@ -653,62 +663,38 @@ type ChatManager = ReturnType<typeof createProductChatManager>;
653
663
  * ```
654
664
  */
655
665
  declare function getChatManager(): Promise<ChatManager | null>;
656
- /**
657
- * Dispatch helper that composes multiple custom-message renderers into a
658
- * single {@link ChatCustomMessageRenderer} keyed by `messageType`.
659
- *
660
- * Mirrors `matchChatCustomRenderers` from `@novasamatech/host-api-wrapper`
661
- * inline (the upstream implementation is pure dispatch logic with no
662
- * transport / runtime dependency on Novasama), so callers get the same
663
- * sync signature instead of an async-with-null wrapper.
664
- *
665
- * @param map - Object mapping `messageType` strings to renderers.
666
- * @returns A composed renderer that dispatches to the entry matching
667
- * `params.messageType`, or throws if no renderer is registered.
668
- */
669
- declare function matchChatCustomRenderers(map: Record<string, ChatCustomMessageRenderer>): ChatCustomMessageRenderer;
670
666
 
671
667
  /**
672
- * Wrapper for the host's payment manager (RFC-0006).
673
- *
674
- * Shipped flat-in-host rather than as `getTruApi().payment.*` because the
675
- * upstream JS `hostApi` is itself a flat object - there is no `.payment`
676
- * accessor to mirror. A flat `getPaymentManager()` matches the singleton
677
- * pattern already used by {@link getPreimageManager},
678
- * {@link getHostLocalStorage}, and {@link getAccountsProvider}.
679
- *
680
- * Returns the shared `paymentManager` singleton from
681
- * `@novasamatech/host-api-wrapper` (not a fresh `createPaymentManager()`
682
- * instance) so callers share one wrapper + hostApi closure across the app.
668
+ * Wrapper for the host's payment manager (RFC-0006), backed by
669
+ * `truApi.payment.*`.
683
670
  *
684
- * Distinct from the CoinPayment / merchant-payments surface tracked under
685
- * `@parity/product-sdk-merchant-payments` (RFC-0017). RFC-0006 is the
686
- * user-initiated balance / top-up / payment-request flow; RFC-0017 is the
687
- * merchant-initiated checkout flow.
671
+ * Exposes balance subscription, top-up, payment requests, and payment-status
672
+ * subscription. Distinct from the CoinPayment / merchant-payments surface
673
+ * (RFC-0017): RFC-0006 is the user-initiated balance / top-up / payment-request
674
+ * flow.
688
675
  *
689
676
  * @module
690
677
  */
691
678
 
692
- /** Available balance for the user's payment account. Re-exported from `@novasamatech/host-api-wrapper`. */
693
- type PaymentBalance = PaymentBalance$1;
694
- /** Status of an in-flight payment request. Re-exported from `@novasamatech/host-api-wrapper`. */
695
- type PaymentStatus = PaymentStatus$1;
696
- /** Source for {@link PaymentManager.topUp}. Re-exported from `@novasamatech/host-api-wrapper`. */
697
- type TopUpSource = TopUpSource$1;
698
679
  /**
699
680
  * Payment manager handle. Exposes balance subscription, top-up, payment
700
- * requests, and payment status subscription.
701
- *
702
- * Type identical to `paymentManager` from `@novasamatech/host-api-wrapper`.
703
- */
704
- type PaymentManager = typeof paymentManager;
681
+ * requests, and payment-status subscription.
682
+ *
683
+ * The balance / status / top-up-source shapes are `@parity/truapi`'s
684
+ * `HostPaymentBalanceSubscribeItem`, `HostPaymentStatusSubscribeItem`, and
685
+ * `PaymentTopUpSource` used directly rather than re-aliased.
686
+ */
687
+ interface PaymentManager {
688
+ subscribeBalance(callback: (balance: HostPaymentBalanceSubscribeItem) => void, purse?: PaymentPurseId): HostSubscription;
689
+ topUp(amount: Balance, source: PaymentTopUpSource, into?: PaymentPurseId): Promise<void>;
690
+ requestPayment(amount: Balance, destination: HexString, from?: PaymentPurseId): Promise<{
691
+ id: string;
692
+ }>;
693
+ subscribePaymentStatus(paymentId: string, callback: (status: HostPaymentStatusSubscribeItem) => void): HostSubscription;
694
+ }
705
695
  /**
706
- * Get the host payment manager.
707
- *
708
- * Returns the shared `paymentManager` singleton from
709
- * `@novasamatech/host-api-wrapper`, or `null` if the package is unavailable
710
- * (running outside a host container or the optional peer dep isn't
711
- * installed).
696
+ * Get the host payment manager, backed by `truApi.payment.*`. Returns `null`
697
+ * when running outside a host container.
712
698
  *
713
699
  * @returns The payment manager, or `null` if unavailable.
714
700
  *
@@ -719,9 +705,8 @@ type PaymentManager = typeof paymentManager;
719
705
  * const payments = await getPaymentManager();
720
706
  * if (payments) {
721
707
  * const sub = payments.subscribeBalance((b) => { ... });
722
- * await payments.topUp(1_000_000n, { type: "productAccount", derivationIndex: 0 });
723
- * const destination = new Uint8Array(32);
724
- * const { id } = await payments.requestPayment(500n, destination);
708
+ * await payments.topUp(1_000_000n, { tag: "ProductAccount", value: { derivationIndex: 0 } });
709
+ * const { id } = await payments.requestPayment(500n, "0x…");
725
710
  * sub.unsubscribe();
726
711
  * }
727
712
  * ```
@@ -729,59 +714,41 @@ type PaymentManager = typeof paymentManager;
729
714
  declare function getPaymentManager(): Promise<PaymentManager | null>;
730
715
 
731
716
  /**
732
- * Wrapper for the host's scheduled push-notification surface.
733
- *
734
- * Shipped flat-in-host rather than as `getTruApi().notification.*` because
735
- * the upstream JS `hostApi` is itself a flat object - there is no
736
- * `.notification` accessor to mirror. A flat `getNotificationManager()`
737
- * matches the singleton pattern already used by {@link getPaymentManager},
738
- * {@link getPreimageManager}, and {@link getHostLocalStorage}.
717
+ * Wrapper for the host's scheduled push-notification surface (RFC-0019),
718
+ * backed by `truApi.notifications.*`.
739
719
  *
740
- * Returns the shared `notificationManager` singleton from
741
- * `@novasamatech/host-api-wrapper` (not a fresh `createNotificationManager()`
742
- * instance) so callers share one wrapper + hostApi closure across the app.
743
- *
744
- * {@link PushNotificationError} is re-exported from `@novasamatech/host-api`
745
- * so consumers can branch on `err instanceof
746
- * PushNotificationError.ScheduleLimitReached` (the host's pending-notification
747
- * cap) without importing the novasama packages directly.
720
+ * `getNotificationManager()` returns a handle exposing `push(input)` (resolves
721
+ * to a {@link NotificationId}) and `cancel(id)`, matching the singleton
722
+ * pattern already used by {@link getPaymentManager}, {@link getPreimageManager},
723
+ * and {@link getHostLocalStorage}.
748
724
  *
749
725
  * @module
750
726
  */
751
727
 
752
728
  /**
753
- * Host notification manager handle. Exposes `push(input)` (resolves to a
754
- * {@link NotificationId}) and `cancel(id)`.
755
- *
756
- * Type identical to `notificationManager` from
757
- * `@novasamatech/host-api-wrapper`.
729
+ * Push payload: `text`, an optional `deeplink`, and an optional `scheduledAt`
730
+ * (Unix timestamp in milliseconds; omit for immediate delivery). Re-exported
731
+ * from the truapi wire request type so the shape stays in lockstep with the
732
+ * protocol.
758
733
  */
759
- type NotificationManager = typeof notificationManager;
734
+ type PushNotificationInput = HostPushNotificationRequest;
760
735
  /**
761
- * Host-assigned id for a scheduled notification pass to
762
- * {@link NotificationManager.cancel}. Derived from the manager's `push`
763
- * return type so codec changes surface here as compile errors.
764
- */
765
- type NotificationId = Awaited<ReturnType<NotificationManager["push"]>>;
766
- /**
767
- * Push payload: `text`, an optional `deeplink`, and an optional
768
- * `scheduledAt` (omit for immediate delivery). Derived from the manager's
769
- * `push` parameter so the shape stays in lockstep with upstream.
736
+ * Host notification manager handle. Exposes `push(input)` (resolves to a
737
+ * {@link NotificationId}) and `cancel(id)`.
770
738
  */
771
- type PushNotificationInput = Parameters<NotificationManager["push"]>[0];
739
+ interface NotificationManager {
740
+ push(input: PushNotificationInput): Promise<NotificationId>;
741
+ cancel(id: NotificationId): Promise<void>;
742
+ }
772
743
  /**
773
- * Get the host notification manager.
774
- *
775
- * Returns the shared `notificationManager` singleton from
776
- * `@novasamatech/host-api-wrapper`, or `null` if the package is unavailable
777
- * (running outside a host container or the optional peer dep isn't
778
- * installed).
744
+ * Get the host notification manager, backed by `truApi.notifications.*`.
745
+ * Returns `null` when running outside a host container.
779
746
  *
780
747
  * @returns The notification manager, or `null` if unavailable.
781
748
  *
782
749
  * @example
783
750
  * ```ts
784
- * import { getNotificationManager, PushNotificationError } from "@parity/product-sdk-host";
751
+ * import { getNotificationManager, type PushNotificationError } from "@parity/product-sdk-host";
785
752
  *
786
753
  * const notifications = await getNotificationManager();
787
754
  * if (notifications) {
@@ -792,7 +759,8 @@ type PushNotificationInput = Parameters<NotificationManager["push"]>[0];
792
759
  * });
793
760
  * // later: await notifications.cancel(id);
794
761
  * } catch (err) {
795
- * if (err instanceof PushNotificationError.ScheduleLimitReached) {
762
+ * const cause = (err as Error).cause as PushNotificationError | undefined;
763
+ * if (cause?.tag === "ScheduleLimitReached") {
796
764
  * // host hit its pending-notification cap — surface to the user
797
765
  * }
798
766
  * }
@@ -804,44 +772,43 @@ declare function getNotificationManager(): Promise<NotificationManager | null>;
804
772
  /**
805
773
  * Higher-level wrapper for the host's deep-link navigation.
806
774
  *
807
- * `hostApi.navigateTo` is reachable via {@link getTruApi}, but consumers have
808
- * to wrap the URL in the versioned envelope (`enumValue("v1", ...)`) and
809
- * unwrap the neverthrow `ResultAsync` themselves. {@link navigateTo} collapses
810
- * that to a throw-on-error Promise that matches the shape of
811
- * {@link requestPermission} and {@link deriveEntropy}.
775
+ * `truApi.system.navigateTo` returns a neverthrow `ResultAsync`; consumers
776
+ * still have to unwrap it themselves. {@link navigateTo} collapses that to a
777
+ * `Result<void, HostError>`-returning Promise.
812
778
  *
813
779
  * @module
814
780
  */
781
+
815
782
  /**
816
783
  * Ask the host to navigate to a URL (deep link or external link).
817
784
  *
818
- * Builds the `v1` envelope, calls `hostApi.navigateTo`, and unwraps the
819
- * response. The host resolves the destination itself — a `dot`-suffixed
820
- * deep link (e.g. `"https://search.dot"`) routes to another app/route inside
821
- * the container, an `https://` URL opens externally.
785
+ * Calls `truApi.system.navigateTo` and unwraps the response. The host resolves
786
+ * the destination itself — a `dot`-suffixed deep link (e.g.
787
+ * `"https://search.dot"`) routes to another app/route inside the container, an
788
+ * `https://` URL opens externally.
822
789
  *
823
790
  * @param url - The URL to navigate to.
824
- * @throws If the host is unavailable, denies the navigation
825
- * (`NavigateToErr::PermissionDenied`), or fails for any other reason
826
- * (`NavigateToErr::Unknown`).
791
+ * @returns `ok` on success, or `err`: {@link HostUnavailableError} if the host
792
+ * is unavailable, or {@link HostCallFailedError} if it denies the navigation
793
+ * (`NavigateToErr::PermissionDenied`) or fails otherwise (`NavigateToErr::Unknown`).
827
794
  *
828
795
  * @example
829
796
  * ```ts
830
797
  * import { navigateTo } from "@parity/product-sdk-host";
831
798
  *
832
- * await navigateTo("https://search.dot");
799
+ * const r = await navigateTo("https://search.dot");
800
+ * if (!r.ok) handle(r.error);
833
801
  * ```
834
802
  */
835
- declare function navigateTo(url: string): Promise<void>;
803
+ declare function navigateTo(url: string): Promise<Result<void, HostError>>;
836
804
 
837
805
  /**
838
806
  * Higher-level wrappers for the host's feature-support probe.
839
807
  *
840
- * `hostApi.featureSupported` is reachable via {@link getTruApi}, but consumers
841
- * have to wrap the feature in the versioned envelope (`enumValue("v1", ...)`)
842
- * and unwrap the neverthrow `ResultAsync` themselves. {@link featureSupported}
843
- * collapses that to a throw-on-error Promise; {@link isChainSupported} is a
844
- * convenience over the only feature variant the host exposes today (`Chain`).
808
+ * `truApi.system.featureSupported` returns a neverthrow `ResultAsync`;
809
+ * {@link featureSupported} collapses that to a `Result` carrying the host's
810
+ * boolean answer. {@link isChainSupported} is a convenience over the only
811
+ * feature variant the host exposes today (`Chain`).
845
812
  *
846
813
  * @module
847
814
  */
@@ -849,10 +816,11 @@ declare function navigateTo(url: string): Promise<void>;
849
816
  /**
850
817
  * A feature the host can be probed for via {@link featureSupported}.
851
818
  *
852
- * As of `host-api` v0.8 the only variant is `Chain`, carrying the chain's
853
- * `0x`-prefixed genesis hash. Modeled locally (rather than derived from an
854
- * upstream codec) because the protocol exposes the feature only inline; new
855
- * variants surface here as a widening of the union.
819
+ * The only variant today is `Chain`, carrying the chain's `0x`-prefixed genesis
820
+ * hash. This is a flattened form of truapi's `HostFeatureSupportedRequest`,
821
+ * which nests the hash as `{ tag: "Chain"; value: { genesisHash } }` — we
822
+ * inline `value` as the `HexString` for ergonomics and re-nest it at the call
823
+ * site. New variants surface here as a widening of the union.
856
824
  */
857
825
  type Feature = {
858
826
  tag: "Chain";
@@ -861,49 +829,51 @@ type Feature = {
861
829
  /**
862
830
  * Probe the host for support of a specific feature.
863
831
  *
864
- * Builds the `v1` envelope, calls `hostApi.featureSupported`, unwraps the
865
- * response, and returns the host's boolean answer.
832
+ * Calls `truApi.system.featureSupported`, unwraps the response, and returns the
833
+ * host's boolean answer.
866
834
  *
867
835
  * @param feature - The feature to probe for.
868
- * @returns `true` if the host supports the feature, `false` otherwise.
869
- * @throws If the host is unavailable or the probe fails (`GenericError`).
836
+ * @returns `ok(true)` if the host supports the feature, `ok(false)` otherwise,
837
+ * or `err(HostUnavailableError | HostCallFailedError)`.
870
838
  *
871
839
  * @example
872
840
  * ```ts
873
841
  * import { featureSupported } from "@parity/product-sdk-host";
874
842
  *
875
- * const ok = await featureSupported({ tag: "Chain", value: genesisHash });
843
+ * const r = await featureSupported({ tag: "Chain", value: genesisHash });
844
+ * if (r.ok && r.value) { ... }
876
845
  * ```
877
846
  */
878
- declare function featureSupported(feature: Feature): Promise<boolean>;
847
+ declare function featureSupported(feature: Feature): Promise<Result<boolean, HostError>>;
879
848
  /**
880
849
  * Convenience probe: is the chain with the given genesis hash supported by the
881
850
  * host? Wraps {@link featureSupported} for the `Chain` feature variant.
882
851
  *
883
852
  * @param genesisHash - The chain's `0x`-prefixed genesis hash.
884
- * @returns `true` if the host supports the chain, `false` otherwise.
885
- * @throws If the host is unavailable or the probe fails.
853
+ * @returns `ok(true)` if the host supports the chain, `ok(false)` otherwise, or
854
+ * `err(HostUnavailableError | HostCallFailedError)`.
886
855
  *
887
856
  * @example
888
857
  * ```ts
889
858
  * import { isChainSupported } from "@parity/product-sdk-host";
890
859
  *
891
- * if (!(await isChainSupported(genesisHash))) {
860
+ * const r = await isChainSupported(genesisHash);
861
+ * if (!r.ok || !r.value) {
892
862
  * tellUserChainUnavailable();
893
863
  * }
894
864
  * ```
895
865
  */
896
- declare function isChainSupported(genesisHash: HexString): Promise<boolean>;
866
+ declare function isChainSupported(genesisHash: HexString): Promise<Result<boolean, HostError>>;
897
867
 
898
868
  /**
899
869
  * Higher-level wrapper for the host's chain-spec lookups.
900
870
  *
901
- * The host exposes three separate chain-spec calls — `chainSpecGenesisHash`,
902
- * `chainSpecChainName`, and `chainSpecProperties` — each reachable via
903
- * {@link getTruApi} but each requiring its own `enumValue("v1", ...)` wrap
904
- * and neverthrow `ResultAsync` unwrap. {@link getChainSpec} fetches all three
905
- * in one call and returns a single struct so callers read whichever field
906
- * they need, matching the JSON-RPC `chainSpec_v1_*` family they mirror.
871
+ * The host exposes three separate chain-spec calls — `chain.getSpecGenesisHash`,
872
+ * `chain.getSpecChainName`, and `chain.getSpecProperties` — each reachable via
873
+ * {@link getTruApi} and each returning a neverthrow `ResultAsync`.
874
+ * {@link getChainSpec} fetches all three in one call and returns a single
875
+ * struct so callers read whichever field they need, matching the JSON-RPC
876
+ * `chainSpec_v1_*` family they mirror.
907
877
  *
908
878
  * @module
909
879
  */
@@ -914,8 +884,8 @@ declare function isChainSupported(genesisHash: HexString): Promise<boolean>;
914
884
  *
915
885
  * The host returns this as a JSON string (mirroring the substrate
916
886
  * `chainSpec_v1_properties` JSON-RPC, whose payload is an open-ended object).
917
- * {@link getChainSpec} parses it into {@link properties} and also surfaces the
918
- * untouched JSON as {@link propertiesRaw}. The well-known substrate fields are
887
+ * {@link getChainSpec} parses it into {@link ChainSpec.properties} and also
888
+ * surfaces the untouched JSON as {@link ChainSpec.propertiesRaw}. The well-known substrate fields are
919
889
  * typed for convenience; the index signature keeps any chain-specific extras
920
890
  * reachable without `any` at the call site.
921
891
  */
@@ -949,37 +919,41 @@ interface ChainSpec {
949
919
  * Fetch a chain's full spec (genesis hash, name, and properties) from the host
950
920
  * in one call.
951
921
  *
952
- * Issues the three underlying `chainSpec*` requests concurrently, unwraps each
953
- * `v1` envelope, and parses the properties JSON. Note the `genesisHash` in the
954
- * result is the value the host echoes back from `chainSpecGenesisHash` for the
922
+ * Issues the three underlying `chain.getSpec*` requests concurrently, unwraps
923
+ * each response, and parses the properties JSON. Note the `genesisHash` in the
924
+ * result is the value the host echoes back from `getSpecGenesisHash` for the
955
925
  * looked-up chain — pass the chain's known genesis hash as the lookup key.
956
926
  *
927
+ * `null` (outside a container) is preserved as an `ok` value — it is an
928
+ * expected state, not a failure — so callers branch on `r.ok && r.value`. A
929
+ * real host-call failure surfaces on the `err` channel.
930
+ *
957
931
  * @param genesisHash - The `0x`-prefixed genesis hash identifying the chain.
958
- * @returns The combined {@link ChainSpec}, or `null` if the host is
959
- * unavailable (running outside a container).
960
- * @throws If any of the underlying host calls fail (`GenericError`).
932
+ * @returns `ok(spec)` with the combined {@link ChainSpec}, `ok(null)` if the
933
+ * host is unavailable (running outside a container), or
934
+ * `err(HostCallFailedError)` if any underlying host call fails.
961
935
  *
962
936
  * @example
963
937
  * ```ts
964
938
  * import { getChainSpec } from "@parity/product-sdk-host";
965
939
  *
966
- * const spec = await getChainSpec(genesisHash);
967
- * if (spec) {
968
- * console.log(spec.name, spec.properties?.tokenSymbol);
940
+ * const r = await getChainSpec(genesisHash);
941
+ * if (r.ok && r.value) {
942
+ * console.log(r.value.name, r.value.properties?.tokenSymbol);
969
943
  * }
970
944
  * ```
971
945
  */
972
- declare function getChainSpec(genesisHash: HexString): Promise<ChainSpec | null>;
946
+ declare function getChainSpec(genesisHash: HexString): Promise<Result<ChainSpec | null, HostError>>;
973
947
 
974
948
  /**
975
949
  * Higher-level wrappers for the host's transaction broadcast lifecycle.
976
950
  *
977
- * `hostApi.chainTransactionBroadcast` / `hostApi.chainTransactionStop` are
978
- * reachable via {@link getTruApi}, but consumers have to build the versioned
979
- * envelope (`enumValue("v1", ...)`) and unwrap the neverthrow `ResultAsync`
980
- * themselves. {@link broadcastTransaction} and {@link stopTransaction}
981
- * collapse that to throw-on-error Promises, mirroring the JSON-RPC
982
- * `transaction_v1_broadcast` / `transaction_v1_stop` pair they wrap.
951
+ * `truApi.chain.broadcastTransaction` / `truApi.chain.stopTransaction` are
952
+ * reachable via {@link getTruApi}, but consumers have to unwrap the neverthrow
953
+ * `ResultAsync` themselves. {@link broadcastTransaction} and
954
+ * {@link stopTransaction} collapse that to `Result`-returning Promises, mirroring
955
+ * the JSON-RPC `transaction_v1_broadcast` / `transaction_v1_stop` pair they
956
+ * wrap.
983
957
  *
984
958
  * @module
985
959
  */
@@ -987,43 +961,41 @@ declare function getChainSpec(genesisHash: HexString): Promise<ChainSpec | null>
987
961
  /**
988
962
  * Broadcast a signed transaction to the network via the host.
989
963
  *
990
- * Builds the `v1` envelope, calls `hostApi.chainTransactionBroadcast`, and
991
- * unwraps the response. The host keeps re-broadcasting until the transaction
992
- * is finalized/dropped or {@link stopTransaction} is called with the returned
993
- * operation id.
964
+ * Calls `truApi.chain.broadcastTransaction` and unwraps the response. The host
965
+ * keeps re-broadcasting until the transaction is finalized/dropped or
966
+ * {@link stopTransaction} is called with the returned operation id.
994
967
  *
995
968
  * @param genesisHash - The `0x`-prefixed genesis hash of the target chain.
996
969
  * @param transaction - The `0x`-prefixed SCALE-encoded signed transaction.
997
- * @returns The operation id to pass to {@link stopTransaction}, or `null` if
998
- * the host accepted the broadcast without issuing one.
999
- * @throws If the host is unavailable or the broadcast fails (`GenericError`).
970
+ * @returns `ok` with the operation id to pass to {@link stopTransaction} (or
971
+ * `null` if the host accepted the broadcast without issuing one), or
972
+ * `err(HostUnavailableError | HostCallFailedError)`.
1000
973
  *
1001
974
  * @example
1002
975
  * ```ts
1003
976
  * import { broadcastTransaction, stopTransaction } from "@parity/product-sdk-host";
1004
977
  *
1005
- * const operationId = await broadcastTransaction(genesisHash, signedTx);
978
+ * const r = await broadcastTransaction(genesisHash, signedTx);
1006
979
  * // later, to stop re-broadcasting:
1007
- * if (operationId) await stopTransaction(genesisHash, operationId);
980
+ * if (r.ok && r.value) await stopTransaction(genesisHash, r.value);
1008
981
  * ```
1009
982
  */
1010
- declare function broadcastTransaction(genesisHash: HexString, transaction: HexString): Promise<string | null>;
983
+ declare function broadcastTransaction(genesisHash: HexString, transaction: HexString): Promise<Result<string | null, HostError>>;
1011
984
  /**
1012
985
  * Stop an in-flight broadcast started by {@link broadcastTransaction}.
1013
986
  *
1014
- * Builds the `v1` envelope, calls `hostApi.chainTransactionStop`, and unwraps
1015
- * the response.
987
+ * Calls `truApi.chain.stopTransaction` and unwraps the response.
1016
988
  *
1017
989
  * @param genesisHash - The `0x`-prefixed genesis hash of the target chain.
1018
990
  * @param operationId - The operation id returned by
1019
991
  * {@link broadcastTransaction}.
1020
- * @throws If the host is unavailable or the stop fails (`GenericError`).
992
+ * @returns `ok` on success, or `err(HostUnavailableError | HostCallFailedError)`.
1021
993
  *
1022
994
  * @example
1023
995
  * ```ts
1024
996
  * await stopTransaction(genesisHash, operationId);
1025
997
  * ```
1026
998
  */
1027
- declare function stopTransaction(genesisHash: HexString, operationId: string): Promise<void>;
999
+ declare function stopTransaction(genesisHash: HexString, operationId: string): Promise<Result<void, HostError>>;
1028
1000
 
1029
- export { type AccountsProvider, type AllocatableResource, type AllocatableResourceTag, type AllocationOutcome, type AllocationOutcomeTag, BULLETIN_RPCS, ChainNotSupportedError, type ChainProperties, type ChainSpec, type ChatBotRegistrationResult, type ChatCustomMessageRenderer, type ChatCustomMessageRendererParams, type ChatManager, type ChatMessageContent, type ChatReceivedAction, type ChatRoom, type ChatRoomRegistrationResult, type ContextualAlias, DEFAULT_BULLETIN_ENDPOINT, type DevicePermissionKind, type Feature, type HostAccount, type HostLocalStorage, type HostStatementStore, type HostSubscription, type NotificationId, type NotificationManager, type PaymentBalance, type PaymentManager, type PaymentStatus, type PreimageManager, type ProductAccount, type ProductAccountId, type PushNotificationInput, type RemotePermission, type RemotePermissionItem, type RemotePermissionTag, type ResultAsync, type SignedStatement, type Statement, type StatementProof, type StatementTopicFilter, type StatementsPage, type ThemeMode, type ThemeName, type ThemeProvider, type ThemeVariant, type TopUpSource, type Topic, type TruApi, broadcastTransaction, createHostLocalStorage, createHostPreimageManager, createProofAuthorized, deriveEntropy, featureSupported, formatHostError, getAccountsProvider, getChainSpec, getChatManager, getHostLocalStorage, getHostProvider, getNotificationManager, getPaymentManager, getPreimageManager, getStatementStore, getThemeProvider, getTruApi, isChainSupported, isInsideContainer, isInsideContainerSync, matchChatCustomRenderers, navigateTo, requestDevicePermission, requestPermission, requestResourceAllocation, stopTransaction };
1001
+ export { type AccountsProvider, BULLETIN_RPCS, ChainNotSupportedError, type ChainProperties, type ChainSpec, type ChatBotRegistrationResult, type ChatManager, type ChatReceivedAction, type ChatRoomRegistrationResult, type ContextualAlias, DEFAULT_BULLETIN_ENDPOINT, type DevicePermissionKind, type Feature, type HostAccount, HostCallFailedError, HostError, type HostErrorPayload, type HostLocalStorage, type HostStatementStore, type HostSubscription, HostUnavailableError, type NotificationManager, type PaymentManager, type PreimageManager, type ProductAccount, type PushNotificationInput, type RemotePermissionItem, type ResultAsync, type StatementTopicFilter, type StatementsPage, type ThemeMode, type ThemeProvider, type TruApi, broadcastTransaction, createHostLocalStorage, createHostPreimageManager, createProofAuthorized, deriveEntropy, featureSupported, formatHostError, fromHex, getAccountsProvider, getChainSpec, getChatManager, getHostLocalStorage, getHostProvider, getNotificationManager, getPaymentManager, getPreimageManager, getStatementStore, getThemeProvider, getTruApi, isChainSupported, isHostError, isInsideContainer, navigateTo, requestDevicePermission, requestPermission, requestResourceAllocation, stopTransaction, toHex };