bulletin-deploy 0.18.4 → 0.19.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.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/dist/auth-config.js +4 -4
  3. package/dist/bug-report.js +4 -4
  4. package/dist/chain-health.js +3 -3
  5. package/dist/{chunk-K23BCUAG.js → chunk-6H3GBTBA.js} +21 -16
  6. package/dist/{chunk-GZ4O5DIU.js → chunk-A7MFUE2N.js} +1 -1
  7. package/dist/chunk-DMNLTQGA.js +64 -0
  8. package/dist/{chunk-WCGCM45C.js → chunk-G2Z4U4OQ.js} +11 -44
  9. package/dist/{chunk-TTUXQMD3.js → chunk-G664B5Y4.js} +1 -1
  10. package/dist/{chunk-CVQ7DJHG.js → chunk-I5PNPQZO.js} +64 -3
  11. package/dist/{chunk-5HFXRNCQ.js → chunk-IQUS43B7.js} +1 -1
  12. package/dist/{chunk-4NIOCONP.js → chunk-J6N3W3KJ.js} +1 -1
  13. package/dist/{chunk-STXAFUTQ.js → chunk-JZTZWMP7.js} +4 -1
  14. package/dist/{chunk-7I3MTGOR.js → chunk-K5SP4OUC.js} +19 -1
  15. package/dist/{chunk-MJCXPKBL.js → chunk-K6OAMQQU.js} +62 -14
  16. package/dist/{chunk-JGIPHFBT.js → chunk-KXQVZWDW.js} +2 -2
  17. package/dist/{chunk-WEVSXHII.js → chunk-NKDGBZBP.js} +1 -1
  18. package/dist/{chunk-HDGD5FYX.js → chunk-NYNAUG4V.js} +13 -4
  19. package/dist/{chunk-A55GRHCX.js → chunk-R7HIFZDM.js} +3 -3
  20. package/dist/{chunk-E7PNP2NP.js → chunk-RBI2B5SW.js} +3 -3
  21. package/dist/{chunk-5MS64TTR.js → chunk-SVVPNIGN.js} +2 -2
  22. package/dist/{chunk-RXV677CJ.js → chunk-YTRNJMI4.js} +7 -36
  23. package/dist/chunk-probe.js +3 -3
  24. package/dist/commands/login.js +13 -13
  25. package/dist/commands/logout.js +5 -5
  26. package/dist/commands/transfer.js +6 -6
  27. package/dist/commands/whoami.js +4 -4
  28. package/dist/deploy-actors.js +8 -8
  29. package/dist/deploy.d.ts +1 -1
  30. package/dist/deploy.js +13 -13
  31. package/dist/dotns-protocol.d.ts +32 -1
  32. package/dist/dotns-protocol.js +5 -1
  33. package/dist/dotns.d.ts +12 -3
  34. package/dist/dotns.js +8 -6
  35. package/dist/environments.d.ts +5 -2
  36. package/dist/environments.js +3 -1
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +21 -20
  39. package/dist/manifest/byte-budget.js +2 -1
  40. package/dist/manifest/compose.d.ts +20 -0
  41. package/dist/manifest/compose.js +8 -0
  42. package/dist/manifest/config-load.js +2 -2
  43. package/dist/manifest/publish.js +18 -17
  44. package/dist/manifest/schema.js +1 -1
  45. package/dist/manifest/types.d.ts +29 -1
  46. package/dist/memory-report.js +2 -2
  47. package/dist/merkle.js +13 -13
  48. package/dist/personhood/bootstrap.js +7 -7
  49. package/dist/personhood/people-client.js +6 -6
  50. package/dist/run-state.js +1 -1
  51. package/dist/sss-allowance-cache.js +5 -5
  52. package/dist/storage-signer.js +13 -13
  53. package/dist/telemetry.d.ts +1 -1
  54. package/dist/telemetry.js +2 -2
  55. package/dist/version-check.js +3 -3
  56. package/docs/product-manifest.md +76 -0
  57. package/package.json +3 -3
package/README.md CHANGED
@@ -71,7 +71,7 @@ Key options:
71
71
  | `--no-transfer-to-signedin-user` | When signed in, sign every DotNS tx with your mobile session instead of the default register-as-worker-then-hand-over flow. |
