bulletin-deploy 0.15.2 → 0.16.0-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 +1 -1
- package/bin/bulletin-deploy +20 -6
- package/dist/auth-config.js +4 -4
- package/dist/bug-report.js +4 -4
- package/dist/chain-health.js +3 -3
- package/dist/{chunk-DN4FDSVM.js → chunk-2BKPLQY2.js} +1 -1
- package/dist/{chunk-CD2NN5LL.js → chunk-33SYDRVZ.js} +1 -1
- package/dist/{chunk-SJPSTDCN.js → chunk-466FDICA.js} +1 -1
- package/dist/{chunk-KYBCFN3P.js → chunk-6C3JLASN.js} +2 -2
- package/dist/{chunk-CL7GQYYK.js → chunk-7CHUI4JX.js} +1 -1
- package/dist/{chunk-X7QKYH3U.js → chunk-BBPA3Q5K.js} +1 -1
- package/dist/{chunk-YXMWCUXP.js → chunk-D6AYE6KA.js} +1 -1
- package/dist/{chunk-JZNSDAZM.js → chunk-OORLC7SM.js} +9 -9
- package/dist/{chunk-EKBGOA24.js → chunk-OWCCOKOP.js} +2 -2
- package/dist/{chunk-CRNBI46S.js → chunk-PK3T6C6T.js} +3 -3
- package/dist/{chunk-4T6LXSOJ.js → chunk-SWD774NU.js} +1 -1
- package/dist/{chunk-ZPQO4PY2.js → chunk-SY2KD7SN.js} +123 -15
- package/dist/{chunk-2M65ETRD.js → chunk-VSLW6WXT.js} +1 -1
- package/dist/{chunk-SNIF5BSD.js → chunk-VTOT4GBT.js} +4 -4
- package/dist/{chunk-5HYWJO57.js → chunk-XFXTMHZX.js} +2 -2
- package/dist/chunk-probe.js +3 -3
- package/dist/commands/login.js +12 -12
- package/dist/commands/logout.js +5 -5
- package/dist/commands/transfer.js +20 -12
- package/dist/commands/whoami.js +4 -4
- package/dist/deploy-actors.js +7 -7
- package/dist/deploy.d.ts +11 -0
- package/dist/deploy.js +12 -12
- package/dist/dotns.d.ts +79 -10
- package/dist/dotns.js +15 -5
- package/dist/environments.js +1 -1
- package/dist/index.js +15 -15
- package/dist/manifest/config-load.js +2 -2
- package/dist/manifest/publish.js +13 -13
- package/dist/manifest/schema.js +1 -1
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +12 -12
- package/dist/personhood/bootstrap.js +5 -5
- package/dist/personhood/people-client.js +5 -5
- package/dist/run-state.js +1 -1
- package/dist/sss-allowance-cache.js +5 -5
- package/dist/storage-signer.js +12 -12
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/package.json +2 -2
package/assets/environments.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"backend": "https://polkadot-app-stg.parity.io/",
|
|
12
12
|
"ipfs": "https://previewnet.substrate.dev",
|
|
13
13
|
"webGateway": "testnet.li",
|
|
14
|
-
"tld": "
|
|
14
|
+
"tld": "testnet",
|
|
15
15
|
"autoAccountMapping": true,
|
|
16
16
|
"nativeToEthRatio": 100000000,
|
|
17
17
|
"registerStorageDeposit": 2000000000000,
|
package/bin/bulletin-deploy
CHANGED
|
@@ -259,7 +259,8 @@ Usage:
|
|
|
259
259
|
bulletin-deploy login Sign in with your Polkadot mobile app
|
|
260
260
|
bulletin-deploy logout Sign out and clear the session
|
|
261
261
|
bulletin-deploy whoami Show the currently signed-in identity
|
|
262
|
-
bulletin-deploy transfer <domain.dot> Hand a name you registered to the signed-in account (or --to)
|
|
262
|
+
bulletin-deploy transfer <domain.dot> Hand a name you registered to the signed-in account (or --to).
|
|
263
|
+
Also reassigns a subname (e.g. app.foo.dot) if you own its parent.
|
|
263
264
|
|
|
264
265
|
Options:
|
|
265
266
|
--env <id> Target environment from environments.json (default: paseo-next-v2).
|
|
@@ -312,7 +313,7 @@ Options:
|
|
|
312
313
|
config at all. Mutually exclusive with --publish.
|
|
313
314
|
--publish After deploy, list <domain> in the on-chain Publisher
|
|
314
315
|
registry (Publisher.publish). Only takes effect on envs
|
|
315
|
-
with a deployed Publisher (currently:
|
|
316
|
+
with a deployed Publisher (currently: PCF-devnet).
|
|
316
317
|
Requires --mnemonic (the signer must own the label).
|
|
317
318
|
--unpublish Standalone mode: removes <domain> from the Publisher
|
|
318
319
|
registry (Publisher.unpublish). Skips the deploy.
|
|
@@ -542,12 +543,21 @@ try {
|
|
|
542
543
|
console.log(` ${display.map(s => s.toLowerCase()).join(" · ")}`);
|
|
543
544
|
}
|
|
544
545
|
},
|
|
545
|
-
|
|
546
|
-
|
|
546
|
+
// #194: `approvalBudgetMs` is threaded through from PHONE_APPROVAL_MS
|
|
547
|
+
// (src/dotns.ts) rather than hardcoded here, so the disclosed number can
|
|
548
|
+
// never drift from the constant that actually governs the deadline.
|
|
549
|
+
// `reason: "silence"` marks a watcher-silence re-arm (no response within
|
|
550
|
+
// the budget) as distinct from the pre-existing verifyEffect-false-negative
|
|
551
|
+
// re-sign case (undefined/"resign", still rendered off `attempt`).
|
|
552
|
+
confirmPhoneReady: ({ label, attempt, approvalBudgetMs, reason }) => new Promise((resolve, reject) => {
|
|
553
|
+
const budgetSeconds = Math.round(approvalBudgetMs / 1000);
|
|
554
|
+
if (reason === "silence") {
|
|
555
|
+
console.log(`\n still nothing from your phone — press Y to re-send, Ctrl-C to abort`);
|
|
556
|
+
} else if (attempt >= 2) {
|
|
547
557
|
console.log(`\n Re-sign needed (attempt ${attempt}) — approve on your phone, then press Y to continue (Ctrl-C to abort).`);
|
|
548
558
|
} else {
|
|
549
559
|
console.log(`\n Check your phone → ${label}`);
|
|
550
|
-
console.log(` Press Y when ready (Ctrl-C to abort):`);
|
|
560
|
+
console.log(` Press Y when ready — you'll have ~${budgetSeconds}s to approve on your phone (Ctrl-C to abort):`);
|
|
551
561
|
}
|
|
552
562
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
553
563
|
let settled = false;
|
|
@@ -556,7 +566,11 @@ try {
|
|
|
556
566
|
const ask = () => {
|
|
557
567
|
rl.question(" > ", (line) => {
|
|
558
568
|
const answer = line.trim().toLowerCase();
|
|
559
|
-
|
|
569
|
+
// #194: require an EXPLICIT y/yes — bare Enter is the input most
|
|
570
|
+
// likely to come from something other than a deliberate keypress
|
|
571
|
+
// (buffered newline, stray Enter, piped stdin), and accepting it
|
|
572
|
+
// starts a fatal clock with nobody watching.
|
|
573
|
+
if (answer === "y" || answer === "yes") {
|
|
560
574
|
settle(resolve);
|
|
561
575
|
} else {
|
|
562
576
|
ask();
|
package/dist/auth-config.js
CHANGED
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
getPeopleChainEndpoints,
|
|
10
10
|
hasPersistedSession,
|
|
11
11
|
resolveBulletinEndpoints
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-6C3JLASN.js";
|
|
13
13
|
import "./chunk-TSPERKUS.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-7CHUI4JX.js";
|
|
15
15
|
import "./chunk-ZOC4GITL.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-BBPA3Q5K.js";
|
|
17
|
+
import "./chunk-XFXTMHZX.js";
|
|
18
18
|
export {
|
|
19
19
|
DOT_DAPP_ID,
|
|
20
20
|
DOT_DERIVATION_INDEX,
|
package/dist/bug-report.js
CHANGED
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
offerBugReport,
|
|
11
11
|
scrubSecrets,
|
|
12
12
|
setDeployContext
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-PK3T6C6T.js";
|
|
14
|
+
import "./chunk-VSLW6WXT.js";
|
|
15
|
+
import "./chunk-BBPA3Q5K.js";
|
|
16
|
+
import "./chunk-XFXTMHZX.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
19
19
|
buildLabels,
|
package/dist/chain-health.js
CHANGED
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
DEFAULT_WINDOW_BLOCKS,
|
|
4
4
|
MAX_SPANS_PER_SAMPLER,
|
|
5
5
|
endpointHost
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-466FDICA.js";
|
|
7
|
+
import "./chunk-BBPA3Q5K.js";
|
|
8
|
+
import "./chunk-XFXTMHZX.js";
|
|
9
9
|
export {
|
|
10
10
|
ChainHealthSampler,
|
|
11
11
|
DEFAULT_WINDOW_BLOCKS,
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-TSPERKUS.js";
|
|
4
4
|
import {
|
|
5
5
|
loadEnvironments
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7CHUI4JX.js";
|
|
7
7
|
import {
|
|
8
8
|
VERSION
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BBPA3Q5K.js";
|
|
10
10
|
|
|
11
11
|
// src/auth-config.ts
|
|
12
12
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -20,7 +20,7 @@ var environments_default = {
|
|
|
20
20
|
backend: "https://polkadot-app-stg.parity.io/",
|
|
21
21
|
ipfs: "https://previewnet.substrate.dev",
|
|
22
22
|
webGateway: "testnet.li",
|
|
23
|
-
tld: "
|
|
23
|
+
tld: "testnet",
|
|
24
24
|
autoAccountMapping: true,
|
|
25
25
|
nativeToEthRatio: 1e8,
|
|
26
26
|
registerStorageDeposit: 2e12,
|
|
@@ -7,7 +7,7 @@ var KIND_WORKER = "worker";
|
|
|
7
7
|
var EXECUTABLE_KINDS = [KIND_APP, KIND_WIDGET, KIND_FUNDING, KIND_WORKER];
|
|
8
8
|
var FUNDING_MODES = ["CARD", "BANK", "CRYPTO"];
|
|
9
9
|
var LABEL = String.raw`(?!-)[a-z0-9-]{1,63}(?<!-)`;
|
|
10
|
-
var KNOWN_TLDS = ["dot", "paseo", "test"];
|
|
10
|
+
var KNOWN_TLDS = ["dot", "paseo", "test", "testnet"];
|
|
11
11
|
var DOMAIN_RE = new RegExp(`^${LABEL}(\\.${LABEL})*\\.(?:${KNOWN_TLDS.join("|")})$`, "i");
|
|
12
12
|
function isPlainObject(value) {
|
|
13
13
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
preflightSssAllowance
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SWD774NU.js";
|
|
4
4
|
import {
|
|
5
5
|
statementSigningAccount
|
|
6
6
|
} from "./chunk-GRPLHUYC.js";
|
|
@@ -26,18 +26,18 @@ import {
|
|
|
26
26
|
} from "./chunk-S7EM5VMW.js";
|
|
27
27
|
import {
|
|
28
28
|
setDeployContext
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-PK3T6C6T.js";
|
|
30
30
|
import {
|
|
31
31
|
getBestBlockNumber,
|
|
32
32
|
probeChunks,
|
|
33
33
|
probeFinalityGap
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-33SYDRVZ.js";
|
|
35
35
|
import {
|
|
36
36
|
packSection
|
|
37
37
|
} from "./chunk-C2TS5MER.js";
|
|
38
38
|
import {
|
|
39
39
|
resolveStorageSigner
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-OWCCOKOP.js";
|
|
41
41
|
import {
|
|
42
42
|
createSlotAccountSigner,
|
|
43
43
|
requestResourceAllocation
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
STALE_SESSION_MESSAGE,
|
|
47
47
|
getPeopleChainEndpoints,
|
|
48
48
|
hasPersistedSession
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-6C3JLASN.js";
|
|
50
50
|
import {
|
|
51
51
|
CLI_NAME
|
|
52
52
|
} from "./chunk-TSPERKUS.js";
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
parseDomainName,
|
|
63
63
|
popStatusName,
|
|
64
64
|
verifyNonceAdvanced
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-SY2KD7SN.js";
|
|
66
66
|
import {
|
|
67
67
|
derivePoolAccounts,
|
|
68
68
|
detectTestnet,
|
|
@@ -77,13 +77,13 @@ import {
|
|
|
77
77
|
getPopSelfServeConfig,
|
|
78
78
|
loadEnvironments,
|
|
79
79
|
resolveEndpoints
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-7CHUI4JX.js";
|
|
81
81
|
import {
|
|
82
82
|
NonRetryableError
|
|
83
83
|
} from "./chunk-ZOC4GITL.js";
|
|
84
84
|
import {
|
|
85
85
|
ChainHealthSampler
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-466FDICA.js";
|
|
87
87
|
import {
|
|
88
88
|
VERSION,
|
|
89
89
|
captureWarning,
|
|
@@ -97,7 +97,7 @@ import {
|
|
|
97
97
|
truncateAddress,
|
|
98
98
|
withDeploySpan,
|
|
99
99
|
withSpan
|
|
100
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-BBPA3Q5K.js";
|
|
101
101
|
|
|
102
102
|
// src/merkle.ts
|
|
103
103
|
import * as fs2 from "fs";
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
} from "./chunk-5FLTDWWP.js";
|
|
5
5
|
import {
|
|
6
6
|
DOT_PRODUCT_ID
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6C3JLASN.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_MNEMONIC
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SY2KD7SN.js";
|
|
11
11
|
|
|
12
12
|
// src/deploy-actors.ts
|
|
13
13
|
var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VSLW6WXT.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId,
|
|
9
9
|
resolveIssueRepoSlug
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BBPA3Q5K.js";
|
|
11
11
|
import {
|
|
12
12
|
package_default
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XFXTMHZX.js";
|
|
14
14
|
|
|
15
15
|
// src/bug-report.ts
|
|
16
16
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
} from "./chunk-KJVRJOKC.js";
|
|
7
7
|
import {
|
|
8
8
|
validateContractAddresses
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7CHUI4JX.js";
|
|
10
10
|
import {
|
|
11
11
|
NonRetryableError
|
|
12
12
|
} from "./chunk-ZOC4GITL.js";
|
|
13
13
|
import {
|
|
14
14
|
ChainHealthSampler
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-466FDICA.js";
|
|
16
16
|
import {
|
|
17
17
|
captureWarning,
|
|
18
18
|
markCodePath,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
setDeploySentryTag,
|
|
21
21
|
truncateAddress,
|
|
22
22
|
withSpan
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-BBPA3Q5K.js";
|
|
24
24
|
|
|
25
25
|
// src/dotns.ts
|
|
26
26
|
import crypto from "crypto";
|
|
@@ -143,6 +143,7 @@ var TX_TIMEOUT_MS = 9e4;
|
|
|
143
143
|
var TX_CHAIN_TIME_BUDGET_MS = 18e4;
|
|
144
144
|
var TX_WALL_CLOCK_CEILING_MS = 24e4;
|
|
145
145
|
var TX_NO_PROGRESS_MS = 9e4;
|
|
146
|
+
var PHONE_APPROVAL_MS = 9e4;
|
|
146
147
|
var DOTNS_BEST_BLOCK_GRACE_MS = parseInt(process.env.BULLETIN_DOTNS_BESTBLOCK_GRACE_MS ?? "60000", 10);
|
|
147
148
|
var WS_HEARTBEAT_TIMEOUT_MS = 3e5;
|
|
148
149
|
var DOTNS_TX_MAX_ATTEMPTS = 3;
|
|
@@ -174,12 +175,15 @@ function classifyTxRetryDecision(err) {
|
|
|
174
175
|
if (lower.includes("transaction watcher silent")) return "retry";
|
|
175
176
|
return "abort";
|
|
176
177
|
}
|
|
178
|
+
var PhoneSilenceNonRetryableError = class extends NonRetryableError {
|
|
179
|
+
};
|
|
177
180
|
function classifyWatcherSilentFastFail(err, isPhoneSigner) {
|
|
178
181
|
if (err instanceof WatcherSilentNoEventError && isPhoneSigner === true) {
|
|
179
|
-
return new
|
|
182
|
+
return new PhoneSilenceNonRetryableError("No signature received from the phone \u2014 re-run when you can approve on your phone.");
|
|
180
183
|
}
|
|
181
184
|
return null;
|
|
182
185
|
}
|
|
186
|
+
var PHONE_SILENCE_MAX_REARMS = 3;
|
|
183
187
|
var DOTNS_RETRY_BASE_MS = 400;
|
|
184
188
|
var DOTNS_RETRY_MAX_MS = 6e3;
|
|
185
189
|
function dotnsRetryBackoffMs(attempt, rand = Math.random) {
|
|
@@ -236,7 +240,7 @@ function makeRetryStatusFilter(sink) {
|
|
|
236
240
|
}
|
|
237
241
|
var DEFAULT_MNEMONIC = "bottom drive obey lake curtain smoke basket hold race lonely fit walk";
|
|
238
242
|
var DEFAULT_TLD = "dot";
|
|
239
|
-
var KNOWN_TLDS = ["dot", "paseo", "test"];
|
|
243
|
+
var KNOWN_TLDS = ["dot", "paseo", "test", "testnet"];
|
|
240
244
|
function normalizeOnChainTld(raw) {
|
|
241
245
|
return raw.startsWith(".") ? raw.slice(1) : raw;
|
|
242
246
|
}
|
|
@@ -418,7 +422,7 @@ var PUBLISHER_ABI = [
|
|
|
418
422
|
];
|
|
419
423
|
var PublisherNotSupportedError = class extends Error {
|
|
420
424
|
constructor(envName) {
|
|
421
|
-
super(`Publisher contract is not configured for environment '${envName}'. Use an env that has a deployed Publisher (currently:
|
|
425
|
+
super(`Publisher contract is not configured for environment '${envName}'. Use an env that has a deployed Publisher (currently: PCF-devnet).`);
|
|
422
426
|
this.name = "PublisherNotSupportedError";
|
|
423
427
|
}
|
|
424
428
|
};
|
|
@@ -572,6 +576,19 @@ function convertWeiToNative(weiValue) {
|
|
|
572
576
|
function computeDomainTokenId(label, tld = DEFAULT_TLD) {
|
|
573
577
|
return BigInt(namehash(`${label}.${tld}`));
|
|
574
578
|
}
|
|
579
|
+
function computeSubnodeIds(sublabel, parentLabel, tld = DEFAULT_TLD) {
|
|
580
|
+
return {
|
|
581
|
+
parentNode: namehash(`${parentLabel}.${tld}`),
|
|
582
|
+
subnode: namehash(`${sublabel}.${parentLabel}.${tld}`)
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
function assertNotZeroRecipient(toH160, fullName) {
|
|
586
|
+
if (toH160.toLowerCase() === zeroAddress) {
|
|
587
|
+
throw new Error(
|
|
588
|
+
`Refusing to transfer ${fullName} to the zero address (${zeroAddress}): this would permanently burn it \u2014 there is no owner to recover it from afterward. Pass a real recipient with --to <0xH160>.`
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
575
592
|
function countTrailingDigits(label) {
|
|
576
593
|
let count = 0;
|
|
577
594
|
for (let i = label.length - 1; i >= 0; i--) {
|
|
@@ -914,10 +931,11 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
914
931
|
let lastEventType = "(none)";
|
|
915
932
|
let startChainTimeMs = null;
|
|
916
933
|
let bestBlockIncluded = false;
|
|
934
|
+
const silenceDeadlineMs = opts.isPhoneSigner === true ? PHONE_APPROVAL_MS : TX_NO_PROGRESS_MS;
|
|
917
935
|
const graceRawEnv = process.env.BULLETIN_DOTNS_BESTBLOCK_GRACE_MS;
|
|
918
936
|
const bestBlockGraceMs = Math.min(
|
|
919
937
|
graceRawEnv != null && graceRawEnv !== "" ? parseInt(graceRawEnv, 10) : DOTNS_BEST_BLOCK_GRACE_MS,
|
|
920
|
-
|
|
938
|
+
silenceDeadlineMs - 5e3
|
|
921
939
|
);
|
|
922
940
|
const poll = async () => {
|
|
923
941
|
if (settled) return;
|
|
@@ -962,7 +980,7 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
962
980
|
return;
|
|
963
981
|
}
|
|
964
982
|
const silentMs = Date.now() - lastEventAt;
|
|
965
|
-
if (silentMs >
|
|
983
|
+
if (silentMs > silenceDeadlineMs) {
|
|
966
984
|
statusCallback("failed");
|
|
967
985
|
if (lastEventType === "(none)") {
|
|
968
986
|
finish(reject)(new WatcherSilentNoEventError(silentMs));
|
|
@@ -1887,7 +1905,7 @@ var DotNS = class _DotNS {
|
|
|
1887
1905
|
if (phoneLabel !== void 0) {
|
|
1888
1906
|
await this._awaitPhoneReady(phoneLabel);
|
|
1889
1907
|
}
|
|
1890
|
-
|
|
1908
|
+
const submitOnce = () => withTimeout(
|
|
1891
1909
|
this.clientWrapper.submitTransaction(contractAddress, value, encodedCallData, this.substrateAddress, this.signer, statusCallback, {
|
|
1892
1910
|
rpcs,
|
|
1893
1911
|
useNoncePolling,
|
|
@@ -1902,11 +1920,26 @@ var DotNS = class _DotNS {
|
|
|
1902
1920
|
// your phone / Press Y") before re-signing. Both _awaitPhoneReady and the
|
|
1903
1921
|
// retry-loop guard no-op for non-phone signers (local/dev workers).
|
|
1904
1922
|
isPhoneSigner: this._isPhoneSigner,
|
|
1905
|
-
|
|
1923
|
+
// #194: thread the re-arm `reason` (undefined/"resign" for the #971
|
|
1924
|
+
// verifyEffect-false-negative case, "silence" for the watcher-silence
|
|
1925
|
+
// re-arm below) through to _awaitPhoneReady so confirmPhoneReady's
|
|
1926
|
+
// consumer can render the right prompt for each case.
|
|
1927
|
+
onResign: phoneLabel !== void 0 ? (_attempt, reason) => this._awaitPhoneReady(phoneLabel, reason) : void 0
|
|
1906
1928
|
}),
|
|
1907
1929
|
OPERATION_TIMEOUT_MS,
|
|
1908
1930
|
functionName
|
|
1909
1931
|
);
|
|
1932
|
+
if (phoneLabel === void 0 || !this._isPhoneSigner) return await submitOnce();
|
|
1933
|
+
const maxAttempts = 1 + PHONE_SILENCE_MAX_REARMS;
|
|
1934
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1935
|
+
try {
|
|
1936
|
+
return await submitOnce();
|
|
1937
|
+
} catch (e) {
|
|
1938
|
+
if (!(e instanceof PhoneSilenceNonRetryableError) || attempt === maxAttempts) throw e;
|
|
1939
|
+
await this._awaitPhoneReady(phoneLabel, "silence");
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
throw new Error("contractTransaction: unreachable \u2014 phone-silence re-arm loop exited without resolving");
|
|
1910
1943
|
}
|
|
1911
1944
|
async checkOwnership(label, ownerAddress = null) {
|
|
1912
1945
|
this.ensureConnected();
|
|
@@ -1940,6 +1973,7 @@ var DotNS = class _DotNS {
|
|
|
1940
1973
|
}) {
|
|
1941
1974
|
this.ensureConnected();
|
|
1942
1975
|
const validated = validateDomainLabel(label);
|
|
1976
|
+
assertNotZeroRecipient(toH160, `${validated}.${this._tld}`);
|
|
1943
1977
|
const tokenId = computeDomainTokenId(validated, this._tld);
|
|
1944
1978
|
const owner = await withTimeout(this.contractCall(this._contracts.DOTNS_REGISTRAR, DOTNS_REGISTRAR_TRANSFER_ABI, "ownerOf", [tokenId]), 3e4, "ownerOf");
|
|
1945
1979
|
if (owner.toLowerCase() === toH160.toLowerCase()) {
|
|
@@ -1964,6 +1998,71 @@ var DotNS = class _DotNS {
|
|
|
1964
1998
|
}
|
|
1965
1999
|
return { status: "ok", txHash: txRes.kind === TX_KIND_HASH ? txRes.hash : void 0, feeWei };
|
|
1966
2000
|
}
|
|
2001
|
+
/** Reassign an existing subname (e.g. `app.foo.<tld>`) to `toH160`.
|
|
2002
|
+
*
|
|
2003
|
+
* Subnames are NOT ERC-721 tokens, so they cannot go through
|
|
2004
|
+
* transferName/transferFrom — the registrar has no token for them. Instead
|
|
2005
|
+
* the *parent-domain* owner reassigns a subname via the registry's
|
|
2006
|
+
* setSubnodeOwner (the same call registerSubdomain uses to create it).
|
|
2007
|
+
* Authorisation is on parent ownership, not on the subname's current owner,
|
|
2008
|
+
* so the connected signer must own `${parentLabel}.${this._tld}`. Idempotent:
|
|
2009
|
+
* a no-op when the recipient already owns it.
|
|
2010
|
+
*
|
|
2011
|
+
* Every node here is derived via `namehash(\`...${this._tld}\`)` — the same
|
|
2012
|
+
* this._tld-templated convention as every other call site (see the comment
|
|
2013
|
+
* above computeDomainTokenId, ~line 1098) — deliberately NOT a hardcoded
|
|
2014
|
+
* ".dot" suffix. A second, manually-hardcoded node-derivation path is
|
|
2015
|
+
* exactly the bug class that burned production once already (registering
|
|
2016
|
+
* "ssoqedtuwf.paseo" minted namehash("ssoqedtuwf.paseo") but a hardcoded
|
|
2017
|
+
* ".dot" lookup queried namehash("ssoqedtuwf.dot") and reverted with
|
|
2018
|
+
* ERC721NonexistentToken after an 11 PAS mint had already succeeded). */
|
|
2019
|
+
async transferSubname(sublabel, parentLabel, toH160, statusCallback = () => {
|
|
2020
|
+
}) {
|
|
2021
|
+
this.ensureConnected();
|
|
2022
|
+
const fullName = `${sublabel}.${parentLabel}.${this._tld}`;
|
|
2023
|
+
assertNotZeroRecipient(toH160, fullName);
|
|
2024
|
+
const { parentNode, subnode } = computeSubnodeIds(sublabel, parentLabel, this._tld);
|
|
2025
|
+
const parentOwner = await withTimeout(
|
|
2026
|
+
this.contractCallNullable(this._contracts.DOTNS_REGISTRY, DOTNS_REGISTRY_ABI, "owner", [parentNode]),
|
|
2027
|
+
3e4,
|
|
2028
|
+
"owner"
|
|
2029
|
+
);
|
|
2030
|
+
if (!parentOwner || parentOwner === zeroAddress) {
|
|
2031
|
+
throw new Error(`Cannot transfer ${fullName}: parent ${parentLabel}.${this._tld} is not registered.`);
|
|
2032
|
+
}
|
|
2033
|
+
if (parentOwner.toLowerCase() !== this.evmAddress.toLowerCase()) {
|
|
2034
|
+
throw new Error(
|
|
2035
|
+
`Cannot transfer ${fullName}: it is a subname, which only the owner of the parent ${parentLabel}.${this._tld} can reassign (subnames are not transferable tokens). Parent is owned by ${parentOwner}, but the signer is ${this.evmAddress}. Sign as the parent owner (e.g. pass its --mnemonic).`
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
2038
|
+
const current = await withTimeout(
|
|
2039
|
+
this.contractCallNullable(this._contracts.DOTNS_REGISTRY, DOTNS_REGISTRY_ABI, "owner", [subnode]),
|
|
2040
|
+
3e4,
|
|
2041
|
+
"owner"
|
|
2042
|
+
);
|
|
2043
|
+
if (current && current.toLowerCase() === toH160.toLowerCase()) {
|
|
2044
|
+
statusCallback("already owned by recipient");
|
|
2045
|
+
return { status: "skipped-already-owned" };
|
|
2046
|
+
}
|
|
2047
|
+
const subnodeRecord = { parentNode, subLabel: sublabel, parentLabel, owner: toH160 };
|
|
2048
|
+
const txRes = await this.contractTransaction(
|
|
2049
|
+
this._contracts.DOTNS_REGISTRY,
|
|
2050
|
+
0n,
|
|
2051
|
+
DOTNS_REGISTRY_ABI,
|
|
2052
|
+
"setSubnodeOwner",
|
|
2053
|
+
[subnodeRecord],
|
|
2054
|
+
statusCallback
|
|
2055
|
+
);
|
|
2056
|
+
const after = await withTimeout(
|
|
2057
|
+
this.contractCallNullable(this._contracts.DOTNS_REGISTRY, DOTNS_REGISTRY_ABI, "owner", [subnode]),
|
|
2058
|
+
3e4,
|
|
2059
|
+
"owner"
|
|
2060
|
+
);
|
|
2061
|
+
if (!after || after.toLowerCase() !== toH160.toLowerCase()) {
|
|
2062
|
+
throw new Error(`Transfer of ${fullName} did not land: owner is ${after ?? "unset"}, expected ${toH160}.`);
|
|
2063
|
+
}
|
|
2064
|
+
return { status: "ok", txHash: txRes.kind === TX_KIND_HASH ? txRes.hash : void 0 };
|
|
2065
|
+
}
|
|
1967
2066
|
async getUserPopStatus(ownerAddress = null) {
|
|
1968
2067
|
if (this._userPopStatusOverrideForTest !== null) {
|
|
1969
2068
|
const result = this._userPopStatusOverrideForTest;
|
|
@@ -1988,7 +2087,7 @@ var DotNS = class _DotNS {
|
|
|
1988
2087
|
async checkSubdomainOwnership(sublabel, parentLabel) {
|
|
1989
2088
|
this.ensureConnected();
|
|
1990
2089
|
if (!this.clientWrapper) return { owned: false, owner: null };
|
|
1991
|
-
const node =
|
|
2090
|
+
const { subnode: node } = computeSubnodeIds(sublabel, parentLabel, this._tld);
|
|
1992
2091
|
try {
|
|
1993
2092
|
const owner = await withTimeout(this.contractCallNullable(this._contracts.DOTNS_REGISTRY, DOTNS_REGISTRY_ABI, "owner", [node]), 3e4, "owner");
|
|
1994
2093
|
if (!owner || owner === zeroAddress) return { owned: false, owner: null };
|
|
@@ -2003,8 +2102,7 @@ var DotNS = class _DotNS {
|
|
|
2003
2102
|
this.ensureConnected();
|
|
2004
2103
|
console.log(`
|
|
2005
2104
|
Registering subdomain ${sublabel}.${parentLabel}.${this._tld}...`);
|
|
2006
|
-
const parentNode =
|
|
2007
|
-
const subnodeNode = namehash(`${sublabel}.${parentLabel}.${this._tld}`);
|
|
2105
|
+
const { parentNode, subnode: subnodeNode } = computeSubnodeIds(sublabel, parentLabel, this._tld);
|
|
2008
2106
|
const subnodeRecord = { parentNode, subLabel: sublabel, parentLabel, owner: this.evmAddress };
|
|
2009
2107
|
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
2010
2108
|
const POLL_INTERVAL_MS = 2e3;
|
|
@@ -3198,13 +3296,18 @@ var DotNS = class _DotNS {
|
|
|
3198
3296
|
* in-process).
|
|
3199
3297
|
* After the gate resolves, fires onPhoneSigningRequired (the "check your
|
|
3200
3298
|
* phone" notification) so the user knows the request is now being sent.
|
|
3299
|
+
*
|
|
3300
|
+
* `reason` (#194): passed straight through to confirmPhoneReady's context so
|
|
3301
|
+
* the consumer can distinguish a watcher-silence re-arm ("silence") from the
|
|
3302
|
+
* pre-existing verifyEffect-false-negative re-sign case (undefined/"resign",
|
|
3303
|
+
* which keeps rendering off `attempt` as before).
|
|
3201
3304
|
*/
|
|
3202
|
-
async _awaitPhoneReady(label) {
|
|
3305
|
+
async _awaitPhoneReady(label, reason) {
|
|
3203
3306
|
if (!this._isPhoneSigner) return;
|
|
3204
3307
|
const attempt = (this._phoneSignatureAttempts.get(label) ?? 0) + 1;
|
|
3205
3308
|
this._phoneSignatureAttempts.set(label, attempt);
|
|
3206
3309
|
if (this._confirmPhoneReady) {
|
|
3207
|
-
await this._confirmPhoneReady({ label, attempt, total: this._phoneSignatureTotal });
|
|
3310
|
+
await this._confirmPhoneReady({ label, attempt, total: this._phoneSignatureTotal, approvalBudgetMs: PHONE_APPROVAL_MS, reason });
|
|
3208
3311
|
}
|
|
3209
3312
|
this._onPhoneSigningRequired?.(label);
|
|
3210
3313
|
}
|
|
@@ -3252,6 +3355,7 @@ export {
|
|
|
3252
3355
|
TX_CHAIN_TIME_BUDGET_MS,
|
|
3253
3356
|
TX_WALL_CLOCK_CEILING_MS,
|
|
3254
3357
|
TX_NO_PROGRESS_MS,
|
|
3358
|
+
PHONE_APPROVAL_MS,
|
|
3255
3359
|
DOTNS_BEST_BLOCK_GRACE_MS,
|
|
3256
3360
|
WS_HEARTBEAT_TIMEOUT_MS,
|
|
3257
3361
|
DOTNS_TX_MAX_ATTEMPTS,
|
|
@@ -3261,7 +3365,9 @@ export {
|
|
|
3261
3365
|
NONCE_ADVANCE_VERIFY_RETRY_INTERVAL_MS,
|
|
3262
3366
|
verifyEffectWithGrace,
|
|
3263
3367
|
classifyTxRetryDecision,
|
|
3368
|
+
PhoneSilenceNonRetryableError,
|
|
3264
3369
|
classifyWatcherSilentFastFail,
|
|
3370
|
+
PHONE_SILENCE_MAX_REARMS,
|
|
3265
3371
|
dotnsRetryBackoffMs,
|
|
3266
3372
|
withRetry,
|
|
3267
3373
|
shouldRetryTxAttempt,
|
|
@@ -3289,6 +3395,8 @@ export {
|
|
|
3289
3395
|
__formatContractDryRunFailureForTest,
|
|
3290
3396
|
convertWeiToNative,
|
|
3291
3397
|
computeDomainTokenId,
|
|
3398
|
+
computeSubnodeIds,
|
|
3399
|
+
assertNotZeroRecipient,
|
|
3292
3400
|
countTrailingDigits,
|
|
3293
3401
|
stripTrailingDigits,
|
|
3294
3402
|
sanitizeDomainLabel,
|
|
@@ -9,19 +9,19 @@ import {
|
|
|
9
9
|
setBulletinEndpoints,
|
|
10
10
|
storeDirectory,
|
|
11
11
|
storeFile
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OORLC7SM.js";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_TLD,
|
|
15
15
|
DotNS,
|
|
16
16
|
TX_KIND_SKIPPED,
|
|
17
17
|
stripTldSuffix
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SY2KD7SN.js";
|
|
19
19
|
import {
|
|
20
20
|
DEFAULT_ENV_ID,
|
|
21
21
|
getPopSelfServeConfig,
|
|
22
22
|
loadEnvironments,
|
|
23
23
|
resolveEndpoints
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-7CHUI4JX.js";
|
|
25
25
|
import {
|
|
26
26
|
NonRetryableError
|
|
27
27
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
setDeployAttribute,
|
|
30
30
|
withManifestSpan,
|
|
31
31
|
withSpan
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-BBPA3Q5K.js";
|
|
33
33
|
|
|
34
34
|
// src/manifest/publish.ts
|
|
35
35
|
import * as fs from "fs/promises";
|
|
@@ -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.
|
|
9
|
+
version: "0.16.0-rc.2",
|
|
10
10
|
private: false,
|
|
11
11
|
repository: {
|
|
12
12
|
type: "git",
|
|
@@ -56,7 +56,7 @@ var package_default = {
|
|
|
56
56
|
"refresh-environments": "node scripts/refresh-environments.mjs",
|
|
57
57
|
postinstall: "patch-package || true",
|
|
58
58
|
prepare: "npm run build",
|
|
59
|
-
test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/chunk-sharing-report.test.js test/dotns-deployments-parser.test.js test/dotns-token-id.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js test/auth-config.test.js test/whoami.test.js test/login.test.js test/logout.test.js test/auth-resolve.test.js test/storage-signer.test.js test/spinner.test.js test/sss-allowance.test.js test/sss-allowance-cache.test.js test/dotns-transfer.test.js test/deploy-actors.test.js test/transfer-command.test.js test/dotns-register-fee.test.js test/deploy-label-ordering.test.js test/benign-teardown.test.js test/verify-baked-dsn.test.js test/test-release-retry-wrapper.js && npm run test:vendor",
|
|
59
|
+
test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/chunk-sharing-report.test.js test/dotns-deployments-parser.test.js test/dotns-token-id.test.js test/dotns-subnode-id.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js test/auth-config.test.js test/whoami.test.js test/login.test.js test/logout.test.js test/auth-resolve.test.js test/storage-signer.test.js test/spinner.test.js test/sss-allowance.test.js test/sss-allowance-cache.test.js test/dotns-transfer.test.js test/deploy-actors.test.js test/transfer-command.test.js test/dotns-register-fee.test.js test/deploy-label-ordering.test.js test/benign-teardown.test.js test/verify-baked-dsn.test.js test/test-release-retry-wrapper.js && npm run test:vendor",
|
|
60
60
|
"test:e2e": "npm run build && node --test test/e2e.test.js",
|
|
61
61
|
"test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
|
|
62
62
|
"test:e2e:pr": "bash scripts/e2e-pass.sh pr",
|