@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,17 +1,23 @@
1
+ import {
2
+ startSpinner
3
+ } from "../chunk-J7CYVTAW.js";
1
4
  import "../chunk-JQKKMUCT.js";
2
- import "../chunk-DHY2ZXVZ.js";
5
+ import {
6
+ BULLETIN_RESOURCE,
7
+ DEFAULT_RESOURCES,
8
+ createSlotAccountSigner,
9
+ requestResourceAllocation,
10
+ summarizeOutcomes
11
+ } from "../chunk-5OKB3TEB.js";
3
12
  import {
4
13
  renderLoginStatus
5
14
  } from "../chunk-RIRDBSBG.js";
6
- import {
7
- startSpinner
8
- } from "../chunk-J7CYVTAW.js";
9
15
  import {
10
16
  waitForBulletinAuthorization
11
- } from "../chunk-WAKSNE7F.js";
17
+ } from "../chunk-ZF2SEY7S.js";
12
18
  import {
13
19
  preflightSssAllowance
14
- } from "../chunk-5UE2IWNB.js";
20
+ } from "../chunk-HEUKYXEZ.js";
15
21
  import {
16
22
  statementSigningAccount
17
23
  } from "../chunk-GRPLHUYC.js";
@@ -25,18 +31,19 @@ import {
25
31
  getAuthClient,
26
32
  getPeopleChainEndpoints,
27
33
  resolveBulletinEndpoints
28
- } from "../chunk-56QBW25C.js";
29
- import "../chunk-FNCBSJ6R.js";
30
- import "../chunk-UC2AYO2P.js";
31
- import "../chunk-D7KZZDU7.js";
34
+ } from "../chunk-2GDPXSW3.js";
35
+ import "../chunk-S42FFXAR.js";
36
+ import "../chunk-HOO5NKN3.js";
37
+ import "../chunk-HA7BNUK3.js";
32
38
  import "../chunk-C2TS5MER.js";
33
- import "../chunk-GCKWJS2T.js";
39
+ import "../chunk-4ADUQDYJ.js";
40
+ import "../chunk-SI2ZUOYD.js";
34
41
  import "../chunk-4PVJ2JBZ.js";
35
- import "../chunk-C7UJ6WZR.js";
36
- import "../chunk-A3O7TLCS.js";
42
+ import "../chunk-64RSUZN4.js";
43
+ import "../chunk-RX3ZUVVS.js";
37
44
  import {
38
45
  loadEnvironments
39
- } from "../chunk-GL3U7K2B.js";
46
+ } from "../chunk-QRKI6MMK.js";
40
47
  import "../chunk-ZOC4GITL.js";
41
48
 
42
49
  // src/commands/login.ts
@@ -56,6 +63,37 @@ function allocationErrorMessage(reason) {
56
63
  return `Allocation failed (${reason}).`;
57
64
  }
58
65
  }