72
72
  | `--to <0xH160>` | Recipient address for the `transfer` subcommand. Defaults to the signed-in account. |
73
73
  | `--js-merkle` | Use pure-JS merkleization (no IPFS Kubo binary required). |
74
- | `--config <path>` | Explicit path to `bulletin-deploy.config.ts` for product deploys. |
74
+ | `--config <path>` | Explicit path to `bulletin-deploy.config.ts` for product deploys. See [`docs/product-manifest.md`](docs/product-manifest.md). |
75
75
  | `--tag "..."` | Label the deploy in telemetry. |
76
76
  | `--version` | Print the installed version and exit. |
77
77
 
@@ -9,12 +9,12 @@ import {
9
9
  getPeopleChainEndpoints,
10
10
  hasPersistedSession,
11
11
  resolveBulletinEndpoints
12
- } from "./chunk-5MS64TTR.js";
12
+ } from "./chunk-SVVPNIGN.js";
13
13
  import "./chunk-TSPERKUS.js";
14
- import "./chunk-HDGD5FYX.js";
14
+ import "./chunk-NYNAUG4V.js";
15
15
  import "./chunk-ZOC4GITL.js";
16
- import "./chunk-STXAFUTQ.js";
17
- import "./chunk-E7PNP2NP.js";
16
+ import "./chunk-JZTZWMP7.js";
17
+ import "./chunk-RBI2B5SW.js";
18
18
  export {
19
19
  DOT_DAPP_ID,
20
20
  DOT_DERIVATION_INDEX,
@@ -10,10 +10,10 @@ import {
10
10
  offerBugReport,
11
11
  scrubSecrets,
12
12
  setDeployContext
13
- } from "./chunk-A55GRHCX.js";
14
- import "./chunk-TTUXQMD3.js";
15
- import "./chunk-STXAFUTQ.js";
16
- import "./chunk-E7PNP2NP.js";
13
+ } from "./chunk-R7HIFZDM.js";
14
+ import "./chunk-G664B5Y4.js";
15
+ import "./chunk-JZTZWMP7.js";
16
+ import "./chunk-RBI2B5SW.js";
17
17
  export {
18
18
  buildCliFlagsSummary,
19
19
  buildLabels,
@@ -3,9 +3,9 @@ import {
3
3
  DEFAULT_WINDOW_BLOCKS,
4
4
  MAX_SPANS_PER_SAMPLER,
5
5
  endpointHost
6
- } from "./chunk-5HFXRNCQ.js";
7
- import "./chunk-STXAFUTQ.js";
8
- import "./chunk-E7PNP2NP.js";
6
+ } from "./chunk-IQUS43B7.js";
7
+ import "./chunk-JZTZWMP7.js";
8
+ import "./chunk-RBI2B5SW.js";
9
9
  export {
10
10
  ChainHealthSampler,
11
11
  DEFAULT_WINDOW_BLOCKS,
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-M5AKL3FL.js";
7
7
  import {
8
8
  preflightSssAllowance
9
- } from "./chunk-GZ4O5DIU.js";
9
+ } from "./chunk-A7MFUE2N.js";
10
10
  import {
11
11
  statementSigningAccount
12
12
  } from "./chunk-GRPLHUYC.js";
@@ -32,18 +32,18 @@ import {
32
32
  } from "./chunk-WPC2PUCV.js";
33
33
  import {
34
34
  setDeployContext
35
- } from "./chunk-A55GRHCX.js";
35
+ } from "./chunk-R7HIFZDM.js";
36
36
  import {
37
37
  getBestBlockNumber,
38
38
  probeChunks,
39
39
  probeFinalityGap
40
- } from "./chunk-4NIOCONP.js";
40
+ } from "./chunk-J6N3W3KJ.js";
41
41
  import {
42
42
  packSection
43
43
  } from "./chunk-C2TS5MER.js";
