@parity/product-sdk-signer 0.1.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.
@@ -0,0 +1,558 @@
1
+ import * as polkadot_api from 'polkadot-api';
2
+ import { PolkadotSigner } from 'polkadot-api';
3
+ import { SS58String } from '@parity/product-sdk-address';
4
+
5
+ /** Function that unsubscribes a listener when called. */
6
+ type Unsubscribe = () => void;
7
+ /**
8
+ * Interface that all signer providers must implement.
9
+ *
10
+ * Providers are responsible for discovering accounts and creating signers
11
+ * from a specific source (Host API or dev accounts).
12
+ */
13
+ interface SignerProvider {
14
+ /** Unique identifier for this provider type. */
15
+ readonly type: ProviderType;
16
+ /**
17
+ * Attempt to connect and discover accounts.
18
+ *
19
+ * @param signal - Optional AbortSignal to cancel the connection attempt.
20
+ * @returns Accounts on success, typed error on failure.
21
+ */
22
+ connect(signal?: AbortSignal): Promise<Result<SignerAccount[], SignerError>>;
23
+ /**
24
+ * Disconnect and clean up resources.
25
+ * Safe to call multiple times.
26
+ */
27
+ disconnect(): void;
28
+ /**
29
+ * Subscribe to connection status changes.
30
+ *
31
+ * Not all providers emit status changes — for example, dev accounts
32
+ * are always "connected" and never emit.
33
+ *
34
+ * @returns Unsubscribe function.
35
+ */
36
+ onStatusChange(callback: (status: ConnectionStatus) => void): Unsubscribe;
37
+ /**
38
+ * Subscribe to account list changes.
39
+ *
40
+ * Emitted when the set of available accounts changes (e.g., user
41
+ * connects/disconnects in the host wallet).
42
+ *
43
+ * @returns Unsubscribe function.
44
+ */
45
+ onAccountsChange(callback: (accounts: SignerAccount[]) => void): Unsubscribe;
46
+ }
47
+
48
+ /** Connection status for a signer provider. */
49
+ type ConnectionStatus = "disconnected" | "connecting" | "connected";
50
+ /**
51
+ * Identifies the source of an account.
52
+ *
53
+ * - `"host"`: Host API provider (Polkadot Desktop / Mobile) — the primary provider
54
+ * - `"dev"`: Development accounts (Alice, Bob, etc.) — for testing only
55
+ */
56
+ type ProviderType = "host" | "dev";
57
+ /** A signing-capable account from any provider. */
58
+ interface SignerAccount {
59
+ /** SS58 address (generic prefix 42 by default). */
60
+ address: SS58String;
61
+ /**
62
+ * H160 EVM address derived from the public key.
63
+ *
64
+ * For native Substrate accounts: keccak256(publicKey), last 20 bytes.
65
+ * For EVM-derived accounts: strips the 0xEE padding.
66
+ * Used for pallet-revive / Asset Hub EVM contract interactions.
67
+ */
68
+ h160Address: `0x${string}`;
69
+ /** Raw public key (32 bytes). May be sr25519, ed25519, or ecdsa depending on the provider. */
70
+ publicKey: Uint8Array;
71
+ /** Human-readable name if available from the provider. */
72
+ name: string | null;
73
+ /** Which provider supplied this account. */
74
+ source: ProviderType;
75
+ /** Get the PolkadotSigner for this account. */
76
+ getSigner(): PolkadotSigner;
77
+ }
78
+ /** Full state snapshot emitted to subscribers. */
79
+ interface SignerState {
80
+ /** Current connection status. */
81
+ status: ConnectionStatus;
82
+ /** All available accounts across all connected providers. */
83
+ accounts: readonly SignerAccount[];
84
+ /** Currently selected account (null if none selected). */
85
+ selectedAccount: SignerAccount | null;
86
+ /** Which provider is active (null if disconnected). */
87
+ activeProvider: ProviderType | null;
88
+ /** Last error (null if no error). */
89
+ error: SignerError | null;
90
+ }
91
+ /** Lightweight Result type for operations that can fail expectedly. */
92
+ type Result<T, E> = {
93
+ ok: true;
94
+ value: T;
95
+ } | {
96
+ ok: false;
97
+ error: E;
98
+ };
99
+ /** Create a successful Result. */
100
+ declare function ok<T>(value: T): Result<T, never>;
101
+ /** Create a failed Result. */
102
+ declare function err<E>(error: E): Result<never, E>;
103
+ /** Factory function that creates a SignerProvider for a given type. */
104
+ type ProviderFactory = (type: ProviderType) => SignerProvider;
105
+ /**
106
+ * Adapter for persisting the selected account address across sessions.
107
+ *
108
+ * `globalThis.localStorage` satisfies this interface. Pass a custom
109
+ * implementation for container environments (e.g., hostLocalStorage)
110
+ * or for testing.
111
+ */
112
+ interface AccountPersistence {
113
+ getItem(key: string): string | null | Promise<string | null>;
114
+ setItem(key: string, value: string): void | Promise<void>;
115
+ removeItem(key: string): void | Promise<void>;
116
+ }
117
+ /** Options for SignerManager construction. */
118
+ interface SignerManagerOptions {
119
+ /** SS58 prefix for address encoding. Default: 42 */
120
+ ss58Prefix?: number;
121
+ /**
122
+ * Maximum time in ms to wait for the Host API.
123
+ * Applied as an AbortSignal timeout on the host provider connection.
124
+ * Default: 10_000
125
+ */
126
+ hostTimeout?: number;
127
+ /** Maximum retry attempts for provider connection. Default: 3 */
128
+ maxRetries?: number;
129
+ /** Custom provider factory. Override to inject test doubles or custom providers. */
130
+ createProvider?: ProviderFactory;
131
+ /**
132
+ * App name used for storage key namespacing. Default: "product-sdk"
133
+ * The selected account is persisted under `product-sdk:signer:{dappName}:selectedAccount`.
134
+ */
135
+ dappName?: string;
136
+ /**
137
+ * Storage adapter for persisting selected account.
138
+ * Uses host localStorage when inside a container.
139
+ * Set to `null` to disable persistence entirely.
140
+ */
141
+ persistence?: AccountPersistence | null;
142
+ }
143
+
144
+ /** Base class for all signer errors. Use `instanceof SignerError` to catch any signer-related error. */
145
+ declare class SignerError extends Error {
146
+ constructor(message: string, options?: ErrorOptions);
147
+ }
148
+ /** The Host API is not available (product-sdk not installed or not inside a container). */
149
+ declare class HostUnavailableError extends SignerError {
150
+ constructor(message?: string);
151
+ }
152
+ /** The host rejected the account or signing request. */
153
+ declare class HostRejectedError extends SignerError {
154
+ constructor(message?: string);
155
+ }
156
+ /** The host connection was lost. */
157
+ declare class HostDisconnectedError extends SignerError {
158
+ constructor(message?: string);
159
+ }
160
+ /** A signing operation failed. */
161
+ declare class SigningFailedError extends SignerError {
162
+ constructor(cause: unknown, message?: string);
163
+ }
164
+ /** No accounts available from the provider. */
165
+ declare class NoAccountsError extends SignerError {
166
+ readonly provider: ProviderType;
167
+ constructor(provider: ProviderType, message?: string);
168
+ }
169
+ /** An operation timed out. */
170
+ declare class TimeoutError extends SignerError {
171
+ readonly operation: string;
172
+ readonly ms: number;
173
+ constructor(operation: string, ms: number);
174
+ }
175
+ /** An account was not found by address. */
176
+ declare class AccountNotFoundError extends SignerError {
177
+ readonly address: string;
178
+ constructor(address: string);
179
+ }
180
+ /** The SignerManager has been destroyed and is no longer usable. */
181
+ declare class DestroyedError extends SignerError {
182
+ constructor();
183
+ }
184
+ /** Check if a SignerError is a host-related error. */
185
+ declare function isHostError(e: SignerError): e is HostUnavailableError | HostRejectedError | HostDisconnectedError;
186
+
187
+ /** Options for the Host API provider. */
188
+ interface HostProviderOptions {
189
+ /** SS58 prefix for address encoding. Default: 42 */
190
+ ss58Prefix?: number;
191
+ /** Max retry attempts for initial connection. Default: 3 */
192
+ maxRetries?: number;
193
+ /** Initial retry delay in ms. Default: 500 */
194
+ retryDelay?: number;
195
+ /**
196
+ * Custom SDK loader. Defaults to `import("@novasamatech/product-sdk")`.
197
+ * Override this for testing or custom SDK setups.
198
+ * @internal
199
+ */
200
+ loadSdk?: () => Promise<ProductSdkModule>;
201
+ /**
202
+ * Custom loader for `@novasamatech/host-api` (used to construct the
203
+ * `TransactionSubmit` permission request). Defaults to dynamic import.
204
+ * @internal
205
+ */
206
+ loadHostApiEnum?: () => Promise<HostApiEnumHelper>;
207
+ /**
208
+ * Whether to request the host's `TransactionSubmit` permission after a
209
+ * successful `connect()`. Without this, subsequent signing requests are
210
+ * rejected by the host with `PermissionDenied`. Default: `true`.
211
+ *
212
+ * Set to `false` if your app needs to defer the permission prompt or
213
+ * drives it manually.
214
+ */
215
+ requestTransactionSubmitPermission?: boolean;
216
+ }
217
+ /**
218
+ * A product account — an app-scoped derived account managed by the host wallet.
219
+ *
220
+ * The host derives a unique keypair for each app (identified by `dotNsIdentifier`)
221
+ * so apps get their own account that the user controls but is scoped to the app.
222
+ */
223
+ interface ProductAccount {
224
+ /** App identifier (e.g., "mark3t.dot"). */
225
+ dotNsIdentifier: string;
226
+ /** Derivation index within the app scope. Default: 0 */
227
+ derivationIndex: number;
228
+ /** Raw public key (32 bytes). */
229
+ publicKey: Uint8Array;
230
+ }
231
+ /**
232
+ * A contextual alias obtained from Ring VRF.
233
+ *
234
+ * Proves account membership in a ring without revealing which account.
235
+ */
236
+ interface ContextualAlias {
237
+ /** Ring context (32 bytes). */
238
+ context: Uint8Array;
239
+ /** The Ring VRF alias bytes. */
240
+ alias: Uint8Array;
241
+ }
242
+ /**
243
+ * Location of a Ring VRF ring on-chain.
244
+ *
245
+ * Matches the product-sdk's `RingLocation` codec shape.
246
+ */
247
+ interface RingLocation {
248
+ genesisHash: string;
249
+ ringRootHash: string;
250
+ hints?: {
251
+ palletInstance?: number;
252
+ } | undefined;
253
+ }
254
+ interface RawAccount {
255
+ publicKey: Uint8Array;
256
+ name?: string | undefined;
257
+ }
258
+ interface NeverthrowResultAsync<T, E> {
259
+ match: <A, B = A>(ok: (t: T) => A, err: (e: E) => B) => Promise<A | B>;
260
+ }
261
+ /** @internal */
262
+ interface AccountsProvider {
263
+ getNonProductAccounts: () => NeverthrowResultAsync<RawAccount[], unknown>;
264
+ getNonProductAccountSigner: (account: ProductAccount) => polkadot_api.PolkadotSigner;
265
+ getProductAccount: (dotNsIdentifier: string, derivationIndex?: number) => NeverthrowResultAsync<RawAccount, unknown>;
266
+ getProductAccountSigner: (account: ProductAccount) => polkadot_api.PolkadotSigner;
267
+ getProductAccountAlias: (dotNsIdentifier: string, derivationIndex?: number) => NeverthrowResultAsync<ContextualAlias, unknown>;
268
+ createRingVRFProof: (dotNsIdentifier: string, derivationIndex: number, location: unknown, message: Uint8Array) => NeverthrowResultAsync<Uint8Array, unknown>;
269
+ subscribeAccountConnectionStatus: (callback: (status: string) => void) => {
270
+ unsubscribe: () => void;
271
+ } | (() => void);
272
+ }
273
+ /** @internal */
274
+ interface HostApiPermissionBridge {
275
+ /**
276
+ * Request a Host API permission. Product-sdk's `hostApi.permission(...)`
277
+ * takes a tagged enum like `enumValue("v1", { tag: "TransactionSubmit" })`
278
+ * and returns a neverthrow ResultAsync.
279
+ */
280
+ permission: (request: unknown) => NeverthrowResultAsync<unknown, unknown>;
281
+ }
282
+ /** @internal */
283
+ interface HostApiEnumHelper {
284
+ enumValue: (version: string, value: {
285
+ tag: string;
286
+ value?: unknown;
287
+ }) => unknown;
288
+ }
289
+ /** @internal */
290
+ interface ProductSdkModule {
291
+ createAccountsProvider: () => AccountsProvider;
292
+ /** Present from product-sdk ≥ 0.6; used to request TransactionSubmit. */
293
+ hostApi?: HostApiPermissionBridge;
294
+ }
295
+ /**
296
+ * Provider for the Host API (Polkadot Desktop / Android).
297
+ *
298
+ * Dynamically imports `@novasamatech/product-sdk` at runtime so it remains
299
+ * an optional peer dependency. Apps running outside a host container will
300
+ * gracefully get a `HOST_UNAVAILABLE` error.
301
+ *
302
+ * Supports both non-product accounts (user's external wallets) and product
303
+ * accounts (app-scoped derived accounts managed by the host).
304
+ */
305
+ declare class HostProvider implements SignerProvider {
306
+ readonly type: ProviderType;
307
+ private readonly ss58Prefix;
308
+ private readonly maxRetries;
309
+ private readonly retryDelay;
310
+ private readonly loadSdk;
311
+ private readonly loadHostApiEnum;
312
+ private readonly requestTxPermission;
313
+ private accountsProvider;
314
+ private statusCleanup;
315
+ private statusListeners;
316
+ private accountListeners;
317
+ constructor(options?: HostProviderOptions);
318
+ connect(signal?: AbortSignal): Promise<Result<SignerAccount[], SignerError>>;
319
+ disconnect(): void;
320
+ onStatusChange(callback: (status: ConnectionStatus) => void): Unsubscribe;
321
+ onAccountsChange(callback: (accounts: SignerAccount[]) => void): Unsubscribe;
322
+ /**
323
+ * Get an app-scoped product account from the host.
324
+ *
325
+ * Product accounts are derived by the host wallet for each app, identified
326
+ * by `dotNsIdentifier` (e.g., "mark3t.dot"). The user controls these accounts
327
+ * but they are scoped to the requesting app.
328
+ *
329
+ * Requires a prior successful `connect()` call.
330
+ */
331
+ getProductAccount(dotNsIdentifier: string, derivationIndex?: number): Promise<Result<SignerAccount, SignerError>>;
332
+ /**
333
+ * Get a PolkadotSigner for a product account.
334
+ *
335
+ * Convenience method for when you already have the product account details.
336
+ * Requires a prior successful `connect()` call.
337
+ */
338
+ getProductAccountSigner(account: ProductAccount): polkadot_api.PolkadotSigner;
339
+ /**
340
+ * Get a contextual alias for a product account via Ring VRF.
341
+ *
342
+ * Aliases prove account membership in a ring without revealing which
343
+ * account produced the alias.
344
+ *
345
+ * Requires a prior successful `connect()` call.
346
+ */
347
+ getProductAccountAlias(dotNsIdentifier: string, derivationIndex?: number): Promise<Result<ContextualAlias, SignerError>>;
348
+ /**
349
+ * Create a Ring VRF proof for anonymous operations.
350
+ *
351
+ * Proves that the signer is a member of the ring at the given location
352
+ * without revealing which member. Used for privacy-preserving protocols.
353
+ *
354
+ * Requires a prior successful `connect()` call.
355
+ */
356
+ createRingVRFProof(dotNsIdentifier: string, derivationIndex: number, location: RingLocation, message: Uint8Array): Promise<Result<Uint8Array, SignerError>>;
357
+ private tryConnect;
358
+ private mapAccounts;
359
+ }
360
+
361
+ /**
362
+ * Core orchestrator for signer management.
363
+ *
364
+ * Manages account discovery and signer creation via the Host API.
365
+ * Framework-agnostic — use the subscribe() pattern to integrate with
366
+ * React, Vue, or any framework.
367
+ *
368
+ * @example
369
+ * ```ts
370
+ * const manager = new SignerManager();
371
+ * manager.subscribe(state => console.log(state.status));
372
+ *
373
+ * // Connect to the host provider
374
+ * await manager.connect();
375
+ *
376
+ * // Or use dev accounts for testing
377
+ * await manager.connect("dev");
378
+ *
379
+ * // Select account and get signer
380
+ * manager.selectAccount("5GrwvaEF...");
381
+ * const signer = manager.getSigner();
382
+ * ```
383
+ */
384
+ declare class SignerManager {
385
+ private state;
386
+ private provider;
387
+ private subscribers;
388
+ private cleanups;
389
+ private isDestroyed;
390
+ private reconnectController;
391
+ private connectController;
392
+ private readonly ss58Prefix;
393
+ private readonly hostTimeout;
394
+ private readonly maxRetries;
395
+ private readonly providerFactory;
396
+ private readonly dappName;
397
+ private readonly persistenceOption;
398
+ private resolvedPersistence;
399
+ constructor(options?: SignerManagerOptions);
400
+ private getPersistence;
401
+ /** Get a snapshot of the current state. */
402
+ getState(): SignerState;
403
+ /**
404
+ * Subscribe to state changes. The callback fires on every state mutation.
405
+ * Returns an unsubscribe function.
406
+ */
407
+ subscribe(callback: (state: SignerState) => void): () => void;
408
+ /**
409
+ * Connect to a provider.
410
+ *
411
+ * If no provider type is specified, connects to the Host API.
412
+ * The SDK is designed to run exclusively inside a host container.
413
+ *
414
+ * When connecting to a specific provider type:
415
+ * - `"host"`: Connect to the Host API (default, recommended)
416
+ * - `"dev"`: Connect using dev accounts (for testing)
417
+ */
418
+ connect(providerType?: ProviderType): Promise<Result<SignerAccount[], SignerError>>;
419
+ /** Disconnect from the current provider and reset state. */
420
+ disconnect(): void;
421
+ /**
422
+ * Select an account by address.
423
+ * Returns the account on success, or ACCOUNT_NOT_FOUND error.
424
+ */
425
+ selectAccount(address: string): Result<SignerAccount, SignerError>;
426
+ /**
427
+ * Get the PolkadotSigner for the currently selected account.
428
+ * Returns null if no account is selected or manager is disconnected.
429
+ */
430
+ getSigner(): PolkadotSigner | null;
431
+ /**
432
+ * Sign arbitrary bytes with the currently selected account.
433
+ *
434
+ * Convenience wrapper around `PolkadotSigner.signBytes` — useful for
435
+ * master key derivation, message signing, and proof generation without
436
+ * constructing a full transaction.
437
+ *
438
+ * Returns a SIGNING_FAILED error if no account is selected or signing fails.
439
+ */
440
+ signRaw(data: Uint8Array): Promise<Result<Uint8Array, SignerError>>;
441
+ /**
442
+ * Get an app-scoped product account from the host.
443
+ *
444
+ * Product accounts are derived by the host wallet for each app, identified
445
+ * by `dotNsIdentifier` (e.g., "mark3t.dot"). Only available when connected
446
+ * via the host provider — returns HOST_UNAVAILABLE otherwise.
447
+ *
448
+ * @example
449
+ * ```ts
450
+ * const result = await manager.getProductAccount("myapp.dot");
451
+ * if (result.ok) {
452
+ * const signer = result.value.getSigner();
453
+ * }
454
+ * ```
455
+ */
456
+ getProductAccount(dotNsIdentifier: string, derivationIndex?: number): Promise<Result<SignerAccount, SignerError>>;
457
+ /**
458
+ * Get a contextual alias for a product account via Ring VRF.
459
+ *
460
+ * Aliases prove account membership in a ring without revealing which
461
+ * account produced the alias. Only available when connected via the host
462
+ * provider — returns HOST_UNAVAILABLE otherwise.
463
+ */
464
+ getProductAccountAlias(dotNsIdentifier: string, derivationIndex?: number): Promise<Result<ContextualAlias, SignerError>>;
465
+ /**
466
+ * Create a Ring VRF proof for anonymous operations.
467
+ *
468
+ * Proves that the signer is a member of the ring at the given location
469
+ * without revealing which member. Only available when connected via the
470
+ * host provider — returns HOST_UNAVAILABLE otherwise.
471
+ */
472
+ createRingVRFProof(dotNsIdentifier: string, derivationIndex: number, location: RingLocation, message: Uint8Array): Promise<Result<Uint8Array, SignerError>>;
473
+ /**
474
+ * Destroy the manager and release all resources.
475
+ * After calling destroy(), the manager is unusable.
476
+ */
477
+ destroy(): void;
478
+ private connectToProvider;
479
+ private createProvider;
480
+ private handleProviderStatusChange;
481
+ private attemptReconnect;
482
+ /** Returns the underlying HostProvider if connected via host, or null otherwise. */
483
+ private getHostProvider;
484
+ private cancelConnect;
485
+ private cancelReconnect;
486
+ private disconnectInternal;
487
+ private persistAccount;
488
+ private loadPersistedAccount;
489
+ private setState;
490
+ }
491
+
492
+ /**
493
+ * Sleep for a given duration, cancellable via AbortSignal.
494
+ *
495
+ * Resolves immediately if the signal is already aborted.
496
+ * Cleans up the abort listener when the timer fires naturally
497
+ * to prevent listener accumulation in retry loops.
498
+ */
499
+ declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
500
+
501
+ /** Options for retry with exponential backoff. */
502
+ interface RetryOptions {
503
+ /** Maximum number of attempts. Default: 3 */
504
+ maxAttempts?: number;
505
+ /** Initial delay in ms before first retry. Default: 500 */
506
+ initialDelay?: number;
507
+ /** Multiplier applied to delay after each attempt. Default: 2 */
508
+ backoffMultiplier?: number;
509
+ /** Maximum delay cap in ms. Default: 10_000 */
510
+ maxDelay?: number;
511
+ /** AbortSignal to cancel retries early. */
512
+ signal?: AbortSignal;
513
+ }
514
+ /**
515
+ * Retry an async operation with exponential backoff.
516
+ *
517
+ * Calls `fn` up to `maxAttempts` times. If `fn` returns an error result,
518
+ * waits with exponential backoff before the next attempt. Returns the first
519
+ * successful result or the last error.
520
+ */
521
+ declare function withRetry<T, E>(fn: (attempt: number) => Promise<Result<T, E>>, options?: RetryOptions): Promise<Result<T, E>>;
522
+
523
+ /** Standard Substrate dev account names. */
524
+ declare const DEFAULT_DEV_NAMES: readonly ["Alice", "Bob", "Charlie", "Dave", "Eve", "Ferdie"];
525
+ type DevAccountName = (typeof DEFAULT_DEV_NAMES)[number];
526
+ /** Supported key types for dev account derivation. */
527
+ type DevKeyType = "sr25519" | "ed25519";
528
+ /** Options for the dev account provider. */
529
+ interface DevProviderOptions {
530
+ /** Which dev accounts to create. Default: all 6 standard accounts. */
531
+ names?: readonly string[];
532
+ /** Custom mnemonic phrase instead of DEV_PHRASE. */
533
+ mnemonic?: string;
534
+ /** SS58 prefix for address encoding. Default: 42 */
535
+ ss58Prefix?: number;
536
+ /** Key type for account derivation. Default: "sr25519" */
537
+ keyType?: DevKeyType;
538
+ }
539
+ /**
540
+ * Provider for Substrate development accounts.
541
+ *
542
+ * Uses the well-known DEV_PHRASE with hard derivation paths (`//Alice`, `//Bob`, etc.)
543
+ * to create deterministic accounts for local development and testing.
544
+ */
545
+ declare class DevProvider implements SignerProvider {
546
+ readonly type: "dev";
547
+ private readonly names;
548
+ private readonly mnemonic;
549
+ private readonly ss58Prefix;
550
+ private readonly keyType;
551
+ constructor(options?: DevProviderOptions);
552
+ connect(): Promise<Result<SignerAccount[], SignerError>>;
553
+ disconnect(): void;
554
+ onStatusChange(_callback: (status: "disconnected" | "connecting" | "connected") => void): Unsubscribe;
555
+ onAccountsChange(_callback: (accounts: SignerAccount[]) => void): Unsubscribe;
556
+ }
557
+
558
+ export { AccountNotFoundError, type AccountPersistence, type ConnectionStatus, type ContextualAlias, DestroyedError, type DevAccountName, type DevKeyType, DevProvider, type DevProviderOptions, HostDisconnectedError, HostProvider, type HostProviderOptions, HostRejectedError, HostUnavailableError, NoAccountsError, type ProductAccount, type ProviderFactory, type ProviderType, type Result, type RetryOptions, type RingLocation, type SignerAccount, SignerError, SignerManager, type SignerManagerOptions, type SignerProvider, type SignerState, SigningFailedError, TimeoutError, type Unsubscribe, err, isHostError, ok, sleep, withRetry };