bulletin-deploy 0.14.1 → 0.14.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 +3 -0
- package/bin/bulletin-bootstrap +7 -0
- package/dist/auth-config.js +4 -4
- package/dist/bug-report.js +4 -4
- package/dist/chain-health.d.ts +139 -0
- package/dist/chain-health.js +14 -0
- package/dist/{chunk-DAFCH55Q.js → chunk-37AN2MHU.js} +2 -2
- package/dist/{chunk-42BNXFWF.js → chunk-6LD3Z2HM.js} +39 -36
- package/dist/{chunk-YDV7M3V2.js → chunk-7V4B775S.js} +3 -3
- package/dist/{chunk-ALTGYSBJ.js → chunk-CRZSDUWV.js} +1 -1
- package/dist/{chunk-AB62NERW.js → chunk-FMQLBYOR.js} +15 -8
- package/dist/{chunk-L7DCLCCK.js → chunk-GEHOB4PE.js} +1 -1
- package/dist/{chunk-4AEFFDHP.js → chunk-IJUKTHEP.js} +8 -2
- package/dist/{chunk-5ZR5L37D.js → chunk-REB37WWY.js} +4 -4
- package/dist/{chunk-PQK6XT6Z.js → chunk-RIQWW2BT.js} +8 -8
- package/dist/{chunk-5NQHQFMH.js → chunk-T2S5M6OH.js} +1 -1
- package/dist/chunk-UDJAYGYU.js +226 -0
- package/dist/{chunk-NLRGFZMQ.js → chunk-VH2HNQG2.js} +17 -1
- package/dist/{chunk-E6J46GNK.js → chunk-XQHRKK7M.js} +5 -1
- package/dist/{chunk-O5TJWVGZ.js → chunk-ZPWTXUA6.js} +7 -6
- package/dist/chunk-probe.js +3 -3
- package/dist/commands/login.js +13 -12
- package/dist/commands/logout.js +5 -5
- package/dist/commands/transfer.js +6 -5
- package/dist/commands/whoami.js +4 -4
- package/dist/deploy-actors.js +8 -7
- package/dist/deploy.js +13 -12
- package/dist/dotns.d.ts +2 -0
- package/dist/dotns.js +6 -5
- package/dist/environments.d.ts +2 -0
- package/dist/environments.js +1 -1
- package/dist/index.js +23 -22
- package/dist/manifest/publish.js +14 -13
- package/dist/memory-report.js +2 -2
- package/dist/merkle.js +13 -12
- package/dist/personhood/bootstrap.js +6 -5
- package/dist/personhood/people-client.js +6 -5
- package/dist/pool.d.ts +2 -0
- 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 +13 -12
- package/dist/telemetry.d.ts +23 -1
- package/dist/telemetry.js +4 -2
- package/dist/version-check.js +3 -3
- package/package.json +7 -6
- package/tools/release-retry-wrapper.mjs +7 -0
package/assets/environments.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"network": "testnet",
|
|
7
7
|
"description": "Product Preview net, used by Product Teams",
|
|
8
8
|
"bulletinAutoAuthorize": true,
|
|
9
|
+
"bulletinAuthorizer": "//Eve",
|
|
9
10
|
"e2eEligible": true,
|
|
10
11
|
"backend": "https://polkadot-app-stg.parity.io/",
|
|
11
12
|
"ipfs": "https://previewnet.substrate.dev",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"description": "Previewnet bare-Rust PolkaVM DotNS deployment",
|
|
44
45
|
"ipfs": "https://previewnet.substrate.dev",
|
|
45
46
|
"webGateway": "testnet.li",
|
|
47
|
+
"bulletinAuthorizer": "//Eve",
|
|
46
48
|
"autoAccountMapping": true,
|
|
47
49
|
"nativeToEthRatio": 100000000,
|
|
48
50
|
"registerStorageDeposit": 2000000000000,
|
|
@@ -99,6 +101,7 @@
|
|
|
99
101
|
"network": "testnet",
|
|
100
102
|
"description": "Next iteration of the Paseo Next testnet",
|
|
101
103
|
"bulletinAutoAuthorize": true,
|
|
104
|
+
"bulletinAuthorizer": "//Alice",
|
|
102
105
|
"e2eEligible": true,
|
|
103
106
|
"backend": "https://identity-backend-next.parity-testnet.parity.io",
|
|
104
107
|
"ipfs": "https://paseo-bulletin-next-ipfs.polkadot.io",
|
package/bin/bulletin-bootstrap
CHANGED
|
@@ -117,6 +117,13 @@ if (flags.env) {
|
|
|
117
117
|
|
|
118
118
|
bootstrapOpts.bulletinAuthorizeV2 = envEntry.bulletinAuthorizeV2 ?? false;
|
|
119
119
|
|
|
120
|
+
// #1209: which key holds TransactionStorage authorizer rights on this env's
|
|
121
|
+
// Bulletin chain. Not always //Alice — previewnet's sole AllowedAuthorizers
|
|
122
|
+
// entry is //Eve. An explicit --authorizer still wins (set above).
|
|
123
|
+
if (envEntry.bulletinAuthorizer) {
|
|
124
|
+
bootstrapOpts.envAuthorizer = envEntry.bulletinAuthorizer;
|
|
125
|
+
}
|
|
126
|
+
|
|
120
127
|
if (flags.preCheck) {
|
|
121
128
|
// #1059: widen the "needs authorization" threshold to 24h-before-expiry,
|
|
122
129
|
// and hard-gate the actual write to environments cleared for it. This is
|
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-REB37WWY.js";
|
|
13
13
|
import "./chunk-TSPERKUS.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-O5TJWVGZ.js";
|
|
16
|
-
import "./chunk-E6J46GNK.js";
|
|
14
|
+
import "./chunk-XQHRKK7M.js";
|
|
17
15
|
import "./chunk-ZOC4GITL.js";
|
|
16
|
+
import "./chunk-VH2HNQG2.js";
|
|
17
|
+
import "./chunk-ZPWTXUA6.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-7V4B775S.js";
|
|
14
|
+
import "./chunk-GEHOB4PE.js";
|
|
15
|
+
import "./chunk-VH2HNQG2.js";
|
|
16
|
+
import "./chunk-ZPWTXUA6.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
19
19
|
buildLabels,
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain-health sampling — measures what the chain was doing underneath a deploy.
|
|
3
|
+
*
|
|
4
|
+
* Motivation: deploy latency drifted ~17% on paseo-next-v2 over the second half
|
|
5
|
+
* of July 2026 while the Bulletin storage phase stayed flat, pointing at Asset
|
|
6
|
+
* Hub extrinsic inclusion. That diagnosis had to be reconstructed by subtracting
|
|
7
|
+
* child-span durations after the fact, because we emit nothing about the chain
|
|
8
|
+
* itself. This module closes that gap.
|
|
9
|
+
*
|
|
10
|
+
* Design note — why interval spans rather than numeric attributes:
|
|
11
|
+
* `@sentry/node` user-defined attributes come back string-typed in EAP no matter
|
|
12
|
+
* how they're set, so `avg()`/`p95()` refuse to run on them (see the numeric
|
|
13
|
+
* attribute caveat in CLAUDE.md). `span.duration` is a built-in numeric column
|
|
14
|
+
* and does aggregate. All three signals here are genuinely elapsed wall-clock
|
|
15
|
+
* intervals, so encoding each as a span whose duration IS the measurement is
|
|
16
|
+
* honest — nothing synthetic — and it is the only shape that gives us
|
|
17
|
+
* `p50(span.duration)` charts.
|
|
18
|
+
*/
|
|
19
|
+
/** Which chain a sampler is watching. Kept to the two that bound deploy time. */
|
|
20
|
+
type ChainHealthChainId = "bulletin" | "asset-hub";
|
|
21
|
+
/**
|
|
22
|
+
* Minimal slice of papi's PolkadotClient that the sampler needs. Declared
|
|
23
|
+
* structurally rather than importing PolkadotClient so tests can drive the
|
|
24
|
+
* sampler with a scripted block stream and no chain.
|
|
25
|
+
*/
|
|
26
|
+
interface ChainHealthClient {
|
|
27
|
+
blocks$: {
|
|
28
|
+
subscribe(observer: {
|
|
29
|
+
next: (block: {
|
|
30
|
+
hash: string;
|
|
31
|
+
number: number;
|
|
32
|
+
}) => void;
|
|
33
|
+
error?: (e: unknown) => void;
|
|
34
|
+
}): {
|
|
35
|
+
unsubscribe(): void;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
finalizedBlock$: {
|
|
39
|
+
subscribe(observer: {
|
|
40
|
+
next: (block: {
|
|
41
|
+
hash: string;
|
|
42
|
+
number: number;
|
|
43
|
+
}) => void;
|
|
44
|
+
error?: (e: unknown) => void;
|
|
45
|
+
}): {
|
|
46
|
+
unsubscribe(): void;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
getBlockHeader(hash: string): Promise<unknown>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Blocks per measurement window. 10 smooths per-block jitter without delaying
|
|
53
|
+
* the first sample past a median-length deploy.
|
|
54
|
+
*/
|
|
55
|
+
declare const DEFAULT_WINDOW_BLOCKS = 10;
|
|
56
|
+
/**
|
|
57
|
+
* Hard cap on spans emitted per sampler, per deploy. A pathological multi-hour
|
|
58
|
+
* deploy must not emit thousands. Hitting it is reported, never silent.
|
|
59
|
+
*/
|
|
60
|
+
declare const MAX_SPANS_PER_SAMPLER = 60;
|
|
61
|
+
/**
|
|
62
|
+
* Strip a wss:// endpoint down to its host. The endpoints in environments.json
|
|
63
|
+
* carry no credentials today; host-only keeps it that way by construction and
|
|
64
|
+
* keeps attribute cardinality at a handful of values.
|
|
65
|
+
*/
|
|
66
|
+
declare function endpointHost(endpoint: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Watches one chain and emits `chain.health.*` interval spans.
|
|
69
|
+
*
|
|
70
|
+
* Lifecycle is attach/detach rather than a one-shot start/stop because the
|
|
71
|
+
* Bulletin client is destroyed and recreated mid-deploy during WS-halt
|
|
72
|
+
* recovery (deploy.ts) and the Asset Hub client is recreated by
|
|
73
|
+
* `recreateReviveClient` (dotns.ts, the #1131 retry path). Each recreation
|
|
74
|
+
* re-attaches; the in-flight window is discarded rather than emitted, because
|
|
75
|
+
* a window spanning a reconnect measures our outage, not the chain's block
|
|
76
|
+
* rate, and would silently poison the metric this exists to provide.
|
|
77
|
+
*/
|
|
78
|
+
declare class ChainHealthSampler {
|
|
79
|
+
private readonly chainId;
|
|
80
|
+
private readonly windowBlocks;
|
|
81
|
+
private host;
|
|
82
|
+
private blocksSub;
|
|
83
|
+
private finalizedSub;
|
|
84
|
+
/** Wall-clock of the block that opened the current window. */
|
|
85
|
+
private windowStartMs;
|
|
86
|
+
private windowStartBlock;
|
|
87
|
+
/** blockNumber -> first-seen wall clock, FIFO-evicted at MAX_TRACKED_BLOCKS. */
|
|
88
|
+
private firstSeen;
|
|
89
|
+
private spansEmitted;
|
|
90
|
+
private capReported;
|
|
91
|
+
/** Set once a window closes, so exactly one ping is issued per window. */
|
|
92
|
+
private pingInFlight;
|
|
93
|
+
/**
|
|
94
|
+
* True while `blocks$.subscribe()` is replaying history.
|
|
95
|
+
*
|
|
96
|
+
* papi documents that on subscribe it synchronously emits the latest
|
|
97
|
+
* finalized block and every known descendant. Those arrive microseconds
|
|
98
|
+
* apart, so letting them close a window would report a near-zero elapsed
|
|
99
|
+
* time and mark the chain as impossibly fast — corrupting the exact metric
|
|
100
|
+
* this module exists to produce. Replayed blocks still record first-seen
|
|
101
|
+
* times (finality lag needs them) and still move the window anchor forward,
|
|
102
|
+
* so timing starts from the moment we caught up rather than in stale history.
|
|
103
|
+
*/
|
|
104
|
+
private inReplay;
|
|
105
|
+
constructor(chainId: ChainHealthChainId, windowBlocks?: number);
|
|
106
|
+
/**
|
|
107
|
+
* Subscribe to a (re)created client. Safe to call repeatedly — an existing
|
|
108
|
+
* subscription is torn down first. Never throws: a sampler failure must not
|
|
109
|
+
* be able to fail a deploy.
|
|
110
|
+
*/
|
|
111
|
+
attach(client: ChainHealthClient, endpoint: string): void;
|
|
112
|
+
/** Unsubscribe and drop the partial window. Idempotent. */
|
|
113
|
+
detach(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Detach and reset per-deploy state. Call from the deploy's teardown.
|
|
116
|
+
*
|
|
117
|
+
* Resetting the span budget here (rather than in attach()) is deliberate.
|
|
118
|
+
* attach() also runs on mid-deploy reconnects, where clearing the counter
|
|
119
|
+
* would defeat the cap; stop() runs exactly once per deploy. deploy.ts holds
|
|
120
|
+
* its Bulletin sampler at module scope, so without this a second deploy() in
|
|
121
|
+
* the same process — playground-cli consumes deploy() as a library — would
|
|
122
|
+
* inherit the first deploy's exhausted budget and emit nothing.
|
|
123
|
+
*/
|
|
124
|
+
stop(): void;
|
|
125
|
+
/** True while subscribed — used by tests and by re-attach guards. */
|
|
126
|
+
get attached(): boolean;
|
|
127
|
+
private resetWindow;
|
|
128
|
+
private atCap;
|
|
129
|
+
private onBlock;
|
|
130
|
+
private onFinalized;
|
|
131
|
+
/**
|
|
132
|
+
* Time one `getBlockHeader` round-trip. Separates "the chain is producing
|
|
133
|
+
* blocks slowly" from "our link to this endpoint is slow" — the endpoints are
|
|
134
|
+
* load-balanced, so those are genuinely different failures.
|
|
135
|
+
*/
|
|
136
|
+
private ping;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export { type ChainHealthChainId, type ChainHealthClient, ChainHealthSampler, DEFAULT_WINDOW_BLOCKS, MAX_SPANS_PER_SAMPLER, endpointHost };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChainHealthSampler,
|
|
3
|
+
DEFAULT_WINDOW_BLOCKS,
|
|
4
|
+
MAX_SPANS_PER_SAMPLER,
|
|
5
|
+
endpointHost
|
|
6
|
+
} from "./chunk-UDJAYGYU.js";
|
|
7
|
+
import "./chunk-VH2HNQG2.js";
|
|
8
|
+
import "./chunk-ZPWTXUA6.js";
|
|
9
|
+
export {
|
|
10
|
+
ChainHealthSampler,
|
|
11
|
+
DEFAULT_WINDOW_BLOCKS,
|
|
12
|
+
MAX_SPANS_PER_SAMPLER,
|
|
13
|
+
endpointHost
|
|
14
|
+
};
|
|
@@ -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-REB37WWY.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_MNEMONIC
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FMQLBYOR.js";
|
|
11
11
|
|
|
12
12
|
// src/deploy-actors.ts
|
|
13
13
|
var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
preflightSssAllowance
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-T2S5M6OH.js";
|
|
4
4
|
import {
|
|
5
5
|
statementSigningAccount
|
|
6
6
|
} from "./chunk-GRPLHUYC.js";
|
|
@@ -31,18 +31,18 @@ import {
|
|
|
31
31
|
} from "./chunk-S7EM5VMW.js";
|
|
32
32
|
import {
|
|
33
33
|
setDeployContext
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-7V4B775S.js";
|
|
35
35
|
import {
|
|
36
36
|
getBestBlockNumber,
|
|
37
37
|
probeChunks,
|
|
38
38
|
probeFinalityGap
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-CRZSDUWV.js";
|
|
40
40
|
import {
|
|
41
41
|
packSection
|
|
42
42
|
} from "./chunk-C2TS5MER.js";
|
|
43
43
|
import {
|
|
44
44
|
resolveStorageSigner
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-37AN2MHU.js";
|
|
46
46
|
import {
|
|
47
47
|
createSlotAccountSigner,
|
|
48
48
|
requestResourceAllocation
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
STALE_SESSION_MESSAGE,
|
|
52
52
|
getPeopleChainEndpoints,
|
|
53
53
|
hasPersistedSession
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-REB37WWY.js";
|
|
55
55
|
import {
|
|
56
56
|
CLI_NAME
|
|
57
57
|
} from "./chunk-TSPERKUS.js";
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
parseDomainName,
|
|
67
67
|
popStatusName,
|
|
68
68
|
verifyNonceAdvanced
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-FMQLBYOR.js";
|
|
70
70
|
import {
|
|
71
71
|
derivePoolAccounts,
|
|
72
72
|
detectTestnet,
|
|
@@ -74,7 +74,19 @@ import {
|
|
|
74
74
|
fetchPoolAuthorizations,
|
|
75
75
|
isAuthorizationSufficient,
|
|
76
76
|
selectAccount
|
|
77
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-IJUKTHEP.js";
|
|
78
|
+
import {
|
|
79
|
+
DEFAULT_ENV_ID,
|
|
80
|
+
getPopSelfServeConfig,
|
|
81
|
+
loadEnvironments,
|
|
82
|
+
resolveEndpoints
|
|
83
|
+
} from "./chunk-XQHRKK7M.js";
|
|
84
|
+
import {
|
|
85
|
+
NonRetryableError
|
|
86
|
+
} from "./chunk-ZOC4GITL.js";
|
|
87
|
+
import {
|
|
88
|
+
ChainHealthSampler
|
|
89
|
+
} from "./chunk-UDJAYGYU.js";
|
|
78
90
|
import {
|
|
79
91
|
VERSION,
|
|
80
92
|
captureWarning,
|
|
@@ -88,16 +100,7 @@ import {
|
|
|
88
100
|
truncateAddress,
|
|
89
101
|
withDeploySpan,
|
|
90
102
|
withSpan
|
|
91
|
-
} from "./chunk-
|
|
92
|
-
import {
|
|
93
|
-
DEFAULT_ENV_ID,
|
|
94
|
-
getPopSelfServeConfig,
|
|
95
|
-
loadEnvironments,
|
|
96
|
-
resolveEndpoints
|
|
97
|
-
} from "./chunk-E6J46GNK.js";
|
|
98
|
-
import {
|
|
99
|
-
NonRetryableError
|
|
100
|
-
} from "./chunk-ZOC4GITL.js";
|
|
103
|
+
} from "./chunk-VH2HNQG2.js";
|
|
101
104
|
|
|
102
105
|
// src/merkle.ts
|
|
103
106
|
import * as fs2 from "fs";
|
|
@@ -416,6 +419,7 @@ function setBulletinEndpoints(endpoints) {
|
|
|
416
419
|
BULLETIN_ENDPOINTS = endpoints;
|
|
417
420
|
}
|
|
418
421
|
var bulletinAutoAuthorize = false;
|
|
422
|
+
var bulletinAuthorizer;
|
|
419
423
|
var _deployRpcFailedOver = false;
|
|
420
424
|
var _onWsHalt = null;
|
|
421
425
|
function setWsHaltCallback(cb) {
|
|
@@ -542,14 +546,22 @@ function toHashingEnum(mhCode) {
|
|
|
542
546
|
throw new Error(`Unhandled multihash code: ${mhCode}`);
|
|
543
547
|
}
|
|
544
548
|
}
|
|
545
|
-
|
|
549
|
+
var bulletinChainHealth = new ChainHealthSampler("bulletin");
|
|
550
|
+
function stopBulletinChainHealth() {
|
|
551
|
+
bulletinChainHealth.stop();
|
|
552
|
+
}
|
|
553
|
+
function createBulletinClient() {
|
|
546
554
|
const primary = BULLETIN_ENDPOINTS[0];
|
|
547
555
|
console.log(` Connecting to Bulletin: ${primary}`);
|
|
548
556
|
const client = createPolkadotClient2(getWsProvider2(
|
|
549
557
|
BULLETIN_ENDPOINTS,
|
|
550
558
|
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS, onStatusChanged: makeBulletinStatusHandler(primary) }
|
|
551
559
|
));
|
|
552
|
-
|
|
560
|
+
bulletinChainHealth.attach(client, primary);
|
|
561
|
+
return { client, unsafeApi: client.getUnsafeApi() };
|
|
562
|
+
}
|
|
563
|
+
async function getProvider() {
|
|
564
|
+
const { client, unsafeApi } = createBulletinClient();
|
|
553
565
|
try {
|
|
554
566
|
await cryptoWaitReady();
|
|
555
567
|
const poolMnemonic = process.env.BULLETIN_POOL_MNEMONIC || void 0;
|
|
@@ -567,7 +579,7 @@ async function getProvider() {
|
|
|
567
579
|
const selectionResult = selectAccount(authorizations, Math.random, pinnedPoolIndex);
|
|
568
580
|
const selectedAccount = selectionResult.account;
|
|
569
581
|
const eligibleCount = selectionResult.eligibleCount;
|
|
570
|
-
await ensureAuthorized(unsafeApi, selectedAccount.address, `pool account ${selectedAccount.index}`, { autoAuthorize: bulletinAutoAuthorize });
|
|
582
|
+
await ensureAuthorized(unsafeApi, selectedAccount.address, `pool account ${selectedAccount.index}`, { autoAuthorize: bulletinAutoAuthorize, authorizer: bulletinAuthorizer });
|
|
571
583
|
console.log(` Using pool account ${selectedAccount.index}: ${selectedAccount.address}`);
|
|
572
584
|
setDeployAttribute("deploy.signer.mode", "pool");
|
|
573
585
|
setDeployAttribute("deploy.pool.account", truncateAddress(selectedAccount.address));
|
|
@@ -580,13 +592,7 @@ async function getProvider() {
|
|
|
580
592
|
}
|
|
581
593
|
}
|
|
582
594
|
async function getDirectProvider(mnemonic, derivationPath = "") {
|
|
583
|
-
const
|
|
584
|
-
console.log(` Connecting to Bulletin: ${primary}`);
|
|
585
|
-
const client = createPolkadotClient2(getWsProvider2(
|
|
586
|
-
BULLETIN_ENDPOINTS,
|
|
587
|
-
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS, onStatusChanged: makeBulletinStatusHandler(primary) }
|
|
588
|
-
));
|
|
589
|
-
const unsafeApi = client.getUnsafeApi();
|
|
595
|
+
const { client, unsafeApi } = createBulletinClient();
|
|
590
596
|
const { signer, ss58 } = deriveRootSigner(mnemonic, derivationPath);
|
|
591
597
|
console.log(` Using direct signer: ${ss58}${derivationPath ? ` (path: ${derivationPath})` : ""}`);
|
|
592
598
|
let [auth, currentBlock] = await Promise.all([
|
|
@@ -596,7 +602,7 @@ async function getDirectProvider(mnemonic, derivationPath = "") {
|
|
|
596
602
|
let now = currentBlock.number;
|
|
597
603
|
if (!auth || Number(auth.expiration ?? 0) <= now) {
|
|
598
604
|
try {
|
|
599
|
-
await ensureAuthorized(unsafeApi, ss58, "direct signer", { autoAuthorize: bulletinAutoAuthorize });
|
|
605
|
+
await ensureAuthorized(unsafeApi, ss58, "direct signer", { autoAuthorize: bulletinAutoAuthorize, authorizer: bulletinAuthorizer });
|
|
600
606
|
[auth, currentBlock] = await Promise.all([
|
|
601
607
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
602
608
|
client.getFinalizedBlock()
|
|
@@ -613,13 +619,7 @@ async function getDirectProvider(mnemonic, derivationPath = "") {
|
|
|
613
619
|
return { client, unsafeApi, signer, ss58 };
|
|
614
620
|
}
|
|
615
621
|
async function getSignerProvider(signer, ss58) {
|
|
616
|
-
const
|
|
617
|
-
console.log(` Connecting to Bulletin: ${primary}`);
|
|
618
|
-
const client = createPolkadotClient2(getWsProvider2(
|
|
619
|
-
BULLETIN_ENDPOINTS,
|
|
620
|
-
{ heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS, onStatusChanged: makeBulletinStatusHandler(primary) }
|
|
621
|
-
));
|
|
622
|
-
const unsafeApi = client.getUnsafeApi();
|
|
622
|
+
const { client, unsafeApi } = createBulletinClient();
|
|
623
623
|
console.log(` Using external signer: ${ss58}`);
|
|
624
624
|
let [auth, currentBlock] = await Promise.all([
|
|
625
625
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
@@ -628,7 +628,7 @@ async function getSignerProvider(signer, ss58) {
|
|
|
628
628
|
let now = currentBlock.number;
|
|
629
629
|
if (!auth || Number(auth.expiration ?? 0) <= now) {
|
|
630
630
|
try {
|
|
631
|
-
await ensureAuthorized(unsafeApi, ss58, "external signer", { autoAuthorize: bulletinAutoAuthorize });
|
|
631
|
+
await ensureAuthorized(unsafeApi, ss58, "external signer", { autoAuthorize: bulletinAutoAuthorize, authorizer: bulletinAuthorizer });
|
|
632
632
|
[auth, currentBlock] = await Promise.all([
|
|
633
633
|
unsafeApi.query.TransactionStorage.Authorizations.getValue(Enum2("Account", ss58)),
|
|
634
634
|
client.getFinalizedBlock()
|
|
@@ -2130,6 +2130,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2130
2130
|
let envRegisterStorageDeposit;
|
|
2131
2131
|
let envPopSelfServe = null;
|
|
2132
2132
|
bulletinAutoAuthorize = false;
|
|
2133
|
+
bulletinAuthorizer = void 0;
|
|
2133
2134
|
if (options.bulletinEndpoints && options.bulletinEndpoints.length > 0) {
|
|
2134
2135
|
envBulletin = options.bulletinEndpoints;
|
|
2135
2136
|
envAssetHub = options.assetHubEndpoints;
|
|
@@ -2150,6 +2151,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2150
2151
|
envRegisterStorageDeposit = resolved.registerStorageDeposit;
|
|
2151
2152
|
envPopSelfServe = getPopSelfServeConfig(doc, envId);
|
|
2152
2153
|
bulletinAutoAuthorize = resolved.bulletinAutoAuthorize;
|
|
2154
|
+
bulletinAuthorizer = resolved.bulletinAuthorizer;
|
|
2153
2155
|
} catch (e) {
|
|
2154
2156
|
if (e instanceof NonRetryableError) throw e;
|
|
2155
2157
|
if (options.env !== void 0) throw e;
|
|
@@ -2718,6 +2720,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
2718
2720
|
return { domainName: name, fullDomain: `${name}.dot`, cid, ipfsCid };
|
|
2719
2721
|
} finally {
|
|
2720
2722
|
if (_deployRpcFailedOver) setDeployAttribute("deploy.rpc.failed_over", "true");
|
|
2723
|
+
stopBulletinChainHealth();
|
|
2721
2724
|
provider?.client.destroy();
|
|
2722
2725
|
}
|
|
2723
2726
|
});
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-GEHOB4PE.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId,
|
|
9
9
|
resolveIssueRepoSlug
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-VH2HNQG2.js";
|
|
11
11
|
import {
|
|
12
12
|
package_default
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ZPWTXUA6.js";
|
|
14
14
|
|
|
15
15
|
// src/bug-report.ts
|
|
16
16
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -3,7 +3,16 @@ import {
|
|
|
3
3
|
} from "./chunk-SI2ZUOYD.js";
|
|
4
4
|
import {
|
|
5
5
|
isTestnetSpecName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IJUKTHEP.js";
|
|
7
|
+
import {
|
|
8
|
+
validateContractAddresses
|
|
9
|
+
} from "./chunk-XQHRKK7M.js";
|
|
10
|
+
import {
|
|
11
|
+
NonRetryableError
|
|
12
|
+
} from "./chunk-ZOC4GITL.js";
|
|
13
|
+
import {
|
|
14
|
+
ChainHealthSampler
|
|
15
|
+
} from "./chunk-UDJAYGYU.js";
|
|
7
16
|
import {
|
|
8
17
|
captureWarning,
|
|
9
18
|
markCodePath,
|
|
@@ -11,13 +20,7 @@ import {
|
|
|
11
20
|
setDeploySentryTag,
|
|
12
21
|
truncateAddress,
|
|
13
22
|
withSpan
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
validateContractAddresses
|
|
17
|
-
} from "./chunk-E6J46GNK.js";
|
|
18
|
-
import {
|
|
19
|
-
NonRetryableError
|
|
20
|
-
} from "./chunk-ZOC4GITL.js";
|
|
23
|
+
} from "./chunk-VH2HNQG2.js";
|
|
21
24
|
|
|
22
25
|
// src/dotns.ts
|
|
23
26
|
import crypto from "crypto";
|
|
@@ -1238,6 +1241,8 @@ var DotNS = class {
|
|
|
1238
1241
|
_phoneSignatureTotal = 0;
|
|
1239
1242
|
/** Running attempt counter per label for re-sign detection. Reset at connect/disconnect. */
|
|
1240
1243
|
_phoneSignatureAttempts = /* @__PURE__ */ new Map();
|
|
1244
|
+
/** Samples Asset Hub block rate / finality lag / RPC latency for the life of this connection. */
|
|
1245
|
+
chainHealth = new ChainHealthSampler("asset-hub");
|
|
1241
1246
|
// Test-only seam: consumed once by classifyAliasAccountState() then cleared.
|
|
1242
1247
|
// Mirrors the __setDeployRootSpanForTest / __setSentryForTest pattern.
|
|
1243
1248
|
_classifyOverrideForTest = null;
|
|
@@ -1285,6 +1290,7 @@ var DotNS = class {
|
|
|
1285
1290
|
}
|
|
1286
1291
|
this.client = createClient(getWsProvider(endpoint, { heartbeatTimeout: WS_HEARTBEAT_TIMEOUT_MS }));
|
|
1287
1292
|
this.clientWrapper = new ReviveClientWrapper(this.client.getUnsafeApi());
|
|
1293
|
+
this.chainHealth.attach(this.client, endpoint);
|
|
1288
1294
|
}
|
|
1289
1295
|
async connect(options = {}) {
|
|
1290
1296
|
if (options.assetHubEndpoints && options.assetHubEndpoints.length > 0) {
|
|
@@ -3067,6 +3073,7 @@ var DotNS = class {
|
|
|
3067
3073
|
this._onPhoneSigningRequired?.(label);
|
|
3068
3074
|
}
|
|
3069
3075
|
disconnect() {
|
|
3076
|
+
this.chainHealth.stop();
|
|
3070
3077
|
if (this.client) {
|
|
3071
3078
|
this.client.destroy();
|
|
3072
3079
|
this.client = null;
|
|
@@ -127,7 +127,8 @@ async function ensureAuthorized(api, address, label, opts = {}) {
|
|
|
127
127
|
if (opts.autoAuthorize) {
|
|
128
128
|
await cryptoWaitReady();
|
|
129
129
|
const keyring = new Keyring({ type: "sr25519" });
|
|
130
|
-
const
|
|
130
|
+
const authorizerUri = opts.authorizer ?? "//Alice";
|
|
131
|
+
const alice = keyring.addFromUri(authorizerUri);
|
|
131
132
|
const signer = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
|
|
132
133
|
const grant = `${TOPUP_TRANSACTIONS} txs / ${Number(TOPUP_BYTES) / 1e6}MB`;
|
|
133
134
|
console.log(` Auto-authorizing ${who} on Bulletin (${grant})...`);
|
|
@@ -139,7 +140,7 @@ async function ensureAuthorized(api, address, label, opts = {}) {
|
|
|
139
140
|
const result = await tx.signAndSubmit(signer);
|
|
140
141
|
if (!result?.ok) {
|
|
141
142
|
throw new Error(
|
|
142
|
-
`Auto-authorization of Bulletin storage account ${who} failed: authorize_account was rejected. This environment is flagged bulletinAutoAuthorize, but
|
|
143
|
+
`Auto-authorization of Bulletin storage account ${who} failed: authorize_account was rejected. This environment is flagged bulletinAutoAuthorize and signed as ${authorizerUri}, but that key may not hold authorizer rights on this chain \u2014 check TransactionStorage.AllowedAuthorizers and set the env's bulletinAuthorizer accordingly.`
|
|
143
144
|
);
|
|
144
145
|
}
|
|
145
146
|
console.log(` Authorized: ${grant}`);
|
|
@@ -254,6 +255,11 @@ ${details}`
|
|
|
254
255
|
const authKey = keyring.addFromUri(opts.authorizerMnemonic);
|
|
255
256
|
authorizerSigner = getPolkadotSigner(authKey.publicKey, "Sr25519", (data) => authKey.sign(data));
|
|
256
257
|
console.log(`Using provided authorizer: ${authKey.address}
|
|
258
|
+
`);
|
|
259
|
+
} else if (opts.envAuthorizer) {
|
|
260
|
+
const authKey = keyring.addFromUri(opts.envAuthorizer);
|
|
261
|
+
authorizerSigner = getPolkadotSigner(authKey.publicKey, "Sr25519", (data) => authKey.sign(data));
|
|
262
|
+
console.log(`Using environment authorizer ${opts.envAuthorizer} (${authKey.address})
|
|
257
263
|
`);
|
|
258
264
|
} else {
|
|
259
265
|
const isTestnet = await detectTestnet(api);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CLI_NAME
|
|
3
3
|
} from "./chunk-TSPERKUS.js";
|
|
4
|
-
import {
|
|
5
|
-
VERSION
|
|
6
|
-
} from "./chunk-NLRGFZMQ.js";
|
|
7
4
|
import {
|
|
8
5
|
loadEnvironments
|
|
9
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XQHRKK7M.js";
|
|
7
|
+
import {
|
|
8
|
+
VERSION
|
|
9
|
+
} from "./chunk-VH2HNQG2.js";
|
|
10
10
|
|
|
11
11
|
// src/auth-config.ts
|
|
12
12
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -9,25 +9,25 @@ import {
|
|
|
9
9
|
setBulletinEndpoints,
|
|
10
10
|
storeDirectory,
|
|
11
11
|
storeFile
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-6LD3Z2HM.js";
|
|
13
13
|
import {
|
|
14
14
|
DotNS,
|
|
15
15
|
TX_KIND_SKIPPED
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
setDeployAttribute,
|
|
19
|
-
withManifestSpan,
|
|
20
|
-
withSpan
|
|
21
|
-
} from "./chunk-NLRGFZMQ.js";
|
|
16
|
+
} from "./chunk-FMQLBYOR.js";
|
|
22
17
|
import {
|
|
23
18
|
DEFAULT_ENV_ID,
|
|
24
19
|
getPopSelfServeConfig,
|
|
25
20
|
loadEnvironments,
|
|
26
21
|
resolveEndpoints
|
|
27
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-XQHRKK7M.js";
|
|
28
23
|
import {
|
|
29
24
|
NonRetryableError
|
|
30
25
|
} from "./chunk-ZOC4GITL.js";
|
|
26
|
+
import {
|
|
27
|
+
setDeployAttribute,
|
|
28
|
+
withManifestSpan,
|
|
29
|
+
withSpan
|
|
30
|
+
} from "./chunk-VH2HNQG2.js";
|
|
31
31
|
|
|
32
32
|
// src/manifest/publish.ts
|
|
33
33
|
import * as fs from "fs/promises";
|