@parity/product-deploy 0.9.0 → 0.10.0-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 (61) hide show
  1. package/DEPLOYMENT.md +124 -0
  2. package/README.md +73 -6
  3. package/assets/environments.json +41 -0
  4. package/bin/bulletin-deploy +49 -21
  5. package/dist/allocations-CEPeZr6T.d.ts +111 -0
  6. package/dist/auth/index.d.ts +3 -2
  7. package/dist/auth/index.js +5 -1
  8. package/dist/auth/vendor/index.d.ts +3 -2
  9. package/dist/auth/vendor/index.js +5 -1
  10. package/dist/auth/vendor/ui/index.d.ts +2 -1
  11. package/dist/auth-CA_YKtM2.d.ts +128 -0
  12. package/dist/auth-config.d.ts +13 -8
  13. package/dist/auth-config.js +4 -4
  14. package/dist/bug-report.js +4 -4
  15. package/dist/{chunk-56QBW25C.js → chunk-2GDPXSW3.js} +5 -5
  16. package/dist/{chunk-GCKWJS2T.js → chunk-4ADUQDYJ.js} +140 -32
  17. package/dist/{chunk-DHY2ZXVZ.js → chunk-5OKB3TEB.js} +8 -1
  18. package/dist/{chunk-C7UJ6WZR.js → chunk-64RSUZN4.js} +10 -2
  19. package/dist/{chunk-D7KZZDU7.js → chunk-HA7BNUK3.js} +1 -1
  20. package/dist/{chunk-5UE2IWNB.js → chunk-HEUKYXEZ.js} +1 -1
  21. package/dist/{chunk-UC2AYO2P.js → chunk-HOO5NKN3.js} +1 -1
  22. package/dist/{chunk-GL3U7K2B.js → chunk-QRKI6MMK.js} +41 -0
  23. package/dist/{chunk-A3O7TLCS.js → chunk-RX3ZUVVS.js} +4 -3
  24. package/dist/{chunk-FNCBSJ6R.js → chunk-S42FFXAR.js} +2 -2
  25. package/dist/{chunk-AQHBKIFF.js → chunk-VHAKRWRH.js} +3 -3
  26. package/dist/{chunk-WAKSNE7F.js → chunk-ZF2SEY7S.js} +115 -29
  27. package/dist/chunk-probe.js +3 -3
  28. package/dist/commands/login.d.ts +42 -6
  29. package/dist/commands/login.js +89 -37
  30. package/dist/commands/logout.d.ts +2 -1
  31. package/dist/commands/logout.js +6 -6
  32. package/dist/commands/transfer.d.ts +14 -0
  33. package/dist/commands/transfer.js +67 -0
  34. package/dist/commands/whoami.d.ts +2 -1
  35. package/dist/commands/whoami.js +4 -4
  36. package/dist/deploy-actors.d.ts +24 -0
  37. package/dist/deploy-actors.js +44 -0
  38. package/dist/deploy.d.ts +20 -1
  39. package/dist/deploy.js +15 -10
  40. package/dist/dotns.d.ts +42 -7
  41. package/dist/dotns.js +15 -6
  42. package/dist/environments.js +1 -1
  43. package/dist/index.js +16 -15
  44. package/dist/manifest/publish.js +12 -11
  45. package/dist/memory-report.js +2 -2
  46. package/dist/merkle.js +11 -10
  47. package/dist/personhood/bootstrap.js +11 -11
  48. package/dist/personhood/people-client.js +5 -4
  49. package/dist/run-state.js +1 -1
  50. package/dist/{signer-vR6KKC7V.d.ts → signer-Duup0hgQ.d.ts} +1 -1
  51. package/dist/sss-allowance-cache.js +5 -5
  52. package/dist/storage-signer.js +11 -10
  53. package/dist/telemetry.d.ts +17 -1
  54. package/dist/telemetry.js +4 -2
  55. package/dist/version-check.js +3 -3
  56. package/docs/bootstrap.md +1 -1
  57. package/docs/e2e-bootstrap.md +34 -12
  58. package/docs/telemetry.md +10 -11
  59. package/docs/testing.md +2 -0
  60. package/package.json +4 -3
  61. package/dist/auth-C-Pel0AT.d.ts +0 -235
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-A3O7TLCS.js";
4
+ } from "./chunk-RX3ZUVVS.js";
5
5
 
6
6
  // src/memory-report.ts
7
7
  import * as fs2 from "fs";
@@ -46,7 +46,14 @@ function isInternalContext() {
46
46
  }
47
47
  var OPT_OUT = process.env.BULLETIN_DEPLOY_TELEMETRY === "0" || process.env.BULLETIN_DEPLOY_TELEMETRY === "off";
