@parity/product-deploy 0.10.0-rc.3 → 0.10.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 (47) hide show
  1. package/DEPLOYMENT.md +61 -83
  2. package/bin/bulletin-bootstrap +24 -9
  3. package/dist/auth/index.js +2 -1
  4. package/dist/auth/vendor/index.js +2 -1
  5. package/dist/auth-config.js +4 -3
  6. package/dist/bug-report.js +4 -4
  7. package/dist/{chunk-GKG2EQKM.js → chunk-32THWODT.js} +50 -21
  8. package/dist/{chunk-4PVJ2JBZ.js → chunk-4IUTMHVB.js} +73 -41
  9. package/dist/{chunk-5OKB3TEB.js → chunk-5FLTDWWP.js} +4 -1
  10. package/dist/{chunk-UBLIZRYW.js → chunk-7HQL3TPT.js} +1 -1
  11. package/dist/{chunk-FAB6BWDB.js → chunk-ARPBPQZQ.js} +2 -2
  12. package/dist/{chunk-7OOKA4BJ.js → chunk-F2SDBU57.js} +5 -2
  13. package/dist/{chunk-D2WW2CIA.js → chunk-OR7LUTET.js} +2 -2
  14. package/dist/{chunk-DFRIBV6O.js → chunk-ORIB2S5P.js} +1 -1
  15. package/dist/{chunk-EJ5QLQU4.js → chunk-QR6HCDY2.js} +5 -4
  16. package/dist/{chunk-IF6BNIKT.js → chunk-SNDIOANW.js} +1 -1
  17. package/dist/chunk-TSPERKUS.js +6 -0
  18. package/dist/{chunk-KY3CRS66.js → chunk-V4RTUMBT.js} +1 -1
  19. package/dist/{chunk-RI3ZLNPN.js → chunk-WIMRJK32.js} +1 -1
  20. package/dist/{chunk-ZG56UL3V.js → chunk-ZC43ORKF.js} +1 -1
  21. package/dist/chunk-probe.js +3 -3
  22. package/dist/commands/login.js +27 -18
  23. package/dist/commands/logout.js +6 -5
  24. package/dist/commands/transfer.js +8 -5
  25. package/dist/commands/whoami.js +7 -4
  26. package/dist/deploy-actors.js +6 -5
  27. package/dist/deploy.d.ts +19 -2
  28. package/dist/deploy.js +17 -10
  29. package/dist/dotns.js +4 -4
  30. package/dist/index.js +13 -12
  31. package/dist/manifest/byte-budget.d.ts +4 -5
  32. package/dist/manifest/byte-budget.js +1 -1
  33. package/dist/manifest/publish.js +13 -12
  34. package/dist/memory-report.js +2 -2
  35. package/dist/merkle.js +11 -10
  36. package/dist/personhood/bootstrap.js +4 -4
  37. package/dist/personhood/people-client.js +4 -4
  38. package/dist/pool.d.ts +7 -2
  39. package/dist/pool.js +3 -1
  40. package/dist/run-state.js +1 -1
  41. package/dist/sss-allowance-cache.js +5 -4
  42. package/dist/storage-signer.js +11 -10
  43. package/dist/telemetry.js +2 -2
  44. package/dist/version-check.js +3 -3
  45. package/docs/bootstrap.md +47 -13
  46. package/docs/e2e-bootstrap.md +5 -0
  47. package/package.json +1 -1
@@ -34,6 +34,9 @@ function isAuthorizationSufficient(auth, currentBlock) {
34
34
  if (Number(auth.expiration ?? 0) <= currentBlock) return false;
35
35
  return true;
36
36
  }