44
44
  import {
45
45
  resolveStorageSigner
46
- } from "./chunk-JGIPHFBT.js";
46
+ } from "./chunk-KXQVZWDW.js";
47
47
  import {
48
48
  createSlotAccountSigner,
49
49
  requestResourceAllocation
@@ -59,7 +59,7 @@ import {
59
59
  parseDomainName,
60
60
  popStatusName,
61
61
  verifyNonceAdvanced
62
- } from "./chunk-MJCXPKBL.js";
62
+ } from "./chunk-K6OAMQQU.js";
63
63
  import {
64
64
  derivePoolAccounts,
65
65
  detectTestnet,
@@ -73,22 +73,23 @@ import {
73
73
  STALE_SESSION_MESSAGE,
74
74
  getPeopleChainEndpoints,
75
75
  hasPersistedSession
76
- } from "./chunk-5MS64TTR.js";
76
+ } from "./chunk-SVVPNIGN.js";
77
77
  import {
78
78
  CLI_NAME
79
79
  } from "./chunk-TSPERKUS.js";
80
80
  import {
81
81
  DEFAULT_ENV_ID,
82
+ describeContractSources,
82
83
  getPopSelfServeConfig,
83
84
  loadEnvironments,
84
85
  resolveEndpoints
85
- } from "./chunk-HDGD5FYX.js";
86
+ } from "./chunk-NYNAUG4V.js";
86
87
  import {
87
88
  NonRetryableError
88
89
  } from "./chunk-ZOC4GITL.js";
89
90
  import {
90
91
  ChainHealthSampler
91
- } from "./chunk-5HFXRNCQ.js";
92
+ } from "./chunk-IQUS43B7.js";
92
93
  import {
93
94
  VERSION,
94
95
  captureWarning,
@@ -102,7 +103,7 @@ import {
102
103
  truncateAddress,
103
104
  withDeploySpan,
104
105
  withSpan
105
- } from "./chunk-STXAFUTQ.js";
106
+ } from "./chunk-JZTZWMP7.js";
106
107
 
107
108
  // src/merkle.ts
108
109
  import * as fs2 from "fs";
@@ -2010,10 +2011,11 @@ function resolveProductSigner(options) {
2010
2011
  console.log(` Product deployer: ${product.ss58} (product ${product.productName}, index 0)`);
2011
2012
  return { signer: product.signer, signerAddress: product.ss58, mnemonic: void 0, localSigner: true };
2012
2013
  }
