@parity/product-deploy 0.8.3-rc.0 → 0.8.3-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +53 -2
  2. package/bin/bulletin-deploy +54 -8
  3. package/dist/allocations-B65Is4Md.d.ts +97 -0
  4. package/dist/auth/index.d.ts +7 -0
  5. package/dist/auth/index.js +26 -0
  6. package/dist/auth/vendor/index.d.ts +32 -0
  7. package/dist/auth/vendor/index.js +27 -0
  8. package/dist/auth/vendor/ui/index.d.ts +15 -0
  9. package/dist/auth/vendor/ui/index.js +10 -0
  10. package/dist/auth-DkRZBK-T.d.ts +122 -0
  11. package/dist/auth-config.d.ts +39 -0
  12. package/dist/auth-config.js +20 -0
  13. package/dist/bug-report.js +4 -4
  14. package/dist/chunk-2OZVKA3D.js +410 -0
  15. package/dist/{chunk-PV3N2XTC.js → chunk-4CZ4GIWK.js} +677 -356
  16. package/dist/{chunk-LJMYOXQV.js → chunk-4GX3KJPU.js} +12 -1
  17. package/dist/{chunk-OAWXITVX.js → chunk-4W6VNILJ.js} +2 -2
  18. package/dist/{chunk-CBCUKOOJ.js → chunk-AKCO2LGH.js} +1 -1
  19. package/dist/{chunk-VRZXAB7J.js → chunk-AMGKEAOH.js} +2 -2
  20. package/dist/chunk-JQKKMUCT.js +0 -0
  21. package/dist/{chunk-UXVBF7TD.js → chunk-KFIIAUQU.js} +17 -3
  22. package/dist/{chunk-L5Z3TJD7.js → chunk-OCKCB72S.js} +6 -6
  23. package/dist/{chunk-YT2XCGZK.js → chunk-P2ZOBSCJ.js} +12 -5
  24. package/dist/chunk-RIRDBSBG.js +36 -0
  25. package/dist/{chunk-Z6PRIHI7.js → chunk-X2Q5FPIQ.js} +1 -1
  26. package/dist/chunk-YUSHBZBX.js +52 -0
  27. package/dist/chunk-probe.js +3 -3
  28. package/dist/commands/login.d.ts +28 -0
  29. package/dist/commands/login.js +116 -0
  30. package/dist/commands/logout.d.ts +21 -0
  31. package/dist/commands/logout.js +37 -0
  32. package/dist/commands/whoami.d.ts +22 -0
  33. package/dist/commands/whoami.js +47 -0
  34. package/dist/deploy.d.ts +49 -3
  35. package/dist/deploy.js +19 -8
  36. package/dist/dotns.d.ts +7 -0
  37. package/dist/dotns.js +3 -3
  38. package/dist/index.d.ts +1 -0
  39. package/dist/index.js +13 -12
  40. package/dist/manifest/publish.js +10 -9
  41. package/dist/memory-report.js +2 -2
  42. package/dist/merkle.d.ts +3 -1
  43. package/dist/merkle.js +9 -8
  44. package/dist/personhood/bind-paid-alias.js +3 -3
  45. package/dist/personhood/bind-personal-id.js +2 -2
  46. package/dist/personhood/bootstrap.js +16 -16
  47. package/dist/personhood/claim-pgas.js +2 -2
  48. package/dist/personhood/people-client.js +3 -3
  49. package/dist/personhood/proof-validity.js +2 -2
  50. package/dist/personhood/reprove.js +5 -5
  51. package/dist/run-state.js +1 -1
  52. package/dist/signer-CriGqahj.d.ts +35 -0
  53. package/dist/storage-signer.d.ts +38 -0
  54. package/dist/storage-signer.js +28 -0
  55. package/dist/telemetry.d.ts +1 -1
  56. package/dist/telemetry.js +2 -2
  57. package/dist/version-check.js +3 -3
  58. package/package.json +17 -3
  59. package/tools/release-retry-wrapper.mjs +1 -0
  60. package/dist/{chunk-LHLCPDGL.js → chunk-7URNKK6J.js} +3 -3
  61. package/dist/{chunk-7Y7RDOGT.js → chunk-EATOPQFR.js} +5 -5
  62. package/dist/{chunk-SLE4P6MO.js → chunk-EJI3MX4G.js} +3 -3
@@ -8,7 +8,7 @@ import {
8
8
  setDeploySentryTag,
9
9
  truncateAddress,
10
10
  withSpan
11
- } from "./chunk-YT2XCGZK.js";
11
+ } from "./chunk-P2ZOBSCJ.js";
12
12
  import {
13
13
  validateContractAddresses
14
14
  } from "./chunk-5K3RI5C2.js";