37
+ function accountsNeedingAuthorization(auths, currentBlock) {
38
+ return auths.filter((a) => !isAuthorizationSufficient(a, currentBlock));
39
+ }
37
40
  function selectAccount(authorizations, random = Math.random, pinnedIndex) {
38
41
  if (pinnedIndex != null) {
39
42
  const pinned = authorizations.find((a) => a.index === pinnedIndex);
@@ -114,8 +117,16 @@ async function ensureAuthorized(api, address, label) {
114
117
  `Bulletin storage account ${who} is not authorized to store. On production the storage account must already carry its own authorization/allowance \u2014 bulletin-deploy cannot grant it.`
115
118
  );
116
119
  }
117
- async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
118
- console.log(`Bootstrapping ${poolSize} pool accounts on ${bulletinRpc}...
120
+ function printAuthStatus(a, currentBlock) {
121
+ if (isAuthorizationSufficient(a, currentBlock)) {
122
+ const mb = (Number(a.bytes) / 1e6).toFixed(1);
123
+ console.log(` [${a.index}] ${a.address} AUTHORIZED \u2014 ${a.transactions} txs / ${mb}MB remaining, expires @${a.expiration}`);
124
+ } else {
125
+ console.log(` [${a.index}] ${a.address} NOT AUTHORIZED`);
126
+ }
127
+ }
128
+ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic, opts = {}) {
129
+ console.log(`Checking ${poolSize} pool accounts on ${bulletinRpc}...
119
130
  `);
120
131
  await cryptoWaitReady();
121
132
  const accounts = derivePoolAccounts(poolSize, mnemonic);
@@ -124,57 +135,78 @@ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
124
135
  { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS }
125
136
  ));
126
137
  const api = client.getUnsafeApi();
127
- const keyring = new Keyring({ type: "sr25519" });
128
- const alice = keyring.addFromUri("//Alice");
129
- const aliceSigner = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
130
- const aliceAccount = await api.query.System.Account.getValue(alice.address);
131
- const aliceBalance = BigInt(aliceAccount.data.free);
132
- console.log(`Alice balance: ${formatPasBalance(aliceBalance)} PAS
138
+ try {
139
+ const currentBlock = await api.query.System.Number.getValue();
140
+ const auths = await fetchPoolAuthorizations(api, accounts);
141
+ console.log("Pool authorization status:");
142
+ for (const a of auths) {
143
+ printAuthStatus(a, currentBlock);
144
+ }
145
+ console.log("");
146
+ const needsAuth = accountsNeedingAuthorization(auths, currentBlock);
147
+ if (needsAuth.length === 0) {
148
+ console.log("All pool accounts are authorized. Nothing to do.");
149
+ return;
150
+ }
151
+ console.log(`${needsAuth.length} account(s) need authorization.
133
152
  `);
134
- console.log(`Authorizing accounts (${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB)
153
+ let authorizerSigner;
154
+ const keyring = new Keyring({ type: "sr25519" });
155
+ if (opts.authorizerMnemonic) {
156
+ const authKey = keyring.addFromUri(opts.authorizerMnemonic);
157
+ authorizerSigner = getPolkadotSigner(authKey.publicKey, "Sr25519", (data) => authKey.sign(data));
158
+ console.log(`Using provided authorizer: ${authKey.address}
135
159
  `);
136
- for (const account of accounts) {
137
- console.log(`Account ${account.index}: ${account.address}`);
138
- try {
139
- const tx = api.tx.TransactionStorage.authorize_account({
140
- who: account.address,
141
- transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
142
- bytes: TOPUP_BYTES
143
- });
144
- const result = await tx.signAndSubmit(aliceSigner);
145
- if (!result.ok) throw new Error("dispatch failed");
146
- console.log(` Authorized: ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`);
147
- } catch (e) {
148
- console.log(` Authorization failed: ${e.message?.slice(0, 80)}`);
160
+ } else {
161
+ const isTestnet = await detectTestnet(api);
162
+ if (isTestnet) {
163
+ const alice = keyring.addFromUri("//Alice");
164
+ authorizerSigner = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
165
+ console.log(`Testnet detected \u2014 defaulting to //Alice as authorizer (${alice.address})
166
+ `);
167
+ } else {
168
+ console.log(
169
+ 'Authorization is needed but no authorizer key was provided.\nRe-run with --authorizer "<seed>" to grant authorization.'
170
+ );
171
+ return;
172
+ }
149
173
  }
150
- try {
151
- const transfer = api.tx.Balances.transfer_allow_death({
152
- dest: Enum("Id", account.address),
153
- value: 100000000000n
154
- // 0.1 PAS
155
- });
156
- const result = await transfer.signAndSubmit(aliceSigner);
157
- if (!result.ok) throw new Error("dispatch failed");
158
- console.log(` Transferred 0.1 PAS`);
159
- } catch (e) {
160
- console.log(` Transfer failed: ${e.message?.slice(0, 80)}`);
174
+ console.log(`Authorizing ${needsAuth.length} account(s) (${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB each):
175
+ `);
176
+ for (const account of needsAuth) {
177
+ console.log(` [${account.index}] ${account.address}`);
178
+ try {
179
+ const tx = api.tx.TransactionStorage.authorize_account({
180
+ who: account.address,
181
+ transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
182
+ bytes: TOPUP_BYTES
183
+ });
184
+ const result = await tx.signAndSubmit(authorizerSigner);
185
+ if (!result.ok) throw new Error("dispatch failed");
186
+ console.log(` granted: ${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`);
187
+ } catch (e) {
188
+ console.log(` could not grant \u2014 is this key the chain's authorizer? (${e.message?.slice(0, 80)})`);
189
+ }
161
190
  }
162
191
  console.log("");
192
+ console.log("=".repeat(60));
193
+ console.log("Final pool authorization status:");
194
+ console.log("=".repeat(60));
195
+ const finalBlock = await api.query.System.Number.getValue();
196
+ const finalAuths = await fetchPoolAuthorizations(api, accounts);
197
+ for (const a of finalAuths) {
198
+ printAuthStatus(a, finalBlock);
199
+ }
200
+ } finally {
201
+ client.destroy();
163
202
  }
164
- console.log("=".repeat(60));
165
- console.log("Pool Summary");
166
- console.log("=".repeat(60));
167
- const auths = await fetchPoolAuthorizations(api, accounts);
168
- for (const a of auths) {
169
- console.log(` ${a.index}: ${a.address} | txs: ${a.transactions} | bytes: ${Number(a.bytes) / 1e6}MB`);
170
- }
171
- client.destroy();
172
203
  }
173
204
 
174
205
  export {
175
206
  formatPasBalance,
176
207
  derivePoolAccounts,
177
208
  isAuthorizationSufficient,
209
+ accountsNeedingAuthorization,
178
210
  selectAccount,
179
211
  fetchPoolAuthorizations,
180
212
  isTestnetSpecName,
@@ -1,3 +1,6 @@
1
+ import {
2
+ CLI_NAME
3
+ } from "./chunk-TSPERKUS.js";
1
4
  import {
2
5
  NonRetryableError
3
6
  } from "./chunk-ZOC4GITL.js";
@@ -66,7 +69,7 @@ function createSessionSigner(session, ref) {
66
69
  clearPoll = setInterval(() => {
67
70
  if (noAllowanceMsg) {
68
71
  reject(new NonRetryableError(
69
- "Session signing allowance has expired (~2-3 days after login). Run `bulletin-deploy login` to renew."
72
+ `Session signing allowance has expired (~2-3 days after login). Run \`${CLI_NAME} login\` to renew.`
70
73
  ));
71
74
  }
72
75
  }, 200);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  captureWarning
3
- } from "./chunk-DFRIBV6O.js";
3
+ } from "./chunk-ORIB2S5P.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-SI2ZUOYD.js";
4
4
  import {
5
5
  isTestnetSpecName
6
- } from "./chunk-4PVJ2JBZ.js";
6
+ } from "./chunk-4IUTMHVB.js";
7
7
  import {
8
8
  captureWarning,
9
9
  markCodePath,
@@ -11,7 +11,7 @@ import {
11
11
  setDeploySentryTag,
12
12
  truncateAddress,
13
13
  withSpan
14
- } from "./chunk-DFRIBV6O.js";
14
+ } from "./chunk-ORIB2S5P.js";
15
15
  import {
16
16
  validateContractAddresses
17
17
  } from "./chunk-QRKI6MMK.js";
@@ -1,6 +1,9 @@
1
+ import {
2
+ CLI_NAME
3
+ } from "./chunk-TSPERKUS.js";
1
4
  import {
2
5
  VERSION
3
- } from "./chunk-DFRIBV6O.js";
6
+ } from "./chunk-ORIB2S5P.js";
4
7
  import {
5
8
  loadEnvironments
6
9
  } from "./chunk-QRKI6MMK.js";