2013
- function resolveDotnsConnectOptions(options, assetHubEndpoints, autoAccountMapping, contracts, nativeToEthRatio, environmentId, popSelfServe, registerStorageDeposit, tld, network) {
2014
+ function resolveDotnsConnectOptions(options, assetHubEndpoints, autoAccountMapping, contracts, nativeToEthRatio, environmentId, popSelfServe, registerStorageDeposit, tld, network, contractSources) {
2014
2015
  const tail = assetHubEndpoints && assetHubEndpoints.length > 0 ? { assetHubEndpoints } : {};
2015
2016
  const mappingTail = autoAccountMapping ? { autoAccountMapping } : {};
2016
2017
  const contractsTail = contracts && Object.keys(contracts).length > 0 ? { contracts } : {};
2018
+ const sourcesTail = contractSources && Object.keys(contractSources).length > 0 ? { contractSources } : {};
2017
2019
  const ratioTail = nativeToEthRatio ? { nativeToEthRatio } : {};
2018
2020
  const envTail = environmentId ? { environmentId } : {};
2019
2021
  const popTail = popSelfServe !== void 0 ? { popSelfServe } : {};
@@ -2021,9 +2023,9 @@ function resolveDotnsConnectOptions(options, assetHubEndpoints, autoAccountMappi
2021
2023
  const tldTail = tld !== void 0 ? { tld } : {};
2022
2024
  const networkTail = network !== void 0 ? { network } : {};
2023
2025
  if (options.signer && options.signerAddress) {
2024
- return { signer: options.signer, signerAddress: options.signerAddress, ...tail, ...mappingTail, ...contractsTail, ...ratioTail, ...envTail, ...popTail, ...storageTail, ...tldTail, ...networkTail };
2026
+ return { signer: options.signer, signerAddress: options.signerAddress, ...tail, ...mappingTail, ...contractsTail, ...sourcesTail, ...ratioTail, ...envTail, ...popTail, ...storageTail, ...tldTail, ...networkTail };
2025
2027
  }
2026
- return { mnemonic: options.mnemonic, derivationPath: options.derivationPath, ...tail, ...mappingTail, ...contractsTail, ...ratioTail, ...envTail, ...popTail, ...storageTail, ...tldTail, ...networkTail };
2028
+ return { mnemonic: options.mnemonic, derivationPath: options.derivationPath, ...tail, ...mappingTail, ...contractsTail, ...sourcesTail, ...ratioTail, ...envTail, ...popTail, ...storageTail, ...tldTail, ...networkTail };
2027
2029
  }
2028
2030
  async function estimateUploadBytes(content) {
2029
2031
  try {
@@ -2133,6 +2135,7 @@ async function deploy(content, domainName = null, options = {}) {
2133
2135
  let envBulletin = [DEFAULT_BULLETIN_RPC];
2134
2136
  let envAssetHub;
2135
2137
  let envSource;
2138
+ let envUserFilePath;
2136
2139
  let envNetwork;
2137
2140
  let envName;
2138
2141
  let envIpfs;
@@ -2152,11 +2155,12 @@ async function deploy(content, domainName = null, options = {}) {
2152
2155
  envAssetHub = options.assetHubEndpoints;
2153
2156
  } else {
2154
2157
  try {
2155
- const { doc, source } = await loadEnvironments();
2158
+ const { doc, source, userFilePath } = await loadEnvironments();
2156
2159
  const resolved = resolveEndpoints(doc, envId);
2157
2160
  envBulletin = resolved.bulletin;
2158
2161
  envAssetHub = options.assetHubEndpoints ?? resolved.assetHub;
2159
2162
  envSource = source;
2163
+ envUserFilePath = userFilePath;
2160
2164
  envNetwork = resolved.network ?? "unknown";
2161
2165
  envName = resolved.envName;
2162
2166
  envIpfs = resolved.ipfs;
@@ -2177,6 +2181,7 @@ async function deploy(content, domainName = null, options = {}) {
2177
2181
  captureWarning(`environments load failed: ${e?.message ?? e}`);
2178
2182
  }
2179
2183
  }
2184
+ const contractSources = describeContractSources(envContracts, options.contracts, envSource, envUserFilePath, envId);
2180
2185
  if (options.contracts && Object.keys(options.contracts).length > 0) {
2181
2186
  envContracts = { ...envContracts, ...options.contracts };
2182
2187
  }
@@ -2320,7 +2325,7 @@ async function deploy(content, domainName = null, options = {}) {
2320
2325
  console.log("Preflight");
2321
2326
  console.log("=".repeat(60));
2322
2327
  const preflight = new DotNS();
2323
- await preflight.connect(resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork));
2328
+ await preflight.connect(resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork, contractSources));
2324
2329
  envTld = preflight.tld;
2325
2330
  if (parsed) parsed = { ...parsed, fullName: `${parsed.label}.${envTld}` };
2326
2331
  console.log(` Domain: ${name}.${envTld}`);
@@ -2559,7 +2564,7 @@ async function deploy(content, domainName = null, options = {}) {
2559
2564
  }
2560
2565
  };
2561
2566
  await ownerDotns.connect({
2562
- ...resolveDotnsConnectOptions({ ...options, signer: owner.signer, signerAddress: owner.address }, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork),
2567
+ ...resolveDotnsConnectOptions({ ...options, signer: owner.signer, signerAddress: owner.address }, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork, contractSources),
2563
2568
  confirmPhoneReady: options.confirmPhoneReady,
2564
2569
  phoneSigner: true
2565
2570
  // owner path is always a real phone/session signer
@@ -2571,7 +2576,7 @@ async function deploy(content, domainName = null, options = {}) {
2571
2576
  }
2572
2577
  const dotns = new DotNS();
2573
2578
  await dotns.connect({
2574
- ...resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork),
2579
+ ...resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit, envConfiguredTld, envNetwork, contractSources),
2575
2580
  confirmPhoneReady: options.confirmPhoneReady,
2576
2581
  // Transfer mode: phoneSigner=false (local worker signs in-process, no phone gate).
2577
2582
  // Genuine phone/session signer: phoneSigner=true (gate enabled). Fixes #980.
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-5MS64TTR.js";
6
+ } from "./chunk-SVVPNIGN.js";
7
7
 
8
8
  // src/sss-allowance-cache.ts
9
9
  import { mkdir, readFile, writeFile, unlink } from "fs/promises";
@@ -0,0 +1,64 @@
1
+ // src/manifest/compose.ts
2
+ function composeRoot(config, iconCid) {
3
+ const labels = config.domain.split(".");
4
+ const selfLabel = (labels[labels.length - 2] ?? labels[0]).toLowerCase();
5
+ const trustedProducts = normalizeTrustedProducts(
6
+ config.trustedProducts,
7
+ selfLabel
8
+ );
9
+ return {
10
+ $v: 1,
11
+ displayName: config.displayName,
12
+ description: config.description,
13
+ icon: { cid: iconCid, format: config.icon.format },
14
+ ...trustedProducts !== void 0 ? { trustedProducts } : {}
15
+ };
16
+ }
17
+ function normalizeTrustedProducts(input, selfLabel) {
18
+ if (input === void 0) return void 0;
19
+ const ids = Object.keys(input).filter(
20
+ (id) => id.toLowerCase() !== selfLabel && input[id].length > 0
21
+ ).sort();
22
+ if (ids.length === 0) return void 0;
23
+ return Object.fromEntries(
24
+ ids.map((id) => [id, normalizeGrants(input[id])])
25
+ );
26
+ }
27
+ function normalizeGrants(grants) {
28
+ const unique = [...new Set(grants)];
29
+ return unique.includes("all") ? ["all"] : unique.sort();
30
+ }
31
+ function composeExecutable(exec) {
32
+ if (exec.kind === "app") {
33
+ return "manifest" in exec ? exec.manifest : { $v: 1, kind: "app", appVersion: exec.appVersion };
34
+ }
35
+ if (exec.kind === "widget") {
36
+ return {
37
+ $v: 1,
38
+ kind: "widget",
39
+ appVersion: exec.appVersion,
40
+ dimensions: exec.dimensions,
41
+ ...exec.description !== void 0 ? { description: exec.description } : {}
42
+ };
43
+ }
44
+ if (exec.kind === "funding") {
45
+ return {
46
+ $v: 1,
47
+ kind: "funding",
48
+ appVersion: exec.appVersion,
49
+ modes: exec.modes
50
+ };
51
+ }
52
+ return {
53
+ $v: 1,
54
+ kind: "worker",
55
+ appVersion: exec.appVersion,
56
+ entrypoint: exec.entrypoint,
57
+ includes: exec.includes
58
+ };
59
+ }
60
+
61
+ export {
62
+ composeRoot,
63
+ composeExecutable
64
+ };
@@ -1,10 +1,14 @@
1
1
  import {
2
2
  getTextRecordBudgetBytes,
3
3
  pessimisticSizePreflight
4
- } from "./chunk-RXV677CJ.js";
4
+ } from "./chunk-YTRNJMI4.js";
5
+ import {
6
+ composeExecutable,
7
+ composeRoot
8
+ } from "./chunk-DMNLTQGA.js";
5
9
  import {
6
10
  tryLoadProductConfig
7
- } from "./chunk-WEVSXHII.js";
11
+ } from "./chunk-NKDGBZBP.js";
8
12
  import {
9
13
  BLAKE2B_256_MULTIHASH_CODE,
10
14
  encodeContenthash,
@@ -14,19 +18,19 @@ import {
14
18
  setBulletinEndpoints,
15
19
  storeDirectory,
16
20
  storeFile
17
- } from "./chunk-K23BCUAG.js";
21
+ } from "./chunk-6H3GBTBA.js";
18
22
  import {
19
23
  DEFAULT_TLD,
20
24
  DotNS,
21
25
  TX_KIND_SKIPPED,
22
26
  stripTldSuffix
23
- } from "./chunk-MJCXPKBL.js";
27
+ } from "./chunk-K6OAMQQU.js";
24
28
  import {
25
29
  DEFAULT_ENV_ID,
26
30
  getPopSelfServeConfig,
27
31
  loadEnvironments,
28
32
  resolveEndpoints
29
- } from "./chunk-HDGD5FYX.js";
33
+ } from "./chunk-NYNAUG4V.js";
30
34
  import {
31
35
  NonRetryableError
32
36
  } from "./chunk-ZOC4GITL.js";
@@ -34,7 +38,7 @@ import {
34
38
  setDeployAttribute,
35
39
  withManifestSpan,
36
40
  withSpan
37
- } from "./chunk-STXAFUTQ.js";
41
+ } from "./chunk-JZTZWMP7.js";
38
42
 
