@parity/product-deploy 0.11.0-rc.3 → 0.11.0-rc.5
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 +2 -0
- package/dist/auth-config.js +4 -4
- package/dist/bug-report.d.ts +10 -1
- package/dist/bug-report.js +6 -4
- package/dist/{chunk-VZTZEW7C.js → chunk-BIJICTV4.js} +41 -28
- package/dist/{chunk-PYGCOK67.js → chunk-ITXKADHO.js} +35 -11
- package/dist/{chunk-QRKI6MMK.js → chunk-JSYQ3JQS.js} +4 -1
- package/dist/{chunk-RVGCHRLK.js → chunk-KBKS3V2V.js} +2 -2
- package/dist/{chunk-PH32GINP.js → chunk-LFRH4HBZ.js} +1 -1
- package/dist/{chunk-RFT2I7TB.js → chunk-M6OQTMDB.js} +1 -1
- package/dist/{chunk-4IUTMHVB.js → chunk-MRQPJLPS.js} +24 -3
- package/dist/{chunk-2NLCZQY4.js → chunk-NEQRG3AY.js} +1 -1
- package/dist/{chunk-24KTLZ67.js → chunk-OZEJEDHM.js} +14 -4
- package/dist/{chunk-CLM3ODFR.js → chunk-PECJ5FDA.js} +9 -3
- package/dist/{chunk-3US5OZWX.js → chunk-RU7Z5Y7Z.js} +1 -1
- package/dist/{chunk-5KRARO46.js → chunk-UIDRWZWX.js} +1 -1
- package/dist/{chunk-REAHYALJ.js → chunk-UJLQBL7C.js} +3 -3
- 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 +5 -5
- package/dist/commands/whoami.js +4 -4
- package/dist/deploy-actors.js +7 -7
- package/dist/deploy.d.ts +19 -1
- package/dist/deploy.js +16 -12
- package/dist/dotns.d.ts +15 -2
- package/dist/dotns.js +9 -5
- package/dist/environments.d.ts +2 -0
- package/dist/environments.js +1 -1
- package/dist/index.js +13 -13
- package/dist/manifest/publish.js +13 -13
- 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/pool.d.ts +3 -1
- package/dist/pool.js +1 -1
- 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 +1 -1
package/assets/environments.json
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
"name": "Preview",
|
|
6
6
|
"network": "testnet",
|
|
7
7
|
"description": "Product Preview net, used by Product Teams",
|
|
8
|
+
"bulletinAutoAuthorize": true,
|
|
8
9
|
"e2eEligible": true,
|
|
9
10
|
"backend": "https://polkadot-app-stg.parity.io/",
|
|
10
11
|
"ipfs": "https://previewnet.substrate.dev",
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
"name": "Paseo Next v2",
|
|
97
98
|
"network": "testnet",
|
|
98
99
|
"description": "Next iteration of the Paseo Next testnet",
|
|
100
|
+
"bulletinAutoAuthorize": true,
|
|
99
101
|
"e2eEligible": true,
|
|
100
102
|
"backend": "https://identity-backend-next.parity-testnet.parity.io",
|
|
101
103
|
"ipfs": "https://paseo-bulletin-next-ipfs.polkadot.io",
|
package/dist/auth-config.js
CHANGED
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
getPeopleChainEndpoints,
|
|
10
10
|
hasPersistedSession,
|
|
11
11
|
resolveBulletinEndpoints
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KBKS3V2V.js";
|
|
13
13
|
import "./chunk-TSPERKUS.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-UIDRWZWX.js";
|
|
15
|
+
import "./chunk-LFRH4HBZ.js";
|
|
16
|
+
import "./chunk-JSYQ3JQS.js";
|
|
17
17
|
import "./chunk-ZOC4GITL.js";
|
|
18
18
|
export {
|
|
19
19
|
DOT_DAPP_ID,
|
package/dist/bug-report.d.ts
CHANGED
|
@@ -24,6 +24,15 @@ declare function buildReportBody(error: Error): string;
|
|
|
24
24
|
declare function buildTitle(error: Error): string;
|
|
25
25
|
declare function buildLabels(error: Error): string[];
|
|
26
26
|
declare function createGhIssue(title: string, body: string, labels: string[]): string;
|
|
27
|
+
/**
|
|
28
|
+
* True for deploy failures caused by user input rather than a code defect, so
|
|
29
|
+
* the bug-report prompt is NOT offered for them (#869). Scoped to DotNS name
|
|
30
|
+
* validation: a malformed or reserved label ("Invalid domain label …",
|
|
31
|
+
* "… reserves base names of N chars …") is something the user fixes by choosing
|
|
32
|
+
* a different name — filing it as a bug just creates noise. The actionable error
|
|
33
|
+
* message has already been printed to the user. Exported for unit testing.
|
|
34
|
+
*/
|
|
35
|
+
declare function isUserInputError(error: Error): boolean;
|
|
27
36
|
declare function offerBugReport(error: Error): Promise<void>;
|
|
28
37
|
|
|
29
|
-
export { buildCliFlagsSummary, buildLabels, buildReportBody, buildTitle, createGhIssue, getCapturedTail, installLogCapture, offerBugReport, scrubSecrets, setDeployContext };
|
|
38
|
+
export { buildCliFlagsSummary, buildLabels, buildReportBody, buildTitle, createGhIssue, getCapturedTail, installLogCapture, isUserInputError, offerBugReport, scrubSecrets, setDeployContext };
|
package/dist/bug-report.js
CHANGED
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
createGhIssue,
|
|
7
7
|
getCapturedTail,
|
|
8
8
|
installLogCapture,
|
|
9
|
+
isUserInputError,
|
|
9
10
|
offerBugReport,
|
|
10
11
|
scrubSecrets,
|
|
11
12
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-PECJ5FDA.js";
|
|
14
|
+
import "./chunk-NEQRG3AY.js";
|
|
15
|
+
import "./chunk-UIDRWZWX.js";
|
|
16
|
+
import "./chunk-LFRH4HBZ.js";
|
|
16
17
|
export {
|
|
17
18
|
buildCliFlagsSummary,
|
|
18
19
|
buildLabels,
|
|
@@ -21,6 +22,7 @@ export {
|
|
|
21
22
|
createGhIssue,
|
|
22
23
|
getCapturedTail,
|
|
23
24
|
installLogCapture,
|
|
25
|
+
isUserInputError,
|
|
24
26
|
offerBugReport,
|
|
25
27
|
scrubSecrets,
|
|
26
28
|
setDeployContext
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
preflightSssAllowance
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M6OQTMDB.js";
|
|
4
4
|
import {
|
|
5
5
|
statementSigningAccount
|
|
6
6
|
} from "./chunk-GRPLHUYC.js";
|
|
@@ -31,16 +31,16 @@ import {
|
|
|
31
31
|
} from "./chunk-S7EM5VMW.js";
|
|
32
32
|
import {
|
|
33
33
|
setDeployContext
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-PECJ5FDA.js";
|
|
35
35
|
import {
|
|
36
36
|
probeChunks
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-RU7Z5Y7Z.js";
|
|
38
38
|
import {
|
|
39
39
|
packSection
|
|
40
40
|
} from "./chunk-C2TS5MER.js";
|
|
41
41
|
import {
|
|
42
42
|
resolveStorageSigner
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-OZEJEDHM.js";
|
|
44
44
|
import {
|
|
45
45
|
createSlotAccountSigner,
|
|
46
46
|
requestResourceAllocation
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
STALE_SESSION_MESSAGE,
|
|
50
50
|
getPeopleChainEndpoints,
|
|
51
51
|
hasPersistedSession
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-KBKS3V2V.js";
|
|
53
53
|
import {
|
|
54
54
|
CLI_NAME
|
|
55
55
|
} from "./chunk-TSPERKUS.js";
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
parseDomainName,
|
|
63
63
|
popStatusName,
|
|
64
64
|
verifyNonceAdvanced
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-ITXKADHO.js";
|
|
66
66
|
import {
|
|
67
67
|
derivePoolAccounts,
|
|
68
68
|
detectTestnet,
|
|
@@ -70,7 +70,7 @@ import {
|
|
|
70
70
|
fetchPoolAuthorizations,
|
|
71
71
|
isAuthorizationSufficient,
|
|
72
72
|
selectAccount
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-MRQPJLPS.js";
|
|
74
74
|
import {
|
|
75
75
|
VERSION,
|
|
76
76
|
captureWarning,
|
|
@@ -84,13 +84,13 @@ import {
|
|
|
84
84
|
truncateAddress,
|
|
85
85
|
withDeploySpan,
|
|
86
86
|
withSpan
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-UIDRWZWX.js";
|
|
88
88
|
import {
|
|
89
89
|
DEFAULT_ENV_ID,
|
|
90
90
|
getPopSelfServeConfig,
|
|
91
91
|
loadEnvironments,
|
|
92
92
|
resolveEndpoints
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-JSYQ3JQS.js";
|
|
94
94
|
import {
|
|
95
95
|
NonRetryableError
|
|
96
96
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -373,6 +373,7 @@ var DEFAULT_BULLETIN_RPC = "wss://paseo-bulletin-rpc.polkadot.io";
|
|
|
373
373
|
var DEFAULT_POOL_SIZE = 10;
|
|
374
374
|
var BULLETIN_ENDPOINTS = [DEFAULT_BULLETIN_RPC];
|
|
375
375
|
var POOL_SIZE = DEFAULT_POOL_SIZE;
|
|
376
|
+
var bulletinAutoAuthorize = false;
|
|
376
377
|
var _deployRpcFailedOver = false;
|
|
377
378
|
var _onWsHalt = null;
|
|
378
379
|
function setWsHaltCallback(cb) {
|
|
@@ -511,7 +512,7 @@ async function getProvider() {
|
|
|
511
512
|
const selectionResult = selectAccount(authorizations, Math.random, pinnedPoolIndex);
|
|
512
513
|
const selectedAccount = selectionResult.account;
|
|
513
514
|
const eligibleCount = selectionResult.eligibleCount;
|
|
514
|
-
await ensureAuthorized(unsafeApi, selectedAccount.address, `pool account ${selectedAccount.index}
|
|
515
|
+
await ensureAuthorized(unsafeApi, selectedAccount.address, `pool account ${selectedAccount.index}`, { autoAuthorize: bulletinAutoAuthorize });
|
|
515
516
|
console.log(` Using pool account ${selectedAccount.index}: ${selectedAccount.address}`);
|
|
516
517
|
setDeployAttribute("deploy.signer.mode", "pool");
|
|
517
518
|
setDeployAttribute("deploy.pool.account", truncateAddress(selectedAccount.address));
|
|
@@ -540,7 +541,7 @@ async function getDirectProvider(mnemonic, derivationPath = "") {
|
|
|
540
541
|
let now = currentBlock.number;
|
|
541
542
|
if (!auth || Number(auth.expiration ?? 0) <= now) {
|
|
542
543
|
try {
|
|
543
|
-
await ensureAuthorized(unsafeApi, ss58, "direct signer");
|
|
544
|
+
await ensureAuthorized(unsafeApi, ss58, "direct signer", { autoAuthorize: bulletinAutoAuthorize });
|
|
544
545
|
[auth, currentBlock] = await Promise.all([
|
|
545
546
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
546
547
|
client.getFinalizedBlock()
|
|
@@ -572,7 +573,7 @@ async function getSignerProvider(signer, ss58) {
|
|
|
572
573
|
let now = currentBlock.number;
|
|
573
574
|
if (!auth || Number(auth.expiration ?? 0) <= now) {
|
|
574
575
|
try {
|
|
575
|
-
await ensureAuthorized(unsafeApi, ss58, "external signer");
|
|
576
|
+
await ensureAuthorized(unsafeApi, ss58, "external signer", { autoAuthorize: bulletinAutoAuthorize });
|
|
576
577
|
[auth, currentBlock] = await Promise.all([
|
|
577
578
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
578
579
|
client.getFinalizedBlock()
|
|
@@ -614,6 +615,12 @@ function formatStorageSignerLine(slotAddress, failReason, owned) {
|
|
|
614
615
|
}
|
|
615
616
|
return ` Storage signer: pool fallback (${failReason ?? "no session"})`;
|
|
616
617
|
}
|
|
618
|
+
function formatTransferModeStorageSignerLine(workerAddress) {
|
|
619
|
+
return ` Storage signer: worker ${workerAddress} (transfer mode)`;
|
|
620
|
+
}
|
|
621
|
+
function formatTransferModeDotnsLine(alreadyOwned, dotName, recipient) {
|
|
622
|
+
return alreadyOwned ? ` DotNS: you already own ${dotName} \u2014 content update needs your phone signature (no transfer)` : ` DotNS: will register ${dotName} and transfer it to your account ${recipient}`;
|
|
623
|
+
}
|
|
617
624
|
function selectStorageReconnect(options) {
|
|
618
625
|
if (options.storageSigner && options.storageSignerAddress) {
|
|
619
626
|
let useSlot = true;
|
|
@@ -965,7 +972,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
965
972
|
while (b < chunks.length) {
|
|
966
973
|
if (wsHaltDetected && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
|
|
967
974
|
wsHaltDetected = false;
|
|
968
|
-
await
|
|
975
|
+
await doReconnectAndRebase();
|
|
969
976
|
}
|
|
970
977
|
const batchSize = reconnectionsUsed > 0 ? BATCH_SIZE_RECOVERY : BATCH_SIZE_INITIAL;
|
|
971
978
|
const batchIndices = [];
|
|
@@ -1009,7 +1016,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1009
1016
|
for (const idx of batchIndices) {
|
|
1010
1017
|
const chunkNonce = assignedNonces.get(idx);
|
|
1011
1018
|
if (chunkNonce !== void 0 && chunkNonce < currentNonce && stored[idx] === null) {
|
|
1012
|
-
console.log(` Chunk ${idx
|
|
1019
|
+
console.log(` Chunk ${idx}: nonce ${chunkNonce} consumed (current=${currentNonce}), treating as included`);
|
|
1013
1020
|
stored[idx] = { cid: createCID(chunks[idx], CID_CONFIG.codec, 18), len: chunks[idx].length, viaFallback: true };
|
|
1014
1021
|
nonceAdvanceIndices.add(idx);
|
|
1015
1022
|
assignedNonces.delete(idx);
|
|
@@ -1027,7 +1034,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1027
1034
|
}
|
|
1028
1035
|
const failCid = createCID(fail.chunkData, CID_CONFIG.codec, 18);
|
|
1029
1036
|
if (probeFailedCids && probeFailedCids.has(failCid.toString()) && fail.error?.message?.includes("isValid:false")) {
|
|
1030
|
-
console.log(` Chunk ${fail.index
|
|
1037
|
+
console.log(` Chunk ${fail.index}: isValid:false but CID was probe-failed \u2014 treating as already on chain`);
|
|
1031
1038
|
captureWarning("isValid:false treated as success (probe-failed backstop)", { chunkIndex: fail.index + 1, cid: failCid.toString() });
|
|
1032
1039
|
stored[fail.index] = { cid: failCid, len: fail.chunkData.length, viaFallback: true };
|
|
1033
1040
|
continue;
|
|
@@ -1035,13 +1042,13 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1035
1042
|
captureWarning("Chunk upload failed, retrying", { chunkIndex: fail.index + 1, maxRetries: MAX_CHUNK_RETRIES, error: fail.error?.message?.slice(0, 200) });
|
|
1036
1043
|
const isExpiryFailure = fail.error?.message?.includes("isValid:false");
|
|
1037
1044
|
if (isExpiryFailure) {
|
|
1038
|
-
console.log(` Chunk ${fail.index
|
|
1045
|
+
console.log(` Chunk ${fail.index}: tx rejected (isValid:false), likely mortal era expiry \u2014 reissuing with fresh nonce`);
|
|
1039
1046
|
}
|
|
1040
1047
|
let retried = false;
|
|
1041
1048
|
for (let attempt = 1; attempt <= MAX_CHUNK_RETRIES; attempt++) {
|
|
1042
1049
|
recordRecoveryAndCheckBudget("chunk_retry");
|
|
1043
1050
|
const retryDelay = Math.min(RETRY_BASE_DELAY_MS * Math.pow(2, attempt - 1), RETRY_MAX_DELAY_MS);
|
|
1044
|
-
console.log(` Retrying chunk ${fail.index
|
|
1051
|
+
console.log(` Retrying chunk ${fail.index} (attempt ${attempt}/${MAX_CHUNK_RETRIES}) in ${(retryDelay / 1e3).toFixed(0)}s...`);
|
|
1045
1052
|
await new Promise((r) => setTimeout(r, retryDelay));
|
|
1046
1053
|
let perRetryChanged = false;
|
|
1047
1054
|
if (isConnectionError(fail.error) && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
|
|
@@ -1056,7 +1063,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1056
1063
|
const currentNonce = await _fetchNonce(BULLETIN_ENDPOINTS, ss58);
|
|
1057
1064
|
const originalNonce = assignedNonces.get(fail.index);
|
|
1058
1065
|
if (!perRetryChanged && originalNonce !== void 0 && originalNonce < currentNonce) {
|
|
1059
|
-
console.log(` Chunk ${fail.index
|
|
1066
|
+
console.log(` Chunk ${fail.index}: nonce ${originalNonce} consumed (current=${currentNonce}), treating as included`);
|
|
1060
1067
|
stored[fail.index] = { cid: createCID(fail.chunkData, CID_CONFIG.codec, 18), len: fail.chunkData.length, viaFallback: true };
|
|
1061
1068
|
nonceAdvanceIndices.add(fail.index);
|
|
1062
1069
|
assignedNonces.delete(fail.index);
|
|
@@ -1073,7 +1080,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1073
1080
|
break;
|
|
1074
1081
|
} catch (e) {
|
|
1075
1082
|
if (probeFailedCids && probeFailedCids.has(failCid.toString()) && e?.message?.includes("isValid:false")) {
|
|
1076
|
-
console.log(` Chunk ${fail.index
|
|
1083
|
+
console.log(` Chunk ${fail.index}: retry isValid:false but CID was probe-failed \u2014 treating as already on chain`);
|
|
1077
1084
|
captureWarning("isValid:false retry treated as success (probe-failed backstop)", { chunkIndex: fail.index + 1, cid: failCid.toString(), attempt });
|
|
1078
1085
|
stored[fail.index] = { cid: failCid, len: fail.chunkData.length, viaFallback: true };
|
|
1079
1086
|
assignedNonces.delete(fail.index);
|
|
@@ -1094,7 +1101,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1094
1101
|
if (isConnectionError(fail.error) && reconnectionsUsed >= MAX_RECONNECTIONS) {
|
|
1095
1102
|
throw new Error(`Connection lost and max reconnections (${MAX_RECONNECTIONS}) exhausted`);
|
|
1096
1103
|
}
|
|
1097
|
-
throw new Error(`Chunk ${fail.index
|
|
1104
|
+
throw new Error(`Chunk ${fail.index} failed after ${MAX_CHUNK_RETRIES} retries: ${fail.error?.message?.slice(0, 100)}`);
|
|
1098
1105
|
}
|
|
1099
1106
|
}
|
|
1100
1107
|
b += batchSize;
|
|
@@ -1118,7 +1125,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1118
1125
|
for (const m of missingResults) {
|
|
1119
1126
|
const idx = cidToIndex.get(m.cid);
|
|
1120
1127
|
for (let attempt = 1; attempt <= MAX_REPROBE_RETRIES; attempt++) {
|
|
1121
|
-
console.log(` Nonce-collision re-upload: chunk ${idx
|
|
1128
|
+
console.log(` Nonce-collision re-upload: chunk ${idx} (attempt ${attempt}/${MAX_REPROBE_RETRIES})`);
|
|
1122
1129
|
try {
|
|
1123
1130
|
const freshNonce = await _fetchNonce(BULLETIN_ENDPOINTS, ss58);
|
|
1124
1131
|
const result2 = await storeChunk(unsafeApi, signer, chunks[idx], freshNonce, ss58, { fetchNonce: fetchNonceOverride });
|
|
@@ -1133,7 +1140,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1133
1140
|
}
|
|
1134
1141
|
}
|
|
1135
1142
|
if (attempt === MAX_REPROBE_RETRIES) {
|
|
1136
|
-
throw new Error(`Nonce-collision re-upload of chunk ${idx
|
|
1143
|
+
throw new Error(`Nonce-collision re-upload of chunk ${idx} failed after ${MAX_REPROBE_RETRIES} attempts: ${e.message?.slice(0, 100)}`);
|
|
1137
1144
|
}
|
|
1138
1145
|
}
|
|
1139
1146
|
}
|
|
@@ -1154,7 +1161,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
1154
1161
|
for (let i = 0; i < chunks.length; i++) {
|
|
1155
1162
|
const expectedCid = createCID(chunks[i], CID_CONFIG.codec, 18);
|
|
1156
1163
|
if (verifiedStored[i].cid.toString() !== expectedCid.toString()) {
|
|
1157
|
-
throw new Error(`Chunk verification failed: chunk ${i
|
|
1164
|
+
throw new Error(`Chunk verification failed: chunk ${i} CID mismatch (expected ${expectedCid}, got ${verifiedStored[i].cid})`);
|
|
1158
1165
|
}
|
|
1159
1166
|
}
|
|
1160
1167
|
console.log(` All ${chunks.length} chunks verified \u2713`);
|
|
@@ -1993,6 +2000,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
1993
2000
|
let envNativeToEthRatio;
|
|
1994
2001
|
let envRegisterStorageDeposit;
|
|
1995
2002
|
let envPopSelfServe = null;
|
|
2003
|
+
bulletinAutoAuthorize = false;
|
|
1996
2004
|
if (options.bulletinEndpoints && options.bulletinEndpoints.length > 0) {
|
|
1997
2005
|
envBulletin = options.bulletinEndpoints;
|
|
1998
2006
|
envAssetHub = options.assetHubEndpoints;
|
|
@@ -2011,6 +2019,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2011
2019
|
envNativeToEthRatio = resolved.nativeToEthRatio;
|
|
2012
2020
|
envRegisterStorageDeposit = resolved.registerStorageDeposit;
|
|
2013
2021
|
envPopSelfServe = getPopSelfServeConfig(doc, envId);
|
|
2022
|
+
bulletinAutoAuthorize = resolved.bulletinAutoAuthorize;
|
|
2014
2023
|
} catch (e) {
|
|
2015
2024
|
if (e instanceof NonRetryableError) throw e;
|
|
2016
2025
|
if (options.env !== void 0) throw e;
|
|
@@ -2056,7 +2065,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2056
2065
|
sessionCleanup = actors.worker.destroy.bind(actors.worker);
|
|
2057
2066
|
if (actors.worker.source === "session") resolvedUserSession = actors.worker;
|
|
2058
2067
|
if (actors.recipientH160) {
|
|
2059
|
-
console.log(` Worker: ${actors.worker.source} signer ${actors.worker.address}
|
|
2068
|
+
console.log(` Worker: ${actors.worker.source} signer ${actors.worker.address} (signs Bulletin storage)`);
|
|
2060
2069
|
} else {
|
|
2061
2070
|
console.log(` Using ${actors.worker.source} signer: ${actors.worker.address}`);
|
|
2062
2071
|
}
|
|
@@ -2107,8 +2116,10 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2107
2116
|
if (slotResult) {
|
|
2108
2117
|
options = { ...options, storageSigner: slotResult.signer, storageSignerAddress: slotResult.slotAddress };
|
|
2109
2118
|
console.log(formatStorageSignerLine(slotResult.slotAddress, void 0, slotResult.owned));
|
|
2119
|
+
} else if (options.transferTo && options.signerAddress) {
|
|
2120
|
+
console.log(formatTransferModeStorageSignerLine(options.signerAddress));
|
|
2110
2121
|
} else {
|
|
2111
|
-
const storageFailReason = resolvedUserSession ? "no allowance" :
|
|
2122
|
+
const storageFailReason = resolvedUserSession ? "no allowance" : void 0;
|
|
2112
2123
|
console.log(formatStorageSignerLine(null, storageFailReason));
|
|
2113
2124
|
}
|
|
2114
2125
|
}
|
|
@@ -2214,8 +2225,8 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2214
2225
|
const fromName = popStatusName(dotnsPreflight.userStatus);
|
|
2215
2226
|
console.log(` Your PoP: ${fromName}`);
|
|
2216
2227
|
console.log(` Domain: ${alreadyOwned ? "owned by you" : "available"}`);
|
|
2217
|
-
if (
|
|
2218
|
-
console.log(
|
|
2228
|
+
if (options.transferTo) {
|
|
2229
|
+
console.log(formatTransferModeDotnsLine(alreadyOwned, `${name}.dot`, options.transferTo));
|
|
2219
2230
|
}
|
|
2220
2231
|
}
|
|
2221
2232
|
if (!dotnsPreflight.canProceed) {
|
|
@@ -2570,7 +2581,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2570
2581
|
console.log("=".repeat(60));
|
|
2571
2582
|
console.log("\nCheck it out here:");
|
|
2572
2583
|
console.log(` ${browserUrlFor(name, envId)}`);
|
|
2573
|
-
console.log(` ${name}.dot (in a Polkadot
|
|
2584
|
+
console.log(` ${name}.dot (in a Polkadot app: mobile or desktop)`);
|
|
2574
2585
|
console.log("\n" + "=".repeat(60) + "\n");
|
|
2575
2586
|
return { domainName: name, fullDomain: `${name}.dot`, cid, ipfsCid };
|
|
2576
2587
|
} finally {
|
|
@@ -3026,6 +3037,8 @@ export {
|
|
|
3026
3037
|
isPhoneSignerActive,
|
|
3027
3038
|
shouldHandoverName,
|
|
3028
3039
|
formatStorageSignerLine,
|
|
3040
|
+
formatTransferModeStorageSignerLine,
|
|
3041
|
+
formatTransferModeDotnsLine,
|
|
3029
3042
|
storeFile,
|
|
3030
3043
|
__assignDenseNoncesForTest,
|
|
3031
3044
|
storeChunkedContent,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-SI2ZUOYD.js";
|
|
4
4
|
import {
|
|
5
5
|
isTestnetSpecName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MRQPJLPS.js";
|
|
7
7
|
import {
|
|
8
8
|
captureWarning,
|
|
9
9
|
markCodePath,
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
setDeploySentryTag,
|
|
12
12
|
truncateAddress,
|
|
13
13
|
withSpan
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UIDRWZWX.js";
|
|
15
15
|
import {
|
|
16
16
|
validateContractAddresses
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-JSYQ3JQS.js";
|
|
18
18
|
import {
|
|
19
19
|
NonRetryableError
|
|
20
20
|
} from "./chunk-ZOC4GITL.js";
|
|
@@ -126,6 +126,7 @@ var TX_WALL_CLOCK_CEILING_MS = 24e4;
|
|
|
126
126
|
var TX_NO_PROGRESS_MS = 9e4;
|
|
127
127
|
var WS_HEARTBEAT_TIMEOUT_MS = 3e5;
|
|
128
128
|
var DOTNS_TX_MAX_ATTEMPTS = 3;
|
|
129
|
+
var VERIFY_EFFECT_CHAIN_SECONDS = 60;
|
|
129
130
|
function classifyTxRetryDecision(err) {
|
|
130
131
|
const msg = err instanceof Error ? err.message : String(err);
|
|
131
132
|
const lower = msg.toLowerCase();
|
|
@@ -146,6 +147,9 @@ function dotnsRetryBackoffMs(attempt, rand = Math.random) {
|
|
|
146
147
|
function shouldRetryTxAttempt(attempt, maxAttempts, decision) {
|
|
147
148
|
return decision === "retry" && attempt < maxAttempts;
|
|
148
149
|
}
|
|
150
|
+
function shouldRegateBeforeResign(attempt, isPhoneSigner) {
|
|
151
|
+
return attempt >= 2 && isPhoneSigner === true;
|
|
152
|
+
}
|
|
149
153
|
function makeRetryStatusFilter(sink) {
|
|
150
154
|
let buffered = false;
|
|
151
155
|
let includedSeen = false;
|
|
@@ -783,6 +787,9 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
783
787
|
let lastError;
|
|
784
788
|
for (let attempt = 1; attempt <= DOTNS_TX_MAX_ATTEMPTS; attempt++) {
|
|
785
789
|
filter.reset();
|
|
790
|
+
if (shouldRegateBeforeResign(attempt, opts.isPhoneSigner)) {
|
|
791
|
+
await opts.onResign?.(attempt);
|
|
792
|
+
}
|
|
786
793
|
try {
|
|
787
794
|
return await this.signAndSubmitExtrinsic(buildExtrinsic(), signer, filter.callback, opts);
|
|
788
795
|
} catch (e) {
|
|
@@ -830,7 +837,7 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
830
837
|
storage_deposit_limit: storageDepositLimit
|
|
831
838
|
};
|
|
832
839
|
}
|
|
833
|
-
async submitTransaction(contractAddress, value, encodedData, signerSubstrateAddress, signer, statusCallback, { rpcs, useNoncePolling, functionName, args, contracts, verifyEffect, feeAsset }) {
|
|
840
|
+
async submitTransaction(contractAddress, value, encodedData, signerSubstrateAddress, signer, statusCallback, { rpcs, useNoncePolling, functionName, args, contracts, verifyEffect, feeAsset, isPhoneSigner, onResign }) {
|
|
834
841
|
await this.ensureAccountMapped(signerSubstrateAddress, signer);
|
|
835
842
|
if (functionName === "register") {
|
|
836
843
|
try {
|
|
@@ -862,7 +869,7 @@ var ReviveClientWrapper = class _ReviveClientWrapper {
|
|
|
862
869
|
"chain.tx.submit",
|
|
863
870
|
`sign+submit ${functionName ?? "Revive.call"}`,
|
|
864
871
|
{ "chain.function_name": functionName ?? "Revive.call", "chain.use_nonce_polling": Boolean(useNoncePolling) },
|
|
865
|
-
() => this.signAndSubmitWithRetry(buildExtrinsic, signer, statusCallback, "Revive.call", { nonceFallback, verifyEffect, feeAsset })
|
|
872
|
+
() => this.signAndSubmitWithRetry(buildExtrinsic, signer, statusCallback, "Revive.call", { nonceFallback, verifyEffect, feeAsset, isPhoneSigner, onResign })
|
|
866
873
|
);
|
|
867
874
|
}
|
|
868
875
|
// Dry-runs each call individually, then wraps them in a single
|
|
@@ -1484,7 +1491,22 @@ var DotNS = class {
|
|
|
1484
1491
|
await this._awaitPhoneReady(phoneLabel);
|
|
1485
1492
|
}
|
|
1486
1493
|
return await withTimeout(
|
|
1487
|
-
this.clientWrapper.submitTransaction(contractAddress, value, encodedCallData, this.substrateAddress, this.signer, statusCallback, {
|
|
1494
|
+
this.clientWrapper.submitTransaction(contractAddress, value, encodedCallData, this.substrateAddress, this.signer, statusCallback, {
|
|
1495
|
+
rpcs,
|
|
1496
|
+
useNoncePolling,
|
|
1497
|
+
functionName,
|
|
1498
|
+
args,
|
|
1499
|
+
contracts: this._contracts,
|
|
1500
|
+
verifyEffect,
|
|
1501
|
+
feeAsset,
|
|
1502
|
+
// Re-gate phone-signer retries (#971): a verifyEffect false-negative
|
|
1503
|
+
// makes signAndSubmitWithRetry re-sign; for a phone signer that needs
|
|
1504
|
+
// another tap, so pause via _awaitPhoneReady ("Re-sign needed … Check
|
|
1505
|
+
// your phone / Press Y") before re-signing. Both _awaitPhoneReady and the
|
|
1506
|
+
// retry-loop guard no-op for non-phone signers (local/dev workers).
|
|
1507
|
+
isPhoneSigner: this._isPhoneSigner,
|
|
1508
|
+
onResign: phoneLabel !== void 0 ? () => this._awaitPhoneReady(phoneLabel) : void 0
|
|
1509
|
+
}),
|
|
1488
1510
|
OPERATION_TIMEOUT_MS,
|
|
1489
1511
|
functionName
|
|
1490
1512
|
);
|
|
@@ -1587,7 +1609,7 @@ var DotNS = class {
|
|
|
1587
1609
|
const parentNode = namehash(`${parentLabel}.dot`);
|
|
1588
1610
|
const subnodeNode = namehash(`${sublabel}.${parentLabel}.dot`);
|
|
1589
1611
|
const subnodeRecord = { parentNode, subLabel: sublabel, parentLabel, owner: this.evmAddress };
|
|
1590
|
-
const MAX_VERIFY_CHAIN_SECONDS =
|
|
1612
|
+
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
1591
1613
|
const POLL_INTERVAL_MS = 2e3;
|
|
1592
1614
|
const verifyEffect = async () => {
|
|
1593
1615
|
const wrapper = this.clientWrapper;
|
|
@@ -1727,7 +1749,7 @@ var DotNS = class {
|
|
|
1727
1749
|
} catch (_) {
|
|
1728
1750
|
}
|
|
1729
1751
|
setDeployAttribute("deploy.dotns.contenthash_unchanged", "false");
|
|
1730
|
-
const MAX_VERIFY_CHAIN_SECONDS =
|
|
1752
|
+
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
1731
1753
|
const POLL_INTERVAL_MS = 2e3;
|
|
1732
1754
|
const verifyEffect = async () => {
|
|
1733
1755
|
const wrapper = this.clientWrapper;
|
|
@@ -1824,7 +1846,7 @@ var DotNS = class {
|
|
|
1824
1846
|
this.ensureConnected();
|
|
1825
1847
|
console.log(` Setting text[${key}]: ${value}`);
|
|
1826
1848
|
const node = namehash(`${domainName}.dot`);
|
|
1827
|
-
const MAX_VERIFY_CHAIN_SECONDS =
|
|
1849
|
+
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
1828
1850
|
const TEXT_POLL_INTERVAL_MS = 2e3;
|
|
1829
1851
|
const verifyEffect = async () => {
|
|
1830
1852
|
const wrapper = this.clientWrapper;
|
|
@@ -1956,7 +1978,7 @@ var DotNS = class {
|
|
|
1956
1978
|
console.log(` Already published \u2014 skipping`);
|
|
1957
1979
|
return { status: "already-published" };
|
|
1958
1980
|
}
|
|
1959
|
-
const MAX_VERIFY_CHAIN_SECONDS =
|
|
1981
|
+
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
1960
1982
|
const PUBLISH_POLL_INTERVAL_MS = 2e3;
|
|
1961
1983
|
const verifyEffect = async () => {
|
|
1962
1984
|
const wrapper = this.clientWrapper;
|
|
@@ -2029,7 +2051,7 @@ var DotNS = class {
|
|
|
2029
2051
|
console.log(` Not currently published \u2014 skipping`);
|
|
2030
2052
|
return { status: "already-unpublished" };
|
|
2031
2053
|
}
|
|
2032
|
-
const MAX_VERIFY_CHAIN_SECONDS =
|
|
2054
|
+
const MAX_VERIFY_CHAIN_SECONDS = VERIFY_EFFECT_CHAIN_SECONDS;
|
|
2033
2055
|
const UNPUBLISH_POLL_INTERVAL_MS = 2e3;
|
|
2034
2056
|
const verifyEffect = async () => {
|
|
2035
2057
|
const wrapper = this.clientWrapper;
|
|
@@ -2737,9 +2759,11 @@ export {
|
|
|
2737
2759
|
TX_NO_PROGRESS_MS,
|
|
2738
2760
|
WS_HEARTBEAT_TIMEOUT_MS,
|
|
2739
2761
|
DOTNS_TX_MAX_ATTEMPTS,
|
|
2762
|
+
VERIFY_EFFECT_CHAIN_SECONDS,
|
|
2740
2763
|
classifyTxRetryDecision,
|
|
2741
2764
|
dotnsRetryBackoffMs,
|
|
2742
2765
|
shouldRetryTxAttempt,
|
|
2766
|
+
shouldRegateBeforeResign,
|
|
2743
2767
|
makeRetryStatusFilter,
|
|
2744
2768
|
DEFAULT_MNEMONIC,
|
|
2745
2769
|
fetchNonce,
|
|
@@ -14,6 +14,7 @@ var environments_default = {
|
|
|
14
14
|
name: "Preview",
|
|
15
15
|
network: "testnet",
|
|
16
16
|
description: "Product Preview net, used by Product Teams",
|
|
17
|
+
bulletinAutoAuthorize: true,
|
|
17
18
|
e2eEligible: true,
|
|
18
19
|
backend: "https://polkadot-app-stg.parity.io/",
|
|
19
20
|
ipfs: "https://previewnet.substrate.dev",
|
|
@@ -105,6 +106,7 @@ var environments_default = {
|
|
|
105
106
|
name: "Paseo Next v2",
|
|
106
107
|
network: "testnet",
|
|
107
108
|
description: "Next iteration of the Paseo Next testnet",
|
|
109
|
+
bulletinAutoAuthorize: true,
|
|
108
110
|
e2eEligible: true,
|
|
109
111
|
backend: "https://identity-backend-next.parity-testnet.parity.io",
|
|
110
112
|
ipfs: "https://paseo-bulletin-next-ipfs.polkadot.io",
|
|
@@ -652,7 +654,8 @@ function resolveEndpoints(doc, envId) {
|
|
|
652
654
|
autoAccountMapping: env.autoAccountMapping ?? false,
|
|
653
655
|
contracts: env.contracts ?? {},
|
|
654
656
|
nativeToEthRatio: BigInt(env.nativeToEthRatio ?? 1e6),
|
|
655
|
-
...env.registerStorageDeposit !== void 0 ? { registerStorageDeposit: BigInt(env.registerStorageDeposit) } : {}
|
|
657
|
+
...env.registerStorageDeposit !== void 0 ? { registerStorageDeposit: BigInt(env.registerStorageDeposit) } : {},
|
|
658
|
+
bulletinAutoAuthorize: env.bulletinAutoAuthorize ?? false
|
|
656
659
|
};
|
|
657
660
|
}
|
|
658
661
|
function getPopSelfServeConfig(doc, envId) {
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-TSPERKUS.js";
|
|
4
4
|
import {
|
|
5
5
|
VERSION
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UIDRWZWX.js";
|
|
7
7
|
import {
|
|
8
8
|
loadEnvironments
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JSYQ3JQS.js";
|
|
10
10
|
|
|
11
11
|
// src/auth-config.ts
|
|
12
12
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -100,17 +100,38 @@ function clampU32(n, name) {
|
|
|
100
100
|
if (n > U32_MAX) throw new Error(`${name} (${n}) exceeds u32 max \u2014 split the deploy into smaller batches`);
|
|
101
101
|
return Number(n);
|
|
102
102
|
}
|
|
103
|
-
async function ensureAuthorized(api, address, label) {
|
|
103
|
+
async function ensureAuthorized(api, address, label, opts = {}) {
|
|
104
104
|
const [auth, currentBlock] = await Promise.all([
|
|
105
105
|
api.query.TransactionStorage.Authorizations.getValue(Enum("Account", address)),
|
|
106
106
|
api.query.System.Number.getValue()
|
|
107
107
|
]);
|
|
108
108
|
if (isAuthorizationSufficient(auth, currentBlock)) return;
|
|
109
|
-
const isTestnet = await detectTestnet(api);
|
|
110
109
|
const who = `${label ?? "account"} (${address.slice(0, 8)}...)`;
|
|
110
|
+
if (opts.autoAuthorize) {
|
|
111
|
+
await cryptoWaitReady();
|
|
112
|
+
const keyring = new Keyring({ type: "sr25519" });
|
|
113
|
+
const alice = keyring.addFromUri("//Alice");
|
|
114
|
+
const signer = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
|
|
115
|
+
const grant = `${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`;
|
|
116
|
+
console.log(` Auto-authorizing ${who} on Bulletin (${grant})...`);
|
|
117
|
+
const tx = api.tx.TransactionStorage.authorize_account({
|
|
118
|
+
who: address,
|
|
119
|
+
transactions: clampU32(BigInt(TOPUP_TRANSACTIONS), "transactions"),
|
|
120
|
+
bytes: TOPUP_BYTES
|
|
121
|
+
});
|
|
122
|
+
const result = await tx.signAndSubmit(signer);
|
|
123
|
+
if (!result?.ok) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Auto-authorization of Bulletin storage account ${who} failed: authorize_account was rejected. This environment is flagged bulletinAutoAuthorize, but //Alice may not hold authorizer rights on this chain.`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
console.log(` Authorized: ${grant}`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const isTestnet = await detectTestnet(api);
|
|
111
132
|
if (isTestnet) {
|
|
112
133
|
throw new Error(
|
|
113
|
-
`Bulletin storage account ${who} is not authorized (or its authorization expired). bulletin-deploy
|
|
134
|
+
`Bulletin storage account ${who} is not authorized (or its authorization expired). bulletin-deploy self-authorizes only on allow-listed testnets (environments.json bulletinAutoAuthorize) \u2014 request authorization for this account from the chain's authorizer (testnet faucet / personhood / pool bootstrap), then retry.`
|
|
114
135
|
);
|
|
115
136
|
}
|
|
116
137
|
throw new Error(
|
|
@@ -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-KBKS3V2V.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_MNEMONIC
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ITXKADHO.js";
|
|
11
11
|
|
|
12
12
|
// src/deploy-actors.ts
|
|
13
13
|
var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
|
|
@@ -23,8 +23,18 @@ async function resolveDeployActors(authClient, { suri, transferEnabled, isTestne
|
|
|
23
23
|
if (sessionPresent && transferEnabled) {
|
|
24
24
|
if (!suri && !isTestnet) throw new MainnetDefaultWorkerError();
|
|
25
25
|
const worker2 = await resolveSigner(authClient, { suri: suri ?? DEFAULT_WORKER_SURI });
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
let handle = null;
|
|
27
|
+
try {
|
|
28
|
+
handle = await authClient.getSessionSigner();
|
|
29
|
+
} catch {
|
|
30
|
+
handle = null;
|
|
31
|
+
}
|
|
32
|
+
if (!handle) {
|
|
33
|
+
console.error(
|
|
34
|
+
"\u26A0 Found a login session on disk but couldn't load it \u2014 deploying without transfer (the worker signs directly). Log in again if you meant to transfer to your account."
|
|
35
|
+
);
|
|
36
|
+
return { worker: worker2 };
|
|
37
|
+
}
|
|
28
38
|
try {
|
|
29
39
|
return { worker: worker2, recipientH160: handle.addresses.productH160 };
|
|
30
40
|
} finally {
|