48
48
  var OPT_IN = process.env.BULLETIN_DEPLOY_TELEMETRY === "1";
49
- var DISABLED = OPT_OUT || !OPT_IN && !isInternalContext();
49
+ var DO_NOT_TRACK = !!process.env.DO_NOT_TRACK && process.env.DO_NOT_TRACK !== "0" && process.env.DO_NOT_TRACK !== "";
50
+ function isTelemetryDisabled(s) {
51
+ if (s.optOut) return true;
52
+ if (s.optIn) return false;
53
+ if (s.doNotTrack) return true;
54
+ return !s.internalContext;
55
+ }
56
+ var DISABLED = isTelemetryDisabled({ optIn: OPT_IN, optOut: OPT_OUT, doNotTrack: DO_NOT_TRACK, internalContext: isInternalContext() });
50
57
  var CONVENTIONAL_BRANCH_PREFIXES = /* @__PURE__ */ new Set([
51
58
  "fix",
52
59
  "feat",
@@ -719,6 +726,7 @@ export {
719
726
  VERSION,
720
727
  isInternalContextFromSignals,
721
728
  isInternalContext,
729
+ isTelemetryDisabled,
722
730
  scrubPaths,
723
731
  truncateAddress,
724
732
  sanitizeBranch,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  captureWarning
3
- } from "./chunk-C7UJ6WZR.js";
3
+ } from "./chunk-64RSUZN4.js";
4
4
 
5
5
  // src/chunk-probe.ts
6
6
  import { Twox128, Blake2128Concat, decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-56QBW25C.js";
6
+ } from "./chunk-2GDPXSW3.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-C7UJ6WZR.js";
3
+ } from "./chunk-64RSUZN4.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -137,6 +137,35 @@ var environments_default = {
137
137
  PUBLISHER: "0xa616254fd98724c7a3d295c98ca393a486096b68"
138
138
  }
139
139
  },