39
43
  // src/manifest/publish.ts
40
44
  import * as fs2 from "fs/promises";
@@ -165,7 +169,7 @@ async function publishManifest(opts) {
165
169
  if (!sizeReport.ok) {
166
170
  const failing = sizeReport.checks.filter((c) => !c.ok).map((c) => `${c.key}: ${c.bytes}/${c.budget} B`).join(", ");
167
171
  throw new NonRetryableError(
168
- `Manifest size preflight failed: ${failing}. Shrink displayName / description / paths or override BULLETIN_TEXT_BUDGET.`
172
+ `Manifest size preflight failed: ${failing}. Shrink displayName / description / paths / trustedProducts or override BULLETIN_TEXT_BUDGET.`
169
173
  );
170
174
  }
171
175
  return withManifestSpan(
@@ -345,43 +349,6 @@ async function connectDotNS(opts, resolved, popSelfServe, envId) {
345
349
  await dotns.connect(connectOpts);
346
350
  return dotns;
347
351
  }
348
- function composeRoot(config, iconCid) {
349
- return {
350
- $v: 1,
351
- displayName: config.displayName,
352
- description: config.description,
353
- icon: { cid: iconCid, format: config.icon.format }
354
- };
355
- }
356
- function composeExecutable(exec) {
357
- if (exec.kind === "app") {
358
- return "manifest" in exec ? exec.manifest : { $v: 1, kind: "app", appVersion: exec.appVersion };
359
- }
360
- if (exec.kind === "widget") {
361
- return {
362
- $v: 1,
363
- kind: "widget",
364
- appVersion: exec.appVersion,
365
- dimensions: exec.dimensions,
366
- ...exec.description !== void 0 ? { description: exec.description } : {}
367
- };
368
- }
369
- if (exec.kind === "funding") {
370
- return {
371
- $v: 1,
372
- kind: "funding",
373
- appVersion: exec.appVersion,
374
- modes: exec.modes
375
- };
376
- }
377
- return {
378
- $v: 1,
379
- kind: "worker",
380
- appVersion: exec.appVersion,
381
- entrypoint: exec.entrypoint,
382
- includes: exec.includes
383
- };
384
- }
385
352
  function domainMatchesEnvTld(domain, tld) {
386
353
  return domain.toLowerCase().endsWith(`.${tld.toLowerCase()}`);
387
354
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-STXAFUTQ.js";
3
+ } from "./chunk-JZTZWMP7.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -11,15 +11,53 @@ var EXECUTABLE_KINDS = [
11
11
  KIND_WORKER
12
12
  ];
13
13
  var FUNDING_MODES = ["CARD", "BANK", "CRYPTO"];
14
+ var GRANTED_VALUES = ["all", "storage", "context"];
14
15
  var LABEL = String.raw`(?!-)[a-z0-9-]{1,63}(?<!-)`;
15
16
  var TLD_FRAGMENT = "[a-z]{2,63}";
16
17
  var DOMAIN_RE = new RegExp(`^${LABEL}(\\.${LABEL})*\\.${TLD_FRAGMENT}$`, "i");
18
+ var PRODUCT_LABEL_RE = new RegExp(`^${LABEL}$`);
17
19
  function isPlainObject(value) {
18
20
  return typeof value === "object" && value !== null && !Array.isArray(value);
19
21
  }
20
22
  function isNonEmptyString(value) {
21
23
  return typeof value === "string" && value.length > 0;
22
24
  }
25
+ function validateTrustedProducts(value, label, strict) {
26
+ if (!isPlainObject(value))
27
+ return [`${label} trustedProducts must be an object`];
28
+ const errors = [];
29
+ for (const [key, grants] of Object.entries(value)) {
30
+ if (key.length === 0) {
31
+ errors.push(`${label} trustedProducts key must not be empty`);
32
+ } else if (key.includes(".")) {
33
+ if (strict) {
34
+ errors.push(
35
+ `${label} trustedProducts key '${key}' must not include a TLD suffix (the host appends its own TLD) \u2014 use '${key.split(".")[0]}' instead of '${key}'`
36
+ );
37
+ }
38
+ } else if (key !== key.toLowerCase()) {
39
+ errors.push(`${label} trustedProducts key '${key}' must be lowercase`);
40
+ } else if (!PRODUCT_LABEL_RE.test(key)) {
41
+ errors.push(
42
+ `${label} trustedProducts key '${key}' must be a valid dotNS label`
43
+ );
44
+ }
45
+ if (!Array.isArray(grants)) {
46
+ errors.push(`${label} trustedProducts['${key}'] must be an array`);
47
+ continue;
48
+ }
49
+ if (strict) {
50
+ errors.push(
51
+ ...rejectUnknownEntries(
52
+ grants,
53
+ GRANTED_VALUES,
54
+ `${label} trustedProducts['${key}']`
55
+ )
56
+ );
57
+ }
58
+ }
59
+ return errors;
60
+ }
23
61
  function isAppVersion(value) {
24
62
  if (!Array.isArray(value)) return false;
25
63
  if (value.length !== 3 && value.length !== 4) return false;
@@ -32,6 +70,11 @@ function isAppVersion(value) {
32
70
  function rejectUnknownFields(input, allowed, prefix) {
33
71
  return Object.keys(input).filter((key) => !allowed.includes(key)).map((key) => `${prefix}contains unknown field '${key}'`);
34
72
  }
73
+ function rejectUnknownEntries(values, allowed, describe) {
74
+ return values.filter((value) => !allowed.includes(value)).map(
75
+ (value) => `${describe} entries must be one of ${allowed.join(", ")} (got ${JSON.stringify(value)})`
76
+ );
77
+ }
35
78
  function validateRelativeEntrypoint(value, suffix, prefix) {
36
79
  if (!isNonEmptyString(value))
37
80
  return [`${prefix}entrypoint must be a non-empty string`];
@@ -246,9 +289,7 @@ function validateFundingFields(input, p) {
246
289
  if (!Array.isArray(input.modes) || input.modes.length === 0) {
247
290
  return [`${p}modes must be a non-empty array`];
248
291
  }
249
- return input.modes.filter((mode) => !FUNDING_MODES.includes(mode)).map(
250
- (mode) => `${p}modes entries must be one of ${FUNDING_MODES.join(", ")} (got ${JSON.stringify(mode)})`
251
- );
292
+ return rejectUnknownEntries(input.modes, FUNDING_MODES, `${p}modes`);
252
293
  }
253
294
  function validateWorkerFields(input, p) {
254
295
  const errors = [];
@@ -294,6 +335,16 @@ function validateRootManifest(input) {
294
335
  );
295
336
  }
296
337
  }
338
+ if (input.trustedProducts !== void 0) {
339
+ errors.push(
340
+ ...validateTrustedProducts(
341
+ input.trustedProducts,
342
+ "root manifest",
343
+ /* strict */
344
+ false
345
+ )
346
+ );
347
+ }
297
348
  return errors.length === 0 ? { ok: true, value: input } : { ok: false, errors };
298
349
  }
299
350
  function validateExecutableManifest(input) {
@@ -363,6 +414,16 @@ function validateProductConfig(input) {
363
414
  );
364
415
  }
365
416
  }
417
+ if (input.trustedProducts !== void 0) {
418
+ errors.push(
419
+ ...validateTrustedProducts(
420
+ input.trustedProducts,
421
+ "product config",
422
+ /* strict */
423
+ true
424
+ )
425
+ );
426
+ }
366
427
  if (!Array.isArray(input.executables) || input.executables.length === 0) {
367
428
  errors.push("product config executables must be a non-empty array");
368
429
  } else {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  emitIntervalSpan,
3
3
  setDeployAttribute
4
- } from "./chunk-STXAFUTQ.js";
4
+ } from "./chunk-JZTZWMP7.js";
5
5
 