@@ -958,6 +958,7 @@ var DotNS = class {
958
958
  _environmentId = null;
959
959
  _popSelfServe = null;
960
960
  _registerStorageDeposit = MINIMUM_REGISTER_STORAGE_DEPOSIT;
961
+ _onPhoneSigningRequired = void 0;
961
962
  // Test-only seam: consumed once by classifyAliasAccountState() then cleared.
962
963
  // Mirrors the __setDeployRootSpanForTest / __setSentryForTest pattern.
963
964
  _classifyOverrideForTest = null;
@@ -1005,6 +1006,9 @@ var DotNS = class {
1005
1006
  if (options.registerStorageDeposit !== void 0) {
1006
1007
  this._registerStorageDeposit = options.registerStorageDeposit;
1007
1008
  }
1009
+ if (options.onPhoneSigningRequired !== void 0) {
1010
+ this._onPhoneSigningRequired = options.onPhoneSigningRequired;
1011
+ }
1008
1012
  const rpc = options.rpc || process.env.DOTNS_RPC || this.assetHubEndpoints[0];
1009
1013
  this.rpc = rpc;
1010
1014
  this._usesExternalSigner = Boolean(options.signer && options.signerAddress);
@@ -1657,6 +1661,9 @@ var DotNS = class {
1657
1661
  await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
1658
1662
  }
1659
1663
  };
1664
+ console.log(`
1665
+ Linking content...`);
1666
+ this._onPhoneSigningRequired?.("Link content");
1660
1667
  const txRes = await this.contractTransaction(this._contracts.DOTNS_CONTENT_RESOLVER, 0n, DOTNS_CONTENT_RESOLVER_ABI, "setContenthash", [node, contenthashHex], (s) => console.log(` ${s}`), { useNoncePolling: true, verifyEffect });
1661
1668
  const finalOnChain = (await this.getContenthash(domainName) || "0x").toLowerCase();
1662
1669
  if (finalOnChain !== expected) {
@@ -1884,6 +1891,7 @@ var DotNS = class {
1884
1891
  }
1885
1892
  };
1886
1893
  try {
1894
+ this._onPhoneSigningRequired?.("Publish to registry");
1887
1895
  const txRes = await this.contractTransaction(publisher, 0n, PUBLISHER_ABI, "publish", [label], (s) => console.log(` ${s}`), { useNoncePolling: true, verifyEffect });
1888
1896
  const finalPublished = await withTimeout(
1889
1897
  this.contractCall(publisher, PUBLISHER_ABI, "isPublished", [labelhash]),
@@ -2028,6 +2036,7 @@ var DotNS = class {
2028
2036
  this.ensureConnected();
2029
2037
  console.log(`
2030
2038
  Submitting commitment...`);
2039
+ this._onPhoneSigningRequired?.("Commitment");
2031
2040
  const commitTxRes = await this.contractTransaction(this._contracts.DOTNS_REGISTRAR_CONTROLLER, 0n, DOTNS_REGISTRAR_CONTROLLER_ABI, "commit", [commitment], (s) => console.log(` ${s}`));
2032
2041
  logTxResolution(commitTxRes);
2033
2042
  console.log(` Committed at: ${(/* @__PURE__ */ new Date()).toISOString()}`);
@@ -2122,6 +2131,7 @@ var DotNS = class {
2122
2131
  setDeployAttribute("deploy.payment_wei", priceWei.toString());
2123
2132
  console.log(` Oracle price: ${formatEther(priceWei)} PAS`);
2124
2133
  console.log(` Paying: ${formatEther(bufferedPaymentWei)} PAS`);
2134
+ this._onPhoneSigningRequired?.("Register");
2125
2135
  const registerTxRes = await this.contractTransaction(this._contracts.DOTNS_REGISTRAR_CONTROLLER, bufferedPaymentNative, DOTNS_REGISTRAR_CONTROLLER_ABI, "register", [registration], (s) => console.log(` ${s}`));
2126
2136
  logTxResolution(registerTxRes);
2127
2137
  if (registerTxRes.kind === TX_KIND_HASH) {
@@ -2545,6 +2555,7 @@ var DotNS = class {
2545
2555
  this.connected = false;
2546
2556
  }
2547
2557
  this._usesExternalSigner = false;
2558
+ this._onPhoneSigningRequired = void 0;
2548
2559
  }
2549
2560
  };
2550
2561
  var dotns = new DotNS();
@@ -6,10 +6,10 @@ import {
6
6
  resolveDotnsConnectOptions,
7
7
  storeDirectory,
8
8
  storeFile
9
- } from "./chunk-PV3N2XTC.js";
9
+ } from "./chunk-4CZ4GIWK.js";
10
10
  import {
11
11
  DotNS
12
- } from "./chunk-LJMYOXQV.js";
12
+ } from "./chunk-4GX3KJPU.js";
13
13
  import {
14
14
  getPopSelfServeConfig,
15
15
  loadEnvironments,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-YT2XCGZK.js";
3
+ } from "./chunk-P2ZOBSCJ.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -2,11 +2,11 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-CBCUKOOJ.js";
5
+ } from "./chunk-AKCO2LGH.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId
9
- } from "./chunk-YT2XCGZK.js";
9
+ } from "./chunk-P2ZOBSCJ.js";
10
10
 
