bulletin-deploy 0.7.22 → 0.7.23-rc.2
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.
- package/assets/environments.json +7 -0
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-V7KIUORT.js → chunk-2C424N5I.js} +1 -1
- package/dist/{chunk-PNZCJPI6.js → chunk-3PUOXYBI.js} +9 -2
- package/dist/{chunk-LMCKLAA5.js → chunk-3T3AWNCO.js} +2 -2
- package/dist/{chunk-F36C363Y.js → chunk-5JHQZDWQ.js} +19 -1
- package/dist/{chunk-6ZVGLZMF.js → chunk-B6TOE4GB.js} +202 -39
- package/dist/{chunk-VQPLU5FL.js → chunk-SAMFZEX3.js} +9 -1
- package/dist/{chunk-5C4E4EMD.js → chunk-VHHUJLP4.js} +1 -1
- package/dist/{chunk-34OG2FRO.js → chunk-X2UWWDBL.js} +72 -69
- package/dist/chunk-probe.js +3 -3
- package/dist/deploy.d.ts +3 -1
- package/dist/deploy.js +8 -8
- package/dist/dotns.d.ts +45 -5
- package/dist/dotns.js +5 -3
- package/dist/environments.d.ts +19 -1
- package/dist/environments.js +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -9
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +8 -8
- package/dist/personhood/bootstrap.js +4 -4
- package/dist/personhood/people-client.js +4 -4
- package/dist/run-state.js +1 -1
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/package.json +9 -1
package/assets/environments.json
CHANGED
|
@@ -56,6 +56,13 @@
|
|
|
56
56
|
"autoAccountMapping": true,
|
|
57
57
|
"bulletinAuthorizeV2": true,
|
|
58
58
|
"nativeToEthRatio": 100000000,
|
|
59
|
+
"popSelfServe": {
|
|
60
|
+
"sudoEnvLabel": "Next V2",
|
|
61
|
+
"faucetUrl": "https://faucet.polkadot.io/?parachain=1500",
|
|
62
|
+
"personhoodFaucetUrl": "https://sudo.personhood.dev/personhood-faucet",
|
|
63
|
+
"dotnsBootstrapUrl": "https://sudo.personhood.dev/dotns-bootstrap",
|
|
64
|
+
"stateAwareGuidance": true
|
|
65
|
+
},
|
|
59
66
|
"contracts": {
|
|
60
67
|
"DOTNS_PROTOCOL_REGISTRY": "0x5Caef84563fc980178e28417414aa65bA32f6B4e",
|
|
61
68
|
"DOTNS_REGISTRAR": "0x885b8085bA92A31c4ef52076f77379E647ECC399",
|
package/dist/bug-report.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
offerBugReport,
|
|
10
10
|
scrubSecrets,
|
|
11
11
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-3T3AWNCO.js";
|
|
13
|
+
import "./chunk-2C424N5I.js";
|
|
14
|
+
import "./chunk-3PUOXYBI.js";
|
|
15
|
+
import "./chunk-SAMFZEX3.js";
|
|
16
16
|
export {
|
|
17
17
|
buildCliFlagsSummary,
|
|
18
18
|
buildLabels,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default,
|
|
3
3
|
writeRunState
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SAMFZEX3.js";
|
|
5
5
|
|
|
6
6
|
// src/memory-report.ts
|
|
7
7
|
import * as fs2 from "fs";
|
|
@@ -212,7 +212,14 @@ function getDeployAttributes(domain) {
|
|
|
212
212
|
"deploy.dotns.signer_below_floor": "false",
|
|
213
213
|
"deploy.dotns.toppedup": "false",
|
|
214
214
|
// Flipped to "true" by deploy() when options.automatedMirror is set.
|
|
215
|
-
"deploy.automated_mirror": "false"
|
|
215
|
+
"deploy.automated_mirror": "false",
|
|
216
|
+
// Seeded "false" so every span carries the attribute for ratio queries.
|
|
217
|
+
// Flipped by deploy.ts storage phase when content is encrypted.
|
|
218
|
+
"deploy.encrypted": "false",
|
|
219
|
+
// Flipped by deploy.ts after parseDomainName resolves isSubdomain.
|
|
220
|
+
"deploy.subdomain": "false",
|
|
221
|
+
// Flipped by deploy.ts after readPreviousContenthashSafe when a prior CID is found.
|
|
222
|
+
"deploy.incremental": "false"
|
|
216
223
|
};
|
|
217
224
|
if (hostApp) attrs["deploy.host_app"] = hostApp;
|
|
218
225
|
const hostAppVersion = process.env.BULLETIN_DEPLOY_HOST_APP_VERSION;
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2C424N5I.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3PUOXYBI.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
12
12
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -65,6 +65,13 @@ var environments_default = {
|
|
|
65
65
|
autoAccountMapping: true,
|
|
66
66
|
bulletinAuthorizeV2: true,
|
|
67
67
|
nativeToEthRatio: 1e8,
|
|
68
|
+
popSelfServe: {
|
|
69
|
+
sudoEnvLabel: "Next V2",
|
|
70
|
+
faucetUrl: "https://faucet.polkadot.io/?parachain=1500",
|
|
71
|
+
personhoodFaucetUrl: "https://sudo.personhood.dev/personhood-faucet",
|
|
72
|
+
dotnsBootstrapUrl: "https://sudo.personhood.dev/dotns-bootstrap",
|
|
73
|
+
stateAwareGuidance: true
|
|
74
|
+
},
|
|
68
75
|
contracts: {
|
|
69
76
|
DOTNS_PROTOCOL_REGISTRY: "0x5Caef84563fc980178e28417414aa65bA32f6B4e",
|
|
70
77
|
DOTNS_REGISTRAR: "0x885b8085bA92A31c4ef52076f77379E647ECC399",
|
|
@@ -319,7 +326,14 @@ var HARDCODED_FALLBACK = {
|
|
|
319
326
|
id: "paseo-next-v2",
|
|
320
327
|
name: "Paseo Next v2",
|
|
321
328
|
network: "testnet",
|
|
322
|
-
description: "Next iteration of the Paseo Next testnet (hardcoded fallback)"
|
|
329
|
+
description: "Next iteration of the Paseo Next testnet (hardcoded fallback)",
|
|
330
|
+
popSelfServe: {
|
|
331
|
+
sudoEnvLabel: "Next V2",
|
|
332
|
+
faucetUrl: "https://faucet.polkadot.io/?parachain=1500",
|
|
333
|
+
personhoodFaucetUrl: "https://sudo.personhood.dev/personhood-faucet",
|
|
334
|
+
dotnsBootstrapUrl: "https://sudo.personhood.dev/dotns-bootstrap",
|
|
335
|
+
stateAwareGuidance: true
|
|
336
|
+
}
|
|
323
337
|
}
|
|
324
338
|
],
|
|
325
339
|
chains: [
|
|
@@ -444,6 +458,9 @@ function resolveEndpoints(doc, envId) {
|
|
|
444
458
|
nativeToEthRatio: BigInt(env.nativeToEthRatio ?? 1e6)
|
|
445
459
|
};
|
|
446
460
|
}
|
|
461
|
+
function getPopSelfServeConfig(doc, envId) {
|
|
462
|
+
return doc.environments.find((e) => e.id === envId)?.popSelfServe ?? null;
|
|
463
|
+
}
|
|
447
464
|
function listEnvironments(doc) {
|
|
448
465
|
const bulletinChain = doc.chains.find((c) => c.id === "bulletin");
|
|
449
466
|
return doc.environments.map((env) => {
|
|
@@ -480,6 +497,7 @@ export {
|
|
|
480
497
|
defaultBundledPath,
|
|
481
498
|
loadEnvironments,
|
|
482
499
|
resolveEndpoints,
|
|
500
|
+
getPopSelfServeConfig,
|
|
483
501
|
listEnvironments,
|
|
484
502
|
formatEnvironmentTable
|
|
485
503
|
};
|
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
captureWarning,
|
|
6
6
|
setDeployAttribute,
|
|
7
|
+
setDeploySentryTag,
|
|
8
|
+
truncateAddress,
|
|
7
9
|
withSpan
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3PUOXYBI.js";
|
|
9
11
|
|
|
10
12
|
// src/dotns.ts
|
|
11
13
|
import crypto from "crypto";
|
|
@@ -35,11 +37,20 @@ var FEE_FLOOR_OWNED = ONE_PAS / 100n;
|
|
|
35
37
|
var FEE_FLOOR_REGISTER = ONE_PAS / 10n;
|
|
36
38
|
var TOP_UP_TARGET = ONE_PAS / 2n;
|
|
37
39
|
var SOURCE_BUFFER = ONE_PAS;
|
|
40
|
+
var REPROVE_FEE_ESTIMATE = ONE_PAS / 100n;
|
|
41
|
+
var REPROVE_FEE_SAFETY_MARGIN_PCT = 110n;
|
|
38
42
|
var TOP_UP_TRANSFER_TIMEOUT_MS = 6e4;
|
|
39
43
|
var PASEO_FAUCET_URL = "https://faucet.polkadot.io";
|
|
40
44
|
function fmtPas(plancks) {
|
|
41
45
|
return (Number(plancks) / Number(ONE_PAS)).toFixed(4);
|
|
42
46
|
}
|
|
47
|
+
function resolveNativeTokenSymbol(envId) {
|
|
48
|
+
if (!envId) return "PAS";
|
|
49
|
+
if (envId.includes("paseo")) return "PAS";
|
|
50
|
+
if (envId.includes("westend")) return "WND";
|
|
51
|
+
if (envId.includes("rococo")) return "ROC";
|
|
52
|
+
return "PAS";
|
|
53
|
+
}
|
|
43
54
|
function feeFloorFor(plannedAction) {
|
|
44
55
|
return plannedAction === "already-owned-by-us" ? FEE_FLOOR_OWNED : FEE_FLOOR_REGISTER;
|
|
45
56
|
}
|
|
@@ -258,12 +269,12 @@ function formatContractDryRunFailure(gasEstimate, context) {
|
|
|
258
269
|
const isBareRevert = (revertData === void 0 || revertData.trim() === "0x") && gasEstimate.revertFlags === 1n;
|
|
259
270
|
if (isBareRevert && BARE_REVERT_DIAGNOSTIC_FUNCTIONS.has(functionName)) {
|
|
260
271
|
lines.push(
|
|
261
|
-
` diagnostic: bare-revert (empty 0x).
|
|
262
|
-
` 1.
|
|
263
|
-
`
|
|
264
|
-
`
|
|
265
|
-
`
|
|
266
|
-
`
|
|
272
|
+
` diagnostic: bare-revert (empty 0x). Account mapping was verified at connect time, so the cause is likely:`,
|
|
273
|
+
` 1. PoP status changed between preflight and registration (race condition).`,
|
|
274
|
+
` 2. Commitment timing: the revealed commitment is still too new or already expired.`,
|
|
275
|
+
` 3. Label was registered by someone else between preflight and register.`,
|
|
276
|
+
` To reproduce in isolation: \`node tools/dotns-dry-run.mjs <label>\``,
|
|
277
|
+
` To rule out a mapping issue: add --fresh (a brand-new unmapped origin) \u2014 if --fresh reverts but the mapped one doesn't, it's a mapping bug.`
|
|
267
278
|
);
|
|
268
279
|
}
|
|
269
280
|
return lines.join("\n");
|
|
@@ -636,21 +647,45 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
636
647
|
}
|
|
637
648
|
};
|
|
638
649
|
var DOTNS_CONTEXT_HEX_LOWER = "0x646f746e73000000000000000000000000000000000000000000000000000000";
|
|
639
|
-
function formatPersonhoodRemediation(state, environmentId) {
|
|
640
|
-
if (
|
|
650
|
+
function formatPersonhoodRemediation(state, popSelfServe, environmentId) {
|
|
651
|
+
if (!popSelfServe?.stateAwareGuidance) {
|
|
641
652
|
return "Self-attestation is no longer available. Contact the DotNS team for whitelisting / Personhood status help.";
|
|
642
653
|
}
|
|
643
654
|
switch (state.state) {
|
|
644
655
|
case "not-bound":
|
|
645
|
-
return
|
|
656
|
+
return `Your account has no DotNS alias binding on ${environmentId ?? "this environment"}. Visit ${popSelfServe.dotnsBootstrapUrl} to complete the recognition and binding steps, or run \`tools/personhood-bootstrap.mjs --mnemonic <your-mnemonic>\` once Stage 2 of the bootstrap tooling lands.`;
|
|
646
657
|
case "bound-likely-stale":
|
|
647
|
-
return
|
|
658
|
+
return `Your alias binding exists but may have a stale ring revision. Run \`node tools/reprove-alias.mjs --mnemonic <your-mnemonic> --env ${environmentId ?? "this environment"}\` to refresh the proof, then retry the registration.`;
|
|
648
659
|
case "wrong-context":
|
|
649
|
-
return "Your alias binding exists but is for a different application context" + (state.storedContextHex ? ` (context: ${state.storedContextHex})` : "") + ". Re-bind under the 'dotns' context using the bootstrap flow:
|
|
660
|
+
return "Your alias binding exists but is for a different application context" + (state.storedContextHex ? ` (context: ${state.storedContextHex})` : "") + ". Re-bind under the 'dotns' context using the bootstrap flow: " + popSelfServe.dotnsBootstrapUrl;
|
|
650
661
|
case "bound-fresh":
|
|
651
662
|
return "Self-attestation is no longer available. Contact the DotNS team for whitelisting / Personhood status help.";
|
|
652
663
|
}
|
|
653
664
|
}
|
|
665
|
+
function formatPopShortfallReason(opts) {
|
|
666
|
+
const { label, requiredName, currentName, isTestnet, environmentId, popSelfServe, aliasState, exampleNoStatusLabel: noStatusEx } = opts;
|
|
667
|
+
const leadIn = `${label}.dot requires ${requiredName}, but this signer is ${currentName}.`;
|
|
668
|
+
let testnetBlock = "";
|
|
669
|
+
if (isTestnet && popSelfServe != null) {
|
|
670
|
+
if (popSelfServe.stateAwareGuidance) {
|
|
671
|
+
const state = aliasState ?? { state: "not-bound" };
|
|
672
|
+
testnetBlock = "\n\n" + formatPersonhoodRemediation(state, popSelfServe, environmentId);
|
|
673
|
+
} else {
|
|
674
|
+
testnetBlock = `
|
|
675
|
+
|
|
676
|
+
On testnets you can self-serve:
|
|
677
|
+
1. Fund the service account mnemonic via ${popSelfServe.faucetUrl}
|
|
678
|
+
2. Go to ${popSelfServe.personhoodFaucetUrl}, pick your env (e.g. ${popSelfServe.sudoEnvLabel}), and paste the mnemonic
|
|
679
|
+
3. Go to ${popSelfServe.dotnsBootstrapUrl} and follow each step (first and last can probably be skipped)`;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const alternativesBlock = `
|
|
683
|
+
|
|
684
|
+
Alternatively:
|
|
685
|
+
- Use a NoStatus-compatible label (base length >= 9 with exactly two trailing digits, e.g. ${noStatusEx})
|
|
686
|
+
- Raise a whitelist issue at https://github.com/paritytech/dotns/`;
|
|
687
|
+
return leadIn + testnetBlock + alternativesBlock;
|
|
688
|
+
}
|
|
654
689
|
var DotNS = class {
|
|
655
690
|
client;
|
|
656
691
|
clientWrapper;
|
|
@@ -664,9 +699,24 @@ var DotNS = class {
|
|
|
664
699
|
// back to the legacy paseo-only RPC_ENDPOINTS for direct library callers.
|
|
665
700
|
assetHubEndpoints;
|
|
666
701
|
_usesExternalSigner = false;
|
|
702
|
+
_localMnemonic = null;
|
|
667
703
|
_contracts = CONTRACTS;
|
|
668
704
|
_nativeToEthRatio = NATIVE_TO_ETH_RATIO;
|
|
669
705
|
_environmentId = null;
|
|
706
|
+
_popSelfServe = null;
|
|
707
|
+
// Test-only seam: consumed once by classifyAliasAccountState() then cleared.
|
|
708
|
+
// Mirrors the __setDeployRootSpanForTest / __setSentryForTest pattern.
|
|
709
|
+
_classifyOverrideForTest = null;
|
|
710
|
+
/** Test-only: inject a fixed classifyAliasAccountState return value for the next call. Consumed once. */
|
|
711
|
+
__setClassifyOverrideForTest(state) {
|
|
712
|
+
this._classifyOverrideForTest = { state, revision: 0 };
|
|
713
|
+
}
|
|
714
|
+
// Test-only seam: consumed once by getUserPopStatus() then cleared.
|
|
715
|
+
_userPopStatusOverrideForTest = null;
|
|
716
|
+
/** Test-only: inject a fixed getUserPopStatus return value for the next call. Consumed once. */
|
|
717
|
+
__setUserPopStatusForTest(status) {
|
|
718
|
+
this._userPopStatusOverrideForTest = status;
|
|
719
|
+
}
|
|
670
720
|
constructor() {
|
|
671
721
|
this.client = null;
|
|
672
722
|
this.clientWrapper = null;
|
|
@@ -687,6 +737,9 @@ var DotNS = class {
|
|
|
687
737
|
if (options.environmentId) {
|
|
688
738
|
this._environmentId = options.environmentId;
|
|
689
739
|
}
|
|
740
|
+
if (options.popSelfServe !== void 0) {
|
|
741
|
+
this._popSelfServe = options.popSelfServe ?? null;
|
|
742
|
+
}
|
|
690
743
|
const rpc = options.rpc || process.env.DOTNS_RPC || this.assetHubEndpoints[0];
|
|
691
744
|
this.rpc = rpc;
|
|
692
745
|
this._usesExternalSigner = Boolean(options.signer && options.signerAddress);
|
|
@@ -698,6 +751,9 @@ var DotNS = class {
|
|
|
698
751
|
const keyUriArg = options.keyUri || process.env.DOTNS_KEY_URI;
|
|
699
752
|
let source = keyUriArg || mnemonicArg || DEFAULT_MNEMONIC;
|
|
700
753
|
const isKeyUri = Boolean(keyUriArg);
|
|
754
|
+
if (!isKeyUri && !options.derivationPath) {
|
|
755
|
+
this._localMnemonic = mnemonicArg || DEFAULT_MNEMONIC;
|
|
756
|
+
}
|
|
701
757
|
if (options.derivationPath && !isKeyUri && source) {
|
|
702
758
|
source = `${source}${options.derivationPath}`;
|
|
703
759
|
}
|
|
@@ -708,28 +764,34 @@ var DotNS = class {
|
|
|
708
764
|
this.substrateAddress = account.address;
|
|
709
765
|
}
|
|
710
766
|
console.log(` SS58 Address: ${this.substrateAddress}`);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
this.
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
this.connected =
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
767
|
+
setDeployAttribute("deploy.dotns.signer", truncateAddress(this.substrateAddress));
|
|
768
|
+
setDeploySentryTag("deploy.dotns.signer", truncateAddress(this.substrateAddress));
|
|
769
|
+
return withSpan("deploy.dotns.connect", "dotns connect", {}, async () => {
|
|
770
|
+
try {
|
|
771
|
+
this.client = createClient(getWsProvider(rpc, { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS }));
|
|
772
|
+
const unsafeApi = this.client.getUnsafeApi();
|
|
773
|
+
this.clientWrapper = new ReviveClientWrapper(unsafeApi);
|
|
774
|
+
this.evmAddress = await withTimeout(
|
|
775
|
+
this.clientWrapper.getEvmAddress(this.substrateAddress),
|
|
776
|
+
CONNECTION_TIMEOUT_MS,
|
|
777
|
+
"ReviveApi.address"
|
|
778
|
+
);
|
|
779
|
+
console.log(` H160 Address: ${this.evmAddress}`);
|
|
780
|
+
} catch (e) {
|
|
781
|
+
throw new Error(`DotNS connect: failed to resolve EVM address from ${this.substrateAddress} via ReviveApi.address (${e.message?.slice(0, 200)})`);
|
|
782
|
+
}
|
|
783
|
+
setDeployAttribute("deploy.dotns.rpc_used", rpc);
|
|
784
|
+
setDeployAttribute("deploy.dotns.evm_address", this.evmAddress);
|
|
785
|
+
this.connected = true;
|
|
786
|
+
if (options.nativeToEthRatio) this._nativeToEthRatio = options.nativeToEthRatio;
|
|
787
|
+
try {
|
|
788
|
+
await this.ensureMappedAccountReady(options.autoAccountMapping ?? false);
|
|
789
|
+
} catch (e) {
|
|
790
|
+
this.connected = false;
|
|
791
|
+
throw e;
|
|
792
|
+
}
|
|
793
|
+
return this;
|
|
794
|
+
});
|
|
733
795
|
}
|
|
734
796
|
async ensureMappedAccountReady(autoAccountMapping = false) {
|
|
735
797
|
this.ensureConnected();
|
|
@@ -737,10 +799,12 @@ var DotNS = class {
|
|
|
737
799
|
throw new Error("Account mapping unavailable before DotNS signer is initialized");
|
|
738
800
|
}
|
|
739
801
|
if (autoAccountMapping) {
|
|
802
|
+
setDeployAttribute("deploy.dotns.mapping_source", "auto-account-mapping");
|
|
740
803
|
await this.ensureAutoMappedAccountReady();
|
|
741
804
|
return;
|
|
742
805
|
}
|
|
743
806
|
if (await this.clientWrapper.checkIfAccountMapped(this.substrateAddress)) {
|
|
807
|
+
setDeployAttribute("deploy.dotns.mapping_source", "already-mapped");
|
|
744
808
|
console.log(` Account: mapped`);
|
|
745
809
|
return;
|
|
746
810
|
}
|
|
@@ -749,6 +813,7 @@ var DotNS = class {
|
|
|
749
813
|
await this.clientWrapper.ensureAccountMapped(this.substrateAddress, this.signer);
|
|
750
814
|
} catch (e) {
|
|
751
815
|
if (await this.clientWrapper.checkIfAccountMapped(this.substrateAddress)) {
|
|
816
|
+
setDeployAttribute("deploy.dotns.mapping_source", "direct-mapped");
|
|
752
817
|
console.log(` Account: mapped`);
|
|
753
818
|
return;
|
|
754
819
|
}
|
|
@@ -756,9 +821,11 @@ var DotNS = class {
|
|
|
756
821
|
signer: this.substrateAddress,
|
|
757
822
|
error: e?.message?.slice?.(0, 200) ?? String(e).slice(0, 200)
|
|
758
823
|
});
|
|
824
|
+
setDeployAttribute("deploy.dotns.mapping_source", "auto-map-fallback");
|
|
759
825
|
await this.ensureAutoMappedAccountReady();
|
|
760
826
|
return;
|
|
761
827
|
}
|
|
828
|
+
setDeployAttribute("deploy.dotns.mapping_source", "direct-mapped");
|
|
762
829
|
console.log(` Account: mapped`);
|
|
763
830
|
}
|
|
764
831
|
async ensureAutoMappedAccountReady() {
|
|
@@ -841,6 +908,11 @@ var DotNS = class {
|
|
|
841
908
|
* Returns "not-bound" if the chain is unreachable (safe fallback to generic advice).
|
|
842
909
|
*/
|
|
843
910
|
async classifyAliasAccountState(ss58) {
|
|
911
|
+
if (this._classifyOverrideForTest !== null) {
|
|
912
|
+
const result = this._classifyOverrideForTest;
|
|
913
|
+
this._classifyOverrideForTest = null;
|
|
914
|
+
return result;
|
|
915
|
+
}
|
|
844
916
|
if (!this.clientWrapper) return { state: "not-bound" };
|
|
845
917
|
try {
|
|
846
918
|
const api = this.clientWrapper.client;
|
|
@@ -1034,6 +1106,11 @@ var DotNS = class {
|
|
|
1034
1106
|
}
|
|
1035
1107
|
}
|
|
1036
1108
|
async getUserPopStatus(ownerAddress = null) {
|
|
1109
|
+
if (this._userPopStatusOverrideForTest !== null) {
|
|
1110
|
+
const result = this._userPopStatusOverrideForTest;
|
|
1111
|
+
this._userPopStatusOverrideForTest = null;
|
|
1112
|
+
return result;
|
|
1113
|
+
}
|
|
1037
1114
|
this.ensureConnected();
|
|
1038
1115
|
const checkAddress = ownerAddress || this.evmAddress;
|
|
1039
1116
|
try {
|
|
@@ -1264,7 +1341,12 @@ var DotNS = class {
|
|
|
1264
1341
|
}
|
|
1265
1342
|
}
|
|
1266
1343
|
const priceMeta = await withTimeout(this.contractCall(this._contracts.POP_RULES, POP_RULES_ABI, "priceWithCheck", [label, this.evmAddress]), 3e4, "priceWithCheck");
|
|
1267
|
-
const priceRaw = priceMeta
|
|
1344
|
+
const priceRaw = priceMeta?.price;
|
|
1345
|
+
if (priceRaw == null) {
|
|
1346
|
+
throw new Error(
|
|
1347
|
+
`priceWithCheck returned unexpected shape (expected object with .price): ` + JSON.stringify(priceMeta, (_, v) => typeof v === "bigint" ? v.toString() : v)
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1268
1350
|
const priceWei = typeof priceRaw === "bigint" ? priceRaw : BigInt(priceRaw);
|
|
1269
1351
|
console.log(` Required status: ${popStatusName(requiredStatus)}`);
|
|
1270
1352
|
console.log(` User status: ${popStatusName(userStatus)}`);
|
|
@@ -1277,6 +1359,12 @@ var DotNS = class {
|
|
|
1277
1359
|
Finalizing registration for ${registration.label}.dot...`);
|
|
1278
1360
|
const bufferedPaymentWei = priceWei * 110n / 100n;
|
|
1279
1361
|
const bufferedPaymentNative = bufferedPaymentWei / this._nativeToEthRatio;
|
|
1362
|
+
if (priceWei > 0n && bufferedPaymentNative === 0n) {
|
|
1363
|
+
throw new Error(
|
|
1364
|
+
`Payment conversion underflow: priceWei=${priceWei} rounds to 0 native units (nativeToEthRatio=${this._nativeToEthRatio}). Cannot call register with zero payment.`
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
setDeployAttribute("deploy.payment_wei", priceWei.toString());
|
|
1280
1368
|
console.log(` Oracle price: ${formatEther(priceWei)} PAS`);
|
|
1281
1369
|
console.log(` Paying: ${formatEther(bufferedPaymentWei)} PAS`);
|
|
1282
1370
|
const txHash = await this.contractTransaction(this._contracts.DOTNS_REGISTRAR_CONTROLLER, bufferedPaymentNative, DOTNS_REGISTRAR_CONTROLLER_ABI, "register", [registration], (s) => console.log(` ${s}`));
|
|
@@ -1299,7 +1387,11 @@ var DotNS = class {
|
|
|
1299
1387
|
// `register(label)` will succeed, so the caller can fail-fast BEFORE the
|
|
1300
1388
|
// Bulletin chunk upload. Never writes to chain. See issue #100.
|
|
1301
1389
|
async preflight(label) {
|
|
1390
|
+
return this._preflightInternal(label, false);
|
|
1391
|
+
}
|
|
1392
|
+
async _preflightInternal(label, reproveAttempted) {
|
|
1302
1393
|
return withSpan("deploy.dotns.preflight", `preflight ${label}.dot`, {}, async () => {
|
|
1394
|
+
setDeployAttribute("deploy.dotns.reprove.auto", "false");
|
|
1303
1395
|
this.ensureConnected();
|
|
1304
1396
|
const validated = validateDomainLabel(label);
|
|
1305
1397
|
const trailingDigits = countTrailingDigits(validated);
|
|
@@ -1414,9 +1506,59 @@ var DotNS = class {
|
|
|
1414
1506
|
signerFreeBalance
|
|
1415
1507
|
};
|
|
1416
1508
|
}
|
|
1417
|
-
if (userStatus === ProofOfPersonhoodStatus.NoStatus && isTestnet && this.
|
|
1509
|
+
if (userStatus === ProofOfPersonhoodStatus.NoStatus && isTestnet && this._popSelfServe?.stateAwareGuidance === true && this.substrateAddress) {
|
|
1418
1510
|
const aliasState = await this.classifyAliasAccountState(this.substrateAddress);
|
|
1419
|
-
|
|
1511
|
+
if (aliasState.state === "bound-likely-stale" && !this._usesExternalSigner && this._localMnemonic && !reproveAttempted) {
|
|
1512
|
+
const minBalance = REPROVE_FEE_ESTIMATE * REPROVE_FEE_SAFETY_MARGIN_PCT / 100n;
|
|
1513
|
+
const symbol = resolveNativeTokenSymbol(this._environmentId);
|
|
1514
|
+
if (signerFreeBalance < minBalance) {
|
|
1515
|
+
setDeployAttribute("deploy.dotns.reprove.auto", "true");
|
|
1516
|
+
setDeployAttribute("deploy.dotns.reprove.outcome", "insufficient_funds");
|
|
1517
|
+
return {
|
|
1518
|
+
label: validated,
|
|
1519
|
+
classification,
|
|
1520
|
+
userStatus,
|
|
1521
|
+
trailingDigits,
|
|
1522
|
+
baselength,
|
|
1523
|
+
isAvailable: true,
|
|
1524
|
+
existingOwner: null,
|
|
1525
|
+
isBaseNameReserved: isReserved,
|
|
1526
|
+
reservationOwner,
|
|
1527
|
+
isTestnet,
|
|
1528
|
+
canProceed: false,
|
|
1529
|
+
reason: `Cannot auto-refresh: signer balance ${fmtPas(signerFreeBalance)} ${symbol} < estimated fee ${fmtPas(REPROVE_FEE_ESTIMATE)} ${symbol}. Top up via the testnet faucet or run \`tools/reprove-alias.mjs --mnemonic <your-mnemonic> --env ${this._environmentId}\` manually.`,
|
|
1530
|
+
plannedAction: "abort",
|
|
1531
|
+
needsPopUpgrade: false,
|
|
1532
|
+
targetPopStatus,
|
|
1533
|
+
signerFreeBalance
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
console.log(`
|
|
1537
|
+
[stage] Personhood preflight \u2014 auto-refresh`);
|
|
1538
|
+
console.log(` Alias binding exists but ring revision is stale (stored=${aliasState.revision ?? "unknown"}).`);
|
|
1539
|
+
console.log(` Refreshing automatically on testnet\u2026`);
|
|
1540
|
+
console.log(` Estimated reprove fee: ${fmtPas(REPROVE_FEE_ESTIMATE)} ${symbol}. Signer balance: ${fmtPas(signerFreeBalance)} ${symbol} \u2014 proceeding.`);
|
|
1541
|
+
setDeployAttribute("deploy.dotns.reprove.auto", "true");
|
|
1542
|
+
let reproveSucceeded = false;
|
|
1543
|
+
try {
|
|
1544
|
+
console.log(` Submitting reprove_alias_account\u2026`);
|
|
1545
|
+
const reproveResult = await this.reprove(this._localMnemonic);
|
|
1546
|
+
console.log(` Refresh complete (old_revision=${reproveResult.oldRevision}, new_revision=${reproveResult.newRevision}, block=${reproveResult.blockHash}).`);
|
|
1547
|
+
setDeployAttribute("deploy.dotns.reprove.outcome", "success");
|
|
1548
|
+
setDeployAttribute("deploy.dotns.reprove.old_revision", String(reproveResult.oldRevision));
|
|
1549
|
+
setDeployAttribute("deploy.dotns.reprove.new_revision", String(reproveResult.newRevision));
|
|
1550
|
+
reproveSucceeded = true;
|
|
1551
|
+
} catch (e) {
|
|
1552
|
+
const msg = e?.message ?? String(e);
|
|
1553
|
+
console.log(` Auto-reprove failed: ${msg}`);
|
|
1554
|
+
setDeployAttribute("deploy.dotns.reprove.outcome", "failed_submission");
|
|
1555
|
+
}
|
|
1556
|
+
if (reproveSucceeded) {
|
|
1557
|
+
console.log(` Continuing with registration of ${validated}.dot.`);
|
|
1558
|
+
return this._preflightInternal(label, true);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
const remediationMessage = formatPersonhoodRemediation(aliasState, this._popSelfServe, this._environmentId);
|
|
1420
1562
|
const currentName2 = popStatusName(userStatus);
|
|
1421
1563
|
const requiredName2 = popStatusName(classification.status);
|
|
1422
1564
|
return {
|
|
@@ -1452,7 +1594,16 @@ var DotNS = class {
|
|
|
1452
1594
|
reservationOwner,
|
|
1453
1595
|
isTestnet,
|
|
1454
1596
|
canProceed: false,
|
|
1455
|
-
reason:
|
|
1597
|
+
reason: formatPopShortfallReason({
|
|
1598
|
+
label: validated,
|
|
1599
|
+
requiredName,
|
|
1600
|
+
currentName,
|
|
1601
|
+
isTestnet,
|
|
1602
|
+
environmentId: this._environmentId,
|
|
1603
|
+
popSelfServe: this._popSelfServe,
|
|
1604
|
+
aliasState: null,
|
|
1605
|
+
exampleNoStatusLabel: exampleNoStatusLabel(validated)
|
|
1606
|
+
}),
|
|
1456
1607
|
plannedAction: "abort",
|
|
1457
1608
|
needsPopUpgrade: false,
|
|
1458
1609
|
targetPopStatus,
|
|
@@ -1533,6 +1684,8 @@ var DotNS = class {
|
|
|
1533
1684
|
if (preRequiredStatus === ProofOfPersonhoodStatus.Reserved) {
|
|
1534
1685
|
throw new Error(preClassification.message);
|
|
1535
1686
|
}
|
|
1687
|
+
const isTestnet = await this.isTestnet();
|
|
1688
|
+
const registerAliasState = isTestnet && this._popSelfServe?.stateAwareGuidance === true && this.substrateAddress ? await this.classifyAliasAccountState(this.substrateAddress) : null;
|
|
1536
1689
|
const rejectIneligible = (statusRequired, userStatus2) => {
|
|
1537
1690
|
if (statusRequired === ProofOfPersonhoodStatus.NoStatus && userStatus2 === ProofOfPersonhoodStatus.ProofOfPersonhoodLite) {
|
|
1538
1691
|
throw new Error(
|
|
@@ -1540,7 +1693,16 @@ var DotNS = class {
|
|
|
1540
1693
|
);
|
|
1541
1694
|
}
|
|
1542
1695
|
throw new Error(
|
|
1543
|
-
|
|
1696
|
+
formatPopShortfallReason({
|
|
1697
|
+
label,
|
|
1698
|
+
requiredName: popStatusName(statusRequired),
|
|
1699
|
+
currentName: popStatusName(userStatus2),
|
|
1700
|
+
isTestnet,
|
|
1701
|
+
environmentId: this._environmentId,
|
|
1702
|
+
popSelfServe: this._popSelfServe,
|
|
1703
|
+
aliasState: registerAliasState,
|
|
1704
|
+
exampleNoStatusLabel: exampleNoStatusLabel(label)
|
|
1705
|
+
})
|
|
1544
1706
|
);
|
|
1545
1707
|
};
|
|
1546
1708
|
const reverse = options.reverse ?? (process.env.DOTNS_REVERSE ?? "false").toLowerCase() === "true";
|
|
@@ -1666,6 +1828,7 @@ export {
|
|
|
1666
1828
|
parseProofOfPersonhoodStatus,
|
|
1667
1829
|
popStatusName,
|
|
1668
1830
|
formatPersonhoodRemediation,
|
|
1831
|
+
formatPopShortfallReason,
|
|
1669
1832
|
DotNS,
|
|
1670
1833
|
dotns
|
|
1671
1834
|
};
|
|
@@ -6,7 +6,7 @@ import * as path from "path";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "bulletin-deploy",
|
|
9
|
-
version: "0.7.
|
|
9
|
+
version: "0.7.23-rc.2",
|
|
10
10
|
private: false,
|
|
11
11
|
repository: {
|
|
12
12
|
type: "git",
|
|
@@ -27,6 +27,14 @@ var package_default = {
|
|
|
27
27
|
".": {
|
|
28
28
|
types: "./dist/index.d.ts",
|
|
29
29
|
import: "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./deploy": {
|
|
32
|
+
types: "./dist/deploy.d.ts",
|
|
33
|
+
import: "./dist/deploy.js"
|
|
34
|
+
},
|
|
35
|
+
"./manifest-roundtrip": {
|
|
36
|
+
types: "./dist/manifest-roundtrip.d.ts",
|
|
37
|
+
import: "./dist/manifest-roundtrip.js"
|
|
30
38
|
}
|
|
31
39
|
},
|
|
32
40
|
files: [
|