140
+ {
141
+ id: "summit",
142
+ name: "Summit",
143
+ network: "testnet",
144
+ description: "Web3 Summit Network",
145
+ e2eEligible: false,
146
+ ipfs: "https://summit-ipfs.polkadot.io",
147
+ autoAccountMapping: true,
148
+ nativeToEthRatio: 1e8,
149
+ registerStorageDeposit: 2e12,
150
+ contracts: {
151
+ DOTNS_PROTOCOL_REGISTRY: "0x09f1AE947950eA2d1f010fE2abC00fDd5A745820",
152
+ DOTNS_REGISTRAR: "0xf3969bCBE60463302306663C62A6A8ef91ab9aA5",
153
+ DOTNS_REGISTRAR_CONTROLLER: "0xA68a5b2A6be6d014be0dB07c0ed4bacc4A6A570A",
154
+ DOTNS_REGISTRY: "0xFb7AB7E142ED0248D77198CA8722D67C1930D783",
155
+ DOTNS_POP_CONTROLLER: "0xC7DD78B145ed109092A2d1E79324E5FE219B9518",
156
+ ROOT_GATEWAY_DISPATCHER: "0x22362162032ED2442b43f5902b3421be5aCF1b60",
157
+ DOTNS_RESOLVER: "0xC7f1C3B16BFd0c5910EE37a4a2033f4506AcE94d",
158
+ DOTNS_CONTENT_RESOLVER: "0xf110e5799c3f0adb8ED885C02c45Ecfe7fD86226",
159
+ DOTNS_REVERSE_RESOLVER: "0x5aa444C6cbA9bd703d1a0B5E5C643FB886F80bB4",
160
+ DOTNS_POP_RESOLVER: "0x03FD2ed7B1b848c59A2428224162dE00D11a8133",
161
+ DOTNS_NAME_ESCROW: "0xDbE911007f8cd9876D384b8c025d3BB157DCCcA4",
162
+ POP_RULES: "0x6331e51C9AfC73BfE12562fd160BA2c66A73f984",
163
+ STORE_FACTORY: "0x2947af3CBFb45b89610524a25921C32cB65C4C39",
164
+ LABEL_STORE_BEACON: "0x670Dab225ea4f2EeB0e6Df2e49AA595aB2CAa5cb",
165
+ USER_STORE_BEACON: "0x31e392736889c973A25509861C7D6E6F2EaD951C",
166
+ MULTICALL3: "0x1C1044BEa5bDe0F435436bB52A8340fBE1D59847"
167
+ }
168
+ },
140
169
  {
141
170
  id: "polkadot",
142
171
  name: "Polkadot",
@@ -175,6 +204,9 @@ var environments_default = {
175
204
  wss: "wss://paseo-rpc.n.dwellir.com",
176
205
  uptimeUrl: "https://stats.uptimerobot.com/UrEXbl6Xyt"
177
206
  },
207
+ summit: {
208
+ wss: "wss://summit-rpc.polkadot.io"
209
+ },
178
210
  polkadot: {
179
211
  wss: [
180
212
  "wss://polkadot-rpc.n.dwellir.com",
@@ -222,6 +254,9 @@ var environments_default = {
222
254
  wss: "wss://paseo-asset-hub-next-rpc.polkadot.io",
223
255
  parachainId: 1500
224
256
  },
257
+ summit: {
258
+ wss: "wss://summit-asset-hub-rpc.polkadot.io"
259
+ },
225
260
  polkadot: {
226
261
  wss: [
227
262
  "wss://asset-hub-polkadot-rpc.n.dwellir.com",
@@ -335,6 +370,9 @@ var environments_default = {
335
370
  wss: "wss://paseo-people-next-system-rpc.polkadot.io",
336
371
  parachainId: 1502
337
372
  },
373
+ summit: {
374
+ wss: "wss://summit-people-rpc.polkadot.io"
375
+ },
338
376
  polkadot: {
339
377
  wss: [
340
378
  "wss://people-polkadot-rpc.n.dwellir.com",
@@ -385,6 +423,9 @@ var environments_default = {
385
423
  wss: "wss://paseo-bulletin-next-rpc.polkadot.io",
386
424
  parachainId: 1501
387
425
  },
426
+ summit: {
427
+ wss: "wss://summit-bulletin-rpc.polkadot.io"
428
+ },
388
429
  custom: {
389
430
  wss: "wss://previewnet.substrate.dev/bulletin",
390
431
  parachainId: 2487
@@ -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.9.0",
9
+ version: "0.10.0-rc.1",
10
10
  private: false,
11
11
  repository: {
12
12
  type: "git",
@@ -47,14 +47,15 @@ var package_default = {
47
47
  "docs",
48
48
  "assets",
49
49
  "patches",
50
+ "DEPLOYMENT.md",
50
51
  "tools/release-retry-wrapper.mjs"
51
52
  ],
52
53
  scripts: {
53
- 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 src/spinner.ts src/sss-allowance.ts src/sss-allowance-cache.ts --format esm --dts --clean --target node22",
54
+ 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/commands/transfer.ts src/storage-signer.ts src/spinner.ts src/sss-allowance.ts src/sss-allowance-cache.ts src/deploy-actors.ts --format esm --dts --clean --target node22",
54
55
  "refresh-environments": "node scripts/refresh-environments.mjs",
55
56
  postinstall: "patch-package || true",
56
57
  prepare: "npm run build",
57
- 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 test/storage-signer.test.js test/spinner.test.js test/sss-allowance.test.js test/sss-allowance-cache.test.js && npm run test:vendor",
58
+ 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 test/storage-signer.test.js test/spinner.test.js test/sss-allowance.test.js test/sss-allowance-cache.test.js test/dotns-transfer.test.js test/deploy-actors.test.js test/transfer-command.test.js test/dotns-register-fee.test.js test/deploy-label-ordering.test.js test/benign-teardown.test.js && npm run test:vendor",
58
59
  "test:e2e": "npm run build && node --test test/e2e.test.js",
59
60
  "test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
60
61
  "test:e2e:pr": "bash scripts/e2e-pass.sh pr",
@@ -2,11 +2,11 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-UC2AYO2P.js";
5
+ } from "./chunk-HOO5NKN3.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId
9
- } from "./chunk-C7UJ6WZR.js";
9
+ } from "./chunk-64RSUZN4.js";
10
10
 
11
11
  // src/bug-report.ts
12
12
  import { execSync, execFileSync } from "child_process";
@@ -6,15 +6,15 @@ import {
6
6
  resolveDotnsConnectOptions,
7
7
  storeDirectory,
8
8
  storeFile
9
- } from "./chunk-WAKSNE7F.js";
9
+ } from "./chunk-ZF2SEY7S.js";
10
10
  import {
11
11
  DotNS
12
- } from "./chunk-GCKWJS2T.js";
12
+ } from "./chunk-4ADUQDYJ.js";
13
13
  import {
14
14
  getPopSelfServeConfig,
15
15
  loadEnvironments,
16
16
  resolveEndpoints
17
- } from "./chunk-GL3U7K2B.js";
17
+ } from "./chunk-QRKI6MMK.js";
18
18
  import {
19
19
  NonRetryableError
20
20
  } from "./chunk-ZOC4GITL.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  preflightSssAllowance
3
- } from "./chunk-5UE2IWNB.js";
3
+ } from "./chunk-HEUKYXEZ.js";
4
4
  import {
5
5
  statementSigningAccount
6
6
  } from "./chunk-GRPLHUYC.js";
@@ -34,13 +34,13 @@ import {
34
34
  STALE_SESSION_MESSAGE,
35
35
  getPeopleChainEndpoints,
36
36
  hasPersistedSession
37
- } from "./chunk-56QBW25C.js";
37
+ } from "./chunk-2GDPXSW3.js";
38
38
  import {
39
39
  setDeployContext
40
- } from "./chunk-FNCBSJ6R.js";
40
+ } from "./chunk-S42FFXAR.js";
41
41
  import {
42
42
  probeChunks
43
- } from "./chunk-D7KZZDU7.js";
43
+ } from "./chunk-HA7BNUK3.js";
44
44
  import {
45
45
  packSection
46
46
  } from "./chunk-C2TS5MER.js";