66
+ function allocationFailedMessage(reason) {
67
+ return `Allowance pre-warm failed: ${reason}
68
+ Likely cause: personhood or alias not yet established for this account.
69
+ Storage will fall back to the pool for now.
70
+ Run: bulletin-deploy logout, then bulletin-deploy login,
71
+ to retry once your wallet's personhood/alias is in place.`;
72
+ }
73
+ function formatAllocationSummary(summary) {
74
+ const parts = [];
75
+ for (const r of summary.granted) {
76
+ parts.push(` \u2713 ${r.tag}`);
77
+ }
78
+ for (const r of summary.rejected) {
79
+ parts.push(` \u2717 ${r.tag} (declined on phone \u2014 deploys will fall back)`);
80
+ }
81
+ for (const r of summary.unavailable) {
82
+ parts.push(` ~ ${r.tag} (not available \u2014 re-pair if this persists)`);
83
+ }
84
+ return parts.join("\n");
85
+ }
86
+ async function withTimeout(promise, ms, message) {
87
+ let timer;
88
+ const timeout = new Promise((_, reject) => {
89
+ timer = setTimeout(() => reject(new Error(message)), ms);
90
+ });
91
+ try {
92
+ return await Promise.race([promise, timeout]);
93
+ } finally {
94
+ if (timer) clearTimeout(timer);
95
+ }
96
+ }
59
97
  function summarizeLogin(address, slotAddress) {
60
98
  const lines = [`Signed in as: ${address}`];
61
99
  if (slotAddress) {
@@ -147,22 +185,31 @@ to re-establish your allowance.`
147
185
  return;
148
186
  }
149
187
  try {
150
- console.log("\nRequesting Bulletin storage allowance \u2014 check your phone to approve.");
151
- const bulletinSignerPromise = handle.adapter.allowance.getBulletinSigner(
152
- handle.userSession.id,
153
- DOT_PRODUCT_ID
154
- );
155
- const timeoutPromise = new Promise(
156
- (_, reject) => setTimeout(
157
- () => reject(new Error(
158
- `Allocation request timed out after ${Math.round(ALLOCATION_TIMEOUT_MS / 1e3)}s \u2014 ensure your phone is unlocked and the Polkadot mobile app is open, then try logging in again.`
159
- )),
160
- ALLOCATION_TIMEOUT_MS
161
- )
188
+ console.log("\nAllocating deploy resources \u2014 check your phone to approve.");
189
+ const resources = DEFAULT_RESOURCES;
190
+ const outcomes = await withTimeout(
191
+ requestResourceAllocation(handle.userSession, handle.adapter, resources),
192
+ ALLOCATION_TIMEOUT_MS,
193
+ `Allocation request timed out after ${Math.round(ALLOCATION_TIMEOUT_MS / 1e3)}s \u2014 the wallet did not respond to the approval request.`
162
194
  );
163
- const signerResult = await Promise.race([bulletinSignerPromise, timeoutPromise]);
164
- if (signerResult.isOk()) {
165
- const slotSigner = signerResult.value;
195
+ const summary = summarizeOutcomes(outcomes, resources);
196
+ const summaryText = formatAllocationSummary(summary);
197
+ if (summaryText) console.log(summaryText);
198
+ if (summary.rejected.length > 0 || summary.unavailable.length > 0) {
199
+ 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."
201
+ );
202
+ }
203
+ let slotSigner = await createSlotAccountSigner(handle.adapter, BULLETIN_RESOURCE);
204
+ if (!slotSigner) {
205
+ const fallbackResult = await withTimeout(
206
+ handle.adapter.allowance.getBulletinSigner(handle.userSession.id, DOT_PRODUCT_ID),
207
+ ALLOCATION_TIMEOUT_MS,
208
+ `Bulletin slot read timed out after ${Math.round(ALLOCATION_TIMEOUT_MS / 1e3)}s \u2014 the wallet did not respond.`
209
+ );
210
+ if (fallbackResult.isOk()) slotSigner = fallbackResult.value;
211
+ }
212
+ if (slotSigner) {
166
213
  const slotAddress = ss58Encode(slotSigner.publicKey);
167
214
  const { doc } = await loadEnvironments();
168
215
  const bulletinEndpoints = resolveBulletinEndpoints(doc, envId) ?? void 0;
@@ -189,24 +236,26 @@ to re-establish your allowance.`
189
236
  spinner.stop();
190
237
  process.removeListener("SIGINT", onSigint);
191
238
  }
192
- const summary = bulletinAuthSummary(
239
+ const authSummary = bulletinAuthSummary(
193
240
  authResult.authorized,
194
241
  authResult.authorized ? authResult.expiration : void 0
195
242
  );
196
- console.log(summary.message);
243
+ console.log(authSummary.message);
197
244
  console.log("\n" + summarizeLogin(handle.address, slotAddress));
198
245
  } else {
199
- const err = signerResult.error;
200
246
  console.log("\n" + summarizeLogin(handle.address, null));
201
- console.warn(` ${allocationErrorMessage(err.reason)}`);
247
+ 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."
249
+ );
202
250
  }
