@parity/product-deploy 0.8.3-rc.8 → 0.9.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -201
- package/README.md +59 -2
- package/assets/environments.json +0 -1
- package/bin/bulletin-deploy +21 -1
- package/dist/auth/index.d.ts +2 -3
- package/dist/auth/index.js +2 -1
- package/dist/auth/vendor/index.d.ts +2 -3
- package/dist/auth/vendor/index.js +2 -1
- package/dist/auth/vendor/ui/index.d.ts +1 -2
- package/dist/auth-C-Pel0AT.d.ts +235 -0
- package/dist/auth-config.d.ts +30 -8
- package/dist/auth-config.js +14 -6
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-YXGNQZZF.js → chunk-2SR5D4CP.js} +19 -15
- package/dist/{chunk-OFVBJOFB.js → chunk-6NW5M3F5.js} +9 -20
- package/dist/{chunk-7DGFJC6E.js → chunk-DHY2ZXVZ.js} +81 -42
- package/dist/chunk-G56VYTUD.js +75 -0
- package/dist/{chunk-5K3RI5C2.js → chunk-GL3U7K2B.js} +0 -1
- package/dist/{chunk-327NAPBD.js → chunk-H4LWILH4.js} +32 -6
- package/dist/chunk-J7CYVTAW.js +43 -0
- package/dist/{chunk-WHMNBSG7.js → chunk-LCKLYFAZ.js} +5 -4
- package/dist/{chunk-3OWKSL7K.js → chunk-NP4SLURL.js} +1 -1
- package/dist/{chunk-T4PAK4YK.js → chunk-O2NWQLYB.js} +2 -2
- package/dist/{chunk-RPU72Z4B.js → chunk-RD2QHYTL.js} +242 -36
- package/dist/{chunk-EGNMZHMR.js → chunk-WZBAQCA5.js} +15 -4
- package/dist/{chunk-YOQLRCQV.js → chunk-YIKGVALU.js} +3 -3
- package/dist/chunk-probe.js +3 -3
- package/dist/commands/login.d.ts +34 -9
- package/dist/commands/login.js +186 -30
- package/dist/commands/logout.d.ts +1 -2
- package/dist/commands/logout.js +5 -3
- package/dist/commands/whoami.d.ts +1 -2
- package/dist/commands/whoami.js +7 -4
- package/dist/deploy.d.ts +19 -4
- package/dist/deploy.js +14 -9
- package/dist/dotns.d.ts +7 -0
- package/dist/dotns.js +4 -4
- package/dist/environments.js +1 -1
- package/dist/index.js +11 -10
- package/dist/manifest/publish.js +11 -10
- package/dist/manifest/types.d.ts +1 -1
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +10 -9
- package/dist/personhood/bootstrap.js +10 -10
- package/dist/personhood/people-client.js +4 -4
- package/dist/run-state.js +1 -1
- package/dist/{signer-CriGqahj.d.ts → signer-vR6KKC7V.d.ts} +1 -1
- package/dist/spinner.d.ts +21 -0
- package/dist/spinner.js +6 -0
- package/dist/sss-allowance.d.ts +29 -0
- package/dist/sss-allowance.js +8 -0
- package/dist/storage-signer.d.ts +94 -2
- package/dist/storage-signer.js +18 -9
- package/dist/telemetry.js +2 -2
- package/dist/version-check.d.ts +0 -3
- package/dist/version-check.js +3 -3
- package/package.json +19 -15
- package/dist/allocations-B65Is4Md.d.ts +0 -97
- package/dist/auth-DkRZBK-T.d.ts +0 -122
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkSSSAllowance
|
|
3
|
+
} from "./chunk-G56VYTUD.js";
|
|
1
4
|
import {
|
|
2
5
|
MirrorSkipped,
|
|
3
6
|
mirrorToGitHubPages,
|
|
@@ -24,28 +27,30 @@ import {
|
|
|
24
27
|
parseManifest
|
|
25
28
|
} from "./chunk-S7EM5VMW.js";
|
|
26
29
|
import {
|
|
27
|
-
DOT_DAPP_ID,
|
|
28
30
|
DOT_PRODUCT_ID,
|
|
31
|
+
STALE_SESSION_MESSAGE,
|
|
32
|
+
getPeopleChainEndpoints,
|
|
29
33
|
hasPersistedSession
|
|
30
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-H4LWILH4.js";
|
|
31
35
|
import {
|
|
32
36
|
setDeployContext
|
|
33
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-O2NWQLYB.js";
|
|
34
38
|
import {
|
|
35
39
|
probeChunks
|
|
36
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-NP4SLURL.js";
|
|
37
41
|
import {
|
|
38
42
|
packSection
|
|
39
43
|
} from "./chunk-C2TS5MER.js";
|
|
40
44
|
import {
|
|
41
45
|
DotNS,
|
|
46
|
+
PUBLISHER_ABI,
|
|
42
47
|
PublisherNotSupportedError,
|
|
43
48
|
TX_TIMEOUT_MS,
|
|
44
49
|
fetchNonce,
|
|
45
50
|
parseDomainName,
|
|
46
51
|
popStatusName,
|
|
47
52
|
verifyNonceAdvanced
|
|
48
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-WZBAQCA5.js";
|
|
49
54
|
import {
|
|
50
55
|
derivePoolAccounts,
|
|
51
56
|
detectTestnet,
|
|
@@ -67,13 +72,13 @@ import {
|
|
|
67
72
|
truncateAddress,
|
|
68
73
|
withDeploySpan,
|
|
69
74
|
withSpan
|
|
70
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-LCKLYFAZ.js";
|
|
71
76
|
import {
|
|
72
77
|
DEFAULT_ENV_ID,
|
|
73
78
|
getPopSelfServeConfig,
|
|
74
79
|
loadEnvironments,
|
|
75
80
|
resolveEndpoints
|
|
76
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-GL3U7K2B.js";
|
|
77
82
|
import {
|
|
78
83
|
NonRetryableError
|
|
79
84
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -104,6 +109,7 @@ import { base32 } from "multiformats/bases/base32";
|
|
|
104
109
|
import { base58btc } from "multiformats/bases/base58";
|
|
105
110
|
import * as dagPB from "@ipld/dag-pb";
|
|
106
111
|
import { UnixFS } from "ipfs-unixfs";
|
|
112
|
+
import { keccak256, toBytes } from "viem";
|
|
107
113
|
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
108
114
|
import { getPolkadotSigner as getPolkadotSigner2 } from "polkadot-api/signer";
|
|
109
115
|
import { sr25519CreateDerive as sr25519CreateDerive2 } from "@polkadot-labs/hdkd";
|
|
@@ -247,10 +253,80 @@ function extractBulletinSlotKey(outcomes) {
|
|
|
247
253
|
if (allocated?.tag !== "BulletInAllowance") continue;
|
|
248
254
|
const key = allocated.value?.slotAccountKey;
|
|
249
255
|
if (!(key instanceof Uint8Array)) continue;
|
|
250
|
-
return toHex(
|
|
256
|
+
return toHex(key);
|
|
251
257
|
}
|
|
252
258
|
return null;
|
|
253
259
|
}
|
|
260
|
+
var BulletinSlotAuthError = class extends Error {
|
|
261
|
+
reason;
|
|
262
|
+
/** The on-chain expiration block (only set when reason === "expired"). */
|
|
263
|
+
expiration;
|
|
264
|
+
constructor(reason, ss58, expiration) {
|
|
265
|
+
const detail = reason === "expired" && expiration != null ? `expired at block ${expiration}` : "no on-chain authorization found";
|
|
266
|
+
super(`Slot account ${ss58} not authorized on Bulletin (${detail})`);
|
|
267
|
+
this.reason = reason;
|
|
268
|
+
this.expiration = expiration;
|
|
269
|
+
this.name = "BulletinSlotAuthError";
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
function isBulletinAuthActive(auth, blockNumber) {
|
|
273
|
+
if (auth == null) return { active: false, reason: "missing" };
|
|
274
|
+
const exp = Number(auth.expiration ?? 0);
|
|
275
|
+
if (exp <= blockNumber) return { active: false, reason: "expired", expiration: exp };
|
|
276
|
+
return { active: true, expiration: exp };
|
|
277
|
+
}
|
|
278
|
+
async function pollUntilBulletinAuthorized(queryFn, opts = {}) {
|
|
279
|
+
const { pollMs = 2e3, timeoutMs = 9e4 } = opts;
|
|
280
|
+
const debug = Boolean(process.env.DOT_DEBUG);
|
|
281
|
+
const deadline = Date.now() + timeoutMs;
|
|
282
|
+
while (Date.now() < deadline) {
|
|
283
|
+
try {
|
|
284
|
+
const { auth, blockNumber } = await queryFn();
|
|
285
|
+
const result = isBulletinAuthActive(auth, blockNumber);
|
|
286
|
+
if (result.active) {
|
|
287
|
+
if (debug) console.error(`[auth-poll] active expiration=${result.expiration}`);
|
|
288
|
+
return { authorized: true, expiration: result.expiration };
|
|
289
|
+
}
|
|
290
|
+
if (debug) {
|
|
291
|
+
console.error(
|
|
292
|
+
`[auth-poll] not-active reason=${result.reason}` + (result.expiration != null ? ` expiration=${result.expiration}` : "")
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
} catch (e) {
|
|
296
|
+
if (debug) console.error(`[auth-poll] query-errored: ${e instanceof Error ? e.message : String(e)}`);
|
|
297
|
+
}
|
|
298
|
+
const remaining = deadline - Date.now();
|
|
299
|
+
if (remaining <= 0) break;
|
|
300
|
+
await new Promise((r) => setTimeout(r, Math.min(pollMs, remaining)));
|
|
301
|
+
}
|
|
302
|
+
return { authorized: false, reason: "timeout" };
|
|
303
|
+
}
|
|
304
|
+
async function waitForBulletinAuthorization(ss58, opts = {}) {
|
|
305
|
+
const { quiet, endpoints, ...pollOpts } = opts;
|
|
306
|
+
const eps = endpoints && endpoints.length > 0 ? endpoints : BULLETIN_ENDPOINTS;
|
|
307
|
+
const primary = eps[0];
|
|
308
|
+
const onStatusChanged = quiet ? () => {
|
|
309
|
+
} : makeBulletinStatusHandler(primary);
|
|
310
|
+
const client = createPolkadotClient(getWsProvider(
|
|
311
|
+
eps,
|
|
312
|
+
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS, onStatusChanged }
|
|
313
|
+
));
|
|
314
|
+
const unsafeApi = client.getUnsafeApi();
|
|
315
|
+
try {
|
|
316
|
+
return await pollUntilBulletinAuthorized(
|
|
317
|
+
async () => {
|
|
318
|
+
const [auth, block] = await Promise.all([
|
|
319
|
+
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum("Account", ss58)),
|
|
320
|
+
client.getFinalizedBlock()
|
|
321
|
+
]);
|
|
322
|
+
return { auth, blockNumber: block.number };
|
|
323
|
+
},
|
|
324
|
+
pollOpts
|
|
325
|
+
);
|
|
326
|
+
} finally {
|
|
327
|
+
client.destroy();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
254
330
|
async function getSlotSignerProvider(signer, ss58) {
|
|
255
331
|
const primary = BULLETIN_ENDPOINTS[0];
|
|
256
332
|
console.log(` Connecting to Bulletin (slot signer): ${primary}`);
|
|
@@ -263,12 +339,12 @@ async function getSlotSignerProvider(signer, ss58) {
|
|
|
263
339
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum("Account", ss58)),
|
|
264
340
|
client.getFinalizedBlock()
|
|
265
341
|
]);
|
|
266
|
-
const
|
|
267
|
-
if (!
|
|
342
|
+
const result = isBulletinAuthActive(auth, currentBlock.number);
|
|
343
|
+
if (!result.active) {
|
|
268
344
|
client.destroy();
|
|
269
|
-
throw new
|
|
345
|
+
throw new BulletinSlotAuthError(result.reason, ss58, result.expiration);
|
|
270
346
|
}
|
|
271
|
-
console.log(` Using slot signer: ${ss58} (authorized until block ${
|
|
347
|
+
console.log(` Using slot signer: ${ss58} (authorized until block ${result.expiration})`);
|
|
272
348
|
setDeployAttribute("deploy.signer.mode", "slot");
|
|
273
349
|
setDeployAttribute("deploy.signer.address", truncateAddress(ss58));
|
|
274
350
|
return { client, unsafeApi, signer, ss58 };
|
|
@@ -452,8 +528,41 @@ async function getDirectProvider(mnemonic, derivationPath = "") {
|
|
|
452
528
|
setDeployAttribute("deploy.signer.address", truncateAddress(ss58));
|
|
453
529
|
return { client, unsafeApi, signer, ss58 };
|
|
454
530
|
}
|
|
531
|
+
async function getSignerProvider(signer, ss58) {
|
|
532
|
+
const primary = BULLETIN_ENDPOINTS[0];
|
|
533
|
+
console.log(` Connecting to Bulletin: ${primary}`);
|
|
534
|
+
const client = createPolkadotClient2(getWsProvider2(
|
|
535
|
+
BULLETIN_ENDPOINTS,
|
|
536
|
+
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS, onStatusChanged: makeBulletinStatusHandler(primary) }
|
|
537
|
+
));
|
|
538
|
+
const unsafeApi = client.getUnsafeApi();
|
|
539
|
+
console.log(` Using external signer: ${ss58}`);
|
|
540
|
+
let [auth, currentBlock] = await Promise.all([
|
|
541
|
+
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
542
|
+
client.getFinalizedBlock()
|
|
543
|
+
]);
|
|
544
|
+
let now = currentBlock.number;
|
|
545
|
+
if (!auth || Number(auth.expiration ?? 0) <= now) {
|
|
546
|
+
try {
|
|
547
|
+
await ensureAuthorized(unsafeApi, ss58, "external signer");
|
|
548
|
+
[auth, currentBlock] = await Promise.all([
|
|
549
|
+
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
550
|
+
client.getFinalizedBlock()
|
|
551
|
+
]);
|
|
552
|
+
now = currentBlock.number;
|
|
553
|
+
} catch (e) {
|
|
554
|
+
client.destroy();
|
|
555
|
+
throw new NonRetryableError(`Account ${ss58} is not authorized for Bulletin storage and auto-authorization failed: ${e.message}`);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
console.log(` Authorization: expires at block ${Number(auth?.expiration ?? 0)} (current: ${now})`);
|
|
559
|
+
setDeployAttribute("deploy.signer.mode", "external");
|
|
560
|
+
setDeployAttribute("deploy.signer.address", truncateAddress(ss58));
|
|
561
|
+
return { client, unsafeApi, signer, ss58 };
|
|
562
|
+
}
|
|
455
563
|
function __selectStorageProviderModeForTest(options) {
|
|
456
564
|
if (options.storageSigner && options.storageSignerAddress) return "storageSigner";
|
|
565
|
+
if (options.signer && options.signerAddress) return "signer";
|
|
457
566
|
if (options.mnemonic) return "direct";
|
|
458
567
|
return "pool";
|
|
459
568
|
}
|
|
@@ -464,6 +573,10 @@ function chooseSignerInput(opts) {
|
|
|
464
573
|
if (opts.hasSession) return "resolve";
|
|
465
574
|
return "pool";
|
|
466
575
|
}
|
|
576
|
+
function formatStorageSignerLine(slotAddress, failReason) {
|
|
577
|
+
if (slotAddress) return ` Storage signer: allowance slot ${slotAddress}`;
|
|
578
|
+
return ` Storage signer: pool fallback (${failReason ?? "no session"})`;
|
|
579
|
+
}
|
|
467
580
|
function selectStorageReconnect(options) {
|
|
468
581
|
if (options.storageSigner && options.storageSignerAddress) {
|
|
469
582
|
let useSlot = true;
|
|
@@ -471,13 +584,26 @@ function selectStorageReconnect(options) {
|
|
|
471
584
|
if (!useSlot) return getProvider();
|
|
472
585
|
try {
|
|
473
586
|
return await getSlotSignerProvider(options.storageSigner, options.storageSignerAddress);
|
|
474
|
-
} catch {
|
|
587
|
+
} catch (e) {
|
|
475
588
|
useSlot = false;
|
|
476
589
|
setDeployAttribute("deploy.signer.mode", "pool-fallback");
|
|
590
|
+
let reason;
|
|
591
|
+
if (e instanceof BulletinSlotAuthError) {
|
|
592
|
+
reason = e.reason === "expired" && e.expiration != null ? `expired at block ${e.expiration}` : "no on-chain authorization found";
|
|
593
|
+
} else {
|
|
594
|
+
reason = e instanceof Error ? e.message : String(e);
|
|
595
|
+
}
|
|
596
|
+
console.warn(
|
|
597
|
+
`\u26A0 Bulletin allowance slot not usable: ${reason}
|
|
598
|
+
Falling back to the shared pool account for storage (fine on testnet).
|
|
599
|
+
To use your own allowance, run: bulletin-deploy logout && bulletin-deploy login`
|
|
600
|
+
);
|
|
477
601
|
return getProvider();
|
|
478
602
|
}
|
|
479
603
|
};
|
|
480
604
|
}
|
|
605
|
+
if (options.signer && options.signerAddress)
|
|
606
|
+
return () => getSignerProvider(options.signer, options.signerAddress);
|
|
481
607
|
if (options.mnemonic)
|
|
482
608
|
return () => getDirectProvider(options.mnemonic, options.derivationPath);
|
|
483
609
|
return () => getProvider();
|
|
@@ -1687,8 +1813,7 @@ async function publish(dotns, parsed, failOnError) {
|
|
|
1687
1813
|
setDeployAttribute("deploy.publish.status", "failed");
|
|
1688
1814
|
if (failOnError) throw e;
|
|
1689
1815
|
const msg = e?.message ?? String(e);
|
|
1690
|
-
console.
|
|
1691
|
-
captureWarning("publish failed", { error: msg.slice(0, 200) });
|
|
1816
|
+
console.log(` Publish failed: ${msg}`);
|
|
1692
1817
|
}
|
|
1693
1818
|
}
|
|
1694
1819
|
async function unpublish(domainName, options = {}) {
|
|
@@ -1830,36 +1955,56 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1830
1955
|
} catch (e) {
|
|
1831
1956
|
if (options.suri) throw e;
|
|
1832
1957
|
if (e?.name === "SignerNotAvailableError") {
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1958
|
+
if (hasSession) {
|
|
1959
|
+
console.error(STALE_SESSION_MESSAGE);
|
|
1960
|
+
} else {
|
|
1961
|
+
console.log(
|
|
1962
|
+
" Login session unavailable or expired \u2014 falling back to pool. Run `bulletin-deploy login` to use your identity."
|
|
1963
|
+
);
|
|
1964
|
+
}
|
|
1836
1965
|
} else {
|
|
1837
1966
|
throw e;
|
|
1838
1967
|
}
|
|
1839
1968
|
}
|
|
1840
1969
|
}
|
|
1970
|
+
if (resolvedUserSession && options.signer) {
|
|
1971
|
+
try {
|
|
1972
|
+
const productPubkey = options.signer.publicKey;
|
|
1973
|
+
const peopleEndpoints = await getPeopleChainEndpoints(envId);
|
|
1974
|
+
const allowed = await checkSSSAllowance(productPubkey, peopleEndpoints);
|
|
1975
|
+
if (allowed === false) {
|
|
1976
|
+
throw new NonRetryableError(
|
|
1977
|
+
"Session signing allowance has expired (~2-3 days after login). Run `bulletin-deploy login` to renew."
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
} catch (e) {
|
|
1981
|
+
if (e instanceof NonRetryableError) throw e;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1841
1984
|
if (!options.storageSigner) {
|
|
1985
|
+
let storageLine = null;
|
|
1842
1986
|
try {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
const
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
resolvedUserSession.userSession,
|
|
1849
|
-
DOT_PRODUCT_ID,
|
|
1850
|
-
[{ tag: "BulletInAllowance", value: void 0 }]
|
|
1987
|
+
if (resolvedUserSession?.userSession && resolvedUserSession?.adapter) {
|
|
1988
|
+
const { ss58Encode } = await import("@parity/product-sdk-address");
|
|
1989
|
+
const signerResult = await resolvedUserSession.adapter.allowance.getBulletinSigner(
|
|
1990
|
+
resolvedUserSession.userSession.id,
|
|
1991
|
+
DOT_PRODUCT_ID
|
|
1851
1992
|
);
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1993
|
+
if (signerResult.isOk()) {
|
|
1994
|
+
const slotSigner = signerResult.value;
|
|
1995
|
+
const slotAddress = ss58Encode(slotSigner.publicKey);
|
|
1996
|
+
options = { ...options, storageSigner: slotSigner, storageSignerAddress: slotAddress };
|
|
1997
|
+
storageLine = formatStorageSignerLine(slotAddress);
|
|
1998
|
+
} else {
|
|
1999
|
+
storageLine = formatStorageSignerLine(null, signerResult.error.reason);
|
|
1856
2000
|
}
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
options = { ...options, storageSigner: slotResult.signer, storageSignerAddress: slotResult.ss58 };
|
|
2001
|
+
} else {
|
|
2002
|
+
storageLine = formatStorageSignerLine(null);
|
|
1860
2003
|
}
|
|
1861
2004
|
} catch {
|
|
2005
|
+
storageLine = formatStorageSignerLine(null, "error");
|
|
1862
2006
|
}
|
|
2007
|
+
if (storageLine) console.log(storageLine);
|
|
1863
2008
|
}
|
|
1864
2009
|
initTelemetry();
|
|
1865
2010
|
const randomSuffix = Math.floor(Math.random() * 100).toString().padStart(2, "0");
|
|
@@ -1894,6 +2039,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1894
2039
|
const reconnect = selectStorageReconnect(options);
|
|
1895
2040
|
let dotnsPreflight = null;
|
|
1896
2041
|
let previousContenthashCid = null;
|
|
2042
|
+
let preflightPublishNeeded = false;
|
|
1897
2043
|
try {
|
|
1898
2044
|
console.log("\n" + "=".repeat(60));
|
|
1899
2045
|
console.log("Preflight");
|
|
@@ -1919,10 +2065,34 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1919
2065
|
}
|
|
1920
2066
|
console.log(` Mode: subdomain (parent ${parsed.parentLabel}.dot owned by signer)`);
|
|
1921
2067
|
} else {
|
|
2068
|
+
preflightPublishNeeded = false;
|
|
1922
2069
|
try {
|
|
1923
2070
|
dotnsPreflight = await preflight.preflight(name);
|
|
1924
2071
|
previousContenthashCid = await readPreviousContenthashSafe(preflight, name);
|
|
1925
2072
|
setDeployAttribute("deploy.incremental", previousContenthashCid ? "true" : "false");
|
|
2073
|
+
if (options.publish && parsed && !parsed.isSubdomain) {
|
|
2074
|
+
const publisher = preflight._contracts?.PUBLISHER;
|
|
2075
|
+
const zeroAddr = "0x0000000000000000000000000000000000000000";
|
|
2076
|
+
if (!publisher || publisher === zeroAddr) {
|
|
2077
|
+
console.log(` Publish: not supported on this environment \u2014 will be skipped`);
|
|
2078
|
+
} else {
|
|
2079
|
+
const labelhash = keccak256(toBytes(name));
|
|
2080
|
+
try {
|
|
2081
|
+
const alreadyPublished = await preflight.contractCall(
|
|
2082
|
+
publisher,
|
|
2083
|
+
PUBLISHER_ABI,
|
|
2084
|
+
"isPublished",
|
|
2085
|
+
[labelhash]
|
|
2086
|
+
);
|
|
2087
|
+
preflightPublishNeeded = !alreadyPublished;
|
|
2088
|
+
if (!preflightPublishNeeded) {
|
|
2089
|
+
console.log(` Publish: already published \u2014 will be skipped`);
|
|
2090
|
+
}
|
|
2091
|
+
} catch {
|
|
2092
|
+
preflightPublishNeeded = true;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
1926
2096
|
} finally {
|
|
1927
2097
|
preflight.disconnect();
|
|
1928
2098
|
}
|
|
@@ -1944,6 +2114,20 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1944
2114
|
);
|
|
1945
2115
|
}
|
|
1946
2116
|
}
|
|
2117
|
+
if (options.signer && options.signerAddress) {
|
|
2118
|
+
const steps = computePhoneSigningSteps(dotnsPreflight, preflightPublishNeeded);
|
|
2119
|
+
if (steps.length === 1) {
|
|
2120
|
+
console.log(`
|
|
2121
|
+
\u{1F4F1} Have your phone ready \u2014 1 signature needed (${steps[0].toLowerCase()})`);
|
|
2122
|
+
} else if (steps.length > 1) {
|
|
2123
|
+
const display = steps.flatMap(
|
|
2124
|
+
(s, i) => s === "Register" && steps[i - 1] === "Commitment" ? ["(wait)", s] : [s]
|
|
2125
|
+
);
|
|
2126
|
+
console.log(`
|
|
2127
|
+
\u{1F4F1} Have your phone ready \u2014 ${steps.length} signatures needed`);
|
|
2128
|
+
console.log(` ${display.map((s) => s.toLowerCase()).join(" \xB7 ")}`);
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
1947
2131
|
provider = await reconnect();
|
|
1948
2132
|
const providerWithReconnect = { ...provider, reconnect };
|
|
1949
2133
|
const isTestnet = await detectTestnet(provider.unsafeApi);
|
|
@@ -2128,7 +2312,11 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2128
2312
|
console.log("=".repeat(60));
|
|
2129
2313
|
await withSpan("deploy.dotns", "2. dotns", { "deploy.domain": name, "deploy.subdomain": String(parsed?.isSubdomain ?? false) }, async () => {
|
|
2130
2314
|
const dotns = new DotNS();
|
|
2131
|
-
await dotns.connect(
|
|
2315
|
+
await dotns.connect({
|
|
2316
|
+
...resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit),
|
|
2317
|
+
...options.signer && options.signerAddress ? { onPhoneSigningRequired: (label) => console.log(`
|
|
2318
|
+
Check your phone \u2192 ${label}`) } : {}
|
|
2319
|
+
});
|
|
2132
2320
|
if (parsed?.isSubdomain) {
|
|
2133
2321
|
const { owned, owner } = await dotns.checkSubdomainOwnership(parsed.sublabel, parsed.parentLabel);
|
|
2134
2322
|
if (owned) {
|
|
@@ -2153,7 +2341,9 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2153
2341
|
const contenthashHex = `0x${encodeContenthash(cid)}`;
|
|
2154
2342
|
await dotns.setContenthash(name, contenthashHex);
|
|
2155
2343
|
if (options.publish && parsed) {
|
|
2156
|
-
|
|
2344
|
+
if (preflightPublishNeeded !== false) {
|
|
2345
|
+
await publish(dotns, parsed, options.failOnPublishError);
|
|
2346
|
+
}
|
|
2157
2347
|
}
|
|
2158
2348
|
dotns.disconnect();
|
|
2159
2349
|
});
|
|
@@ -2219,6 +2409,16 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2219
2409
|
sessionCleanup?.();
|
|
2220
2410
|
}
|
|
2221
2411
|
}
|
|
2412
|
+
function computePhoneSigningSteps(dotnsPreflight, publishNeeded) {
|
|
2413
|
+
if (!dotnsPreflight || dotnsPreflight.plannedAction === "abort") return [];
|
|
2414
|
+
const steps = [];
|
|
2415
|
+
if (dotnsPreflight.plannedAction === "register") {
|
|
2416
|
+
steps.push("Commitment", "Register");
|
|
2417
|
+
}
|
|
2418
|
+
steps.push("Link content");
|
|
2419
|
+
if (publishNeeded) steps.push("Publish to registry");
|
|
2420
|
+
return steps;
|
|
2421
|
+
}
|
|
2222
2422
|
|
|
2223
2423
|
// src/merkle.ts
|
|
2224
2424
|
var CidPreservingBlockstore = class {
|
|
@@ -2620,6 +2820,10 @@ export {
|
|
|
2620
2820
|
readBulletinSlotSigner,
|
|
2621
2821
|
writeBulletinSlotKey,
|
|
2622
2822
|
extractBulletinSlotKey,
|
|
2823
|
+
BulletinSlotAuthError,
|
|
2824
|
+
isBulletinAuthActive,
|
|
2825
|
+
pollUntilBulletinAuthorized,
|
|
2826
|
+
waitForBulletinAuthorization,
|
|
2623
2827
|
getSlotSignerProvider,
|
|
2624
2828
|
friendlyChainError,
|
|
2625
2829
|
DEFAULT_BULLETIN_RPC,
|
|
@@ -2643,6 +2847,7 @@ export {
|
|
|
2643
2847
|
encryptContent,
|
|
2644
2848
|
__selectStorageProviderModeForTest,
|
|
2645
2849
|
chooseSignerInput,
|
|
2850
|
+
formatStorageSignerLine,
|
|
2646
2851
|
storeFile,
|
|
2647
2852
|
__assignDenseNoncesForTest,
|
|
2648
2853
|
storeChunkedContent,
|
|
@@ -2664,5 +2869,6 @@ export {
|
|
|
2664
2869
|
browserUrlFor,
|
|
2665
2870
|
interpretBitswapResult,
|
|
2666
2871
|
probeP2pRetrieval,
|
|
2667
|
-
deploy
|
|
2872
|
+
deploy,
|
|
2873
|
+
computePhoneSigningSteps
|
|
2668
2874
|
};
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
setDeploySentryTag,
|
|
9
9
|
truncateAddress,
|
|
10
10
|
withSpan
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-LCKLYFAZ.js";
|
|
12
12
|
import {
|
|
13
13
|
validateContractAddresses
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GL3U7K2B.js";
|
|
15
15
|
import {
|
|
16
16
|
NonRetryableError
|
|
17
17
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -759,8 +759,8 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
759
759
|
const decision = classifyTxRetryDecision(e);
|
|
760
760
|
if (decision === "abort" || attempt === DOTNS_TX_MAX_ATTEMPTS) break;
|
|
761
761
|
const ms = dotnsRetryBackoffMs(attempt);
|
|
762
|
-
const
|
|
763
|
-
console.log(` ${label}: attempt ${attempt}/${DOTNS_TX_MAX_ATTEMPTS} failed (${
|
|
762
|
+
const msg = e?.message ?? String(e);
|
|
763
|
+
console.log(` ${label}: attempt ${attempt}/${DOTNS_TX_MAX_ATTEMPTS} failed (${msg}), retrying in ${ms}ms\u2026`);
|
|
764
764
|
await new Promise((r) => setTimeout(r, ms));
|
|
765
765
|
}
|
|
766
766
|
}
|
|
@@ -958,6 +958,7 @@ var DotNS = class {
|
|
|
958
958
|
_environmentId = null;
|
|
959
959
|
_popSelfServe = null;
|
|
960
960
|
_registerStorageDeposit = MINIMUM_REGISTER_STORAGE_DEPOSIT;
|
|
961
|
+
_onPhoneSigningRequired = void 0;
|
|
961
962
|
// Test-only seam: consumed once by classifyAliasAccountState() then cleared.
|
|
962
963
|
// Mirrors the __setDeployRootSpanForTest / __setSentryForTest pattern.
|
|
963
964
|
_classifyOverrideForTest = null;
|
|
@@ -1005,6 +1006,9 @@ var DotNS = class {
|
|
|
1005
1006
|
if (options.registerStorageDeposit !== void 0) {
|
|
1006
1007
|
this._registerStorageDeposit = options.registerStorageDeposit;
|
|
1007
1008
|
}
|
|
1009
|
+
if (options.onPhoneSigningRequired !== void 0) {
|
|
1010
|
+
this._onPhoneSigningRequired = options.onPhoneSigningRequired;
|
|
1011
|
+
}
|
|
1008
1012
|
const rpc = options.rpc || process.env.DOTNS_RPC || this.assetHubEndpoints[0];
|
|
1009
1013
|
this.rpc = rpc;
|
|
1010
1014
|
this._usesExternalSigner = Boolean(options.signer && options.signerAddress);
|
|
@@ -1657,6 +1661,9 @@ var DotNS = class {
|
|
|
1657
1661
|
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
1658
1662
|
}
|
|
1659
1663
|
};
|
|
1664
|
+
console.log(`
|
|
1665
|
+
Linking content...`);
|
|
1666
|
+
this._onPhoneSigningRequired?.("Link content");
|
|
1660
1667
|
const txRes = await this.contractTransaction(this._contracts.DOTNS_CONTENT_RESOLVER, 0n, DOTNS_CONTENT_RESOLVER_ABI, "setContenthash", [node, contenthashHex], (s) => console.log(` ${s}`), { useNoncePolling: true, verifyEffect });
|
|
1661
1668
|
const finalOnChain = (await this.getContenthash(domainName) || "0x").toLowerCase();
|
|
1662
1669
|
if (finalOnChain !== expected) {
|
|
@@ -1884,6 +1891,7 @@ var DotNS = class {
|
|
|
1884
1891
|
}
|
|
1885
1892
|
};
|
|
1886
1893
|
try {
|
|
1894
|
+
this._onPhoneSigningRequired?.("Publish to registry");
|
|
1887
1895
|
const txRes = await this.contractTransaction(publisher, 0n, PUBLISHER_ABI, "publish", [label], (s) => console.log(` ${s}`), { useNoncePolling: true, verifyEffect });
|
|
1888
1896
|
const finalPublished = await withTimeout(
|
|
1889
1897
|
this.contractCall(publisher, PUBLISHER_ABI, "isPublished", [labelhash]),
|
|
@@ -2028,6 +2036,7 @@ var DotNS = class {
|
|
|
2028
2036
|
this.ensureConnected();
|
|
2029
2037
|
console.log(`
|
|
2030
2038
|
Submitting commitment...`);
|
|
2039
|
+
this._onPhoneSigningRequired?.("Commitment");
|
|
2031
2040
|
const commitTxRes = await this.contractTransaction(this._contracts.DOTNS_REGISTRAR_CONTROLLER, 0n, DOTNS_REGISTRAR_CONTROLLER_ABI, "commit", [commitment], (s) => console.log(` ${s}`));
|
|
2032
2041
|
logTxResolution(commitTxRes);
|
|
2033
2042
|
console.log(` Committed at: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
@@ -2122,6 +2131,7 @@ var DotNS = class {
|
|
|
2122
2131
|
setDeployAttribute("deploy.payment_wei", priceWei.toString());
|
|
2123
2132
|
console.log(` Oracle price: ${formatEther(priceWei)} PAS`);
|
|
2124
2133
|
console.log(` Paying: ${formatEther(bufferedPaymentWei)} PAS`);
|
|
2134
|
+
this._onPhoneSigningRequired?.("Register");
|
|
2125
2135
|
const registerTxRes = await this.contractTransaction(this._contracts.DOTNS_REGISTRAR_CONTROLLER, bufferedPaymentNative, DOTNS_REGISTRAR_CONTROLLER_ABI, "register", [registration], (s) => console.log(` ${s}`));
|
|
2126
2136
|
logTxResolution(registerTxRes);
|
|
2127
2137
|
if (registerTxRes.kind === TX_KIND_HASH) {
|
|
@@ -2545,6 +2555,7 @@ var DotNS = class {
|
|
|
2545
2555
|
this.connected = false;
|
|
2546
2556
|
}
|
|
2547
2557
|
this._usesExternalSigner = false;
|
|
2558
|
+
this._onPhoneSigningRequired = void 0;
|
|
2548
2559
|
}
|
|
2549
2560
|
};
|
|
2550
2561
|
var dotns = new DotNS();
|
|
@@ -6,15 +6,15 @@ import {
|
|
|
6
6
|
resolveDotnsConnectOptions,
|
|
7
7
|
storeDirectory,
|
|
8
8
|
storeFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RD2QHYTL.js";
|
|
10
10
|
import {
|
|
11
11
|
DotNS
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WZBAQCA5.js";
|
|
13
13
|
import {
|
|
14
14
|
getPopSelfServeConfig,
|
|
15
15
|
loadEnvironments,
|
|
16
16
|
resolveEndpoints
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GL3U7K2B.js";
|
|
18
18
|
import {
|
|
19
19
|
NonRetryableError
|
|
20
20
|
} from "./chunk-ZOC4GITL.js";
|
package/dist/chunk-probe.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
_decodeStorageValue,
|
|
6
6
|
_resetProbeSession,
|
|
7
7
|
probeChunks
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-NP4SLURL.js";
|
|
9
|
+
import "./chunk-LCKLYFAZ.js";
|
|
10
|
+
import "./chunk-2SR5D4CP.js";
|
|
11
11
|
export {
|
|
12
12
|
ChainProbeCrossValidationError,
|
|
13
13
|
ChainProbeMetadataError,
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { b as AllocationSummary } from '../allocations-B65Is4Md.js';
|
|
2
|
-
import '@parity/product-sdk-terminal';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* login — QR/mobile sign-in command.
|
|
6
3
|
*
|
|
@@ -8,15 +5,43 @@ import '@parity/product-sdk-terminal';
|
|
|
8
5
|
* 1. connect() → existing session (already logged in) OR QR code
|
|
9
6
|
* 2. Print QR → user scans on phone
|
|
10
7
|
* 3. waitForLogin() → phone approves → paired
|
|
11
|
-
* 4.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
8
|
+
* 4. getBulletinSigner() — resolves the slot account from host-papp's allowance service.
|
|
9
|
+
* Uses DOT_PRODUCT_ID ("playground.dot") as callingProductId, which matches what the
|
|
10
|
+
* mobile wallet allocated during pairing. A 60s timeout prevents hanging on unresponsive phones.
|
|
11
|
+
* 5. Print summarizeLogin() + slot address on success; map AllowanceError.reason → message on failure
|
|
12
|
+
* 6. Destroy adapters and exit
|
|
14
13
|
*/
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Map an AllowanceError.reason to a user-facing message.
|
|
16
|
+
*
|
|
17
|
+
* - NoSession: the paired session was not found (should not happen right after login)
|
|
18
|
+
* - Rejected: the user dismissed the wallet prompt
|
|
19
|
+
* - NotAvailable: the wallet has no allocation for this product (re-pair needed)
|
|
20
|
+
* - UnexpectedResponse: protocol-level error in the wire exchange
|
|
21
|
+
*/
|
|
22
|
+
declare function allocationErrorMessage(reason: string): string;
|
|
16
23
|
/**
|
|
17
24
|
* Format a post-login summary. Pure function, unit-testable.
|
|
25
|
+
*
|
|
26
|
+
* @param address SS58 product address (the identity signing on-chain)
|
|
27
|
+
* @param slotAddress SS58 slot account address for Bulletin storage, or null if not obtained
|
|
28
|
+
*/
|
|
29
|
+
declare function summarizeLogin(address: string, slotAddress: string | null): string;
|
|
30
|
+
/**
|
|
31
|
+
* Produce the on-chain authorization result message shown after the active-wait completes.
|
|
32
|
+
* Pure function — unit-testable without a real WS connection.
|
|
33
|
+
*
|
|
34
|
+
* - authorized = true → ✓ success message with expiration block (exit-0, show summarizeLogin).
|
|
35
|
+
* - authorized = false → soft-warning: active wait timed out before the authorization landed.
|
|
36
|
+
* Login is still valid — the slot is deterministic and often already authorized; the deploy
|
|
37
|
+
* path re-probes before use and falls back to the pool if still absent. isWarning=true so
|
|
38
|
+
* callers know it's a non-fatal outcome. The timeout bound (timeoutSeconds) is embedded in
|
|
39
|
+
* the message so users understand the ceiling that was used.
|
|
18
40
|
*/
|
|
19
|
-
declare function
|
|
41
|
+
declare function bulletinAuthSummary(authorized: boolean, expiration?: number, timeoutSeconds?: number): {
|
|
42
|
+
message: string;
|
|
43
|
+
isWarning: boolean;
|
|
44
|
+
};
|
|
20
45
|
interface LoginOptions {
|
|
21
46
|
suri?: string;
|
|
22
47
|
}
|
|
@@ -25,4 +50,4 @@ interface LoginOptions {
|
|
|
25
50
|
*/
|
|
26
51
|
declare function runLogin(envId: string, _opts?: LoginOptions): Promise<void>;
|
|
27
52
|
|
|
28
|
-
export { type LoginOptions, runLogin, summarizeLogin };
|
|
53
|
+
export { type LoginOptions, allocationErrorMessage, bulletinAuthSummary, runLogin, summarizeLogin };
|