@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 +28 -2
- package/dist/index.js +44 -51
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/providers/host.ts +108 -135
- package/src/signer-manager.ts +87 -0
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
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
|
|
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({
|