@@ -13,7 +16,7 @@ var DOT_DAPP_ID = "polkadot-app-deploy";
13
16
  var DOT_PRODUCT_ID = DOT_DAPP_ID;
14
17
  var DOT_DERIVATION_INDEX = 0;
15
18
  var DOT_HOST_NAME = "polkadot-app-deploy";
16
- var STALE_SESSION_MESSAGE = 'Stored login session could not be read \u2014 it may have been written by an older version. Run "bulletin-deploy logout", then "bulletin-deploy login" to pair again.';
19
+ var STALE_SESSION_MESSAGE = `Stored login session could not be read \u2014 it may have been written by an older version. Run "${CLI_NAME} logout", then "${CLI_NAME} login" to pair again.`;
17
20
  function hasPersistedSession() {
18
21
  const dir = join(homedir(), ".polkadot-apps");
19
22
  if (!existsSync(dir)) return false;
@@ -2,11 +2,11 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-ZG56UL3V.js";
5
+ } from "./chunk-ZC43ORKF.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId
9
- } from "./chunk-DFRIBV6O.js";
9
+ } from "./chunk-ORIB2S5P.js";
10
10
 
11
11
  // src/bug-report.ts
12
12
  import { execSync, execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-KY3CRS66.js";
4
+ } from "./chunk-V4RTUMBT.js";
5
5
 