11
11
  // src/bug-report.ts
12
12
  import { execSync, execFileSync } from "child_process";
File without changes
@@ -6,7 +6,7 @@ import * as path from "path";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@parity/product-deploy",
9
- version: "0.8.3-rc.0",
9
+ version: "0.8.3-rc.11",
10
10
  private: false,
11
11
  repository: {
12
12
  type: "git",
@@ -49,10 +49,10 @@ var package_default = {
49
49
  "tools/release-retry-wrapper.mjs"
50
50
  ],
51
51
  scripts: {
52
- build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/memory-report.ts src/merkle.ts src/gh-pages-mirror.ts src/version-check.ts src/bug-report.ts src/run-state.ts src/environments.ts src/errors.ts src/manifest.ts src/chunk-probe.ts src/manifest-embed.ts src/manifest-fetch.ts src/manifest-roundtrip.ts src/incremental-stats.ts src/chunker.ts src/personhood/encoding.ts src/personhood/hashing.ts src/personhood/constants.ts src/personhood/member-key.ts src/personhood/people-client.ts src/personhood/proof-validity.ts src/personhood/reprove.ts src/personhood/bind-personal-id.ts src/personhood/claim-pgas.ts src/personhood/bind-paid-alias.ts src/personhood/bootstrap.ts src/personhood/chain-prereqs.ts src/manifest/types.ts src/manifest/schema.ts src/manifest/byte-budget.ts src/manifest/config-load.ts src/manifest/publish.ts --format esm --dts --clean --target node22",
52
+ build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/memory-report.ts src/merkle.ts src/gh-pages-mirror.ts src/version-check.ts src/bug-report.ts src/run-state.ts src/environments.ts src/errors.ts src/manifest.ts src/chunk-probe.ts src/manifest-embed.ts src/manifest-fetch.ts src/manifest-roundtrip.ts src/incremental-stats.ts src/chunker.ts src/personhood/encoding.ts src/personhood/hashing.ts src/personhood/constants.ts src/personhood/member-key.ts src/personhood/people-client.ts src/personhood/proof-validity.ts src/personhood/reprove.ts src/personhood/bind-personal-id.ts src/personhood/claim-pgas.ts src/personhood/bind-paid-alias.ts src/personhood/bootstrap.ts src/personhood/chain-prereqs.ts src/manifest/types.ts src/manifest/schema.ts src/manifest/byte-budget.ts src/manifest/config-load.ts src/manifest/publish.ts src/auth/index.ts src/auth/vendor/index.ts src/auth/vendor/ui/index.ts src/auth-config.ts src/commands/login.ts src/commands/logout.ts src/commands/whoami.ts src/storage-signer.ts --format esm --dts --clean --target node22",
53
53
  "refresh-environments": "node scripts/refresh-environments.mjs",
54
54
  prepare: "npm run build",
55
- test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/chunk-sharing-report.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js",
55
+ test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/chunk-sharing-report.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js test/auth-config.test.js test/whoami.test.js test/login.test.js test/logout.test.js test/auth-resolve.test.js",
56
56
  "test:e2e": "npm run build && node --test test/e2e.test.js",
57
57
  "test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
58
58
  "test:e2e:pr": "bash scripts/e2e-pass.sh pr",
@@ -63,6 +63,10 @@ var package_default = {
63
63
  "@ipld/car": "^5.4.3",
64
64
  "@ipld/dag-pb": "^4.1.3",
65
65
  "@noble/hashes": "^1.7.2",
66
+ "@parity/product-sdk-address": "^0.1.1",
67
+ "@parity/product-sdk-keys": "^0.3.0",
68
+ "@parity/product-sdk-terminal": "^0.2.1",
69
+ "@parity/product-sdk-tx": "^0.2.4",
66
70
  "@polkadot-api/metadata-builders": "^0.14.2",
67
71
  "@polkadot-api/substrate-bindings": "^0.20.2",
68
72
  "@polkadot-labs/hdkd": "^0.0.28",
@@ -82,8 +86,18 @@ var package_default = {
82
86
  "@types/node": "^22.0.0",
83
87
  tsup: "^8.5.0",
84
88
  typescript: "^5.9.3",
89
+ vitest: "^3.0.0",
85
90
  ws: "^8.20.1"
86
91
  },
92
+ overrides: {
93
+ "@polkadot-api/json-rpc-provider": "^0.2.0",
94
+ "@novasamatech/host-api": "0.7.9-4",
95
+ "@novasamatech/host-papp": "0.7.9-4",
96
+ "@novasamatech/product-sdk": "0.7.9-4",
97
+ "@novasamatech/scale": "0.7.9-4",
98
+ "@novasamatech/statement-store": "0.7.9-4",
99
+ "@novasamatech/storage-adapter": "0.7.9-4"
100
+ },
87
101
  minimumVersion: "0.5.6",
88
102
  engines: {
89
103
  node: ">=22"
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  buildAliasProofMessage,
3
3
  getProofValidAtSec
4
- } from "./chunk-SLE4P6MO.js";
4
+ } from "./chunk-EJI3MX4G.js";
5
+ import {
6
+ bytesToHex,
7
+ encodeMembers,
8
+ hexToBytes
9
+ } from "./chunk-ZYVGHDMU.js";
5
10
  import {
6
11
  PEOPLE_MEMBER_IDENTIFIER_HEX,
7
12
  PGAS_ASSET_ID,
8
13
  PGAS_ASSET_LOCATION,
9
14
  PROOF_BYTES
10
15
  } from "./chunk-SI2ZUOYD.js";
11
- import {
12
- bytesToHex,
13
- encodeMembers,
14
- hexToBytes
15
- } from "./chunk-ZYVGHDMU.js";
16
16
 
17
17
  // src/personhood/bind-paid-alias.ts
18
18
  import { getSs58AddressInfo, Binary } from "polkadot-api";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-UXVBF7TD.js";
4
+ } from "./chunk-KFIIAUQU.js";
5
5
 
6
6
  // src/memory-report.ts
7
7
  import * as fs2 from "fs";
@@ -17,7 +17,6 @@ import * as path from "path";
17
17
  var VERSION = package_default.version;
18
18
  var DOTNS_BACKEND = "contract";
19
19
  var DOTNS_POP_SOURCE = "personhood-precompile";
20
- var DEFAULT_DSN = "https://e021c025d79c4c3ade2862a11f13c40b@o4511059872841728.ingest.de.sentry.io/4511093597405264";
21
20
  var INTERNAL_ORG_RE = /^(paritytech|w3f|polkadot-fellows)\//i;
22
21
  var PARITY_HOST_APPS = /* @__PURE__ */ new Set(["playground-cli"]);
23
22
  function extractRepoSlug(url) {
@@ -45,7 +44,7 @@ function isInternalContext() {
45
44
  hostApp: process.env.BULLETIN_DEPLOY_HOST_APP
46
45
  });
47
46
  }