6
6
  // src/chain-health.ts
7
7
  var DEFAULT_WINDOW_BLOCKS = 10;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  captureWarning
3
- } from "./chunk-STXAFUTQ.js";
3
+ } from "./chunk-JZTZWMP7.js";
4
4
 
5
5
  // src/chunk-probe.ts
6
6
  import { Twox128, Blake2128Concat, decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-E7PNP2NP.js";
4
+ } from "./chunk-RBI2B5SW.js";
5
5
 
6
6
  // src/memory-report.ts
7
7
  import * as fs2 from "fs";
@@ -399,6 +399,9 @@ var ERROR_KIND_RULES = [
399
399
  // unrelated error, so there's no upside to anchoring — only fragility if a
400
400
  // future wrapper is added upstream.
401
401
  [new RegExp(PHONE_NONINTERACTIVE_FRAGMENT, "i"), "signer.phone_confirmation_unavailable"],
402
+ // Ahead of the generic contract-revert rule: a soulbound refusal is a
403
+ // permanent naming fact, not a transient chain error.
404
+ [/is soulbound and cannot be transferred/i, "naming.soulbound"],
402
405
  [/Contract reverted|Contract execution would revert|revert(?:ed|ing)?\s*\(flags=[0-9]+\)|"type"\s*:\s*"ContractReverted"/i, "contract-revert"],
403
406
  [/timed out after \d+s waiting for block|Transaction not included after \d+s|Transaction did not settle within|Commitment still too new after \d+s/i, "chain-timeout"],
404
407
  [/\bstale\b.*nonce|nonce.*\bstale\b|"type"\s*:\s*"(?:Future|Stale)"|Invalid::Future|tx rejected by pool/i, "nonce-stale"],
@@ -16,12 +16,28 @@ var DOTNS_ABI_PROFILES = {
16
16
  discriminator: "isPopIssued"
17
17
  }
18
18
  };