6
6
  // src/memory-report.ts
7
7
  import * as fs2 from "fs";
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  pessimisticSizePreflight
3
- } from "./chunk-RI3ZLNPN.js";
3
+ } from "./chunk-WIMRJK32.js";
4
4
  import {
5
+ BLAKE2B_256_MULTIHASH_CODE,
5
6
  encodeContenthash,
6
7
  resolveDotnsConnectOptions,
7
8
  storeDirectory,
8
9
  storeFile
9
- } from "./chunk-GKG2EQKM.js";
10
+ } from "./chunk-32THWODT.js";
10
11
  import {
11
12
  DotNS
12
- } from "./chunk-FAB6BWDB.js";
13
+ } from "./chunk-ARPBPQZQ.js";
13
14
  import {
14
15
  getPopSelfServeConfig,
15
16
  loadEnvironments,
@@ -43,7 +44,7 @@ async function publishManifest(opts) {
43
44
  Manifest publish \u2014 ${config.domain}`);
44
45
  console.log(` Loaded config: ${sourcePath}`);
45
46
  console.log(` Uploading icon (${iconBytes.length} B)\u2026`);
46
- const iconCid = await storeFile(iconBytes);
47
+ const iconCid = await storeFile(iconBytes, { hashCode: BLAKE2B_256_MULTIHASH_CODE });
47
48
  console.log(` Icon CID: ${iconCid}`);
48
49
  const executableCids = {};
49
50
  for (const exec of config.executables) {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-7OOKA4BJ.js";
6
+ } from "./chunk-F2SDBU57.js";
7
7
 
8
8
  // src/sss-allowance-cache.ts
9
9
  import { mkdir, readFile, writeFile, unlink } from "fs/promises";
@@ -0,0 +1,6 @@
1
+ // src/cli-name.ts
2
+ var CLI_NAME = "bulletin-deploy";
3
+
4
+ export {
5
+ CLI_NAME
6
+ };
@@ -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.10.0-rc.3",
9
+ version: "0.10.0",
10
10
  private: false,
11
11
  repository: {
12
12
  type: "git",
@@ -1,6 +1,6 @@
1
1
  // src/manifest/byte-budget.ts
2
2
  var DEFAULT_TEXT_RECORD_BUDGET_BYTES = 1024;
3
- var PLACEHOLDER_CID = "bafkreigh2akiscaildc7zh3vznzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
3
+ var PLACEHOLDER_CID = "bafk2bzacecjiwibwnfb6fl6rd26a5lrokoutx4lxut6pgw6mmtkqg4comxrae";
4
4
  function getTextRecordBudgetBytes() {
5
5
  const raw = process.env.BULLETIN_TEXT_BUDGET;
6
6
  if (raw === void 0 || raw === "") return DEFAULT_TEXT_RECORD_BUDGET_BYTES;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-DFRIBV6O.js";
3
+ } from "./chunk-ORIB2S5P.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
@@ -5,9 +5,9 @@ import {
5
5
  _decodeStorageValue,
6
6
  _resetProbeSession,
7
7
  probeChunks
8
- } from "./chunk-UBLIZRYW.js";
9
- import "./chunk-DFRIBV6O.js";
10
- import "./chunk-KY3CRS66.js";
8
+ } from "./chunk-7HQL3TPT.js";
9
+ import "./chunk-ORIB2S5P.js";
10
+ import "./chunk-V4RTUMBT.js";
11
11
  export {
12
12
  ChainProbeCrossValidationError,
13
13
  ChainProbeMetadataError,
@@ -8,16 +8,16 @@ import {
8
8
  createSlotAccountSigner,
9
9
  requestResourceAllocation,
10
10
  summarizeOutcomes
11
- } from "../chunk-5OKB3TEB.js";
11
+ } from "../chunk-5FLTDWWP.js";
12
12
  import {
13
13
  renderLoginStatus
14
14
  } from "../chunk-RIRDBSBG.js";
15
15
  import {
16
16
  waitForBulletinAuthorization
17
- } from "../chunk-GKG2EQKM.js";
17
+ } from "../chunk-32THWODT.js";
18
18
  import {
19
19
  preflightSssAllowance
20
- } from "../chunk-IF6BNIKT.js";
20
+ } from "../chunk-SNDIOANW.js";
21
21
  import {
22
22
  statementSigningAccount
23
23
  } from "../chunk-GRPLHUYC.js";
@@ -31,16 +31,19 @@ import {
31
31
  getAuthClient,
32
32
  getPeopleChainEndpoints,
33
33
  resolveBulletinEndpoints
34
- } from "../chunk-7OOKA4BJ.js";
35
- import "../chunk-D2WW2CIA.js";
36
- import "../chunk-ZG56UL3V.js";
37
- import "../chunk-UBLIZRYW.js";
34
+ } from "../chunk-F2SDBU57.js";
35
+ import "../chunk-OR7LUTET.js";
36
+ import "../chunk-ZC43ORKF.js";
37
+ import "../chunk-7HQL3TPT.js";
38
38
  import "../chunk-C2TS5MER.js";
39
- import "../chunk-FAB6BWDB.js";
39
+ import {
40
+ CLI_NAME
41
+ } from "../chunk-TSPERKUS.js";
42
+ import "../chunk-ARPBPQZQ.js";
40
43
  import "../chunk-SI2ZUOYD.js";
41
- import "../chunk-4PVJ2JBZ.js";
42
- import "../chunk-DFRIBV6O.js";
43
- import "../chunk-KY3CRS66.js";
44
+ import "../chunk-4IUTMHVB.js";
45
+ import "../chunk-ORIB2S5P.js";
46
+ import "../chunk-V4RTUMBT.js";
44
47
  import {
45
48
  loadEnvironments
46
49
  } from "../chunk-QRKI6MMK.js";
@@ -56,7 +59,11 @@ function allocationErrorMessage(reason) {
56
59
  case "Rejected":
57
60
  return "Bulletin storage access was declined on your phone. Approve the request to enable storage signing.";
58
61
  case "NotAvailable":
59
- return "Bulletin storage is not available for this product on your phone.\n This may mean the wallet paired under a different product ID.\n Run: bulletin-deploy logout\n Then: bulletin-deploy login\n to re-pair and establish the allocation.";
62
+ return `Bulletin storage is not available for this product on your phone.
63
+ This may mean the wallet paired under a different product ID.
64
+ Run: ${CLI_NAME} logout
65
+ Then: ${CLI_NAME} login
66
+ to re-pair and establish the allocation.`;
60
67
  case "UnexpectedResponse":
61
68
  return "Unexpected response from the mobile wallet during storage allocation. Try again.";
62
69
  default:
@@ -67,7 +74,7 @@ function allocationFailedMessage(reason) {
67
74
  return `Allowance pre-warm failed: ${reason}
68
75
  Likely cause: personhood or alias not yet established for this account.
69
76
  Storage will fall back to the pool for now.
70
- Run: bulletin-deploy logout, then bulletin-deploy login,
77
+ Run: ${CLI_NAME} logout, then ${CLI_NAME} login,
71
78
  to retry once your wallet's personhood/alias is in place.`;
72
79
  }
73
80
  function formatAllocationSummary(summary) {
@@ -137,8 +144,8 @@ async function runLogin(envId, _opts = {}) {
137
144
  console.error(
138
145
  `
139
146
  Statement Store allowance has expired for ${result.address}.
140
- Run: bulletin-deploy logout
141
- Then: bulletin-deploy login
147
+ Run: ${CLI_NAME} logout
148
+ Then: ${CLI_NAME} login
142
149
  to re-pair and renew (allowance lasts ~2-3 days).`
143
150
  );
144
151
  tearingDown = true;
@@ -154,7 +161,7 @@ to re-pair and renew (allowance lasts ~2-3 days).`
154
161
  console.warn(
155
162
  `
156
163
  Bulletin storage slot allowance not available \u2014 storage will fall back to pool.
157
- Run: bulletin-deploy logout && bulletin-deploy login
164
+ Run: ${CLI_NAME} logout && ${CLI_NAME} login
158
165
  to re-establish your allowance.`
159
166
  );
160
167
  }
@@ -197,7 +204,8 @@ to re-establish your allowance.`
197
204
  if (summaryText) console.log(summaryText);
198
205
  if (summary.rejected.length > 0 || summary.unavailable.length > 0) {
199
206
  console.warn(
200
- " Some allowances were not granted \u2014 Bulletin storage falls back to a pool account;\n PGAS/contract gaps surface at deploy time. Run: bulletin-deploy logout && bulletin-deploy login to retry."
207
+ ` Some allowances were not granted \u2014 Bulletin storage falls back to a pool account;
208
+ PGAS/contract gaps surface at deploy time. Run: ${CLI_NAME} logout && ${CLI_NAME} login to retry.`
201
209
  );
202
210
  }
203
211
  let slotSigner = await createSlotAccountSigner(handle.adapter, BULLETIN_RESOURCE);
@@ -245,7 +253,8 @@ to re-establish your allowance.`
245
253
  } else {
246
254
  console.log("\n" + summarizeLogin(handle.address, null));
247
255
  console.warn(
248
- " Bulletin storage slot not available \u2014 storage will fall back to a pool account.\n Run: bulletin-deploy logout && bulletin-deploy login to retry."
256
+ ` Bulletin storage slot not available \u2014 storage will fall back to a pool account.
257
+ Run: ${CLI_NAME} logout && ${CLI_NAME} login to retry.`
249
258
  );
250
259
  }
251
260
  } catch (err) {
@@ -1,17 +1,18 @@
1
1
  import "../chunk-JQKKMUCT.js";
2
- import "../chunk-5OKB3TEB.js";
2
+ import "../chunk-5FLTDWWP.js";
3
3
  import {
4
4
  renderLogoutStatus
5
5
  } from "../chunk-RIRDBSBG.js";
6
6
  import {
7
7
  clearSssAllowanceCache
8
- } from "../chunk-IF6BNIKT.js";
8
+ } from "../chunk-SNDIOANW.js";
9
9
  import "../chunk-GRPLHUYC.js";
10
10
  import {
11
11
  getAuthClient
12
- } from "../chunk-7OOKA4BJ.js";
13
- import "../chunk-DFRIBV6O.js";
14
- import "../chunk-KY3CRS66.js";
12
+ } from "../chunk-F2SDBU57.js";
13
+ import "../chunk-TSPERKUS.js";
14
+ import "../chunk-ORIB2S5P.js";
15
+ import "../chunk-V4RTUMBT.js";
15
16
  import "../chunk-QRKI6MMK.js";
16
17
  import "../chunk-ZOC4GITL.js";
17
18
 
@@ -1,11 +1,14 @@
1
+ import {
2
+ CLI_NAME
3
+ } from "../chunk-TSPERKUS.js";
1
4
  import {
2
5
  DEFAULT_MNEMONIC,
3
6
  DotNS
4
- } from "../chunk-FAB6BWDB.js";
7
+ } from "../chunk-ARPBPQZQ.js";
5
8
  import "../chunk-SI2ZUOYD.js";
6
- import "../chunk-4PVJ2JBZ.js";
7
- import "../chunk-DFRIBV6O.js";
8
- import "../chunk-KY3CRS66.js";
9
+ import "../chunk-4IUTMHVB.js";
10
+ import "../chunk-ORIB2S5P.js";
11
+ import "../chunk-V4RTUMBT.js";
9
12
  import {
10
13
  getPopSelfServeConfig,
11
14
  loadEnvironments,
@@ -23,7 +26,7 @@ async function resolveTransferRecipient(to, ctx) {
23
26
  async function runTransfer(envId, opts) {
24
27
  const label = (opts.label ?? "").replace(/\.dot$/, "");
25
28
  if (!label) {
26
- throw new Error("Usage: bulletin-deploy transfer <label> [--to <0xH160>] [--mnemonic <key>]");
29
+ throw new Error(`Usage: ${CLI_NAME} transfer <label> [--to <0xH160>] [--mnemonic <key>]`);
27
30
  }
28
31
  let sessionH160;
29
32
  if (!opts.to) {
@@ -2,16 +2,19 @@ import {
2
2
  STALE_SESSION_MESSAGE,
3
3
  getAuthClient,
4
4
  hasPersistedSession
5
- } from "../chunk-7OOKA4BJ.js";
6
- import "../chunk-DFRIBV6O.js";
7
- import "../chunk-KY3CRS66.js";
5
+ } from "../chunk-F2SDBU57.js";
6
+ import {
7
+ CLI_NAME
8
+ } from "../chunk-TSPERKUS.js";
9
+ import "../chunk-ORIB2S5P.js";
10
+ import "../chunk-V4RTUMBT.js";
8
11
  import "../chunk-QRKI6MMK.js";
9
12
  import "../chunk-ZOC4GITL.js";
10
13
 
11
14
  // src/commands/whoami.ts
12
15
  function formatWhoami(addresses) {
13
16
  if (!addresses) {
14
- return "Not logged in. Run `bulletin-deploy login` to sign in.";
17
+ return `Not logged in. Run \`${CLI_NAME} login\` to sign in.`;
15
18
  }
16
19
  return [
17
20
  `Logged in:`,
@@ -1,15 +1,16 @@
1
1
  import "./chunk-JQKKMUCT.js";
2
2
  import {
3
3
  resolveSigner
4
- } from "./chunk-5OKB3TEB.js";
4
+ } from "./chunk-5FLTDWWP.js";
5
5
  import "./chunk-RIRDBSBG.js";
6
+ import "./chunk-TSPERKUS.js";
6
7
  import {
7
8
  DEFAULT_MNEMONIC
8
- } from "./chunk-FAB6BWDB.js";
9
+ } from "./chunk-ARPBPQZQ.js";
9
10
  import "./chunk-SI2ZUOYD.js";
10
- import "./chunk-4PVJ2JBZ.js";
11
- import "./chunk-DFRIBV6O.js";
12
- import "./chunk-KY3CRS66.js";
11
+ import "./chunk-4IUTMHVB.js";
12
+ import "./chunk-ORIB2S5P.js";
13
+ import "./chunk-V4RTUMBT.js";
13
14
  import "./chunk-QRKI6MMK.js";
14
15
  import "./chunk-ZOC4GITL.js";
15
16
 
package/dist/deploy.d.ts CHANGED
@@ -80,6 +80,8 @@ declare function isConnectionError(error: any): boolean;
80
80
  * even when its message differs.
81
81
  */
82
82
  declare function isBenignTeardownError(error: any): boolean;
83
+ declare const SHA256_MULTIHASH_CODE = 18;
84
+ declare const BLAKE2B_256_MULTIHASH_CODE = 45600;
83
85
  declare function deriveRootSigner(mnemonic: string, path?: string): {
84
86
  signer: PolkadotSigner;
85
87
  ss58: string;
@@ -118,13 +120,28 @@ declare function chooseSignerInput(opts: {
118
120
  hasSession?: boolean;
119
121
  }): "mnemonic" | "injected" | "resolve" | "pool";
120
122
  declare function isPhoneSignerActive(options: Pick<DeployOptions, "signer" | "signerAddress" | "transferTo">): boolean;
123
+ /**
124
+ * Decide whether to hand the name over to the signed-in user after a deploy.
125
+ * The handover only fires when the worker FRESHLY REGISTERED the name in this
126
+ * run (#928): updating the content of a name that already exists must never
127
+ * change its ownership. Without this, re-deploying any pre-existing name in
128
+ * transfer mode silently transferred it to whatever session was on disk —
129
+ * which captured shared E2E fixture labels for a local developer's account.
130
+ * Exported for unit testing.
131
+ */
132
+ declare function shouldHandoverName(opts: {
133
+ transferTo?: string;
134
+ registeredFresh: boolean;
135
+ }): boolean;
121
136
  /**
122
137
  * Produce the one-line storage-signer status printed at resolution time. Exported for unit testing.
123
138
  * Success: " Storage signer: allowance slot <ss58>"
124
139
  * Fallback: " Storage signer: pool fallback (<reason>)"
125
140
  */
126
141
  declare function formatStorageSignerLine(slotAddress: string | null, failReason?: string): string;
127
- declare function storeFile(contentBytes: Uint8Array, { client: existingClient, unsafeApi: existingApi, signer: existingSigner }?: ExistingProvider): Promise<string>;
142
+ declare function storeFile(contentBytes: Uint8Array, { client: existingClient, unsafeApi: existingApi, signer: existingSigner, hashCode, }?: ExistingProvider & {
143
+ hashCode?: number;
144
+ }): Promise<string>;
128
145
  /**
129
146
  * Pre-compute dense nonces for chunks that need submission.
130
147
  * Chunks where stored[i] !== null are already on chain (skipped via skipCids or
@@ -413,4 +430,4 @@ declare function computePhoneSigningSteps(dotnsPreflight: {
413
430
  needsPopUpgrade: boolean;
414
431
  } | null, publishNeeded: boolean): string[];
415
432
 
416
- export { BULLETIN_ENDPOINTS, type BitswapErrorVariant, type BitswapProbeResult, CHUNK_MORTALITY_PERIOD, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, type SizeDecision, type StoreDirectoryOptions, WS_HEARTBEAT_TIMEOUT_MS, __assignDenseNoncesForTest, __selectStorageProviderModeForTest, applyManifestFetchAttributes, assertSubdomainOwnerMatchesSigner, browserUrlFor, buildFilesMap, checkDeploySize, chooseSignerInput, chunk, computePhoneSigningSteps, computeStorageCid, createCID, deploy, deriveRootSigner, detectFramework, encodeContenthash, encryptContent, estimateUploadBytes, formatStorageSignerLine, friendlyChainError, hasIPFS, interpretBitswapResult, isBenignTeardownError, isConnectionError, isPhoneSignerActive, makeBulletinStatusHandler, merkleize, probeP2pRetrieval, resolveDotnsConnectOptions, resolveReproducibleTimestamp, retryBudgetExhausted, setWsHaltCallback, storeChunkedContent, storeDirectory, storeDirectoryV2, storeFile, unpublish };
433
+ export { BLAKE2B_256_MULTIHASH_CODE, BULLETIN_ENDPOINTS, type BitswapErrorVariant, type BitswapProbeResult, CHUNK_MORTALITY_PERIOD, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, SHA256_MULTIHASH_CODE, type SizeDecision, type StoreDirectoryOptions, WS_HEARTBEAT_TIMEOUT_MS, __assignDenseNoncesForTest, __selectStorageProviderModeForTest, applyManifestFetchAttributes, assertSubdomainOwnerMatchesSigner, browserUrlFor, buildFilesMap, checkDeploySize, chooseSignerInput, chunk, computePhoneSigningSteps, computeStorageCid, createCID, deploy, deriveRootSigner, detectFramework, encodeContenthash, encryptContent, estimateUploadBytes, formatStorageSignerLine, friendlyChainError, hasIPFS, interpretBitswapResult, isBenignTeardownError, isConnectionError, isPhoneSignerActive, makeBulletinStatusHandler, merkleize, probeP2pRetrieval, resolveDotnsConnectOptions, resolveReproducibleTimestamp, retryBudgetExhausted, setWsHaltCallback, shouldHandoverName, storeChunkedContent, storeDirectory, storeDirectoryV2, storeFile, unpublish };