48
- var OPT_OUT = process.env.BULLETIN_DEPLOY_TELEMETRY === "0";
47
+ var OPT_OUT = process.env.BULLETIN_DEPLOY_TELEMETRY === "0" || process.env.BULLETIN_DEPLOY_TELEMETRY === "off";
49
48
  var OPT_IN = process.env.BULLETIN_DEPLOY_TELEMETRY === "1";
50
49
  var DISABLED = OPT_OUT || !OPT_IN && !isInternalContext();
51
50
  var CONVENTIONAL_BRANCH_PREFIXES = /* @__PURE__ */ new Set([
@@ -117,8 +116,10 @@ function initTelemetry() {
117
116
  if (process.env.BULLETIN_DEPLOY_USE_AMBIENT_SENTRY === "1") {
118
117
  return;
119
118
  }
119
+ const dsn = process.env.SENTRY_DSN || (true ? "" : "");
120
+ if (!dsn) return;
120
121
  Sentry.init({
121
- dsn: process.env.SENTRY_DSN || DEFAULT_DSN,
122
+ dsn,
122
123
  release: `${package_default.name}@${VERSION}`,
123
124
  tracesSampleRate: 1,
124
125
  environment: process.env.CI ? "ci" : "local",
@@ -316,15 +317,21 @@ var ERROR_KIND_RULES = [
316
317
  [/\bstale\b.*nonce|nonce.*\bstale\b|"type"\s*:\s*"(?:Future|Stale)"|Invalid::Future|tx rejected by pool/i, "nonce-stale"],
317
318
  [/heartbeat timeout|WS halt|Unable to connect|ChainHead disjointed|websocket.*closed|socket closed|disconnect/i, "connection"],
318
319
  [/requires ProofOfPersonhood(?:Full|Lite|Light),\s*but this signer is NoStatus/i, "naming.pop_required"],
320
+ [/requires NoStatus,\s*but this signer is ProofOfPersonhood/i, "naming.nostatus_required"],
321
+ [/Cannot decode zero data.*with ABI parameters/i, "naming.contract_unavailable"],
319
322
  [/Domain\s+\S+\.dot\s+is already owned by\s+0x[a-fA-F0-9]+/i, "naming.already_owned"],
320
323
  [/Cannot deploy\s+[\w.-]+\.dot:\s*parent\s+[\w.-]+\.dot\s+is owned by/i, "naming.subdomain_orphan"],
321
324
  [/Post-deploy verification failed for .+: on-chain contenthash is /i, "verify.contenthash_mismatch"],
322
325
  [/Deploy verification failed:\s*DAG-PB root.+not finalised/i, "verify.dagpb_not_finalised"],
323
326
  [/Retry budget exhausted:.*recovery attempts/i, "network.recovery_exhausted"],
327
+ [/Account auto-mapping did not take effect on-chain/i, "account.mapping_pending"],
324
328
  [/ReviveApi\.\w+ timed out after \d+ms/i, "chain.api_timeout"],
325
329
  [/ReviveApi\.\w+ returned empty result/i, "chain.api_timeout"],
326
330
  [/transaction watcher silent for \d+s/i, "chain.tx_silent"],
327
- [/^(?:commit|register|setSubnodeOwner|setResolver|setContenthash|setText|publish|unpublish|Revive\.call|Utility\.batch_all) timed out after \d+ms/i, "chain.tx_timeout"],
331
+ [/(?:commit|register|setSubnodeOwner|setResolver|setContenthash|setText|publish|unpublish|Revive\.call|Utility\.batch_all) timed out after \d+ms/i, "chain.tx_timeout"],
332
+ [/AncientBirthBlock/i, "chain.extrinsic_expired"],
333
+ [/Bulletin quota exhausted/i, "chain.quota_exhausted"],
334
+ [/Mobile signing (?:failed|rejected).*message too big/i, "signer.message_too_large"],
328
335
  [/^INVARIANT FAILED:/i, "tool.invariant"]
329
336
  ];
330
337
  function classifyErrorKind(msg) {
@@ -0,0 +1,36 @@
1
+ // src/auth/vendor/ui/qr.ts
2
+ import { renderQrCode } from "@parity/product-sdk-terminal";
3
+
4
+ // src/auth/vendor/ui/status.ts
5
+ function renderLoginStatus(status) {
6
+ switch (status.step) {
7
+ case "waiting":
8
+ return "Waiting for you to scan the QR code with your phone\u2026";
9
+ case "paired":
10
+ return "Paired \u2014 finishing sign-in\u2026";
11
+ case "pending":
12
+ return `Working: ${status.stage}\u2026`;
13
+ case "success":
14
+ return `Signed in as ${status.address}`;
15
+ case "error":
16
+ return `Sign-in failed: ${status.message}`;
17
+ }
18
+ }
19
+ function renderLogoutStatus(status) {
20
+ switch (status.step) {
21
+ case "disconnecting":
22
+ return `Signing out ${status.address}\u2026`;
23
+ case "success":
24
+ return `Signed out ${status.address}`;
25
+ case "partial":
26
+ return `Signed out locally (${status.address}); the phone was not notified: ${status.reason}`;
27
+ case "error":
28
+ return `Sign-out error: ${status.message}`;
29
+ }
30
+ }
31
+
32
+ export {
33
+ renderQrCode,
34
+ renderLoginStatus,
35
+ renderLogoutStatus
36
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  captureWarning
3
- } from "./chunk-YT2XCGZK.js";
3
+ } from "./chunk-P2ZOBSCJ.js";
4
4
 
5
5
  // src/chunk-probe.ts
6
6
  import { Twox128, Blake2128Concat, decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
@@ -0,0 +1,52 @@
1
+ import {
2
+ loadEnvironments
3
+ } from "./chunk-5K3RI5C2.js";
4
+
5
+ // src/auth-config.ts
6
+ import { existsSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ var DOT_DAPP_ID = "dot-cli";
10
+ var DOT_PRODUCT_ID = "playground.dot";
11
+ var DOT_DERIVATION_INDEX = 0;
12
+ var DOT_TERMINAL_METADATA_URL = "https://gist.githubusercontent.com/ReinhardHatko/1967dd3f4afe78683cc0ba14d6ec8744/raw/c1625eb7ed7671b7e09a3fa2a25998dde33c70b8/metadata.json";
13
+ function hasPersistedSession() {
14
+ return existsSync(join(homedir(), ".polkadot-apps", `${DOT_DAPP_ID}_SsoSessions.json`));
15
+ }
16
+ function buildAuthConfig(doc, envId) {
17
+ const peopleChain = doc.chains.find((c) => c.id === "people");
18
+ if (!peopleChain) {
19
+ throw new Error(
20
+ `No "people" chain found in environments doc. Add a "people" entry under "chains" in environments.json.`
21
+ );
22
+ }
23
+ const endpoint = peopleChain.endpoints[envId];
24
+ if (!endpoint) {
25
+ throw new Error(
26
+ `No people-chain endpoint for environment "${envId}". Available envs: ${Object.keys(peopleChain.endpoints).join(", ")}.`
27
+ );
28
+ }
29
+ const peopleEndpoints = Array.isArray(endpoint.wss) ? endpoint.wss : [endpoint.wss];
30
+ return {
31
+ dappId: DOT_DAPP_ID,
32
+ productId: DOT_PRODUCT_ID,
33
+ derivationIndex: DOT_DERIVATION_INDEX,
34
+ metadataUrl: DOT_TERMINAL_METADATA_URL,
35
+ peopleEndpoints
36
+ };
37
+ }
38
+ async function getAuthClient(envId) {
39
+ const { createAuthClient } = await import("./auth/index.js");
40
+ const { doc } = await loadEnvironments();
41
+ return createAuthClient(buildAuthConfig(doc, envId));
42
+ }
43
+
44
+ export {
45
+ DOT_DAPP_ID,
46
+ DOT_PRODUCT_ID,
47
+ DOT_DERIVATION_INDEX,
48
+ DOT_TERMINAL_METADATA_URL,
49
+ hasPersistedSession,
50
+ buildAuthConfig,
51
+ getAuthClient
52
+ };
@@ -5,9 +5,9 @@ import {
5
5
  _decodeStorageValue,
6
6
  _resetProbeSession,
7
7
  probeChunks
8
- } from "./chunk-Z6PRIHI7.js";
9
- import "./chunk-YT2XCGZK.js";
10
- import "./chunk-UXVBF7TD.js";
8
+ } from "./chunk-X2Q5FPIQ.js";
9
+ import "./chunk-P2ZOBSCJ.js";
10
+ import "./chunk-KFIIAUQU.js";
11
11
  export {
12
12
  ChainProbeCrossValidationError,
13
13
  ChainProbeMetadataError,
@@ -0,0 +1,28 @@
1
+ import { b as AllocationSummary } from '../allocations-B65Is4Md.js';
2
+ import '@parity/product-sdk-terminal';
3
+
4
+ /**
5
+ * login — QR/mobile sign-in command.
6
+ *
7
+ * Flow:
8
+ * 1. connect() → existing session (already logged in) OR QR code
9
+ * 2. Print QR → user scans on phone
10
+ * 3. waitForLogin() → phone approves → paired
11
+ * 4. requestAllocation() — REQUIRED before the fresh session can sign (RFC-0010)
12
+ * 5. Print summarizeLogin()
13
+ * 6. destroy()
14
+ */
15
+
16
+ /**
17
+ * Format a post-login summary. Pure function, unit-testable.
18
+ */
19
+ declare function summarizeLogin(address: string, summary: AllocationSummary): string;
20
+ interface LoginOptions {
21
+ suri?: string;
22
+ }
23
+ /**
24
+ * Run the login command. Prints the QR code to stdout and waits for mobile approval.
25
+ */
26
+ declare function runLogin(envId: string, _opts?: LoginOptions): Promise<void>;
27
+
28
+ export { type LoginOptions, runLogin, summarizeLogin };
@@ -0,0 +1,116 @@
1
+ import "../chunk-JQKKMUCT.js";
2
+ import {
3
+ DEFAULT_RESOURCES,
4
+ summarizeOutcomes
5
+ } from "../chunk-2OZVKA3D.js";
6
+ import {
7
+ renderLoginStatus
8
+ } from "../chunk-RIRDBSBG.js";
9
+ import {
10
+ extractBulletinSlotKey,
11
+ writeBulletinSlotKey
12
+ } from "../chunk-4CZ4GIWK.js";
13
+ import "../chunk-HOTQDYHD.js";
14
+ import "../chunk-IW3X2MJF.js";
15
+ import "../chunk-KOSF5FDO.js";
16
+ import "../chunk-J3NIXHZZ.js";
17
+ import "../chunk-S7EM5VMW.js";
18
+ import {
19
+ DOT_DAPP_ID,
20
+ getAuthClient
21
+ } from "../chunk-YUSHBZBX.js";
22
+ import "../chunk-AMGKEAOH.js";
23
+ import "../chunk-AKCO2LGH.js";
24
+ import "../chunk-X2Q5FPIQ.js";
25
+ import "../chunk-C2TS5MER.js";
26
+ import "../chunk-4GX3KJPU.js";
27
+ import "../chunk-QS7YU76C.js";
28
+ import "../chunk-P2ZOBSCJ.js";
29
+ import "../chunk-KFIIAUQU.js";
30
+ import "../chunk-5K3RI5C2.js";
31
+ import "../chunk-ZOC4GITL.js";
32
+
33
+ // src/commands/login.ts
34
+ function summarizeLogin(address, summary) {
35
+ const lines = [
36
+ `Signed in as: ${address}`,
37
+ `Resources granted: ${summary.granted.length}`
38
+ ];
39
+ if (summary.rejected.length > 0) {
40
+ lines.push(`Resources rejected: ${summary.rejected.length} (${summary.rejected.map((r) => r.tag).join(", ")})`);
41
+ }
42
+ if (summary.unavailable.length > 0) {
43
+ lines.push(`Resources unavailable: ${summary.unavailable.length}`);
44
+ }
45
+ return lines.join("\n");
46
+ }
47
+ async function runLogin(envId, _opts = {}) {
48
+ const client = await getAuthClient(envId);
49
+ const result = await client.connect();
50
+ if (result.kind === "existing") {
51
+ const sessionHandle2 = await client.getSessionSigner();
52
+ if (sessionHandle2) {
53
+ let sssExpired = false;
54
+ const origErr = console.error;
55
+ console.error = (...args) => {
56
+ const msg = args.map(String).join(" ");
57
+ if (msg.includes("NoAllowanceError") || msg.includes("no allowance set")) {
58
+ sssExpired = true;
59
+ return;
60
+ }
61
+ origErr(...args);
62
+ };
63
+ await Promise.race([
64
+ client.requestAllocation(sessionHandle2.userSession, DEFAULT_RESOURCES).catch(() => {
65
+ }),
66
+ new Promise((r) => setTimeout(r, 3e3))
67
+ ]);
68
+ console.error = origErr;
69
+ sessionHandle2.destroy();
70
+ if (sssExpired) {
71
+ console.error(
72
+ `
73
+ Statement Store allowance has expired for ${result.address}.
74
+ Run: bulletin-deploy logout
75
+ Then: bulletin-deploy login
76
+ to re-pair and renew (allowance lasts ~2-3 days).`
77
+ );
78
+ process.exit(1);
79
+ }
80
+ }
81
+ console.log(`Already signed in as: ${result.address}`);
82
+ return;
83
+ }
84
+ console.log(result.qrCode);
85
+ console.log("Scan the QR code with your Polkadot wallet app.");
86
+ const address = await client.waitForLogin(result.login, (status) => {
87
+ const msg = renderLoginStatus(status);
88
+ if (msg) process.stdout.write(`\r${msg}`);
89
+ });
90
+ if (!address) {
91
+ console.error("\nLogin failed.");
92
+ return;
93
+ }
94
+ const sessionHandle = await client.getSessionSigner();
95
+ if (sessionHandle) {
96
+ try {
97
+ const outcomes = await client.requestAllocation(sessionHandle.userSession, DEFAULT_RESOURCES);
98
+ const summary = summarizeOutcomes(outcomes, DEFAULT_RESOURCES);
99
+ console.log("\n" + summarizeLogin(address, summary));
100
+ const hexKey = extractBulletinSlotKey(outcomes);
101
+ if (hexKey) {
102
+ await writeBulletinSlotKey(DOT_DAPP_ID, hexKey);
103
+ console.log(` Bulletin storage key cached \u2713`);
104
+ }
105
+ } finally {
106
+ sessionHandle.destroy();
107
+ }
108
+ } else {
109
+ console.log(`
110
+ Signed in as: ${address}`);
111
+ }
112
+ }
113
+ export {
114
+ runLogin,
115
+ summarizeLogin
116
+ };
@@ -0,0 +1,21 @@
1
+ import { d as LogoutStatus } from '../auth-DkRZBK-T.js';
2
+ import '@parity/product-sdk-terminal';
3
+ import 'polkadot-api';
4
+ import '../allocations-B65Is4Md.js';
5
+
6
+ /**
7
+ * logout — sign out the current session.
8
+ *
9
+ * Flow: findSession() → null → "no session" ; else waitForLogout()
10
+ */
11
+
12
+ /**
13
+ * Format a logout status line. Pure function, unit-testable.
14
+ */
15
+ declare function formatLogout(status: LogoutStatus): string;
16
+ /**
17
+ * Run the logout command. Finds the current session and signs out.
18
+ */
19
+ declare function runLogout(envId: string): Promise<void>;
20
+
21
+ export { formatLogout, runLogout };
@@ -0,0 +1,37 @@
1
+ import "../chunk-JQKKMUCT.js";
2
+ import "../chunk-2OZVKA3D.js";
3
+ import {
4
+ renderLogoutStatus
5
+ } from "../chunk-RIRDBSBG.js";
6
+ import {
7
+ getAuthClient
8
+ } from "../chunk-YUSHBZBX.js";
9
+ import "../chunk-5K3RI5C2.js";
10
+ import "../chunk-ZOC4GITL.js";
11
+
12
+ // src/commands/logout.ts
13
+ function formatLogout(status) {
14
+ return renderLogoutStatus(status);
15
+ }
16
+ async function runLogout(envId) {
17
+ const client = await getAuthClient(envId);
18
+ try {
19
+ const handle = await client.findSession();
20
+ if (!handle) {
21
+ console.log("Not logged in. No session to sign out.");
22
+ return;
23
+ }
24
+ await client.waitForLogout(handle, (status) => {
25
+ console.log(formatLogout(status));
26
+ });
27
+ } finally {
28
+ try {
29
+ await client.clearLocalAppStorage();
30
+ } catch {
31
+ }
32
+ }
33
+ }
34
+ export {
35
+ formatLogout,
36
+ runLogout
37
+ };
@@ -0,0 +1,22 @@
1
+ import { S as SessionAddresses } from '../auth-DkRZBK-T.js';
2
+ import '@parity/product-sdk-terminal';
3
+ import 'polkadot-api';
4
+ import '../allocations-B65Is4Md.js';
5
+
6
+ /**
7
+ * whoami — show the currently logged-in session account, or "not logged in".
8
+ * Pure formatter `formatWhoami` is unit-tested; `runWhoami` is the live async path.
9
+ */
10
+
11
+ /**
12
+ * Format session address info for display. Pass `null` when no session exists.
13
+ * Pure function — unit-testable without any SSO stack.
14
+ */
15
+ declare function formatWhoami(addresses: SessionAddresses | null): string;
16
+ /**
17
+ * Run the whoami command. Gets the session signer (if any) and prints the
18
+ * formatted output. Never throws — "no session" prints the not-logged-in message.
19
+ */
20
+ declare function runWhoami(envId: string): Promise<void>;
21
+
22
+ export { formatWhoami, runWhoami };
@@ -0,0 +1,47 @@
1
+ import {
2
+ getAuthClient,
3
+ hasPersistedSession
4
+ } from "../chunk-YUSHBZBX.js";
5
+ import "../chunk-5K3RI5C2.js";
6
+ import "../chunk-ZOC4GITL.js";
7
+
8
+ // src/commands/whoami.ts
9
+ function formatWhoami(addresses) {
10
+ if (!addresses) {
11
+ return "Not logged in. Run `bulletin-deploy login` to sign in.";
12
+ }
13
+ return [
14
+ `Logged in:`,
15
+ ` Root address: ${addresses.rootAddress}`,
16
+ ` Product address: ${addresses.productAddress}`,
17
+ ` H160 (EVM): ${addresses.productH160}`
18
+ ].join("\n");
19
+ }
20
+ async function runWhoami(envId) {
21
+ if (!hasPersistedSession()) {
22
+ console.log(formatWhoami(null));
23
+ return;
24
+ }
25
+ try {
26
+ const client = await getAuthClient(envId);
27
+ const handle = await client.getSessionSigner();
28
+ if (handle) {
29
+ console.log(formatWhoami(handle.addresses));
30
+ handle.destroy();
31
+ } else {
32
+ console.log(formatWhoami(null));
33
+ }
34
+ } catch (err) {
35
+ const e = err;
36
+ if (e?.name === "SignerNotAvailableError") {
37
+ console.log(formatWhoami(null));
38
+ } else {
39
+ console.log(`Could not reach login service: ${e?.message ?? String(err)}`);
40
+ console.log(formatWhoami(null));
41
+ }
42
+ }
43
+ }
44
+ export {
45
+ formatWhoami,
46
+ runWhoami
47
+ };