bulletin-deploy 0.19.3 → 0.19.4-rc.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.
Files changed (69) hide show
  1. package/assets/environments.json +5 -5
  2. package/bin/bulletin-deploy +10 -1
  3. package/dist/auth/index.js +7 -7
  4. package/dist/auth/vendor/index.js +2 -2
  5. package/dist/auth-config.js +5 -5
  6. package/dist/bug-report.js +5 -4
  7. package/dist/chain-health.js +4 -3
  8. package/dist/{chunk-NA3SXVY6.js → chunk-3NR3T7US.js} +22 -12
  9. package/dist/{chunk-6FQJLLEF.js → chunk-54O7BQEM.js} +1 -1
  10. package/dist/{chunk-SNFGJOR2.js → chunk-5BQHK7PU.js} +1 -1
  11. package/dist/{chunk-QU5GJF6U.js → chunk-6Q5E2QFC.js} +3 -3
  12. package/dist/{chunk-LPTKBQII.js → chunk-7DDOVCV5.js} +1 -1
  13. package/dist/{chunk-I5PNPQZO.js → chunk-ANX3RZAS.js} +38 -10
  14. package/dist/{chunk-IW3X2MJF.js → chunk-D3YME2EG.js} +30 -1
  15. package/dist/{chunk-RJDHC56V.js → chunk-DRITBDAW.js} +53 -16
  16. package/dist/{chunk-3MAIF2SF.js → chunk-F24S4EV5.js} +49 -7
  17. package/dist/{chunk-WPC2PUCV.js → chunk-H44LXDQJ.js} +43 -8
  18. package/dist/{chunk-5FLTDWWP.js → chunk-H44NO63C.js} +1 -1
  19. package/dist/{chunk-IP6ABIIC.js → chunk-HAFVFPXQ.js} +29 -4
  20. package/dist/{chunk-H4OZ6PTA.js → chunk-L6NQO7A3.js} +8 -8
  21. package/dist/{chunk-VBIFKNUS.js → chunk-LHMS6D6V.js} +1 -1
  22. package/dist/{chunk-ABMNC34K.js → chunk-LVOHDGTK.js} +2 -2
  23. package/dist/{chunk-NKDGBZBP.js → chunk-O56KLG7Z.js} +2 -2
  24. package/dist/{chunk-3ACNAWUD.js → chunk-PGRQ6QIV.js} +3 -3
  25. package/dist/{chunk-ZOC4GITL.js → chunk-SH2LG52Z.js} +5 -1
  26. package/dist/{chunk-PSYA6E5M.js → chunk-TUK6SMCX.js} +1 -1
  27. package/dist/{chunk-KTKFHROI.js → chunk-Z27FUDEB.js} +4 -4
  28. package/dist/chunk-ZG3HAH5A.js +18 -0
  29. package/dist/{chunk-6MSHWNJT.js → chunk-ZIFIY6C2.js} +138 -54
  30. package/dist/chunk-probe.js +4 -3
  31. package/dist/commands/login.js +24 -23
  32. package/dist/commands/logout.js +7 -7
  33. package/dist/commands/transfer.js +7 -6
  34. package/dist/commands/whoami.js +5 -5
  35. package/dist/deploy-actors.js +10 -9
  36. package/dist/deploy.d.ts +45 -18
  37. package/dist/deploy.js +30 -20
  38. package/dist/dotns.d.ts +56 -2
  39. package/dist/dotns.js +9 -6
  40. package/dist/environments.d.ts +7 -1
  41. package/dist/environments.js +2 -2
  42. package/dist/errors.d.ts +5 -1
  43. package/dist/errors.js +7 -3
  44. package/dist/incremental-stats.d.ts +14 -0
  45. package/dist/incremental-stats.js +1 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.js +23 -22
  48. package/dist/manifest/config-load.js +3 -3
  49. package/dist/manifest/publish.d.ts +1 -0
  50. package/dist/manifest/publish.js +23 -22
  51. package/dist/manifest/schema.js +1 -1
  52. package/dist/manifest-embed.js +2 -2
  53. package/dist/manifest-fetch.js +2 -2
  54. package/dist/manifest-roundtrip.js +2 -2
  55. package/dist/manifest.d.ts +14 -1
  56. package/dist/manifest.js +5 -1
  57. package/dist/memory-report.js +3 -2
  58. package/dist/merkle.js +20 -19
  59. package/dist/mnemonic.d.ts +35 -0
  60. package/dist/mnemonic.js +8 -0
  61. package/dist/personhood/bootstrap.js +7 -6
  62. package/dist/personhood/people-client.js +7 -6
  63. package/dist/run-state.js +1 -1
  64. package/dist/sss-allowance-cache.js +6 -6
  65. package/dist/storage-signer.js +20 -19
  66. package/dist/telemetry.d.ts +2 -1
  67. package/dist/telemetry.js +5 -2
  68. package/dist/version-check.js +4 -3
  69. package/package.json +4 -4