@@ -53,7 +53,7 @@ import {
53
53
  parseDomainName,
54
54
  popStatusName,
55
55
  verifyNonceAdvanced
56
- } from "./chunk-GCKWJS2T.js";
56
+ } from "./chunk-4ADUQDYJ.js";
57
57
  import {
58
58
  derivePoolAccounts,
59
59
  detectTestnet,
@@ -75,13 +75,13 @@ import {
75
75
  truncateAddress,
76
76
  withDeploySpan,
77
77
  withSpan
78
- } from "./chunk-C7UJ6WZR.js";
78
+ } from "./chunk-64RSUZN4.js";
79
79
  import {
80
80
  DEFAULT_ENV_ID,
81
81
  getPopSelfServeConfig,
82
82
  loadEnvironments,
83
83
  resolveEndpoints
84
- } from "./chunk-GL3U7K2B.js";
84
+ } from "./chunk-QRKI6MMK.js";
85
85
  import {
86
86
  NonRetryableError
87
87
  } from "./chunk-ZOC4GITL.js";
@@ -412,6 +412,11 @@ function isConnectionError(error) {
412
412
  const msg = error?.message || String(error);
413
413
  return /heartbeat timeout|WS halt|Unable to connect|ChainHead disjointed/i.test(msg);
414
414
  }
415
+ function isBenignTeardownError(error) {
416
+ if (isConnectionError(error)) return true;
417
+ const s = error instanceof Error ? `${error.name ?? ""} ${error.message ?? ""}` : String(error);
418
+ return /DestroyedError|Client destroyed/.test(s);
419
+ }
415
420
  var CID_CONFIG = { version: 1, codec: 85, hashCode: 18, hashLength: 32 };