203
251
  } catch (err) {
204
252
  await Promise.resolve(handle.userSession.abortPendingRequests()).catch(() => {
205
253
  });
206
254
  tearingDown = true;
207
- console.error(`
208
- Allocation failed: ${err instanceof Error ? err.message : String(err)}`);
209
- process.exit(1);
255
+ console.log(
256
+ "\n" + allocationFailedMessage(err instanceof Error ? err.message : String(err))
257
+ );
258
+ console.log("\n" + summarizeLogin(handle.address, null));
210
259
  } finally {
211
260
  tearingDown = true;
212
261
  handle.destroy();
@@ -215,7 +264,10 @@ Allocation failed: ${err instanceof Error ? err.message : String(err)}`);
215
264
  }
216
265
  export {
217
266
  allocationErrorMessage,
267
+ allocationFailedMessage,
218
268
  bulletinAuthSummary,
269
+ formatAllocationSummary,
219
270
  runLogin,
220
- summarizeLogin
271
+ summarizeLogin,
272
+ withTimeout
221
273
  };
@@ -1,6 +1,7 @@
1
- import { g as LogoutStatus } from '../auth-C-Pel0AT.js';
1
+ import { d as LogoutStatus } from '../auth-CA_YKtM2.js';
2
2
  import '@parity/product-sdk-terminal';
3
3
  import 'polkadot-api';
4
+ import '../allocations-CEPeZr6T.js';
4
5
 
5
6
  /**
6
7
  * logout — sign out the current session.
@@ -1,18 +1,18 @@
1
1
  import "../chunk-JQKKMUCT.js";
2
- import "../chunk-DHY2ZXVZ.js";
2
+ import "../chunk-5OKB3TEB.js";
3
3
  import {
4
4
  renderLogoutStatus
5
5
  } from "../chunk-RIRDBSBG.js";
6
6
  import {
7
7
  clearSssAllowanceCache
8
- } from "../chunk-5UE2IWNB.js";
8
+ } from "../chunk-HEUKYXEZ.js";
9
9
  import "../chunk-GRPLHUYC.js";
10
10
  import {
11
11
  getAuthClient
12
- } from "../chunk-56QBW25C.js";
13
- import "../chunk-C7UJ6WZR.js";
14
- import "../chunk-A3O7TLCS.js";
15
- import "../chunk-GL3U7K2B.js";
12
+ } from "../chunk-2GDPXSW3.js";
13
+ import "../chunk-64RSUZN4.js";
14
+ import "../chunk-RX3ZUVVS.js";
15
+ import "../chunk-QRKI6MMK.js";
16
16
  import "../chunk-ZOC4GITL.js";
17
17
 
18
18
  // src/commands/logout.ts
@@ -0,0 +1,14 @@
1
+ interface TransferRecipientContext {
2
+ sessionH160?: string;
3
+ }
4
+ /** Pure: pick the recipient H160 from --to (0x) or the signed-in session.
5
+ * Label/SS58 recipient resolution is intentionally out of scope for the
6
+ * recovery command — it takes an explicit 0x address or the live session. */
7
+ declare function resolveTransferRecipient(to: string | undefined, ctx: TransferRecipientContext): Promise<string>;
8
+ declare function runTransfer(envId: string, opts: {
9
+ label?: string;
10
+ to?: string;
11
+ mnemonic?: string;
12
+ }): Promise<void>;
13
+
14
+ export { type TransferRecipientContext, resolveTransferRecipient, runTransfer };
@@ -0,0 +1,67 @@
1
+ import {
2
+ DEFAULT_MNEMONIC,
3
+ DotNS
4
+ } from "../chunk-4ADUQDYJ.js";
5
+ import "../chunk-SI2ZUOYD.js";
6
+ import "../chunk-4PVJ2JBZ.js";
7
+ import "../chunk-64RSUZN4.js";
8
+ import "../chunk-RX3ZUVVS.js";
9
+ import {
10
+ getPopSelfServeConfig,
11
+ loadEnvironments,
12
+ resolveEndpoints
13
+ } from "../chunk-QRKI6MMK.js";
14
+ import "../chunk-ZOC4GITL.js";
15
+
16
+ // src/commands/transfer.ts
17
+ async function resolveTransferRecipient(to, ctx) {
18
+ if (to && to.startsWith("0x") && to.length === 42) return to;
19
+ if (to) throw new Error(`--to must be a 0x H160 address (got "${to}").`);
20
+ if (ctx.sessionH160) return ctx.sessionH160;
21
+ throw new Error("No recipient: pass --to <0xH160> or sign in first (no session found).");
22
+ }
23
+ async function runTransfer(envId, opts) {
24
+ const label = (opts.label ?? "").replace(/\.dot$/, "");
25
+ if (!label) {
26
+ throw new Error("Usage: bulletin-deploy transfer <label> [--to <0xH160>] [--mnemonic <key>]");
27
+ }
28
+ let sessionH160;
29
+ if (!opts.to) {
30
+ const { getAuthClient } = await import("../auth-config.js");
31
+ const authClient = await getAuthClient(envId);
32
+ const handle = await authClient.getSessionSigner();
33
+ if (handle) {
34
+ sessionH160 = handle.addresses.productH160;
35
+ handle.destroy();
36
+ }
37
+ }
38
+ const recipient = await resolveTransferRecipient(opts.to, { sessionH160 });
39
+ const { doc } = await loadEnvironments();
40
+ const resolved = resolveEndpoints(doc, envId);
41
+ const dotns = new DotNS();
42
+ await dotns.connect({
43
+ mnemonic: opts.mnemonic ?? DEFAULT_MNEMONIC,
44
+ rpc: resolved.assetHub[0],
45
+ assetHubEndpoints: resolved.assetHub,
46
+ autoAccountMapping: resolved.autoAccountMapping,
47
+ environmentId: envId,
48
+ contracts: Object.keys(resolved.contracts).length > 0 ? resolved.contracts : void 0,
49
+ nativeToEthRatio: resolved.nativeToEthRatio,
50
+ popSelfServe: getPopSelfServeConfig(doc, envId),
51
+ registerStorageDeposit: resolved.registerStorageDeposit
52
+ });
53
+ try {
54
+ const result = await dotns.transferName(label, recipient, (s) => console.log(` ${s}`));
55
+ if (result.status === "skipped-already-owned") {
56
+ console.log(`\u2713 ${label}.dot is already owned by ${recipient}. Nothing to do.`);
57
+ } else {
58
+ console.log(`\u2713 Transferred ${label}.dot to ${recipient}${result.txHash ? ` (tx ${result.txHash})` : ""}.`);
59
+ }
60
+ } finally {
61
+ dotns.disconnect();
62
+ }
63
+ }
64
+ export {
65
+ resolveTransferRecipient,
66
+ runTransfer
67
+ };
@@ -1,6 +1,7 @@
1
- import { S as SessionAddresses } from '../auth-C-Pel0AT.js';
1
+ import { S as SessionAddresses } from '../auth-CA_YKtM2.js';
2
2
  import '@parity/product-sdk-terminal';
3
3
  import 'polkadot-api';
4
+ import '../allocations-CEPeZr6T.js';
4
5
 
5
6
  /**
6
7
  * whoami — show the currently logged-in session account, or "not logged in".
@@ -2,10 +2,10 @@ import {
2
2
  STALE_SESSION_MESSAGE,
3
3
  getAuthClient,
4
4
  hasPersistedSession
5
- } from "../chunk-56QBW25C.js";
6
- import "../chunk-C7UJ6WZR.js";
7
- import "../chunk-A3O7TLCS.js";
8
- import "../chunk-GL3U7K2B.js";
5
+ } from "../chunk-2GDPXSW3.js";
6
+ import "../chunk-64RSUZN4.js";
7
+ import "../chunk-RX3ZUVVS.js";
8
+ import "../chunk-QRKI6MMK.js";
9
9
  import "../chunk-ZOC4GITL.js";
10
10
 
11
11
  // src/commands/whoami.ts
@@ -0,0 +1,24 @@
1
+ import { A as AuthClient } from './auth-CA_YKtM2.js';
2
+ import { R as ResolvedSigner } from './signer-Duup0hgQ.js';
3
+ import '@parity/product-sdk-terminal';
4
+ import 'polkadot-api';
5
+ import './allocations-CEPeZr6T.js';
6
+ import '@parity/product-sdk-tx';
7
+
8
+ declare class MainnetDefaultWorkerError extends Error {
9
+ constructor();
10
+ }
11
+ interface DeployActors {
12
+ worker: ResolvedSigner;
13
+ /** Set ⇔ transfer-mode is active (signed in && transfer enabled). */
14
+ recipientH160?: string;
15
+ }
16
+ interface ResolveDeployActorsOptions {
17
+ suri?: string;
18
+ transferEnabled: boolean;
19
+ isTestnet: boolean;
20
+ sessionPresent: boolean;
21
+ }
22
+ declare function resolveDeployActors(authClient: AuthClient, { suri, transferEnabled, isTestnet, sessionPresent }: ResolveDeployActorsOptions): Promise<DeployActors>;
23
+
24
+ export { type DeployActors, MainnetDefaultWorkerError, type ResolveDeployActorsOptions, resolveDeployActors };
@@ -0,0 +1,44 @@
1
+ import "./chunk-JQKKMUCT.js";
2
+ import {
3
+ resolveSigner
4
+ } from "./chunk-5OKB3TEB.js";
5
+ import "./chunk-RIRDBSBG.js";
6
+ import {
7
+ DEFAULT_MNEMONIC
8
+ } from "./chunk-4ADUQDYJ.js";
9
+ import "./chunk-SI2ZUOYD.js";
10
+ import "./chunk-4PVJ2JBZ.js";
11
+ import "./chunk-64RSUZN4.js";
12
+ import "./chunk-RX3ZUVVS.js";
13
+ import "./chunk-QRKI6MMK.js";
14
+ import "./chunk-ZOC4GITL.js";
15
+
16
+ // src/deploy-actors.ts
17
+ var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
18
+ var MainnetDefaultWorkerError = class extends Error {
19
+ constructor() {
20
+ super(
21
+ "Refusing to default the deploy worker to Alice on a non-testnet environment. Pass --mnemonic <a funded, sufficiently-verified key> to do the transfer flow, or --no-transfer-to-signedin-user to sign directly with your mobile session."
22
+ );
23
+ this.name = "MainnetDefaultWorkerError";
24
+ }
25
+ };
26
+ async function resolveDeployActors(authClient, { suri, transferEnabled, isTestnet, sessionPresent }) {
27
+ if (sessionPresent && transferEnabled) {
28
+ if (!suri && !isTestnet) throw new MainnetDefaultWorkerError();
29
+ const worker2 = await resolveSigner(authClient, { suri: suri ?? DEFAULT_WORKER_SURI });
30
+ const handle = await authClient.getSessionSigner();
31
+ if (!handle) throw new Error("transfer mode active but no session resolved; pass --no-transfer-to-signedin-user.");
32
+ try {
33
+ return { worker: worker2, recipientH160: handle.addresses.productH160 };
34
+ } finally {
35
+ handle.destroy();
36
+ }
37
+ }
38
+ const worker = await resolveSigner(authClient, { suri });
39
+ return { worker };
40
+ }
41
+ export {
42
+ MainnetDefaultWorkerError,
43
+ resolveDeployActors
44
+ };
package/dist/deploy.d.ts CHANGED
@@ -69,6 +69,17 @@ declare const CHUNK_MORTALITY_PERIOD: number;
69
69
  declare const WS_HEARTBEAT_TIMEOUT_MS: number;
70
70
  declare function retryBudgetExhausted(history: number[], maxEvents: number, windowMs: number, now?: number): boolean;
71
71
  declare function isConnectionError(error: any): boolean;
72
+ /**
73
+ * True for benign teardown noise that must NOT fail a deploy/command. Covers:
74
+ * - connection errors (recoverable via the storage reconnect path), and
75
+ * - "DestroyedError: Client destroyed" — orphaned pending-response promises the
76
+ * SSO/papi client rejects while a session adapter is torn down AFTER the work
77
+ * is done (e.g. the owner-signs update path destroying its re-acquired session).
78
+ * The CLI's crash handlers use this so a successful deploy isn't marked killed
79
+ * (exit 2) by late teardown noise. Checks name+message so DestroyedError matches
80
+ * even when its message differs.
81
+ */
82
+ declare function isBenignTeardownError(error: any): boolean;
72
83
  declare function deriveRootSigner(mnemonic: string, path?: string): {
73
84
  signer: PolkadotSigner;
74
85
  ss58: string;
@@ -106,6 +117,7 @@ declare function chooseSignerInput(opts: {
106
117
  hasInjectedSigner: boolean;
107
118
  hasSession?: boolean;
108
119
  }): "mnemonic" | "injected" | "resolve" | "pool";
120
+ declare function isPhoneSignerActive(options: Pick<DeployOptions, "signer" | "signerAddress" | "transferTo">): boolean;
109
121
  /**
110
122
  * Produce the one-line storage-signer status printed at resolution time. Exported for unit testing.
111
123
  * Success: " Storage signer: allowance slot <ss58>"
@@ -231,6 +243,13 @@ interface DeployOptions {
231
243
  storageSignerAddress?: string;
232
244
  /** Secret URI for dev signers (e.g. "//Alice" or a BIP-39 mnemonic). Passed to resolveSigner. */
233
245
  suri?: string;
246
+ /** When signed in, deploy with a local worker signer and transfer the finished
247
+ * name to the signed-in account (zero mobile signatures). Default true.
248
+ * CLI: --no-transfer-to-signedin-user sets this false. */
249
+ transferToSignedInUser?: boolean;
250
+ /** Internal: recipient H160 for the post-deploy handover. Set by the resolve
251
+ * branch; callers normally let it be derived. */
252
+ transferTo?: string;
234
253
  rpc?: string;
235
254
  poolSize?: number;
236
255
  password?: string;
@@ -394,4 +413,4 @@ declare function computePhoneSigningSteps(dotnsPreflight: {
394
413
  needsPopUpgrade: boolean;
395
414
  } | null, publishNeeded: boolean): string[];
396
415
 
397
- 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, isConnectionError, makeBulletinStatusHandler, merkleize, probeP2pRetrieval, resolveDotnsConnectOptions, resolveReproducibleTimestamp, retryBudgetExhausted, setWsHaltCallback, storeChunkedContent, storeDirectory, storeDirectoryV2, storeFile, unpublish };
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 };
package/dist/deploy.js CHANGED
@@ -32,7 +32,9 @@ import {
32
32
  friendlyChainError,
33
33
  hasIPFS,
34
34
  interpretBitswapResult,
35
+ isBenignTeardownError,
35
36
  isConnectionError,
37
+ isPhoneSignerActive,
36
38
  makeBulletinStatusHandler,
37
39
  merkleize,
38
40
  probeP2pRetrieval,
@@ -45,24 +47,25 @@ import {
45
47
  storeDirectoryV2,
46
48
  storeFile,
47
49
  unpublish
48
- } from "./chunk-WAKSNE7F.js";
49
- import "./chunk-5UE2IWNB.js";
50
+ } from "./chunk-ZF2SEY7S.js";
51
+ import "./chunk-HEUKYXEZ.js";
50
52
  import "./chunk-GRPLHUYC.js";
51
53
  import "./chunk-HOTQDYHD.js";
52
54
  import "./chunk-IW3X2MJF.js";
53
55
  import "./chunk-KOSF5FDO.js";
54
56
  import "./chunk-J3NIXHZZ.js";
55
57
  import "./chunk-S7EM5VMW.js";
56
- import "./chunk-56QBW25C.js";
57
- import "./chunk-FNCBSJ6R.js";
58
- import "./chunk-UC2AYO2P.js";
59
- import "./chunk-D7KZZDU7.js";
58
+ import "./chunk-2GDPXSW3.js";
59
+ import "./chunk-S42FFXAR.js";
60
+ import "./chunk-HOO5NKN3.js";
61
+ import "./chunk-HA7BNUK3.js";
60
62
  import "./chunk-C2TS5MER.js";
61
- import "./chunk-GCKWJS2T.js";
63
+ import "./chunk-4ADUQDYJ.js";
64
+ import "./chunk-SI2ZUOYD.js";
62
65
  import "./chunk-4PVJ2JBZ.js";
63
- import "./chunk-C7UJ6WZR.js";
64
- import "./chunk-A3O7TLCS.js";
65
- import "./chunk-GL3U7K2B.js";
66
+ import "./chunk-64RSUZN4.js";
67
+ import "./chunk-RX3ZUVVS.js";
68
+ import "./chunk-QRKI6MMK.js";
66
69
  import {
67
70
  EXIT_CODE_NO_RETRY,
68
71
  NonRetryableError
@@ -103,7 +106,9 @@ export {
103
106
  friendlyChainError,
104
107
  hasIPFS,
105
108
  interpretBitswapResult,
109
+ isBenignTeardownError,
106
110
  isConnectionError,
111
+ isPhoneSignerActive,
107
112
  makeBulletinStatusHandler,
108
113
  merkleize,
109
114
  probeP2pRetrieval,
package/dist/dotns.d.ts CHANGED
@@ -84,7 +84,7 @@ interface DotnsPreflightResult {
84
84
  isTestnet: boolean;
85
85
  canProceed: boolean;
86
86
  reason?: string;
87
- plannedAction: "register" | "already-owned-by-us" | "abort";
87
+ plannedAction: "register" | "already-owned-by-us" | "already-owned-by-recipient" | "abort";
88
88
  needsPopUpgrade: boolean;
89
89
  targetPopStatus?: number;
90
90
  /** Free PAS balance of the DotNS signer at preflight time, in plancks (10 decimals). */
@@ -98,9 +98,12 @@ interface DotnsPreflightResult {
98
98
  };
99
99
  }
100
100
  declare const MINIMUM_REGISTER_STORAGE_DEPOSIT = 2000000000000n;
101
+ declare function registerDepositWei(userStatus: number, startingPriceWei: bigint): bigint;
102
+ declare function bufferedWeiToNative(weiValue: bigint, nativeToEthRatio: bigint): bigint;
103
+ declare function weiToNative(feeWei: bigint, nativeToEthRatio: bigint): bigint;
101
104
  declare function fmtPas(plancks: bigint): string;
102
105
  type DotnsSuccessAction = Exclude<DotnsPreflightResult["plannedAction"], "abort">;
103
- declare function feeFloorFor(plannedAction: DotnsSuccessAction, storageDeposit?: bigint, rentPriceNative?: bigint): bigint;
106
+ declare function feeFloorFor(plannedAction: DotnsSuccessAction, storageDeposit?: bigint, rentPriceNative?: bigint, transferFeeNative?: bigint): bigint;
104
107
  declare const RPC_ENDPOINTS: string[];
105
108
  declare const CONTRACTS: {
106
109
  readonly DOTNS_REGISTRAR: "0x329aAA5b6bEa94E750b2dacBa74Bf41291E6c2BD";
@@ -124,6 +127,15 @@ declare const WS_HEARTBEAT_TIMEOUT_MS: number;
124
127
  declare const DOTNS_TX_MAX_ATTEMPTS: number;
125
128
  declare function classifyTxRetryDecision(err: unknown): "retry" | "abort";
126
129
  declare function dotnsRetryBackoffMs(attempt: number, rand?: () => number): number;
130
+ /**
131
+ * Whether a failed attempt should be retried: only when the error is
132
+ * retry-eligible AND there's a later attempt left in the budget. Extracted so
133
+ * the loop logs EVERY failed attempt consistently (`attempt N/MAX failed`) and
134
+ * the final/aborted attempt is announced rather than breaking silently — the
135
+ * old loop only printed the line when a retry followed, so the last attempt was
136
+ * invisible and the count appeared to stop one short.
137
+ */
138
+ declare function shouldRetryTxAttempt(attempt: number, maxAttempts: number, decision: "retry" | "abort"): boolean;
127
139
  /** Wraps `sink` so that "failed" status events are buffered and only forwarded
128
140
  * when `flush()` is called (i.e. on final abort). All other statuses pass
129
141
  * through immediately. Call `reset()` at the top of each retry attempt to
@@ -292,6 +304,7 @@ declare class ReviveClientWrapper {
292
304
  expectedNonce: number;
293
305
  };
294
306
  verifyEffect?: () => Promise<boolean>;
307
+ feeAsset?: "pgas";
295
308
  }): Promise<TxResolution>;
296
309
  signAndSubmitWithRetry(buildExtrinsic: () => any, signer: PolkadotSigner, statusCallback: (status: string) => void, label: string, opts?: {
297
310
  nonceFallback?: {
@@ -300,15 +313,17 @@ declare class ReviveClientWrapper {
300
313
  expectedNonce: number;
301
314
  };
302
315
  verifyEffect?: () => Promise<boolean>;
316
+ feeAsset?: "pgas";
303
317
  }): Promise<TxResolution>;
304
318
  private dryRunReviveCall;
305
- submitTransaction(contractAddress: string, value: bigint, encodedData: string, signerSubstrateAddress: string, signer: PolkadotSigner, statusCallback: (status: string) => void, { rpcs, useNoncePolling, functionName, args, contracts, verifyEffect }: {
319
+ submitTransaction(contractAddress: string, value: bigint, encodedData: string, signerSubstrateAddress: string, signer: PolkadotSigner, statusCallback: (status: string) => void, { rpcs, useNoncePolling, functionName, args, contracts, verifyEffect, feeAsset }: {
306
320
  rpcs: string[];
307
321
  useNoncePolling?: boolean;
308
322
  functionName?: string;
309
323
  args?: unknown[];
310
324
  contracts?: Record<string, string>;
311
325
  verifyEffect?: () => Promise<boolean>;
326
+ feeAsset?: "pgas";
312
327
  }): Promise<TxResolution>;
313
328
  submitBatchedTransactions(calls: {
314
329
  contractAddress: string;
@@ -453,11 +468,27 @@ declare class DotNS {
453
468
  * for read paths that must always return a value.
454
469
  */
455
470
  contractCallNullable(contractAddress: string, contractAbi: readonly any[], functionName: string, args?: any[]): Promise<any | null>;
456
- contractTransaction(contractAddress: string, value: bigint, contractAbi: readonly any[], functionName: string, args?: any[], statusCallback?: (status: string) => void, { useNoncePolling, verifyEffect }?: {
471
+ contractTransaction(contractAddress: string, value: bigint, contractAbi: readonly any[], functionName: string, args?: any[], statusCallback?: (status: string) => void, { useNoncePolling, verifyEffect, feeAsset }?: {
457
472
  useNoncePolling?: boolean;
458
473
  verifyEffect?: () => Promise<boolean>;
474
+ feeAsset?: "pgas";
459
475
  }): Promise<TxResolution>;
460
476
  checkOwnership(label: string, ownerAddress?: string | null): Promise<OwnershipResult>;
477
+ /** Live transfer-fee quote. transferFloor is a pure PopRules view — it
478
+ * classifies the label and reads both tiers, so it works BEFORE the name is
479
+ * registered (unlike quoteTransferFee, which reverts on an unregistered token). */
480
+ quoteTransferFloorNative(label: string, fromH160: string, toH160: string): Promise<{
481
+ feeWei: bigint;
482
+ feeNative: bigint;
483
+ }>;
484
+ /** Hand `label`.dot from the connected signer (the worker, current owner) to
485
+ * `toH160`, paying the transferFloor friction fee. Idempotent: a no-op if the
486
+ * recipient already owns it; errors if a third party does. */
487
+ transferName(label: string, toH160: string, statusCallback?: (status: string) => void): Promise<{
488
+ status: "ok" | "skipped-already-owned";
489
+ txHash?: string;
490
+ feeWei?: bigint;
491
+ }>;
461
492
  getUserPopStatus(ownerAddress?: string | null): Promise<number>;
462
493
  checkSubdomainOwnership(sublabel: string, parentLabel: string): Promise<OwnershipResult>;
463
494
  registerSubdomain(sublabel: string, parentLabel: string): Promise<{
@@ -477,7 +508,9 @@ declare class DotNS {
477
508
  * registry/resolver writes are similarly sized.
478
509
  */
479
510
  private submitBatchedContractCalls;
480
- setContenthash(domainName: string, contenthashHex: string): Promise<{
511
+ setContenthash(domainName: string, contenthashHex: string, opts?: {
512
+ feeAsset?: "pgas";
513
+ }): Promise<{
481
514
  node: string;
482
515
  }>;
483
516
  /**
@@ -531,7 +564,9 @@ declare class DotNS {
531
564
  getPriceAndValidate(label: string): Promise<PriceValidationResult>;
532
565
  finalizeRegistration(registration: any, priceWei: bigint): Promise<void>;
533
566
  verifyOwnership(label: string): Promise<void>;
534
- preflight(label: string): Promise<DotnsPreflightResult>;
567
+ preflight(label: string, opts?: {
568
+ transferRecipientH160?: string;
569
+ }): Promise<DotnsPreflightResult>;
535
570
  private _preflightInternal;
536
571
  private gateOnFeeBalance;
537
572
  register(label: string, options?: DotNSConnectOptions & {
@@ -567,4 +602,4 @@ declare class DotNS {
567
602
  }
568
603
  declare const dotns: DotNS;
569
604
 
570
- export { ATTR_TX_RESOLUTION_KIND, type AliasAccountClassification, type AliasAccountState, CONNECTION_TIMEOUT_MS, CONTRACTS, ContractDryRunRevertError, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, type DotnsSuccessAction, MINIMUM_REGISTER_STORAGE_DEPOSIT, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, PUBLISHER_ABI, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, PublisherNotSupportedError, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_KIND_HASH, TX_KIND_NONCE_ADVANCED, TX_NO_PROGRESS_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, type TxResolution, WS_HEARTBEAT_TIMEOUT_MS, __formatContractDryRunFailureForTest, canRegister, classifyAliasAccountRow, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertToHexString, convertWeiToNative, countTrailingDigits, decodePublisherRevert, dotns, dotnsRetryBackoffMs, feeFloorFor, fetchNonce, fmtPas, formatDispatchError, formatPersonhoodRemediation, formatPopShortfallReason, isCommitmentMature, isCommitmentTimingBarerevert, makeRetryStatusFilter, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, sanitizeDomainLabel, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
605
+ export { ATTR_TX_RESOLUTION_KIND, type AliasAccountClassification, type AliasAccountState, CONNECTION_TIMEOUT_MS, CONTRACTS, ContractDryRunRevertError, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, type DotnsSuccessAction, MINIMUM_REGISTER_STORAGE_DEPOSIT, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, PUBLISHER_ABI, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, PublisherNotSupportedError, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_KIND_HASH, TX_KIND_NONCE_ADVANCED, TX_NO_PROGRESS_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, type TxResolution, WS_HEARTBEAT_TIMEOUT_MS, __formatContractDryRunFailureForTest, bufferedWeiToNative, canRegister, classifyAliasAccountRow, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertToHexString, convertWeiToNative, countTrailingDigits, decodePublisherRevert, dotns, dotnsRetryBackoffMs, feeFloorFor, fetchNonce, fmtPas, formatDispatchError, formatPersonhoodRemediation, formatPopShortfallReason, isCommitmentMature, isCommitmentTimingBarerevert, makeRetryStatusFilter, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, registerDepositWei, sanitizeDomainLabel, shouldRetryTxAttempt, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced, weiToNative };