@@ -14,7 +14,7 @@
14
14
  "tld": "testnet",
15
15
  "autoAccountMapping": true,
16
16
  "nativeToEthRatio": 100000000,
17
- "registerStorageDeposit": 2000000000000,
17
+ "registerStorageDeposit": 50000000000,
18
18
  "popSelfServe": {
19
19
  "sudoEnvLabel": "Preview",
20
20
  "personhoodFaucetUrl": "https://sudo.personhood.dev/personhood-faucet",
@@ -46,7 +46,7 @@
46
46
  "ipfs": "https://previewnet.substrate.dev",
47
47
  "autoAccountMapping": true,
48
48
  "nativeToEthRatio": 100000000,
49
- "registerStorageDeposit": 2000000000000,
49
+ "registerStorageDeposit": 50000000000,
50
50
  "contracts": {}
51
51
  },
52
52
  {
@@ -82,7 +82,7 @@
82
82
  "tld": "paseo",
83
83
  "autoAccountMapping": true,
84
84
  "nativeToEthRatio": 100000000,
85
- "registerStorageDeposit": 2000000000000,
85
+ "registerStorageDeposit": 50000000000,
86
86
  "popSelfServe": {
87
87
  "sudoEnvLabel": "Next V2",
88
88
  "faucetUrl": "https://faucet.polkadot.io/?parachain=1500",
@@ -117,7 +117,7 @@
117
117
  "tld": "dot",
118
118
  "autoAccountMapping": true,
119
119
  "nativeToEthRatio": 100000000,
120
- "registerStorageDeposit": 2000000000000,
120
+ "registerStorageDeposit": 50000000000,
121
121
  "contracts": {
122
122
  "DOTNS_PROTOCOL_REGISTRY": "0xD19e3D0C97CF501125a04A97405e3e6592fa846E",
123
123
  "DOTNS_REGISTRAR": "0x4f06E818Ba3d987704fd91cf3d868E4b019106Ab",
@@ -146,7 +146,7 @@
146
146
  "webGateway": "dev-dot.li",
147
147
  "autoAccountMapping": true,
148
148
  "nativeToEthRatio": 100000000,
149
- "registerStorageDeposit": 2000000000000,
149
+ "registerStorageDeposit": 50000000000,
150
150
  "contracts": {
151
151
  "DOTNS_PROTOCOL_REGISTRY": "0xEdb3e17649ABccc69e6fab4cc640bc578C47AbeA",
152
152
  "DOTNS_REGISTRAR": "0x7f0dF075cc8B7FE7218E90fFC5a553450dB120F3",
@@ -6,7 +6,7 @@
6
6
  // SDK modules that trigger the "@parity/product-sdk-logger" localStorage warning.
7
7
  import "../dist/suppress-localstorage-warning.js";
8
8
 
9
- import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY, isConnectionError, isBenignTeardownError, resolveEffectiveMnemonic, resolveEnvId, shouldPublishManifest, nonInteractivePhoneConfirmationError } from "../dist/deploy.js";
9
+ import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY, isConnectionError, isBenignTeardownError, resolveEffectiveMnemonic, mnemonicConflictNotice, resolveEnvId, shouldPublishManifest, nonInteractivePhoneConfirmationError } from "../dist/deploy.js";
10
10
  import { VERSION, setDeployAttribute, captureWarning, closeTelemetry, setRunStateActive, markRelaunchOomHintShown, setVersionFreshness } from "../dist/telemetry.js";
11
11
  import { handleFailedDeploy, handlePreflightVersionCheck, fetchVersionInfo, preReleaseWarning, checkNodeVersion, classifyVersionFreshness, isInteractive } from "../dist/version-check.js";
12
12
  import { setDeployContext, installLogCapture, buildCliFlagsSummary } from "../dist/bug-report.js";
@@ -82,6 +82,15 @@ const effectiveMnemonic = resolveEffectiveMnemonic({
82
82
  envDotnsMnemonic: process.env.DOTNS_MNEMONIC,
83
83
  });
84
84
 
85
+ // #1461: surface it when MNEMONIC and DOTNS_MNEMONIC are both set and
86
+ // disagree — only meaningful when no --mnemonic flag was given (a flag makes
87
+ // both env vars irrelevant), and skipped on --help/--version since neither
88
+ // deploys anything.
89
+ if (!flags.mnemonic && !flags.help && !flags.version) {
90
+ const mnemonicNotice = mnemonicConflictNotice({ envMnemonic: process.env.MNEMONIC, envDotnsMnemonic: process.env.DOTNS_MNEMONIC });
91
+ if (mnemonicNotice) console.error(mnemonicNotice);
92
+ }
93
+
85
94
  // #1165: the env id actually targeted this session — --env flag >
86
95
  // BULLETIN_DEPLOY_ENV env var. `undefined` here still means "let
87
96
  // deploy()/the DEFAULT_ENV_ID fallback below decide" — this only resolves
@@ -1,4 +1,9 @@
1
1
  import "../chunk-JQKKMUCT.js";
2
+ import {
3
+ renderLoginStatus,
4
+ renderLogoutStatus,
5
+ renderQrCode
6
+ } from "../chunk-RIRDBSBG.js";
2
7
  import {
3
8
  BULLETIN_RESOURCE,
4
9
  DEFAULT_RESOURCES,
@@ -8,14 +13,9 @@ import {
8
13
  requestResourceAllocation,
9
14
  resolveSigner,
10
15
  summarizeOutcomes
11
- } from "../chunk-5FLTDWWP.js";
12
- import {
13
- renderLoginStatus,
14
- renderLogoutStatus,
15
- renderQrCode
16
- } from "../chunk-RIRDBSBG.js";
16
+ } from "../chunk-H44NO63C.js";
17
17
  import "../chunk-TSPERKUS.js";
18
- import "../chunk-ZOC4GITL.js";
18
+ import "../chunk-SH2LG52Z.js";
19
19
  export {
20
20
  BULLETIN_RESOURCE,
21
21
  DEFAULT_RESOURCES,
@@ -12,9 +12,9 @@ import {
12
12
  resolveSigner,
13
13
  sessionRootPublicKey,
14
14
  summarizeOutcomes
15
- } from "../../chunk-5FLTDWWP.js";
15
+ } from "../../chunk-H44NO63C.js";
16
16
  import "../../chunk-TSPERKUS.js";
17
- import "../../chunk-ZOC4GITL.js";
17
+ import "../../chunk-SH2LG52Z.js";
18
18
  export {
19
19
  BULLETIN_RESOURCE,
20
20
  DEFAULT_RESOURCES,
@@ -9,12 +9,12 @@ import {
9
9
  getPeopleChainEndpoints,
10
10
  hasPersistedSession,
11
11
  resolveBulletinEndpoints
12
- } from "./chunk-ABMNC34K.js";
12
+ } from "./chunk-LVOHDGTK.js";
13
13
  import "./chunk-TSPERKUS.js";
14
- import "./chunk-NA3SXVY6.js";
15
- import "./chunk-ZOC4GITL.js";
16
- import "./chunk-IP6ABIIC.js";
17
- import "./chunk-KTKFHROI.js";
14
+ import "./chunk-3NR3T7US.js";
15
+ import "./chunk-HAFVFPXQ.js";
16
+ import "./chunk-Z27FUDEB.js";
17
+ import "./chunk-SH2LG52Z.js";
18
18
  export {
19
19
  DOT_DAPP_ID,
20
20
  DOT_DERIVATION_INDEX,
@@ -10,10 +10,11 @@ import {
10
10
  offerBugReport,
11
11
  scrubSecrets,
12
12
  setDeployContext
13
- } from "./chunk-QU5GJF6U.js";
14
- import "./chunk-SNFGJOR2.js";
15
- import "./chunk-IP6ABIIC.js";
16
- import "./chunk-KTKFHROI.js";
13
+ } from "./chunk-6Q5E2QFC.js";
14
+ import "./chunk-5BQHK7PU.js";
15
+ import "./chunk-HAFVFPXQ.js";
16
+ import "./chunk-Z27FUDEB.js";
17
+ import "./chunk-SH2LG52Z.js";
17
18
  export {
18
19
  buildCliFlagsSummary,
19
20
  buildLabels,
@@ -3,9 +3,10 @@ import {
3
3
  DEFAULT_WINDOW_BLOCKS,
4
4
  MAX_SPANS_PER_SAMPLER,
5
5
  endpointHost
6
- } from "./chunk-VBIFKNUS.js";
7
- import "./chunk-IP6ABIIC.js";
8
- import "./chunk-KTKFHROI.js";
6
+ } from "./chunk-LHMS6D6V.js";
7
+ import "./chunk-HAFVFPXQ.js";
8
+ import "./chunk-Z27FUDEB.js";
9
+ import "./chunk-SH2LG52Z.js";
9
10
  export {
10
11
  ChainHealthSampler,
11
12
  DEFAULT_WINDOW_BLOCKS,
@@ -1,6 +1,8 @@
1
1
  import {
2
- NonRetryableError
3
- } from "./chunk-ZOC4GITL.js";
2
+ FALLBACK_CONFIG_ORIGIN,
3
+ NonRetryableError,
4
+ SHIPPED_CONFIG_ORIGIN
5
+ } from "./chunk-SH2LG52Z.js";
4
6
 
5
7
  // src/environments.ts
6
8
  import * as fs from "fs/promises";
@@ -23,7 +25,7 @@ var environments_default = {
23
25
  tld: "testnet",
24
26
  autoAccountMapping: true,
25
27
  nativeToEthRatio: 1e8,
26
- registerStorageDeposit: 2e12,
28
+ registerStorageDeposit: 5e10,
27
29
  popSelfServe: {
28
30
  sudoEnvLabel: "Preview",
29
31
  personhoodFaucetUrl: "https://sudo.personhood.dev/personhood-faucet",
@@ -55,7 +57,7 @@ var environments_default = {
55
57
  ipfs: "https://previewnet.substrate.dev",
56
58
  autoAccountMapping: true,
57
59
  nativeToEthRatio: 1e8,
58
- registerStorageDeposit: 2e12,
60
+ registerStorageDeposit: 5e10,
59
61
  contracts: {}
60
62
  },
61
63
  {
@@ -91,7 +93,7 @@ var environments_default = {
91
93
  tld: "paseo",
92
94
  autoAccountMapping: true,
93
95
  nativeToEthRatio: 1e8,
94
- registerStorageDeposit: 2e12,
96
+ registerStorageDeposit: 5e10,
95
97
  popSelfServe: {
96
98
  sudoEnvLabel: "Next V2",
97
99
  faucetUrl: "https://faucet.polkadot.io/?parachain=1500",
@@ -126,7 +128,7 @@ var environments_default = {
126
128
  tld: "dot",
127
129
  autoAccountMapping: true,
128
130
  nativeToEthRatio: 1e8,
129
- registerStorageDeposit: 2e12,
131
+ registerStorageDeposit: 5e10,
130
132
  contracts: {
131
133
  DOTNS_PROTOCOL_REGISTRY: "0xD19e3D0C97CF501125a04A97405e3e6592fa846E",
132
134
  DOTNS_REGISTRAR: "0x4f06E818Ba3d987704fd91cf3d868E4b019106Ab",
@@ -155,7 +157,7 @@ var environments_default = {
155
157
  webGateway: "dev-dot.li",
156
158
  autoAccountMapping: true,
157
159
  nativeToEthRatio: 1e8,
158
- registerStorageDeposit: 2e12,
160
+ registerStorageDeposit: 5e10,
159
161
  contracts: {
160
162
  DOTNS_PROTOCOL_REGISTRY: "0xEdb3e17649ABccc69e6fab4cc640bc578C47AbeA",
161
163
  DOTNS_REGISTRAR: "0x7f0dF075cc8B7FE7218E90fFC5a553450dB120F3",
@@ -519,11 +521,15 @@ function validateContractAddresses(contracts, envId, sources) {
519
521
  }
520
522
  }
521
523
  }
522
- function describeContractSources(envContracts, cliContracts, source, userFilePath, envId) {
524
+ function describeContractSources(envContracts, cliContracts, source, userFilePath, envId, userFileKeys) {
523
525
  const env = envId ?? "unknown";
524
- const docOrigin = source === "file" && userFilePath ? `${userFilePath} (environment ${env})` : source === "hardcoded-fallback" ? `the built-in fallback for ${env}` : `assets/environments.json shipped with bulletin-deploy (environment ${env})`;
526
+ const shippedOrigin = source === "hardcoded-fallback" ? `${FALLBACK_CONFIG_ORIGIN} ${env}` : `${SHIPPED_CONFIG_ORIGIN} (environment ${env})`;
527
+ const fileOrigin = userFilePath ? `${userFilePath} (environment ${env})` : null;
528
+ const declared = new Set(userFileKeys ?? []);
525
529
  const out = {};
526
- for (const key of Object.keys(envContracts)) out[key] = docOrigin;
530
+ for (const key of Object.keys(envContracts)) {
531
+ out[key] = fileOrigin && declared.has(key) ? fileOrigin : shippedOrigin;
532
+ }
527
533
  for (const [key, addr] of Object.entries(cliContracts ?? {})) out[key] = `the --contract flag or contracts option (${key}=${addr})`;
528
534
  return out;
529
535
  }
@@ -597,19 +603,23 @@ async function loadEnvironments(opts = {}) {
597
603
  const baseDoc = base ?? (isValidDoc(environments_default) ? environments_default : HARDCODED_FALLBACK);
598
604
  const partial = userDoc && typeof userDoc === "object" && !Array.isArray(userDoc) ? userDoc : {};
599
605
  const merged = deepMergeEnvironments(baseDoc, partial);
606
+ const userFileContractKeys = /* @__PURE__ */ Object.create(null);
607
+ for (const e of partial.environments ?? []) {
608
+ if (e?.id && !(e.id in userFileContractKeys)) userFileContractKeys[e.id] = Object.keys(e.contracts ?? {});
609
+ }
600
610
  warn(
601
611
  `bulletin-deploy: Using user-supplied environment file "${userFilePath}" \u2014 values are NOT validated against chain; you own correctness.`
602
612
  );
603
613
  for (const env of merged.environments) {
604
614
  if (env.contracts && Object.keys(env.contracts).length > 0) {
605
615
  try {
606
- validateContractAddresses(env.contracts, env.id, describeContractSources(env.contracts, void 0, "file", userFilePath, env.id));
616
+ validateContractAddresses(env.contracts, env.id, describeContractSources(env.contracts, void 0, "file", userFilePath, env.id, userFileContractKeys[env.id] ?? []));
607
617
  } catch (err) {
608
618
  warn(`bulletin-deploy: Warning: ${err?.message ?? err}`);
609
619
  }
610
620
  }
611
621
  }
612
- return { doc: merged, source: "file", userFilePath };
622
+ return { doc: merged, source: "file", userFilePath, userFileContractKeys };
613
623
  }
614
624
  const bundled = await readBundled(bundledPath, capture);
615
625
  if (bundled) return { doc: bundled, source: "bundled" };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-ABMNC34K.js";
6
+ } from "./chunk-LVOHDGTK.js";
7
7
 
8
8
  // src/sss-allowance-cache.ts
9
9
  import { mkdir, readFile, writeFile, unlink } from "fs/promises";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-IP6ABIIC.js";
3
+ } from "./chunk-HAFVFPXQ.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -2,15 +2,15 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-SNFGJOR2.js";
5
+ } from "./chunk-5BQHK7PU.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId,
9
9
  resolveIssueRepoSlug
10
- } from "./chunk-IP6ABIIC.js";
10
+ } from "./chunk-HAFVFPXQ.js";
11
11
  import {
12
12
  package_default
13
- } from "./chunk-KTKFHROI.js";
13
+ } from "./chunk-Z27FUDEB.js";
14
14
 
15
15
  // src/bug-report.ts
16
16
  import { execSync, execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MANIFEST_DIR,
3
3
  MANIFEST_PATH
4
- } from "./chunk-WPC2PUCV.js";
4
+ } from "./chunk-H44LXDQJ.js";
5
5
 
6
6
  // src/manifest-embed.ts
7
7
  import * as fs from "fs";
@@ -16,12 +16,31 @@ var LABEL = String.raw`(?!-)[a-z0-9-]{1,63}(?<!-)`;
16
16
  var TLD_FRAGMENT = "[a-z]{2,63}";
17
17
  var DOMAIN_RE = new RegExp(`^${LABEL}(\\.${LABEL})*\\.${TLD_FRAGMENT}$`, "i");
18
18
  var PRODUCT_LABEL_RE = new RegExp(`^${LABEL}$`);
19
+ var PRODUCT_CONFIG_TOP_LEVEL_FIELDS = [
20
+ "domain",
21
+ "displayName",
22
+ "description",
23
+ "icon",
24
+ "executables",
25
+ "trustedProducts"
26
+ ];
19
27
  function isPlainObject(value) {
20
28
  return typeof value === "object" && value !== null && !Array.isArray(value);
21
29
  }
22
30
  function isNonEmptyString(value) {
23
31
  return typeof value === "string" && value.length > 0;
24
32
  }
33
+ function validateIconFormat(format, label, strict) {
34
+ if (!isNonEmptyString(format)) {
35
+ return [`${label} icon.format must be a non-empty string (got ${JSON.stringify(format)})`];
36
+ }
37
+ if (strict && !ICON_FORMATS.includes(format)) {
38
+ return [
39
+ `${label} icon.format must be one of ${ICON_FORMATS.join(", ")} (got ${JSON.stringify(format)})`
40
+ ];
41
+ }
42
+ return [];
43
+ }
25
44
  function validateTrustedProducts(value, label, strict) {
26
45
  if (!isPlainObject(value))
27
46
  return [`${label} trustedProducts must be an object`];
@@ -329,11 +348,14 @@ function validateRootManifest(input) {
329
348
  } else {
330
349
  if (!isNonEmptyString(input.icon.cid))
331
350
  errors.push("root manifest icon.cid must be a non-empty string");
332
- if (!ICON_FORMATS.includes(input.icon.format)) {
333
- errors.push(
334
- `root manifest icon.format must be one of ${ICON_FORMATS.join(", ")} (got ${JSON.stringify(input.icon.format)})`
335
- );
336
- }
351
+ errors.push(
352
+ ...validateIconFormat(
353
+ input.icon.format,
354
+ "root manifest",
355
+ /* strict */
356
+ false
357
+ )
358
+ );
337
359
  }
338
360
  if (input.trustedProducts !== void 0) {
339
361
  errors.push(
@@ -394,6 +416,9 @@ function validateProductConfig(input) {
394
416
  ]
395
417
  };
396
418
  }
419
+ errors.push(
420
+ ...rejectUnknownFields(input, PRODUCT_CONFIG_TOP_LEVEL_FIELDS, "product config ")
421
+ );
397
422
  if (!isNonEmptyString(input.domain) || !DOMAIN_RE.test(input.domain)) {
398
423
  errors.push(
399
424
  "product config domain must be a non-empty dotNS name ending in a TLD of 2 or more letters (e.g. 'myapp.dot')"
@@ -408,11 +433,14 @@ function validateProductConfig(input) {
408
433
  } else {
409
434
  if (!isNonEmptyString(input.icon.path))
410
435
  errors.push("product config icon.path must be a non-empty string");
411
- if (!ICON_FORMATS.includes(input.icon.format)) {
412
- errors.push(
413
- `product config icon.format must be one of ${ICON_FORMATS.join(", ")}`
414
- );
415
- }
436
+ errors.push(
437
+ ...validateIconFormat(
438
+ input.icon.format,
439
+ "product config",
440
+ /* strict */
441
+ true
442
+ )
443
+ );
416
444
  }
417
445
  if (input.trustedProducts !== void 0) {
418
446
  errors.push(
@@ -16,6 +16,13 @@ function computeStats(input) {
16
16
  filesTotal: input.filesTotal,
17
17
  filesStable: input.filesStable,
18
18
  filesVolatile: input.filesVolatile,
19
+ filesStablePacked: input.filesStablePacked ?? input.filesStable,
20
+ heuristicAgreeStable: input.heuristicAgreeStable ?? 0,
21
+ heuristicAgreeVolatile: input.heuristicAgreeVolatile ?? 0,
22
+ heuristicFalseVolatile: input.heuristicFalseVolatile ?? 0,
23
+ heuristicFalseStable: input.heuristicFalseStable ?? 0,
24
+ buildMarkers: input.buildMarkers ?? [],
25
+ unhashedStableSample: input.unhashedStableSample ?? [],
19
26
  probedTotal: input.probeResults.length,
20
27
  probePresent: present.length,
21
28
  probeAbsent: input.probeResults.filter((r) => r.present === false).length,
@@ -43,7 +50,7 @@ function computeStats(input) {
43
50
  };
44
51
  }
45
52
  function telemetryAttributes(s) {
46
- const hitRate = s.filesTotal === 0 ? 0 : s.filesStable / s.filesTotal;
53
+ const hitRate = s.filesTotal === 0 ? 0 : s.filesStablePacked / s.filesTotal;
47
54
  return {
48
55
  "deploy.cache.manifest_source": s.manifestSource,
49
56
  "deploy.cache.manifest_fetch_attempts": String(s.manifestFetchAttempts),
@@ -54,6 +61,28 @@ function telemetryAttributes(s) {
54
61
  "deploy.cache.files_total": String(s.filesTotal),
55
62
  "deploy.cache.files_stable": String(s.filesStable),
56
63
  "deploy.cache.files_volatile": String(s.filesVolatile),
64
+ // Raw per-deploy counts, not ratios — @sentry/node user-defined attributes
65
+ // are string-typed in EAP regardless of value type, so sum()/avg() don't
66
+ // work on them; the arithmetic happens locally on rows pulled from
67
+ // Sentry. A pre-divided ratio would also lose the byte weighting #1539
68
+ // establishes as the correct ranking (see the design doc's "Emission
69
+ // caveat" section).
70
+ "deploy.cache.heuristic_agree_stable": String(s.heuristicAgreeStable),
71
+ "deploy.cache.heuristic_agree_volatile": String(s.heuristicAgreeVolatile),
72
+ "deploy.cache.heuristic_false_volatile": String(s.heuristicFalseVolatile),
73
+ "deploy.cache.heuristic_false_stable": String(s.heuristicFalseStable),
74
+ // Every marker observed in the deployed tree, even when detectFramework
75
+ // returned null (ambiguous or none) — an UNKNOWN deploy still names what
76
+ // it shipped. Comma-joined, "" when no marker matched.
77
+ "deploy.cache.build_markers": s.buildMarkers.join(","),
78
+ // The basename evidence behind heuristic_false_volatile — those are the
79
+ // files a new framework rule could have saved, and this says which ones.
80
+ // There is deliberately no separate count attribute: it would emit
81
+ // heuristic_false_volatile's number under a second name, and a schema
82
+ // where two keys always carry the same value teaches every dashboard
83
+ // author to check whether they really do. Deduped, capped sample,
84
+ // basenames only — a path leaks site structure.
85
+ "deploy.cache.unhashed_stable_sample": s.unhashedStableSample.join(","),
57
86
  "deploy.cache.probed_total": String(s.probedTotal),
58
87
  "deploy.cache.probe_present": String(s.probePresent),
59
88
  "deploy.cache.probe_absent": String(s.probeAbsent),
@@ -1,19 +1,20 @@
1
1
  import {
2
2
  PGAS_ASSET_LOCATION
3
3
  } from "./chunk-SI2ZUOYD.js";
4
+ import {
5
+ mnemonicConflictNotice,
6
+ resolveEffectiveMnemonic
7
+ } from "./chunk-ZG3HAH5A.js";
4
8
  import {
5
9
  isTestnetSpecName,
6
10
  testnetFromNetworkField
7
11
  } from "./chunk-FWJQAIVO.js";
8
12
  import {
9
13
  validateContractAddresses
10
- } from "./chunk-NA3SXVY6.js";
11
- import {
12
- NonRetryableError
13
- } from "./chunk-ZOC4GITL.js";
14
+ } from "./chunk-3NR3T7US.js";
14
15
  import {
15
16
  ChainHealthSampler
16
- } from "./chunk-VBIFKNUS.js";
17
+ } from "./chunk-LHMS6D6V.js";
17
18
  import {
18
19
  captureWarning,
19
20
  markCodePath,
@@ -21,7 +22,10 @@ import {
21
22
  setDeploySentryTag,
22
23
  truncateAddress,
23
24
  withSpan
24
- } from "./chunk-IP6ABIIC.js";
25
+ } from "./chunk-HAFVFPXQ.js";
26
+ import {
27
+ NonRetryableError
28
+ } from "./chunk-SH2LG52Z.js";
25
29
  import {
26
30
  HIGHEST_VERIFIED_DOTNS_RELEASE,
27
31
  POP_CONTROLLER_PROBE_ABI,
@@ -81,7 +85,7 @@ var FEE_FLOOR_OWNED = ONE_PAS / 100n;
81
85
  var FEE_FLOOR_REGISTER = ONE_PAS / 10n;
82
86
  var TOP_UP_TARGET = ONE_PAS / 2n;
83
87
  var SOURCE_BUFFER = ONE_PAS;
84
- var MINIMUM_REGISTER_STORAGE_DEPOSIT = 2000000000000n;
88
+ var MINIMUM_REGISTER_STORAGE_DEPOSIT = 50000000000n;
85
89
  function registerDepositWei(userStatus, startingPriceWei) {
86
90
  return userStatus === ProofOfPersonhoodStatus.NoStatus ? startingPriceWei : 0n;
87
91
  }
@@ -119,6 +123,12 @@ function storageDepositLimitFor(estimate, floor = MINIMUM_REGISTER_STORAGE_DEPOS
119
123
  const buffered = estimate * 120n / 100n;
120
124
  return buffered < floor ? floor : buffered;
121
125
  }
126
+ function weightLimitFor(gasRequired) {
127
+ return {
128
+ ref_time: gasRequired.referenceTime * 120n / 100n,
129
+ proof_size: gasRequired.proofSize * 120n / 100n
130
+ };
131
+ }
122
132
  function feeFloorFor(plannedAction, storageDeposit = MINIMUM_REGISTER_STORAGE_DEPOSIT, rentPriceNative = 0n, transferFeeNative = 0n) {
123
133
  if (isOwnedAction(plannedAction)) return FEE_FLOOR_OWNED + transferFeeNative;
124
134
  return FEE_FLOOR_REGISTER + storageDeposit + rentPriceNative + transferFeeNative;
@@ -548,9 +558,15 @@ function formatContractDryRunFailure(gasEstimate, context) {
548
558
  const isBareRevert = isBareRevertResult(gasEstimate.revertData, gasEstimate.revertFlags);
549
559
  if (isBareRevert && BARE_REVERT_DIAGNOSTIC_FUNCTIONS.has(functionName)) {
550
560
  if (functionName === "register") {
561
+ const floor = context.registerStorageDeposit ?? MINIMUM_REGISTER_STORAGE_DEPOSIT;
551
562
  lines.push(
552
563
  ` diagnostic: bare-revert (empty 0x) during register. Most likely cause: insufficient signer balance for storage deposit.`,
553
- ` A fresh TLD register() requires sufficient free balance to cover the chain's storage deposit (typically 200+ PAS).`,
564
+ // #1518: this used to say "typically 200+ PAS" — a hardcoded, never-measured figure.
565
+ // The real chain-side storage deposit is well under 1 PAS (see MINIMUM_REGISTER_STORAGE_DEPOSIT's
566
+ // doc comment); the number that actually matters is the FLOOR this specific call declared,
567
+ // since pallet-revive requires the signer's free balance to cover the declared limit, not the
568
+ // (much smaller) real charge. Name that configured value here so a user tops up the right amount.
569
+ ` A fresh TLD register() requires sufficient free balance to cover the declared storage-deposit limit (currently ${fmtPas(floor)} PAS for this environment).`,
554
570
  ` Other possible causes:`,
555
571
  ` 1. PoP status changed between preflight and registration (race condition).`,
556
572
  ` 2. Commitment timing: the revealed commitment is still too new or already expired.`,
@@ -889,10 +905,23 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
889
905
  static DRY_RUN_WEIGHT_LIMIT = { ref_time: 18446744073709551615n, proof_size: 18446744073709551615n };
890
906
  client;
891
907
  mappedAccounts;
908
+ // #1518: the storage-deposit floor this wrapper declares on every Revive.call
909
+ // it dry-runs/submits (dryRunReviveCall, submitTransaction, submitBatchedTransactions).
910
+ // Defaults to the module constant so a wrapper nobody configured (e.g. a bare
911
+ // `new ReviveClientWrapper(api)` in a test) still declares a SAFE, measured
912
+ // floor rather than silently falling back to 0. DotNS.recreateReviveClient —
913
+ // the only place a wrapper is ever constructed — calls setStorageDepositFloor
914
+ // right after construction, so every dry-run path through this wrapper picks
915
+ // up the owning DotNS instance's configured/measured value automatically; no
916
+ // per-call parameter to thread (and forget) at each new call site.
917
+ _storageDepositFloor = MINIMUM_REGISTER_STORAGE_DEPOSIT;
892
918
  constructor(client) {
893
919
  this.client = client;
894
920
  this.mappedAccounts = /* @__PURE__ */ new Set();
895
921
  }
922
+ setStorageDepositFloor(floor) {
923
+ this._storageDepositFloor = floor;
924
+ }
896
925
  async getEvmAddress(substrateAddress) {
897
926
  if (isAddress(substrateAddress)) return substrateAddress;
898
927
  const address = await this.client.apis.ReviveApi.address(substrateAddress);
@@ -1166,13 +1195,14 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
1166
1195
  value,
1167
1196
  encodedData,
1168
1197
  args: context.args,
1169
- contracts: context.contracts
1198
+ contracts: context.contracts,
1199
+ registerStorageDeposit: this._storageDepositFloor
1170
1200
  });
1171
1201
  throw new ContractDryRunRevertError(msg, gasEstimate.revertData ?? "0x", gasEstimate.revertFlags ?? 0n);
1172
1202
  }
1173
1203
  return {
1174
- weight_limit: { ref_time: gasEstimate.gasRequired.referenceTime, proof_size: gasEstimate.gasRequired.proofSize },
1175
- storage_deposit_limit: storageDepositLimitFor(gasEstimate.storageDeposit)
1204
+ weight_limit: weightLimitFor(gasEstimate.gasRequired),
1205
+ storage_deposit_limit: storageDepositLimitFor(gasEstimate.storageDeposit, this._storageDepositFloor)
1176
1206
  };
1177
1207
  }
1178
1208
  async submitTransaction(contractAddress, value, encodedData, signerSubstrateAddress, signer, statusCallback, { rpcs, useNoncePolling, functionName, args, contracts, verifyEffect, feeAsset, isPhoneSigner, onResign }) {
@@ -1517,6 +1547,7 @@ var DotNS = class _DotNS {
1517
1547
  }
1518
1548
  this.client = createClient(getWsProvider(endpoint, { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS }));
1519
1549
  this.clientWrapper = new ReviveClientWrapper(this.client.getUnsafeApi());
1550
+ this.clientWrapper.setStorageDepositFloor(this._registerStorageDeposit);
1520
1551
  this.chainHealth.attach(this.client, endpoint);
1521
1552
  }
1522
1553
  async connect(options = {}) {
@@ -1557,7 +1588,15 @@ var DotNS = class _DotNS {
1557
1588
  this.signer = options.signer;
1558
1589
  this.substrateAddress = options.signerAddress;
1559
1590
  } else {
1560
- const mnemonicArg = options.mnemonic || process.env.DOTNS_MNEMONIC || process.env.MNEMONIC;
1591
+ if (!options.mnemonic) {
1592
+ const notice = mnemonicConflictNotice({ envMnemonic: process.env.MNEMONIC, envDotnsMnemonic: process.env.DOTNS_MNEMONIC });
1593
+ if (notice) console.error(notice);
1594
+ }
1595
+ const mnemonicArg = resolveEffectiveMnemonic({
1596
+ flagMnemonic: options.mnemonic,
1597
+ envMnemonic: process.env.MNEMONIC,
1598
+ envDotnsMnemonic: process.env.DOTNS_MNEMONIC
1599
+ });
1561
1600
  const keyUriArg = options.keyUri || process.env.DOTNS_KEY_URI;
1562
1601
  let source = keyUriArg || mnemonicArg || DEFAULT_MNEMONIC;
1563
1602
  const isKeyUri = Boolean(keyUriArg);
@@ -2643,10 +2682,7 @@ var DotNS = class _DotNS {
2643
2682
  contracts: this._contracts
2644
2683
  }));
2645
2684
  }
2646
- const weight_limit = {
2647
- proof_size: headEstimate.gasRequired.proofSize,
2648
- ref_time: headEstimate.gasRequired.referenceTime
2649
- };
2685
+ const weight_limit = weightLimitFor(headEstimate.gasRequired);
2650
2686
  const storage_deposit_limit = storageDepositLimitFor(headEstimate.storageDeposit, this._registerStorageDeposit);
2651
2687
  const client = this.clientWrapper.client;
2652
2688
  const buildBatch = () => {
@@ -3792,6 +3828,7 @@ export {
3792
3828
  weiToNative,
3793
3829
  fmtPas,
3794
3830
  storageDepositLimitFor,
3831
+ weightLimitFor,
3795
3832
  feeFloorFor,
3796
3833
  RPC_ENDPOINTS,
3797
3834
  CONTRACTS,