@parity/product-sdk-signer 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -257,6 +257,22 @@ interface HostProviderOptions {
257
257
  maxRetries?: number;
258
258
  /** Initial retry delay in ms. Default: 500 */
259
259
  retryDelay?: number;
260
+ /**
261
+ * Dapp identifier the SDK falls back to when {@link productAccount} is
262
+ * not set, so `connect()` can still surface a usable account on hosts
263
+ * that don't enumerate legacy accounts.
264
+ *
265
+ * The value is treated as a dotNS identifier (`.dot` is appended if
266
+ * missing) and routed through `getProductAccount(dappName, 0)`. If the
267
+ * host rejects the derivation (e.g. the identifier isn't registered),
268
+ * `connect()` resolves with an empty accounts list rather than
269
+ * throwing — consumers can still drive the explicit signing paths
270
+ * (`signMessageWithDotNsIdentity`, `getLegacyAccountSigner`).
271
+ *
272
+ * Wired through from `SignerManager` automatically; only set directly
273
+ * when instantiating `HostProvider` outside the manager.
274
+ */
275
+ dappName?: string;
260
276
  /**
261
277
  * Custom SDK loader. Defaults to `import("@novasamatech/host-api-wrapper")`.
262
278
  * Override this for testing or custom SDK setups.
@@ -357,7 +373,6 @@ interface NeverthrowResultAsync<T, E> {
357
373
  }
358
374
  /** @internal */
359
375
  interface AccountsProvider {
360
- getLegacyAccounts: () => NeverthrowResultAsync<RawAccount[], unknown>;
361
376
  getLegacyAccountSigner: (account: ProductAccount) => polkadot_api.PolkadotSigner;
362
377
  getProductAccount: (dotNsIdentifier: string, derivationIndex?: number) => NeverthrowResultAsync<RawAccount, unknown>;
363
378
  getProductAccountSigner: (account: ProductAccount, signerType?: "signPayload" | "createTransaction") => polkadot_api.PolkadotSigner;
@@ -426,6 +441,7 @@ declare class HostProvider implements SignerProvider {
426
441
  private readonly loadHostApiEnum;
427
442
  private readonly requestChainSubmitPermission;
428
443
  private readonly productAccount;
444
+ private readonly dappName;
429
445
  private accountsProvider;
430
446
  private statusCleanup;
431
447
  private statusListeners;
@@ -494,7 +510,6 @@ declare class HostProvider implements SignerProvider {
494
510
  createRingVRFProof(dotNsIdentifier: string, derivationIndex: number, location: RingLocation, message: Uint8Array): Promise<Result<Uint8Array, SignerError>>;
495
511
  private tryConnect;
496
512
  private fetchProductSignerAccount;
497
- private mapAccounts;
498
513
  }
499
514
 
500
515
  /**
@@ -643,6 +658,17 @@ declare class SignerManager {
643
658
  * Returns a SIGNING_FAILED error if no account is selected or signing fails.
644
659
  */
645
660
  signRaw(data: Uint8Array): Promise<Result<Uint8Array, SignerError>>;
661
+ /**
662
+ * Fetch the connected user's host identity.
663
+ *
664
+ * This uses the Host API identity permission path and is only available
665
+ * when connected through the host provider. The primary username can be
666
+ * used by higher-level helpers that need to bind an action to the user's
667
+ * DotNS / people username.
668
+ */
669
+ getUserId(): Promise<Result<{
670
+ primaryUsername: string;
671
+ }, SignerError>>;
646
672
  /**
647
673
  * Get an app-scoped product account from the host.
648
674
  *
package/dist/index.js CHANGED
@@ -196,6 +196,7 @@ var HostProvider = class {
196
196
  loadHostApiEnum;
197
197
  requestChainSubmitPermission;
198
198
  productAccount;
199
+ dappName;
199
200
  accountsProvider = null;
200
201
  statusCleanup = null;
201
202
  statusListeners = /* @__PURE__ */ new Set();
@@ -208,6 +209,7 @@ var HostProvider = class {
208
209
  this.loadHostApiEnum = options?.loadHostApiEnum ?? defaultLoadHostApiEnum;
209
210
  this.requestChainSubmitPermission = options?.requestChainSubmitPermission ?? options?.requestTransactionSubmitPermission ?? true;
210
211
  this.productAccount = options?.productAccount;
212
+ this.dappName = options?.dappName;
211
213
  }
212
214
  async connect(signal) {
213
215
  log2.debug("attempting Host API connection");
@@ -446,36 +448,31 @@ var HostProvider = class {
446
448
  );
447
449
  if (!accountResult.ok) return accountResult;
448
450
  signerAccounts = [accountResult.value];
449
- } else {
450
- let rawAccounts;
451
- try {
452
- rawAccounts = await provider.getLegacyAccounts().match(
453
- (accounts) => accounts,
454
- (error) => {
455
- throw new Error(`Host rejected account request: ${formatError(error)}`);
451
+ } else if (this.dappName) {
452
+ const dotNsIdentifier = this.dappName.endsWith(".dot") ? this.dappName : `${this.dappName}.dot`;
453
+ const accountResult = await this.fetchProductSignerAccount(
454
+ provider,
455
+ dotNsIdentifier,
456
+ 0,
457
+ true
458
+ );
459
+ if (!accountResult.ok) {
460
+ log2.warn(
461
+ "host could not derive a product account for dappName; resolving with empty accounts",
462
+ {
463
+ dotNsIdentifier,
464
+ error: accountResult.error.message
456
465
  }
457
466
  );
458
- } catch (cause) {
459
- if (cause instanceof Error && /environment is not correct/i.test(cause.message)) {
460
- log2.warn("not inside a host container (detected at getLegacyAccounts)");
461
- return err(
462
- new HostUnavailableError(
463
- "Host API is not available: not running inside a Polkadot host container. Open this app inside Polkadot Desktop or the Polkadot Mobile WebView, or pick a non-host signer provider (e.g. dev accounts)."
464
- )
465
- );
466
- }
467
- log2.error("failed to get accounts from host", { cause });
468
- return err(
469
- new HostRejectedError(
470
- cause instanceof Error ? cause.message : "Failed to get accounts from host"
471
- )
472
- );
473
- }
474
- if (rawAccounts.length === 0) {
475
- log2.warn("host returned no accounts");
476
- return err(new NoAccountsError("host"));
467
+ signerAccounts = [];
468
+ } else {
469
+ signerAccounts = [accountResult.value];
477
470
  }
478
- signerAccounts = this.mapAccounts(rawAccounts);
471
+ } else {
472
+ log2.warn(
473
+ "no productAccount or dappName configured; resolving connect() with empty accounts"
474
+ );
475
+ signerAccounts = [];
479
476
  }
480
477
  if (this.requestChainSubmitPermission && sdk.hostApi) {
481
478
  try {
@@ -535,29 +532,6 @@ var HostProvider = class {
535
532
  const account = accountResult.value;
536
533
  return ok({ ...account, name: account.name ?? primaryUsername });
537
534
  }
538
- mapAccounts(rawAccounts) {
539
- return rawAccounts.map((raw) => {
540
- const address = ss58Encode(raw.publicKey, this.ss58Prefix);
541
- const h160Address = deriveH160(raw.publicKey);
542
- return {
543
- address,
544
- h160Address,
545
- publicKey: raw.publicKey,
546
- name: raw.name ?? null,
547
- source: "host",
548
- getSigner: () => {
549
- if (!this.accountsProvider) {
550
- throw new Error("Host provider is disconnected");
551
- }
552
- return this.accountsProvider.getLegacyAccountSigner({
553
- dotNsIdentifier: "",
554
- derivationIndex: 0,
555
- publicKey: raw.publicKey
556
- });
557
- }
558
- };
559
- });
560
- }
561
535
  };
562
536
  function formatError(error) {
563
537
  if (!error || typeof error !== "object") return String(error);
@@ -775,6 +749,24 @@ var SignerManager = class {
775
749
  }
776
750
  }
777
751
  // ── Host-only: Product Account API ─────────────────────────────
752
+ /**
753
+ * Fetch the connected user's host identity.
754
+ *
755
+ * This uses the Host API identity permission path and is only available
756
+ * when connected through the host provider. The primary username can be
757
+ * used by higher-level helpers that need to bind an action to the user's
758
+ * DotNS / people username.
759
+ */
760
+ async getUserId() {
761
+ if (this.isDestroyed) return err(new DestroyedError());
762
+ const host = this.getHostProvider();
763
+ if (!host) {
764
+ return err(
765
+ new HostUnavailableError("User identity requires a host provider connection")
766
+ );
767
+ }
768
+ return host.getUserId();
769
+ }
778
770
  /**
779
771
  * Get an app-scoped product account from the host.
780
772
  *
@@ -904,7 +896,8 @@ var SignerManager = class {
904
896
  return new HostProvider({
905
897
  ss58Prefix: this.ss58Prefix,
906
898
  maxRetries: this.maxRetries,
907
- retryDelay: 500
899
+ retryDelay: 500,
900
+ dappName: this.dappName
908
901
  });
909
902
  case "dev":
910
903
  return new DevProvider({