bulletin-deploy 0.6.9-rc.6 → 0.6.9

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.
@@ -2,10 +2,10 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-ZJW37GNT.js";
5
+ } from "./chunk-TF4MTBZF.js";
6
6
  import {
7
7
  VERSION
8
- } from "./chunk-YZ4SOO2E.js";
8
+ } from "./chunk-BUAELY3G.js";
9
9
  import "./chunk-QGM4M3NI.js";
10
10
 
11
11
  // src/bug-report.ts
@@ -7,7 +7,7 @@ import * as path from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "bulletin-deploy",
10
- version: "0.6.9-rc.6",
10
+ version: "0.6.9",
11
11
  private: false,
12
12
  repository: {
13
13
  type: "git",
@@ -1,7 +1,10 @@
1
+ import {
2
+ isTestnetSpecName
3
+ } from "./chunk-JHNW2EKY.js";
1
4
  import {
2
5
  captureWarning,
3
6
  withSpan
4
- } from "./chunk-YZ4SOO2E.js";
7
+ } from "./chunk-BUAELY3G.js";
5
8
 
6
9
  // src/dotns.ts
7
10
  import crypto from "crypto";
@@ -200,6 +203,44 @@ function validateDomainLabel(label) {
200
203
  function isCommitmentMature(chainNowSeconds, commitTimestampSeconds, minimumAgeSeconds) {
201
204
  return chainNowSeconds > commitTimestampSeconds + minimumAgeSeconds;
202
205
  }
206
+ function classifyDotnsLabel(label) {
207
+ const totalLength = label.length;
208
+ const trailingDigits = countTrailingDigits(label);
209
+ if (trailingDigits > 2) {
210
+ return { status: ProofOfPersonhoodStatus.Reserved, message: "Name can have maximum 2 digit suffix" };
211
+ }
212
+ const baselength = totalLength - trailingDigits;
213
+ if (baselength <= 5) return { status: ProofOfPersonhoodStatus.Reserved, message: "Reserved for Governance" };
214
+ if (baselength >= 6 && baselength <= 8) {
215
+ if (trailingDigits === 2) return { status: ProofOfPersonhoodStatus.ProofOfPersonhoodLite, message: "Requires Light personhood verification" };
216
+ return { status: ProofOfPersonhoodStatus.ProofOfPersonhoodFull, message: "Requires Full personhood verification" };
217
+ }
218
+ if (trailingDigits === 2) return { status: ProofOfPersonhoodStatus.NoStatus, message: "Available to all" };
219
+ return { status: ProofOfPersonhoodStatus.ProofOfPersonhoodFull, message: "Requires Full personhood verification" };
220
+ }
221
+ function canRegister(requiredStatus, userStatus, trailingDigits) {
222
+ if (requiredStatus === ProofOfPersonhoodStatus.Reserved) return false;
223
+ if (requiredStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodFull) {
224
+ return userStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodFull;
225
+ }
226
+ if (requiredStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite) {
227
+ return userStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite || userStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodFull;
228
+ }
229
+ return trailingDigits !== 0 && userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodLite;
230
+ }
231
+ function simulateUserStatus(currentStatus, requiredStatus, options) {
232
+ const max = (a, b) => a > b ? a : b;
233
+ if (options.explicitStatus !== void 0) {
234
+ return max(currentStatus, options.explicitStatus);
235
+ }
236
+ if (requiredStatus === ProofOfPersonhoodStatus.NoStatus && currentStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite && options.isTestnet) {
237
+ return ProofOfPersonhoodStatus.ProofOfPersonhoodFull;
238
+ }
239
+ if (requiredStatus !== ProofOfPersonhoodStatus.NoStatus) {
240
+ return max(currentStatus, requiredStatus);
241
+ }
242
+ return currentStatus;
243
+ }
203
244
  function parseProofOfPersonhoodStatus(status) {
204
245
  const s = (status ?? "none").toLowerCase();
205
246
  if (s === "none" || s === "nostatus") return ProofOfPersonhoodStatus.NoStatus;
@@ -207,6 +248,9 @@ function parseProofOfPersonhoodStatus(status) {
207
248
  if (s === "full" || s === "popfull") return ProofOfPersonhoodStatus.ProofOfPersonhoodFull;
208
249
  throw new Error("Invalid status. Use none, lite, or full");
209
250
  }
251
+ function popStatusName(status) {
252
+ return Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === status) ?? String(status);
253
+ }
210
254
  var ReviveClientWrapper = class _ReviveClientWrapper {
211
255
  static DRY_RUN_STORAGE_LIMIT = 18446744073709551615n;
212
256
  static DRY_RUN_WEIGHT_LIMIT = { ref_time: 18446744073709551615n, proof_size: 18446744073709551615n };
@@ -441,6 +485,24 @@ var DotNS = class {
441
485
  ensureConnected() {
442
486
  if (!this.connected) throw new Error("Not connected. Call connect() first.");
443
487
  }
488
+ // Returns true when the DotNS chain (Asset Hub) reports a testnet spec_name.
489
+ // Used to gate test-only behaviors like self-granting Full PoP on a Lite
490
+ // signer for a NoStatus label. Mainnet must never self-grant — Personhood
491
+ // is attested, not self-declared, there.
492
+ _testnetCache = null;
493
+ async isTestnet() {
494
+ if (this._testnetCache !== null) return this._testnetCache;
495
+ this.ensureConnected();
496
+ try {
497
+ const version = await this.clientWrapper.client.constants.System.Version();
498
+ const raw = version?.spec_name ?? version?.specName;
499
+ const specName = typeof raw === "string" ? raw : raw?.asText?.() ?? String(raw ?? "");
500
+ this._testnetCache = isTestnetSpecName(specName);
501
+ } catch {
502
+ this._testnetCache = false;
503
+ }
504
+ return this._testnetCache;
505
+ }
444
506
  async contractCall(contractAddress, contractAbi, functionName, args = []) {
445
507
  this.ensureConnected();
446
508
  const encodedCallData = encodeFunctionData({ abi: contractAbi, functionName, args });
@@ -480,7 +542,7 @@ var DotNS = class {
480
542
  const result = await withTimeout(this.contractCall(CONTRACTS.POP_RULES, POP_RULES_ABI, "classifyName", [label]), 3e4, "classifyName");
481
543
  const requiredStatus = typeof result[0] === "bigint" ? Number(result[0]) : result[0];
482
544
  const message = result[1];
483
- console.log(` Required status: ${Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === requiredStatus)}`);
545
+ console.log(` Required status: ${popStatusName(requiredStatus)}`);
484
546
  console.log(` Message: ${message}`);
485
547
  return { requiredStatus, message };
486
548
  }
@@ -495,8 +557,8 @@ var DotNS = class {
495
557
  console.log(`
496
558
  Checking current PoP status...`);
497
559
  const currentStatus = await this.getUserPopStatus();
498
- const currentStatusName = Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === currentStatus);
499
- const desiredStatusName = Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === status);
560
+ const currentStatusName = popStatusName(currentStatus);
561
+ const desiredStatusName = popStatusName(status);
500
562
  console.log(` Current: ${currentStatusName}`);
501
563
  console.log(` Desired: ${desiredStatusName}`);
502
564
  if (currentStatus === status) {
@@ -596,12 +658,14 @@ var DotNS = class {
596
658
  if (userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodLite && userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodFull) throw new Error("Requires Personhood Lite verification");
597
659
  } else {
598
660
  const trailingDigitCount = countTrailingDigits(label);
599
- if (trailingDigitCount === 0) throw new Error("Personhood Lite cannot register base names");
661
+ if (trailingDigitCount === 0 || userStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite) {
662
+ throw new Error("Personhood Lite cannot register base names \u2014 this name class requires a Full or NoStatus signer");
663
+ }
600
664
  }
601
665
  const priceRaw = await withTimeout(this.contractCall(CONTRACTS.POP_RULES, POP_RULES_ABI, "price", [label]), 3e4, "price");
602
666
  const priceWei = typeof priceRaw === "bigint" ? priceRaw : BigInt(priceRaw);
603
- const requiredStatusName = Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === requiredStatus);
604
- const userStatusName = Object.keys(ProofOfPersonhoodStatus).find((k) => ProofOfPersonhoodStatus[k] === userStatus);
667
+ const requiredStatusName = popStatusName(requiredStatus);
668
+ const userStatusName = popStatusName(userStatus);
605
669
  console.log(` Required status: ${requiredStatusName}`);
606
670
  console.log(` User status: ${userStatusName}`);
607
671
  console.log(` Price: ${formatEther(priceWei)} PAS`);
@@ -651,6 +715,140 @@ var DotNS = class {
651
715
  return { node };
652
716
  });
653
717
  }
718
+ // View-only readiness check. Runs every chain read needed to predict whether
719
+ // `register(label)` will succeed, so the caller can fail-fast BEFORE the
720
+ // Bulletin chunk upload. Never writes to chain. See issue #100.
721
+ async preflight(label, explicitStatusOverride) {
722
+ return withSpan("deploy.dotns.preflight", `preflight ${label}.dot`, {}, async () => {
723
+ this.ensureConnected();
724
+ const validated = validateDomainLabel(label);
725
+ const trailingDigits = countTrailingDigits(validated);
726
+ const baselength = validated.length - trailingDigits;
727
+ const classification = classifyDotnsLabel(validated);
728
+ if (classification.status === ProofOfPersonhoodStatus.Reserved) {
729
+ return {
730
+ label: validated,
731
+ classification,
732
+ userStatus: 0,
733
+ trailingDigits,
734
+ baselength,
735
+ isAvailable: false,
736
+ existingOwner: null,
737
+ isBaseNameReserved: false,
738
+ reservationOwner: null,
739
+ isTestnet: false,
740
+ canProceed: false,
741
+ reason: classification.message,
742
+ plannedAction: "abort",
743
+ needsPopUpgrade: false
744
+ };
745
+ }
746
+ const baseName = stripTrailingDigits(validated);
747
+ const [userStatus, baseReservation, ownership, isTestnet] = await Promise.all([
748
+ this.getUserPopStatus(),
749
+ withTimeout(this.contractCall(CONTRACTS.POP_RULES, POP_RULES_ABI, "isBaseNameReserved", [baseName]), 3e4, "isBaseNameReserved"),
750
+ this.checkOwnership(validated),
751
+ this.isTestnet()
752
+ ]);
753
+ const [isReserved, reservationOwnerRaw] = baseReservation;
754
+ const reservationOwner = isReserved ? reservationOwnerRaw.toLowerCase() : null;
755
+ const ownerRaw = ownership.owner?.toLowerCase() ?? null;
756
+ const existingOwner = ownerRaw && ownerRaw !== zeroAddress ? ownerRaw : null;
757
+ const selfAddress = this.evmAddress.toLowerCase();
758
+ if (existingOwner !== null && existingOwner !== selfAddress) {
759
+ return {
760
+ label: validated,
761
+ classification,
762
+ userStatus,
763
+ trailingDigits,
764
+ baselength,
765
+ isAvailable: false,
766
+ existingOwner,
767
+ isBaseNameReserved: isReserved,
768
+ reservationOwner,
769
+ isTestnet,
770
+ canProceed: false,
771
+ reason: `Domain ${validated}.dot is already owned by ${existingOwner}.`,
772
+ plannedAction: "abort",
773
+ needsPopUpgrade: false
774
+ };
775
+ }
776
+ if (existingOwner !== null && existingOwner === selfAddress) {
777
+ return {
778
+ label: validated,
779
+ classification,
780
+ userStatus,
781
+ trailingDigits,
782
+ baselength,
783
+ isAvailable: true,
784
+ existingOwner,
785
+ isBaseNameReserved: isReserved,
786
+ reservationOwner,
787
+ isTestnet,
788
+ canProceed: true,
789
+ plannedAction: "already-owned-by-us",
790
+ needsPopUpgrade: false
791
+ };
792
+ }
793
+ if (isReserved && reservationOwner !== selfAddress) {
794
+ return {
795
+ label: validated,
796
+ classification,
797
+ userStatus,
798
+ trailingDigits,
799
+ baselength,
800
+ isAvailable: true,
801
+ existingOwner: null,
802
+ isBaseNameReserved: true,
803
+ reservationOwner,
804
+ isTestnet,
805
+ canProceed: false,
806
+ reason: `Base name ${baseName} is reserved for ${reservationOwner}.`,
807
+ plannedAction: "abort",
808
+ needsPopUpgrade: false
809
+ };
810
+ }
811
+ const explicitStatus = explicitStatusOverride ?? process.env.DOTNS_STATUS;
812
+ const explicitStatusNum = explicitStatus ? parseProofOfPersonhoodStatus(explicitStatus) : void 0;
813
+ const targetPopStatus = simulateUserStatus(userStatus, classification.status, { explicitStatus: explicitStatusNum, isTestnet });
814
+ if (!canRegister(classification.status, targetPopStatus, trailingDigits)) {
815
+ const className = popStatusName(classification.status);
816
+ return {
817
+ label: validated,
818
+ classification,
819
+ userStatus,
820
+ trailingDigits,
821
+ baselength,
822
+ isAvailable: true,
823
+ existingOwner: null,
824
+ isBaseNameReserved: isReserved,
825
+ reservationOwner,
826
+ isTestnet,
827
+ canProceed: false,
828
+ reason: `${validated}.dot classifies as ${className}; this signer cannot register it (PopRules.priceWithCheck gate). Remediations: use a signer with Full PoP, or pick a base name of 6-8 chars + trailing 00 (which classifies as PopLite).`,
829
+ plannedAction: "abort",
830
+ needsPopUpgrade: false,
831
+ targetPopStatus
832
+ };
833
+ }
834
+ return {
835
+ label: validated,
836
+ classification,
837
+ userStatus,
838
+ trailingDigits,
839
+ baselength,
840
+ isAvailable: true,
841
+ existingOwner: null,
842
+ isBaseNameReserved: isReserved,
843
+ reservationOwner,
844
+ isTestnet,
845
+ canProceed: true,
846
+ plannedAction: "register",
847
+ needsPopUpgrade: targetPopStatus !== userStatus,
848
+ targetPopStatus
849
+ };
850
+ });
851
+ }
654
852
  async register(label, options = {}) {
655
853
  return withSpan("deploy.dotns.register", `2a. register ${label}.dot`, {}, async () => {
656
854
  const explicitStatus = options.status || process.env.DOTNS_STATUS;
@@ -665,17 +863,22 @@ var DotNS = class {
665
863
  if (requiredStatus === ProofOfPersonhoodStatus.Reserved) {
666
864
  throw new Error(classification.message);
667
865
  }
668
- if (requiredStatus !== ProofOfPersonhoodStatus.NoStatus || explicitStatus) {
669
- const targetStatus = explicitStatus ? parseProofOfPersonhoodStatus(explicitStatus) : requiredStatus;
670
- if (targetStatus !== ProofOfPersonhoodStatus.NoStatus) {
671
- await this.setUserPopStatus(targetStatus);
672
- }
866
+ const initialUserStatus = await this.getUserPopStatus();
867
+ const isTestnet = await this.isTestnet();
868
+ const explicitStatusNum = explicitStatus ? parseProofOfPersonhoodStatus(explicitStatus) : void 0;
869
+ const targetUserStatus = simulateUserStatus(initialUserStatus, requiredStatus, { explicitStatus: explicitStatusNum, isTestnet });
870
+ if (!canRegister(requiredStatus, targetUserStatus, countTrailingDigits(label))) {
871
+ throw new Error(
872
+ `This label classifies as ${popStatusName(requiredStatus)}; the registrar will reject this signer (PopRules.priceWithCheck). Remediations: use a signer with Full PoP, or pick a shorter base name (6-8 chars + trailing 00) that classifies as PopLite.`
873
+ );
874
+ }
875
+ if (targetUserStatus !== initialUserStatus && targetUserStatus !== ProofOfPersonhoodStatus.NoStatus) {
876
+ await this.setUserPopStatus(targetUserStatus);
673
877
  const userStatus = await this.getUserPopStatus();
674
- if (requiredStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodFull && userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodFull) {
675
- throw new Error("Requires Full Personhood verification. Set DOTNS_STATUS=full or use a domain with trailing digits (e.g. my-app00.dot)");
676
- }
677
- if (requiredStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite && userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodLite && userStatus !== ProofOfPersonhoodStatus.ProofOfPersonhoodFull) {
678
- throw new Error("Requires Personhood Lite verification. Set DOTNS_STATUS=lite or DOTNS_STATUS=full");
878
+ if (userStatus !== targetUserStatus) {
879
+ throw new Error(
880
+ "setUserPopStatus did not land as expected (wanted " + targetUserStatus + ", got " + userStatus + "). Check RPC connectivity and POP_RULES contract."
881
+ );
679
882
  }
680
883
  }
681
884
  const { commitment, registration } = await this.generateCommitment(label, reverse);
@@ -719,7 +922,11 @@ export {
719
922
  sanitizeDomainLabel,
720
923
  validateDomainLabel,
721
924
  isCommitmentMature,
925
+ classifyDotnsLabel,
926
+ canRegister,
927
+ simulateUserStatus,
722
928
  parseProofOfPersonhoodStatus,
929
+ popStatusName,
723
930
  DotNS,
724
931
  dotns
725
932
  };
@@ -3,8 +3,9 @@ import {
3
3
  DotNS,
4
4
  TX_TIMEOUT_MS,
5
5
  fetchNonce,
6
+ popStatusName,
6
7
  validateDomainLabel
7
- } from "./chunk-UR3MEEN4.js";
8
+ } from "./chunk-CE67XAQY.js";
8
9
  import {
9
10
  merkleizeJS
10
11
  } from "./chunk-GZ5UUECB.js";
@@ -26,7 +27,7 @@ import {
26
27
  truncateAddress,
27
28
  withDeploySpan,
28
29
  withSpan
29
- } from "./chunk-YZ4SOO2E.js";
30
+ } from "./chunk-BUAELY3G.js";
30
31
 
31
32
  // src/deploy.ts
32
33
  import { Buffer } from "buffer";
@@ -918,17 +919,27 @@ async function deploy(content, domainName = null, options = {}) {
918
919
  );
919
920
  }
920
921
  console.log(` Account: mapped`);
921
- const { owned, owner } = await preflight.checkOwnership(name);
922
- if (owner && owner !== "0x0000000000000000000000000000000000000000" && !owned) {
922
+ let dotnsPreflight;
923
+ try {
924
+ dotnsPreflight = await preflight.preflight(name);
925
+ } finally {
923
926
  preflight.disconnect();
924
- throw new NonRetryableError(`Domain ${name}.dot is owned by a different account (${owner}). To fix, transfer it:
925
-
926
- dotns lookup transfer ${name} -d ${preflight.evmAddress}
927
-
928
- Or deploy with the original account, or use a different domain name.`);
929
927
  }
930
- console.log(` Domain: ${owned ? "owned by you" : "available"}`);
931
- preflight.disconnect();
928
+ console.log(` DotNS: ${name}.dot classifies as ${popStatusName(dotnsPreflight.classification.status)}`);
929
+ if (dotnsPreflight.canProceed) {
930
+ const fromName = popStatusName(dotnsPreflight.userStatus);
931
+ if (dotnsPreflight.needsPopUpgrade && dotnsPreflight.targetPopStatus !== void 0) {
932
+ console.log(` PoP: ${fromName} \u2192 will upgrade to ${popStatusName(dotnsPreflight.targetPopStatus)}`);
933
+ } else {
934
+ console.log(` PoP: ${fromName} (no upgrade required)`);
935
+ }
936
+ console.log(` Domain: ${dotnsPreflight.plannedAction === "already-owned-by-us" ? "owned by you" : "available"}`);
937
+ }
938
+ if (!dotnsPreflight.canProceed) {
939
+ throw new NonRetryableError(
940
+ dotnsPreflight.reason ?? "DotNS preflight rejected the deploy; please check the label and signer."
941
+ );
942
+ }
932
943
  provider = await reconnect();
933
944
  const providerWithReconnect = { ...provider, reconnect };
934
945
  const [isTestnet, estimated] = await Promise.all([
@@ -1027,8 +1038,8 @@ Or deploy with the original account, or use a different domain name.`);
1027
1038
  await dotns.connect(
1028
1039
  options.signer && options.signerAddress ? { signer: options.signer, signerAddress: options.signerAddress } : options.mnemonic ? { mnemonic: options.mnemonic, derivationPath: options.derivationPath } : {}
1029
1040
  );
1030
- const { owned: owned2 } = await dotns.checkOwnership(name);
1031
- if (owned2) {
1041
+ const { owned } = await dotns.checkOwnership(name);
1042
+ if (owned) {
1032
1043
  console.log(` Status: Already owned`);
1033
1044
  } else {
1034
1045
  console.log(` Status: Registering...`);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-YZ4SOO2E.js";
3
+ } from "./chunk-BUAELY3G.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
package/dist/deploy.js CHANGED
@@ -23,11 +23,11 @@ import {
23
23
  storeChunkedContent,
24
24
  storeDirectory,
25
25
  storeFile
26
- } from "./chunk-SJVY55D3.js";
27
- import "./chunk-UR3MEEN4.js";
26
+ } from "./chunk-INDAKTSG.js";
27
+ import "./chunk-CE67XAQY.js";
28
28
  import "./chunk-GZ5UUECB.js";
29
29
  import "./chunk-JHNW2EKY.js";
30
- import "./chunk-YZ4SOO2E.js";
30
+ import "./chunk-BUAELY3G.js";
31
31
  import "./chunk-QGM4M3NI.js";
32
32
  export {
33
33
  DEFAULT_BULLETIN_RPC,
package/dist/dotns.d.ts CHANGED
@@ -18,6 +18,26 @@ interface PriceValidationResult {
18
18
  userStatus: number;
19
19
  message: string;
20
20
  }
21
+ interface DotnsPreflightResult {
22
+ label: string;
23
+ classification: {
24
+ status: number;
25
+ message: string;
26
+ };
27
+ userStatus: number;
28
+ trailingDigits: number;
29
+ baselength: number;
30
+ isAvailable: boolean;
31
+ existingOwner: string | null;
32
+ isBaseNameReserved: boolean;
33
+ reservationOwner: string | null;
34
+ isTestnet: boolean;
35
+ canProceed: boolean;
36
+ reason?: string;
37
+ plannedAction: "register" | "already-owned-by-us" | "abort";
38
+ needsPopUpgrade: boolean;
39
+ targetPopStatus?: number;
40
+ }
21
41
  declare const RPC_ENDPOINTS: string[];
22
42
  declare const CONTRACTS: {
23
43
  readonly DOTNS_REGISTRAR: "0x329aAA5b6bEa94E750b2dacBa74Bf41291E6c2BD";
@@ -50,7 +70,17 @@ declare function stripTrailingDigits(label: string): string;
50
70
  declare function sanitizeDomainLabel(label: string): string;
51
71
  declare function validateDomainLabel(label: string): string;
52
72
  declare function isCommitmentMature(chainNowSeconds: number, commitTimestampSeconds: number, minimumAgeSeconds: number): boolean;
73
+ declare function classifyDotnsLabel(label: string): {
74
+ status: number;
75
+ message: string;
76
+ };
77
+ declare function canRegister(requiredStatus: number, userStatus: number, trailingDigits: number): boolean;
78
+ declare function simulateUserStatus(currentStatus: number, requiredStatus: number, options: {
79
+ explicitStatus?: number;
80
+ isTestnet: boolean;
81
+ }): number;
53
82
  declare function parseProofOfPersonhoodStatus(status: string): number;
83
+ declare function popStatusName(status: number): string;
54
84
  declare class ReviveClientWrapper {
55
85
  static DRY_RUN_STORAGE_LIMIT: bigint;
56
86
  static DRY_RUN_WEIGHT_LIMIT: {
@@ -88,6 +118,8 @@ declare class DotNS {
88
118
  constructor();
89
119
  connect(options?: DotNSConnectOptions): Promise<this>;
90
120
  ensureConnected(): void;
121
+ private _testnetCache;
122
+ isTestnet(): Promise<boolean>;
91
123
  contractCall(contractAddress: string, contractAbi: readonly any[], functionName: string, args?: any[]): Promise<any>;
92
124
  contractTransaction(contractAddress: string, value: bigint, contractAbi: readonly any[], functionName: string, args?: any[], statusCallback?: (status: string) => void, { useNoncePolling }?: {
93
125
  useNoncePolling?: boolean;
@@ -112,6 +144,7 @@ declare class DotNS {
112
144
  setContenthash(domainName: string, contenthashHex: string): Promise<{
113
145
  node: string;
114
146
  }>;
147
+ preflight(label: string, explicitStatusOverride?: string): Promise<DotnsPreflightResult>;
115
148
  register(label: string, options?: DotNSConnectOptions & {
116
149
  status?: string;
117
150
  reverse?: boolean;
@@ -123,4 +156,4 @@ declare class DotNS {
123
156
  }
124
157
  declare const dotns: DotNS;
125
158
 
126
- export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOT_NODE, DotNS, type DotNSConnectOptions, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_TIMEOUT_MS, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, fetchNonce, isCommitmentMature, parseProofOfPersonhoodStatus, sanitizeDomainLabel, stripTrailingDigits, validateDomainLabel };
159
+ export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_TIMEOUT_MS, canRegister, classifyDotnsLabel, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, fetchNonce, isCommitmentMature, parseProofOfPersonhoodStatus, popStatusName, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel };
package/dist/dotns.js CHANGED
@@ -10,6 +10,8 @@ import {
10
10
  ProofOfPersonhoodStatus,
11
11
  RPC_ENDPOINTS,
12
12
  TX_TIMEOUT_MS,
13
+ canRegister,
14
+ classifyDotnsLabel,
13
15
  computeDomainTokenId,
14
16
  convertWeiToNative,
15
17
  countTrailingDigits,
@@ -17,11 +19,14 @@ import {
17
19
  fetchNonce,
18
20
  isCommitmentMature,
19
21
  parseProofOfPersonhoodStatus,
22
+ popStatusName,
20
23
  sanitizeDomainLabel,
24
+ simulateUserStatus,
21
25
  stripTrailingDigits,
22
26
  validateDomainLabel
23
- } from "./chunk-UR3MEEN4.js";
24
- import "./chunk-YZ4SOO2E.js";
27
+ } from "./chunk-CE67XAQY.js";
28
+ import "./chunk-JHNW2EKY.js";
29
+ import "./chunk-BUAELY3G.js";
25
30
  import "./chunk-QGM4M3NI.js";
26
31
  export {
27
32
  CONNECTION_TIMEOUT_MS,
@@ -35,6 +40,8 @@ export {
35
40
  ProofOfPersonhoodStatus,
36
41
  RPC_ENDPOINTS,
37
42
  TX_TIMEOUT_MS,
43
+ canRegister,
44
+ classifyDotnsLabel,
38
45
  computeDomainTokenId,
39
46
  convertWeiToNative,
40
47
  countTrailingDigits,
@@ -42,7 +49,9 @@ export {
42
49
  fetchNonce,
43
50
  isCommitmentMature,
44
51
  parseProofOfPersonhoodStatus,
52
+ popStatusName,
45
53
  sanitizeDomainLabel,
54
+ simulateUserStatus,
46
55
  stripTrailingDigits,
47
56
  validateDomainLabel
48
57
  };
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deploy
3
- } from "./chunk-SJVY55D3.js";
3
+ } from "./chunk-INDAKTSG.js";
4
4
  import {
5
5
  DotNS
6
- } from "./chunk-UR3MEEN4.js";
6
+ } from "./chunk-CE67XAQY.js";
7
7
  import {
8
8
  merkleizeJS
9
9
  } from "./chunk-GZ5UUECB.js";
@@ -14,7 +14,7 @@ import {
14
14
  fetchPoolAuthorizations,
15
15
  selectAccount
16
16
  } from "./chunk-JHNW2EKY.js";
17
- import "./chunk-YZ4SOO2E.js";
17
+ import "./chunk-BUAELY3G.js";
18
18
  import "./chunk-QGM4M3NI.js";
19
19
  export {
20
20
  DotNS,
package/dist/telemetry.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  truncateAddress,
18
18
  withDeploySpan,
19
19
  withSpan
20
- } from "./chunk-YZ4SOO2E.js";
20
+ } from "./chunk-BUAELY3G.js";
21
21
  import "./chunk-QGM4M3NI.js";
22
22
  export {
23
23
  VERSION,
@@ -8,8 +8,8 @@ import {
8
8
  isPreReleaseVersion,
9
9
  preReleaseWarning,
10
10
  promptYesNo
11
- } from "./chunk-ZJW37GNT.js";
12
- import "./chunk-YZ4SOO2E.js";
11
+ } from "./chunk-TF4MTBZF.js";
12
+ import "./chunk-BUAELY3G.js";
13
13
  import "./chunk-QGM4M3NI.js";
14
14
  export {
15
15
  assessVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulletin-deploy",
3
- "version": "0.6.9-rc.6",
3
+ "version": "0.6.9",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",