19
+ var HIGHEST_VERIFIED_DOTNS_RELEASE = "0.8.0";
20
+ function classifyDeclaredProtocolVersion(raw) {
21
+ if (!raw) return null;
22
+ const parts = raw.split("-")[0].split(".").slice(0, 3);
23
+ if (parts.length < 2 || !parts.every((part) => /^\d+$/.test(part))) return null;
24
+ return {
25
+ raw,
26
+ profile: "v0.6.0",
27
+ // Numeric collation, so 0.10.0 sorts above 0.8.0 rather than below it.
28
+ aboveVerifiedCeiling: parts.join(".").localeCompare(HIGHEST_VERIFIED_DOTNS_RELEASE, void 0, { numeric: true }) > 0
29
+ };
30
+ }
19
31
  function classifyProtocolVersion(probe) {
20
32
  const { hasCode, pricingVersionOk, startingPriceOk, isPopIssuedOk } = probe;
21
33
  if (hasCode === false) {
22
34
  return {
23
35
  profile: null,
24
- reason: "No contract deployed at this address \u2014 could not detect the DotNS ABI profile because no contract code was found here. Check environments.json / --contract config for this network."
36
+ reason: (
37
+ // No config pointer here: this function has no environment context, so it
38
+ // cannot know which file holds the address. The caller appends that.
39
+ "No contract deployed at this address: could not detect the DotNS ABI profile because no contract code was found here."
40
+ )
25
41
  };
26
42
  }
27
43
  if (pricingVersionOk) return { profile: isPopIssuedOk === true ? "v0.6.0" : "v0.5.8-rc1" };
@@ -143,6 +159,8 @@ function getAdapter(profile) {
143
159
 
144
160
  export {
145
161
  DOTNS_ABI_PROFILES,
162
+ HIGHEST_VERIFIED_DOTNS_RELEASE,
163
+ classifyDeclaredProtocolVersion,
146
164
  classifyProtocolVersion,
147
165
  OLD_CONTROLLER_ABI,
148
166
  V0_5_8_RC1_CONTROLLER_ABI,