416
421
  function deriveRootSigner(mnemonic, path3 = "") {
417
422
  const entropy = mnemonicToEntropy(mnemonic);
@@ -585,6 +590,9 @@ function chooseSignerInput(opts) {
585
590
  if (opts.hasSession) return "resolve";
586
591
  return "pool";
587
592
  }
593
+ function isPhoneSignerActive(options) {
594
+ return !!(options.signer && options.signerAddress && !options.transferTo);
595
+ }
588
596
  function formatStorageSignerLine(slotAddress, failReason) {
589
597
  if (slotAddress) return ` Storage signer: allowance slot ${slotAddress}`;
590
598
  return ` Storage signer: pool fallback (${failReason ?? "no session"})`;
@@ -1948,6 +1956,7 @@ async function deploy(content, domainName = null, options = {}) {
1948
1956
  BULLETIN_ENDPOINTS = userRpc ? [userRpc, ...envBulletin.filter((e) => e !== userRpc)] : envBulletin;
1949
1957
  _deployRpcFailedOver = false;
1950
1958
  POOL_SIZE = options.poolSize ?? parseInt(process.env.BULLETIN_POOL_SIZE ?? String(DEFAULT_POOL_SIZE), 10);
1959
+ const parsed = domainName ? parseDomainName(domainName) : null;
1951
1960
  let sessionCleanup;
1952
1961
  const hasSession = hasPersistedSession();
1953
1962
  const signerChoice = chooseSignerInput({
@@ -1958,25 +1967,36 @@ async function deploy(content, domainName = null, options = {}) {
1958
1967
  });
1959
1968
  let resolvedUserSession = void 0;
1960
1969
  if (signerChoice === "resolve") {
1961
- const { resolveSigner: resolveSignerFn } = await import("./auth/index.js");
1970
+ const { resolveDeployActors } = await import("./deploy-actors.js");
1962
1971
  const { getAuthClient } = await import("./auth-config.js");
1963
1972
  const authClient = await getAuthClient(envId);
1973
+ const isTestnetEnv = envNetwork === "testnet";
1974
+ const transferEnabled = options.transferToSignedInUser !== false;
1964
1975
  try {
1965
- const resolved = await resolveSignerFn(authClient, { suri: options.suri });
1966
- options = { ...options, signer: resolved.signer, signerAddress: resolved.address };
1967
- sessionCleanup = resolved.destroy.bind(resolved);
1968
- console.log(` Using ${resolved.source} signer: ${resolved.address}`);
1969
- if (resolved.source === "session") resolvedUserSession = resolved;
1976
+ const actors = await resolveDeployActors(authClient, {
1977
+ suri: options.suri,
1978
+ transferEnabled,
1979
+ isTestnet: isTestnetEnv,
1980
+ sessionPresent: hasSession
1981
+ });
1982
+ options = {
1983
+ ...options,
1984
+ signer: actors.worker.signer,
1985
+ signerAddress: actors.worker.address,
1986
+ ...actors.recipientH160 ? { transferTo: actors.recipientH160 } : {}
1987
+ };
1988
+ sessionCleanup = actors.worker.destroy.bind(actors.worker);
1989
+ if (actors.worker.source === "session") resolvedUserSession = actors.worker;
1990
+ if (actors.recipientH160) {
1991
+ console.log(` Worker: ${actors.worker.source} signer ${actors.worker.address} \u2192 will transfer ${domainName ?? "the name"} to ${actors.recipientH160}`);
1992
+ } else {
1993
+ console.log(` Using ${actors.worker.source} signer: ${actors.worker.address}`);
1994
+ }
1970
1995
  } catch (e) {
1971
1996
  if (options.suri) throw e;
1972
1997
  if (e?.name === "SignerNotAvailableError") {
1973
- if (hasSession) {
1974
- console.error(STALE_SESSION_MESSAGE);
1975
- } else {
1976
- console.log(
1977
- " Login session unavailable or expired \u2014 falling back to pool. Run `bulletin-deploy login` to use your identity."
1978
- );
1979
- }
1998
+ if (hasSession) console.error(STALE_SESSION_MESSAGE);
1999
+ else console.log(" Login session unavailable or expired \u2014 falling back to pool. Run `bulletin-deploy login` to use your identity.");
1980
2000
  } else {
1981
2001
  throw e;
1982
2002
  }
@@ -2026,8 +2046,8 @@ async function deploy(content, domainName = null, options = {}) {
2026
2046
  }
2027
2047
  initTelemetry();
2028
2048
  const randomSuffix = Math.floor(Math.random() * 100).toString().padStart(2, "0");
2029
- const parsed = domainName ? parseDomainName(domainName) : null;
2030
2049
  const name = parsed ? parsed.label : `test-domain-${Date.now().toString(36)}${randomSuffix}`;
2050
+ const phoneSignerActive = isPhoneSignerActive(options);
2031
2051
  try {
2032
2052
  return await withDeploySpan(name, async () => {
2033
2053
  const deployTag = options.tag ?? process.env.DEPLOY_TAG;
@@ -2040,6 +2060,7 @@ async function deploy(content, domainName = null, options = {}) {
2040
2060
  setDeployAttribute("deploy.subdomain", String(parsed?.isSubdomain ?? false));
2041
2061
  if (envNetwork) setDeployAttribute("deploy.network", envNetwork);
2042
2062
  if (envSource) setDeployAttribute("deploy.environments_source", envSource);
2063
+ setDeployAttribute("deploy.transfer.enabled", options.transferTo ? "true" : "false");
2043
2064
  let cid;
2044
2065
  let ipfsCid;
2045
2066
  let mirrorPromise = Promise.resolve(null);
@@ -2085,7 +2106,7 @@ async function deploy(content, domainName = null, options = {}) {
2085
2106
  } else {
2086
2107
  preflightPublishNeeded = false;
2087
2108
  try {
2088
- dotnsPreflight = await preflight.preflight(name);
2109
+ dotnsPreflight = await preflight.preflight(name, { transferRecipientH160: options.transferTo });
2089
2110
  previousContenthashCid = await readPreviousContenthashSafe(preflight, name);
2090
2111
  setDeployAttribute("deploy.incremental", previousContenthashCid ? "true" : "false");
2091
2112
  if (options.publish && parsed && !parsed.isSubdomain) {
@@ -2118,13 +2139,13 @@ async function deploy(content, domainName = null, options = {}) {
2118
2139
  setDeployAttribute("deploy.dotns.preflight.action", dotnsPreflight.plannedAction);
2119
2140
  setDeployAttribute("deploy.dotns.preflight.classification", popStatusName(dotnsPreflight.classification.status));
2120
2141
  }
2121
- const alreadyOwned = dotnsPreflight.plannedAction === "already-owned-by-us";
2142
+ const alreadyOwned = dotnsPreflight.plannedAction === "already-owned-by-us" || dotnsPreflight.plannedAction === "already-owned-by-recipient";
2122
2143
  const reqSuffix = alreadyOwned ? " (already owned, requirement not enforced)" : "";
2123
2144
  console.log(` DotNS: ${name}.dot requires ${popStatusName(dotnsPreflight.classification.status)}${reqSuffix}`);
2124
2145
  if (dotnsPreflight.canProceed) {
2125
2146
  const fromName = popStatusName(dotnsPreflight.userStatus);
2126
2147
  console.log(` Your PoP: ${fromName}`);
2127
- console.log(` Domain: ${dotnsPreflight.plannedAction === "already-owned-by-us" ? "owned by you" : "available"}`);
2148
+ console.log(` Domain: ${alreadyOwned ? "owned by you" : "available"}`);
2128
2149
  }
2129
2150
  if (!dotnsPreflight.canProceed) {
2130
2151
  throw new NonRetryableError(
@@ -2132,17 +2153,17 @@ async function deploy(content, domainName = null, options = {}) {
2132
2153
  );
2133
2154
  }
2134
2155
  }
2135
- if (options.signer && options.signerAddress) {
2156
+ if (phoneSignerActive) {
2136
2157
  const steps = computePhoneSigningSteps(dotnsPreflight, preflightPublishNeeded);
2137
2158
  if (steps.length === 1) {
2138
2159
  console.log(`
2139
- \u{1F4F1} Have your phone ready \u2014 1 signature needed (${steps[0].toLowerCase()})`);
2160
+ Have your phone ready \u2014 1 signature needed (${steps[0].toLowerCase()})`);
2140
2161
  } else if (steps.length > 1) {
2141
2162
  const display = steps.flatMap(
2142
2163
  (s, i) => s === "Register" && steps[i - 1] === "Commitment" ? ["(wait)", s] : [s]
2143
2164
  );
2144
2165
  console.log(`
2145
- \u{1F4F1} Have your phone ready \u2014 ${steps.length} signatures needed`);
2166
+ Have your phone ready \u2014 ${steps.length} signatures needed`);
2146
2167
  console.log(` ${display.map((s) => s.toLowerCase()).join(" \xB7 ")}`);
2147
2168
  }
2148
2169
  }
@@ -2329,10 +2350,48 @@ async function deploy(content, domainName = null, options = {}) {
2329
2350
  console.log("DotNS");
2330
2351
  console.log("=".repeat(60));
2331
2352
  await withSpan("deploy.dotns", "2. dotns", { "deploy.domain": name, "deploy.subdomain": String(parsed?.isSubdomain ?? false) }, async () => {
2353
+ if (dotnsPreflight?.plannedAction === "already-owned-by-recipient") {
2354
+ console.log(` You already own ${name}.dot \u2014 updating its content needs your signature.`);
2355
+ const { getAuthClient } = await import("./auth-config.js");
2356
+ const { resolveSigner } = await import("./auth/index.js");
2357
+ const authClient = await getAuthClient(envId);
2358
+ const owner = await resolveSigner(authClient, {});
2359
+ const ownerDotns = new DotNS();
2360
+ const prevSessionCleanup = sessionCleanup;
2361
+ sessionCleanup = () => {
2362
+ try {
2363
+ prevSessionCleanup?.();
2364
+ } catch {
2365
+ }
2366
+ try {
2367
+ ownerDotns.disconnect();
2368
+ } catch {
2369
+ }
2370
+ try {
2371
+ owner.destroy();
2372
+ } catch {
2373
+ }
2374
+ };
2375
+ await ownerDotns.connect({
2376
+ ...resolveDotnsConnectOptions({ ...options, signer: owner.signer, signerAddress: owner.address }, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit),
2377
+ onPhoneSigningRequired: (label) => console.log(`
2378
+ Check your phone \u2192 ${label}`)
2379
+ });
2380
+ const willPublish = !!(options.publish && parsed && preflightPublishNeeded !== false);
2381
+ console.log(willPublish ? `
2382
+ Have your phone ready \u2014 2 signatures needed (link content \xB7 publish)` : `
2383
+ Have your phone ready \u2014 1 signature needed (link content)`);
2384
+ const contenthashHex2 = `0x${encodeContenthash(cid)}`;
2385
+ await ownerDotns.setContenthash(name, contenthashHex2, { feeAsset: "pgas" });
2386
+ if (willPublish) await publish(ownerDotns, parsed, options.failOnPublishError);
2387
+ return;
2388
+ }
2332
2389
  const dotns = new DotNS();
2333
2390
  await dotns.connect({
2334
2391
  ...resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit),
2335
- ...options.signer && options.signerAddress ? { onPhoneSigningRequired: (label) => console.log(`
2392
+ // Per-step "check your phone" reminder only for a phone-backed signer
2393
+ // (see phoneSignerActive); a transfer-mode local worker signs locally.
2394
+ ...phoneSignerActive ? { onPhoneSigningRequired: (label) => console.log(`
2336
2395
  Check your phone \u2192 ${label}`) } : {}
2337
2396
  });
2338
2397
  if (parsed?.isSubdomain) {
@@ -2363,6 +2422,31 @@ async function deploy(content, domainName = null, options = {}) {
2363
2422
  await publish(dotns, parsed, options.failOnPublishError);
2364
2423
  }
2365
2424
  }
2425
+ if (options.transferTo) {
2426
+ const transferTo = options.transferTo;
2427
+ await withSpan("deploy.transfer", `3. transfer ${name}.dot`, { "deploy.transfer.to": transferTo }, async () => {
2428
+ setDeployAttribute("deploy.transfer.worker", truncateAddress(options.signerAddress ?? ""));
2429
+ setDeployAttribute("deploy.transfer.to", transferTo);
2430
+ try {
2431
+ const transferRes = await dotns.transferName(name, transferTo, (s) => console.log(` ${s}`));
2432
+ setDeployAttribute("deploy.transfer.status", transferRes.status);
2433
+ if (transferRes.feeWei != null) setDeployAttribute("deploy.transfer.fee_wei", transferRes.feeWei.toString());
2434
+ console.log(` Handed ${name}.dot to ${transferTo} (${transferRes.status}${transferRes.txHash ? `, tx ${transferRes.txHash}` : ""}).`);
2435
+ } catch (e) {
2436
+ setDeployAttribute("deploy.transfer.status", "failed");
2437
+ const recover = `bulletin-deploy transfer ${name} --env ${envId}` + (options.suri ? ` --mnemonic "<your worker key>"` : "");
2438
+ try {
2439
+ dotns.disconnect();
2440
+ } catch {
2441
+ }
2442
+ throw new NonRetryableError(
2443
+ `Deploy succeeded but the handover to ${transferTo} failed: ${e.message}
2444
+ The name is owned by the worker with content set. Recover with:
2445
+ ${recover}`
2446
+ );
2447
+ }
2448
+ });
2449
+ }
2366
2450
  dotns.disconnect();
2367
2451
  });
2368
2452
  await withSpan("deploy.p2p-check", "3. p2p-check", { "deploy.domain": name }, async () => {
@@ -2413,7 +2497,7 @@ async function deploy(content, domainName = null, options = {}) {
2413
2497
  console.log("\n" + "=".repeat(60));
2414
2498
  console.log("DEPLOYMENT COMPLETE!");
2415
2499
  console.log("=".repeat(60));
2416
- console.log("\n\u{1F53A} Polkadot Triangle");
2500
+ console.log("\nPolkadot Triangle");
2417
2501
  console.log(` - Polkadot Desktop: ${name}.dot`);
2418
2502
  console.log(` - Polkadot Browser: ${browserUrlFor(name, envId)}`);
2419
2503
  console.log("\n" + "=".repeat(60) + "\n");
@@ -2853,6 +2937,7 @@ export {
2853
2937
  WS_HEARTBEAT_TIMEOUT_MS,
2854
2938
  retryBudgetExhausted,
2855
2939
  isConnectionError,
2940
+ isBenignTeardownError,
2856
2941
  deriveRootSigner,
2857
2942
  createCID,
2858
2943
  encodeContenthash,
@@ -2865,6 +2950,7 @@ export {
2865
2950
  encryptContent,
2866
2951
  __selectStorageProviderModeForTest,
2867
2952
  chooseSignerInput,
2953
+ isPhoneSignerActive,
2868
2954
  formatStorageSignerLine,
2869
2955
  storeFile,
2870
2956
  __assignDenseNoncesForTest,
@@ -5,9 +5,9 @@ import {
5
5
  _decodeStorageValue,
6
6
  _resetProbeSession,
7
7
  probeChunks
8
- } from "./chunk-D7KZZDU7.js";
9
- import "./chunk-C7UJ6WZR.js";
10
- import "./chunk-A3O7TLCS.js";
8
+ } from "./chunk-HA7BNUK3.js";
9
+ import "./chunk-64RSUZN4.js";
10
+ import "./chunk-RX3ZUVVS.js";
11
11
  export {
12
12
  ChainProbeCrossValidationError,
13
13
  ChainProbeMetadataError,
@@ -1,3 +1,7 @@
1
+ import { b as AllocationSummary } from '../allocations-CEPeZr6T.js';
2
+ import 'polkadot-api';
3
+ import '@parity/product-sdk-terminal';
4
+
1
5
  /**
2
6
  * login — QR/mobile sign-in command.
3
7
  *
@@ -5,12 +9,17 @@
5
9
  * 1. connect() → existing session (already logged in) OR QR code
6
10
  * 2. Print QR → user scans on phone
7
11
  * 3. waitForLogin() → phone approves → paired
8
- * 4. getBulletinSigner() — resolves the slot account from host-papp's allowance service.
9
- * Uses DOT_PRODUCT_ID ("playground.dot") as callingProductId, which matches what the
10
- * mobile wallet allocated during pairing. A 60s timeout prevents hanging on unresponsive phones.
11
- * 5. Print summarizeLogin() + slot address on success; map AllowanceError.reason message on failure
12
- * 6. Destroy adapters and exit
12
+ * 4. requestResourceAllocation(DEFAULT_RESOURCES) — one batched claim for all three deploy
13
+ * allowances (BulletInAllowance, StatementStoreAllowance, SmartContractAllowance). Triggers
14
+ * a single wallet prompt; granted key material is cached by product-sdk-terminal so later
15
+ * deploys find it without re-prompting. Non-fatal: Rejected/NotAvailablelog + continue.
16
+ * 5. createSlotAccountSigner(BULLETIN_RESOURCE) reads the now-cached Bulletin slot from the
17
+ * terminal cache written in step 4 (pure cache-hit, no phone prompt). Falls back to
18
+ * getBulletinSigner() only on a rare cache miss.
19
+ * 6. Print summarizeLogin() + slot address on success; map AllowanceError.reason → message on failure
20
+ * 7. Destroy adapters and exit
13
21
  */
22
+
14
23
  /**
15
24
  * Map an AllowanceError.reason to a user-facing message.
16
25
  *
@@ -20,6 +29,33 @@
20
29
  * - UnexpectedResponse: protocol-level error in the wire exchange
21
30
  */
22
31
  declare function allocationErrorMessage(reason: string): string;
32
+ /**
33
+ * Soft-warning message shown when the post-sign-in allowance pre-warm steps fail.
34
+ * The user IS already signed in; this is non-fatal.
35
+ * Pure function, unit-testable.
36
+ */
37
+ declare function allocationFailedMessage(reason: string): string;
38
+ /**
39
+ * Format the up-front batched allocation result as a human-readable log line.
40
+ * Pure function, unit-testable.
41
+ *
42
+ * Granted resources are logged with ✓; rejected/unavailable are logged as warnings.
43
+ * Non-fatal: callers should log the message but NEVER process.exit on a non-empty
44
+ * rejected or unavailable list — deploys can still fall back.
45
+ */
46
+ declare function formatAllocationSummary(summary: AllocationSummary): string;
47
+ /**
48
+ * Race `promise` against a timeout, clearing the timer once either side settles.
49
+ *
50
+ * CRITICAL: `Promise.race` does not cancel the loser, and `setTimeout` fires on
51
+ * wall-clock from creation. A bare `race([p, timeoutPromise])` leaves the timer
52
+ * armed after `p` wins — it then rejects an un-awaited promise later, surfacing as
53
+ * an `unhandledRejection`. In login that rejection ("…timed out…") is NOT a benign
54
+ * teardown string, so bin's `unhandledRejection` guard treats it as fatal → exit 1
55
+ * AFTER a successful login (the on-chain authorization wait can push total elapsed
56
+ * past the 60s window). `clearTimeout` in `finally` closes that window.
57
+ */
58
+ declare function withTimeout<T>(promise: PromiseLike<T>, ms: number, message: string): Promise<T>;
23
59
  /**
24
60
  * Format a post-login summary. Pure function, unit-testable.
25
61
  *
@@ -50,4 +86,4 @@ interface LoginOptions {
50
86
  */
51
87
  declare function runLogin(envId: string, _opts?: LoginOptions): Promise<void>;
52
88
 
53
- export { type LoginOptions, allocationErrorMessage, bulletinAuthSummary, runLogin, summarizeLogin };
89
+ export { type LoginOptions, allocationErrorMessage, allocationFailedMessage, bulletinAuthSummary, formatAllocationSummary, runLogin, summarizeLogin, withTimeout };