bulletin-deploy 0.7.21 → 0.7.22-rc.1

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.
Files changed (56) hide show
  1. package/dist/bug-report.js +4 -4
  2. package/dist/chunk-74ETPOKH.js +284 -0
  3. package/dist/chunk-A5IQ5MKO.js +207 -0
  4. package/dist/{chunk-VTTN4BX7.js → chunk-CIXT75OF.js} +151 -2
  5. package/dist/chunk-EJ5TNGAY.js +24 -0
  6. package/dist/{chunk-RJAFD4LO.js → chunk-FSSKFXTZ.js} +1 -1
  7. package/dist/{chunk-ZY6QLNKQ.js → chunk-KFHGT4A2.js} +1 -1
  8. package/dist/{chunk-MJTQOXBC.js → chunk-LEYQOOWC.js} +3 -2
  9. package/dist/chunk-QHOZEY5X.js +231 -0
  10. package/dist/{chunk-BFXHVC23.js → chunk-SPWQNU3F.js} +21 -17
  11. package/dist/chunk-T7EEVWNU.js +32 -0
  12. package/dist/chunk-UPWEOGLQ.js +37 -0
  13. package/dist/{chunk-SA37SLYF.js → chunk-V5NUBOEX.js} +2 -2
  14. package/dist/{chunk-2VNGK2MU.js → chunk-WNUWAA6F.js} +26 -3
  15. package/dist/{chunk-4TS6R26J.js → chunk-WVCIU6WM.js} +22 -9
  16. package/dist/{chunk-G2P5UIPX.js → chunk-XWA3NPMX.js} +4 -3
  17. package/dist/chunk-ZYVGHDMU.js +117 -0
  18. package/dist/chunk-probe.js +3 -3
  19. package/dist/deploy.d.ts +4 -2
  20. package/dist/deploy.js +9 -9
  21. package/dist/dotns.d.ts +74 -1
  22. package/dist/dotns.js +8 -4
  23. package/dist/incremental-stats.d.ts +3 -1
  24. package/dist/incremental-stats.js +1 -1
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.js +9 -9
  27. package/dist/memory-report.js +2 -2
  28. package/dist/merkle.js +9 -9
  29. package/dist/personhood/bind-paid-alias.d.ts +43 -0
  30. package/dist/personhood/bind-paid-alias.js +10 -0
  31. package/dist/personhood/bind-personal-id.d.ts +55 -0
  32. package/dist/personhood/bind-personal-id.js +12 -0
  33. package/dist/personhood/bootstrap.d.ts +85 -0
  34. package/dist/personhood/bootstrap.js +245 -0
  35. package/dist/personhood/claim-pgas.d.ts +61 -0
  36. package/dist/personhood/claim-pgas.js +12 -0
  37. package/dist/personhood/constants.d.ts +23 -0
  38. package/dist/personhood/constants.js +22 -0
  39. package/dist/personhood/encoding.d.ts +49 -0
  40. package/dist/personhood/encoding.js +24 -0
  41. package/dist/personhood/hashing.d.ts +4 -0
  42. package/dist/personhood/hashing.js +8 -0
  43. package/dist/personhood/member-key.d.ts +12 -0
  44. package/dist/personhood/member-key.js +10 -0
  45. package/dist/personhood/people-client.d.ts +14 -0
  46. package/dist/personhood/people-client.js +48 -0
  47. package/dist/personhood/reprove.d.ts +43 -0
  48. package/dist/personhood/reprove.js +225 -0
  49. package/dist/pool.d.ts +7 -2
  50. package/dist/pool.js +3 -1
  51. package/dist/run-state.js +1 -1
  52. package/dist/telemetry.d.ts +7 -1
  53. package/dist/telemetry.js +8 -2
  54. package/dist/version-check.js +3 -3
  55. package/docs/e2e-bootstrap.md +36 -10
  56. package/package.json +4 -3
@@ -0,0 +1,32 @@
1
+ // src/personhood/constants.ts
2
+ import { Binary } from "polkadot-api";
3
+ var DOTNS_CONTEXT_HEX = "0x646f746e73000000000000000000000000000000000000000000000000000000";
4
+ var DOTNS_CONTEXT_BYTES = Binary.fromHex(DOTNS_CONTEXT_HEX);
5
+ var PGAS_ASSET_ID = 2e9;
6
+ var PGAS_ASSET_LOCATION = {
7
+ parents: 0,
8
+ interior: {
9
+ type: "X2",
10
+ value: [
11
+ { type: "PalletInstance", value: 50 },
12
+ { type: "GeneralIndex", value: BigInt(PGAS_ASSET_ID) }
13
+ ]
14
+ }
15
+ };
16
+ var PROOF_BYTES = 788;
17
+ var BANDERSNATCH_SIGNATURE_BYTES = 96;
18
+ var PEOPLE_MEMBER_IDENTIFIER_HEX = "0x70656f706c652020202020202020202020202020202020202020202020202020";
19
+ var MEMBER_ENTROPY_KEY = new TextEncoder().encode("candidate");
20
+ var PAID_PROOF_TAG = new TextEncoder().encode("alias-accounts:paid");
21
+
22
+ export {
23
+ DOTNS_CONTEXT_HEX,
24
+ DOTNS_CONTEXT_BYTES,
25
+ PGAS_ASSET_ID,
26
+ PGAS_ASSET_LOCATION,
27
+ PROOF_BYTES,
28
+ BANDERSNATCH_SIGNATURE_BYTES,
29
+ PEOPLE_MEMBER_IDENTIFIER_HEX,
30
+ MEMBER_ENTROPY_KEY,
31
+ PAID_PROOF_TAG
32
+ };
@@ -0,0 +1,37 @@
1
+ // src/personhood/hashing.ts
2
+ import { blake2b } from "@noble/hashes/blake2b";
3
+ import { Binary } from "polkadot-api";
4
+ var hexToBytes = (hex) => {
5
+ const h = hex.startsWith("0x") ? hex.slice(2) : hex;
6
+ const out = new Uint8Array(h.length / 2);
7
+ for (let i = 0; i < out.length; i++) {
8
+ out[i] = Number.parseInt(h.slice(i * 2, i * 2 + 2), 16);
9
+ }
10
+ return out;
11
+ };
12
+ function blake2b256(data) {
13
+ let payload;
14
+ if (typeof data === "string") {
15
+ if (data.startsWith("0x")) {
16
+ payload = hexToBytes(data);
17
+ } else {
18
+ payload = Binary.fromText(data);
19
+ }
20
+ } else {
21
+ if (data[0] === 48 && data[1] === 120) {
22
+ const hexString = new TextDecoder().decode(data);
23
+ payload = hexToBytes(hexString);
24
+ } else {
25
+ payload = data;
26
+ }
27
+ }
28
+ return blake2b(payload, { dkLen: 32 });
29
+ }
30
+ function blake2b256Keyed(data, key) {
31
+ return blake2b(data, { key, dkLen: 32 });
32
+ }
33
+
34
+ export {
35
+ blake2b256,
36
+ blake2b256Keyed
37
+ };
@@ -2,11 +2,11 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-RJAFD4LO.js";
5
+ } from "./chunk-FSSKFXTZ.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId
9
- } from "./chunk-2VNGK2MU.js";
9
+ } from "./chunk-WNUWAA6F.js";
10
10
 
11
11
  // src/bug-report.ts
12
12
  import { execSync, execFileSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  package_default,
3
3
  writeRunState
4
- } from "./chunk-G2P5UIPX.js";
4
+ } from "./chunk-XWA3NPMX.js";
5
5
 
6
6
  // src/memory-report.ts
7
7
  import * as fs2 from "fs";
@@ -246,13 +246,26 @@ function computeDeployOutcome(errorCategory, isSad, sadReason) {
246
246
  if (isSad) return `sad_${sadReason}`;
247
247
  return "clean";
248
248
  }
249
+ function classifyErrorKind(msg) {
250
+ if (/Contract reverted|Contract execution would revert|revert(?:ed|ing)?\s*\(flags=[0-9]+\)/i.test(msg)) return "contract-revert";
251
+ if (/timed out after \d+s waiting for block|Transaction not included after \d+s|Transaction did not settle within/i.test(msg)) return "chain-timeout";
252
+ if (/\bstale\b.*nonce|nonce.*\bstale\b|"type"\s*:\s*"Future"|Invalid::Future|tx rejected by pool/i.test(msg)) return "nonce-stale";
253
+ if (/heartbeat timeout|WS halt|Unable to connect|ChainHead disjointed|websocket.*closed|socket closed|disconnect/i.test(msg)) return "connection";
254
+ return "unknown";
255
+ }
256
+ function sanitizeErrorMessage(msg) {
257
+ return scrubPaths(msg.slice(0, 500));
258
+ }
249
259
  async function withSpan(op, description, attributes, fn) {
250
260
  if (!Sentry) return fn();
251
261
  return Sentry.startSpan({ op, name: description, attributes }, async (span) => {
252
262
  try {
253
263
  return await fn();
254
264
  } catch (error) {
255
- span.setAttribute("error.message", error.message);
265
+ const msg = error.message ?? String(error);
266
+ span.setAttribute("error.message", msg);
267
+ span.setAttribute("deploy.error_kind", classifyErrorKind(msg));
268
+ span.setAttribute("deploy.error_message", sanitizeErrorMessage(msg));
256
269
  span.setStatus({ code: 2, message: "internal_error" });
257
270
  throw error;
258
271
  }
@@ -345,11 +358,13 @@ async function withDeploySpan(domain, fn) {
345
358
  span.setAttribute("deploy.status", "ok");
346
359
  return result;
347
360
  } catch (error) {
348
- const msg = error.message;
361
+ const msg = error.message ?? String(error);
349
362
  span.setAttribute("deploy.status", "error");
350
363
  span.setAttribute("deploy.error", msg.slice(0, 500));
351
364
  const errorCategory = classifyDeployError(msg);
352
365
  span.setAttribute("deploy.error_category", errorCategory);
366
+ span.setAttribute("deploy.error_kind", classifyErrorKind(msg));
367
+ span.setAttribute("deploy.error_message", sanitizeErrorMessage(msg));
353
368
  currentErrorCategory = errorCategory;
354
369
  const isExpected = isExpectedError(msg);
355
370
  span.setAttribute("deploy.expected", isExpected ? "true" : "false");
@@ -429,6 +444,11 @@ function setDeployAttribute(key, value) {
429
444
  function __setDeployRootSpanForTest(span) {
430
445
  deployRootSpan = span;
431
446
  }
447
+ function __setSentryForTest(stub) {
448
+ const prev = Sentry;
449
+ Sentry = stub;
450
+ return prev;
451
+ }
432
452
  function getCurrentSentryTraceId() {
433
453
  if (!Sentry) return void 0;
434
454
  const span = Sentry.getActiveSpan();
@@ -603,12 +623,15 @@ export {
603
623
  classifyDeployError,
604
624
  classifySadReason,
605
625
  computeDeployOutcome,
626
+ classifyErrorKind,
627
+ sanitizeErrorMessage,
606
628
  withSpan,
607
629
  sampleMemory,
608
630
  withDeploySpan,
609
631
  setDeployReportContext,
610
632
  setDeployAttribute,
611
633
  __setDeployRootSpanForTest,
634
+ __setSentryForTest,
612
635
  getCurrentSentryTraceId,
613
636
  setDeploySentryTag,
614
637
  captureWarning,
@@ -32,8 +32,16 @@ function derivePoolAccounts(poolSize = 10, mnemonic = DEV_PHRASE) {
32
32
  }
33
33
  var MIN_TRANSACTIONS = 30n;
34
34
  var MIN_BYTES = 20000000n;
35
- function isAuthorizationActive(auth, currentBlock) {
36
- return auth !== void 0 && Number(auth.expiration ?? 0) > currentBlock;
35
+ function isAuthorizationSufficient(auth, currentBlock, check = {}) {
36
+ if (auth === void 0) return false;
37
+ if (Number(auth.expiration ?? 0) <= currentBlock) return false;
38
+ if (check.bulletinAuthorizeV2 && check.needs) {
39
+ const txsRemaining = BigInt(auth.extent.transactions_allowance) - BigInt(auth.extent.transactions);
40
+ const bytesRemaining = BigInt(auth.extent.bytes_allowance) - BigInt(auth.extent.bytes);
41
+ if (txsRemaining < check.needs.txs) return false;
42
+ if (bytesRemaining < check.needs.bytes) return false;
43
+ }
44
+ return true;
37
45
  }
38
46
  function selectAccount(authorizations, random = Math.random, currentBlock) {
39
47
  const eligible = authorizations.filter(
@@ -139,12 +147,12 @@ function clampU32(n, name) {
139
147
  if (n > U32_MAX) throw new Error(`${name} (${n}) exceeds u32 max \u2014 split the deploy into smaller batches`);
140
148
  return Number(n);
141
149
  }
142
- async function ensureAuthorized(api, address, label, bulletinAuthorizeV2) {
150
+ async function ensureAuthorized(api, address, label, bulletinAuthorizeV2, needs) {
143
151
  const [auth, currentBlock] = await Promise.all([
144
152
  api.query.TransactionStorage.Authorizations.getValue(Enum("Account", address)),
145
153
  api.query.System.Number.getValue()
146
154
  ]);
147
- if (isAuthorizationActive(auth, currentBlock)) return;
155
+ if (isAuthorizationSufficient(auth, currentBlock, { needs, bulletinAuthorizeV2 })) return;
148
156
  console.log(` Auto-authorizing ${label ?? "account"} (${address.slice(0, 8)}...)...`);
149
157
  const { signer } = aliceKeyring();
150
158
  if (bulletinAuthorizeV2) {
@@ -176,12 +184,16 @@ async function topUpBy(api, address, needs, label, bulletinAuthorizeV2) {
176
184
  api.query.TransactionStorage.Authorizations.getValue(Enum("Account", address)),
177
185
  api.query.System.Number.getValue()
178
186
  ]);
179
- if (isAuthorizationActive(currentAuth, currentBlock)) {
180
- const fmtMB = (b) => (Number(b) / 1e6).toFixed(1);
181
- const txsRemaining = BigInt(currentAuth.extent.transactions_allowance) - BigInt(currentAuth.extent.transactions);
182
- const bytesRemaining = BigInt(currentAuth.extent.bytes_allowance) - BigInt(currentAuth.extent.bytes);
187
+ if (isAuthorizationSufficient(currentAuth, currentBlock, { needs, bulletinAuthorizeV2 })) {
183
188
  const expiration = Number(currentAuth.expiration);
184
- console.log(` Pre-auth skipped for ${label ?? "account"} (${address.slice(0, 8)}...): authorized until block ${expiration}, ${txsRemaining} txs / ${fmtMB(bytesRemaining)}MB remaining.`);
189
+ if (currentAuth.extent) {
190
+ const fmtMB = (b) => (Number(b) / 1e6).toFixed(1);
191
+ const txsRemaining = BigInt(currentAuth.extent.transactions_allowance) - BigInt(currentAuth.extent.transactions);
192
+ const bytesRemaining = BigInt(currentAuth.extent.bytes_allowance) - BigInt(currentAuth.extent.bytes);
193
+ console.log(` Pre-auth skipped for ${label ?? "account"} (${address.slice(0, 8)}...): authorized until block ${expiration}, ${txsRemaining} txs / ${fmtMB(bytesRemaining)}MB remaining.`);
194
+ } else {
195
+ console.log(` Pre-auth skipped for ${label ?? "account"} (${address.slice(0, 8)}...): authorized until block ${expiration}.`);
196
+ }
185
197
  return;
186
198
  }
187
199
  const { signer } = aliceKeyring();
@@ -292,6 +304,7 @@ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic, opts = {}) {
292
304
  export {
293
305
  formatPasBalance,
294
306
  derivePoolAccounts,
307
+ isAuthorizationSufficient,
295
308
  selectAccount,
296
309
  fetchPoolAuthorizations,
297
310
  computeTopUpTarget,
@@ -6,7 +6,7 @@ import * as path from "path";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "bulletin-deploy",
9
- version: "0.7.21",
9
+ version: "0.7.22-rc.1",
10
10
  private: false,
11
11
  repository: {
12
12
  type: "git",
@@ -36,11 +36,11 @@ var package_default = {
36
36
  "assets"
37
37
  ],
38
38
  scripts: {
39
- build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/memory-report.ts src/merkle.ts src/gh-pages-mirror.ts src/version-check.ts src/bug-report.ts src/run-state.ts src/environments.ts src/errors.ts src/manifest.ts src/chunk-probe.ts src/manifest-embed.ts src/manifest-fetch.ts src/manifest-roundtrip.ts src/incremental-stats.ts src/chunker.ts src/mirror.ts --format esm --dts --clean --target node22",
39
+ build: "tsup src/index.ts src/deploy.ts src/dotns.ts src/pool.ts src/telemetry.ts src/memory-report.ts src/merkle.ts src/gh-pages-mirror.ts src/version-check.ts src/bug-report.ts src/run-state.ts src/environments.ts src/errors.ts src/manifest.ts src/chunk-probe.ts src/manifest-embed.ts src/manifest-fetch.ts src/manifest-roundtrip.ts src/incremental-stats.ts src/chunker.ts src/mirror.ts src/personhood/encoding.ts src/personhood/hashing.ts src/personhood/constants.ts src/personhood/member-key.ts src/personhood/people-client.ts src/personhood/reprove.ts src/personhood/bind-personal-id.ts src/personhood/claim-pgas.ts src/personhood/bind-paid-alias.ts src/personhood/bootstrap.ts --format esm --dts --clean --target node22",
40
40
  "refresh-environments": "node scripts/refresh-environments.mjs",
41
41
  "check:watched-dependencies": "node tools/check-watched-dependencies.mjs",
42
42
  prepare: "npm run build",
43
- test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/watched-dependencies.test.js",
43
+ test: "npm run build && node --test test/test.js test/cli-help.test.js test/helpers/e2e-helpers.test.js test/environments.test.js test/refresh-environments.test.js test/watched-dependencies.test.js test/chunk-sharing-report.test.js",
44
44
  "test:e2e": "npm run build && node --test test/e2e.test.js",
45
45
  "test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
46
46
  "test:e2e:pr": "bash scripts/e2e-pass.sh pr",
@@ -62,6 +62,7 @@ var package_default = {
62
62
  "ipfs-unixfs-importer": "^16.1.4",
63
63
  multiformats: "^13.4.1",
64
64
  "polkadot-api": "^2.1.3",
65
+ verifiablejs: "^1.2.0",
65
66
  viem: "^2.30.5"
66
67
  },
67
68
  devDependencies: {
@@ -0,0 +1,117 @@
1
+ // src/personhood/encoding.ts
2
+ import { blake2b } from "@noble/hashes/blake2b";
3
+ var concatBytes = (...arrays) => {
4
+ let total = 0;
5
+ for (const a of arrays) total += a.length;
6
+ const out = new Uint8Array(total);
7
+ let offset = 0;
8
+ for (const a of arrays) {
9
+ out.set(a, offset);
10
+ offset += a.length;
11
+ }
12
+ return out;
13
+ };
14
+ var compactEncode = (n) => {
15
+ if (n < 0) throw new Error("compactEncode: negative");
16
+ if (n < 64) return new Uint8Array([n << 2]);
17
+ if (n < 16384) {
18
+ const v = n << 2 | 1;
19
+ return new Uint8Array([v & 255, v >> 8 & 255]);
20
+ }
21
+ if (n < 1073741824) {
22
+ const v = n << 2 | 2;
23
+ return new Uint8Array([
24
+ v & 255,
25
+ v >> 8 & 255,
26
+ v >> 16 & 255,
27
+ v >>> 24 & 255
28
+ ]);
29
+ }
30
+ throw new Error("compactEncode: value too large for inline path");
31
+ };
32
+ var blake2_256 = (data) => blake2b(data, { dkLen: 32 });
33
+ var buildImplicationMessage = (callBytes, extensions, excludeIdentifiers) => {
34
+ const exclude = typeof excludeIdentifiers === "string" ? /* @__PURE__ */ new Set([excludeIdentifiers]) : excludeIdentifiers;
35
+ const restExplicit = [];
36
+ const restImplicit = [];
37
+ for (const id of extensions.order) {
38
+ if (exclude.has(id)) continue;
39
+ const ext = extensions.byIdentifier[id];
40
+ if (!ext) throw new Error(`buildImplication: missing extension '${id}'`);
41
+ restExplicit.push(ext.value);
42
+ restImplicit.push(ext.additionalSigned);
43
+ }
44
+ const implication = concatBytes(
45
+ new Uint8Array([0]),
46
+ callBytes,
47
+ ...restExplicit,
48
+ ...restImplicit
49
+ );
50
+ return blake2_256(implication);
51
+ };
52
+ var buildV5GeneralExtrinsic = (callBytes, extensions) => {
53
+ const explicit = extensions.order.map((id) => {
54
+ const ext = extensions.byIdentifier[id];
55
+ if (!ext) throw new Error(`buildV5General: missing extension '${id}'`);
56
+ return ext.value;
57
+ });
58
+ const body = concatBytes(
59
+ new Uint8Array([69]),
60
+ new Uint8Array([0]),
61
+ ...explicit,
62
+ callBytes
63
+ );
64
+ return concatBytes(compactEncode(body.length), body);
65
+ };
66
+ var toHex = (bytes) => {
67
+ let hex = "0x";
68
+ for (const b of bytes) {
69
+ hex += b.toString(16).padStart(2, "0");
70
+ }
71
+ return hex;
72
+ };
73
+ var hexToBytes = (hex) => {
74
+ const h = hex.startsWith("0x") ? hex.slice(2) : hex;
75
+ const out = new Uint8Array(h.length / 2);
76
+ for (let i = 0; i < out.length; i++) {
77
+ out[i] = Number.parseInt(h.slice(i * 2, i * 2 + 2), 16);
78
+ }
79
+ return out;
80
+ };
81
+ var bytesToHex = (b) => "0x" + Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
82
+ var readExtensionOrder = async (metadata) => {
83
+ const { decAnyMetadata, unifyMetadata } = await import("@polkadot-api/substrate-bindings");
84
+ const meta = unifyMetadata(decAnyMetadata(metadata));
85
+ const raw = meta.extrinsic.signedExtensions;
86
+ let list = null;
87
+ if (Array.isArray(raw) && raw.length > 0 && Array.isArray(raw[0])) {
88
+ list = raw[0];
89
+ } else if (Array.isArray(raw)) {
90
+ list = raw;
91
+ } else if (typeof raw === "object" && raw !== null && Array.isArray(raw[0])) {
92
+ list = raw[0];
93
+ }
94
+ if (!list || list.length === 0) {
95
+ throw new Error("metadata has no signed extensions");
96
+ }
97
+ return list.map((entry) => entry.identifier);
98
+ };
99
+ var encodeMembers = (members) => {
100
+ for (const m of members) {
101
+ if (m.length !== 32) throw new Error("member key must be 32 bytes");
102
+ }
103
+ return concatBytes(compactEncode(members.length), ...members);
104
+ };
105
+
106
+ export {
107
+ concatBytes,
108
+ compactEncode,
109
+ blake2_256,
110
+ buildImplicationMessage,
111
+ buildV5GeneralExtrinsic,
112
+ toHex,
113
+ hexToBytes,
114
+ bytesToHex,
115
+ readExtensionOrder,
116
+ encodeMembers
117
+ };
@@ -5,9 +5,9 @@ import {
5
5
  _decodeStorageValue,
6
6
  _resetProbeSession,
7
7
  probeChunks
8
- } from "./chunk-ZY6QLNKQ.js";
9
- import "./chunk-2VNGK2MU.js";
10
- import "./chunk-G2P5UIPX.js";
8
+ } from "./chunk-KFHGT4A2.js";
9
+ import "./chunk-WNUWAA6F.js";
10
+ import "./chunk-XWA3NPMX.js";
11
11
  export {
12
12
  ChainProbeCrossValidationError,
13
13
  ChainProbeMetadataError,
package/dist/deploy.d.ts CHANGED
@@ -28,6 +28,7 @@ interface ExistingProvider {
28
28
  skipCids?: Set<string>;
29
29
  probeFailedCids?: Set<string>;
30
30
  gateway?: string;
31
+ bulletinAuthorizeV2?: boolean;
31
32
  }
32
33
  interface StoredChunk {
33
34
  cid: CID;
@@ -63,7 +64,7 @@ declare function storeFile(contentBytes: Uint8Array, { client: existingClient, u
63
64
  */
64
65
  declare function assignDenseNonces(stored: (StoredChunk | null)[], startNonce: number): Map<number, number>;
65
66
  declare const __assignDenseNoncesForTest: typeof assignDenseNonces;
66
- declare function storeChunkedContent(chunks: Uint8Array[], { client: existingClient, unsafeApi: existingApi, signer: existingSigner, ss58: existingSS58, reconnect, fetchNonce: fetchNonceOverride, skipCids, probeFailedCids, gateway: providerGateway }?: ExistingProvider): Promise<{
67
+ declare function storeChunkedContent(chunks: Uint8Array[], { client: existingClient, unsafeApi: existingApi, signer: existingSigner, ss58: existingSS58, reconnect, fetchNonce: fetchNonceOverride, skipCids, probeFailedCids, gateway: providerGateway, bulletinAuthorizeV2 }?: ExistingProvider): Promise<{
67
68
  storageCid: string;
68
69
  tier2Verified: number;
69
70
  tier2Inconclusive: number;
@@ -202,7 +203,7 @@ interface DeployOptions {
202
203
  /** When true, marks this as an automated mirror deploy in telemetry. */
203
204
  automatedMirror?: boolean;
204
205
  }
205
- declare function resolveDotnsConnectOptions(options: Pick<DeployOptions, "mnemonic" | "derivationPath" | "signer" | "signerAddress">, assetHubEndpoints?: string[], autoAccountMapping?: boolean, contracts?: Record<string, string>, nativeToEthRatio?: bigint): {
206
+ declare function resolveDotnsConnectOptions(options: Pick<DeployOptions, "mnemonic" | "derivationPath" | "signer" | "signerAddress">, assetHubEndpoints?: string[], autoAccountMapping?: boolean, contracts?: Record<string, string>, nativeToEthRatio?: bigint, environmentId?: string): {
206
207
  signer?: PolkadotSigner;
207
208
  signerAddress?: string;
208
209
  mnemonic?: string;
@@ -211,6 +212,7 @@ declare function resolveDotnsConnectOptions(options: Pick<DeployOptions, "mnemon
211
212
  autoAccountMapping?: boolean;
212
213
  contracts?: Record<string, string>;
213
214
  nativeToEthRatio?: bigint;
215
+ environmentId?: string;
214
216
  };
215
217
  declare function estimateUploadBytes(content: DeployContent): Promise<number | null>;
216
218
  declare function deploy(content: DeployContent, domainName?: string | null, options?: DeployOptions): Promise<DeployResult>;
package/dist/deploy.js CHANGED
@@ -32,19 +32,19 @@ import {
32
32
  storeDirectory,
33
33
  storeDirectoryV2,
34
34
  storeFile
35
- } from "./chunk-BFXHVC23.js";
36
- import "./chunk-MJTQOXBC.js";
35
+ } from "./chunk-SPWQNU3F.js";
36
+ import "./chunk-LEYQOOWC.js";
37
37
  import "./chunk-KOSF5FDO.js";
38
38
  import "./chunk-5MRZ3V4A.js";
39
39
  import "./chunk-S7EM5VMW.js";
40
- import "./chunk-SA37SLYF.js";
41
- import "./chunk-RJAFD4LO.js";
42
- import "./chunk-ZY6QLNKQ.js";
40
+ import "./chunk-V5NUBOEX.js";
41
+ import "./chunk-FSSKFXTZ.js";
42
+ import "./chunk-KFHGT4A2.js";
43
43
  import "./chunk-C2TS5MER.js";
44
- import "./chunk-VTTN4BX7.js";
45
- import "./chunk-4TS6R26J.js";
46
- import "./chunk-2VNGK2MU.js";
47
- import "./chunk-G2P5UIPX.js";
44
+ import "./chunk-CIXT75OF.js";
45
+ import "./chunk-WVCIU6WM.js";
46
+ import "./chunk-WNUWAA6F.js";
47
+ import "./chunk-XWA3NPMX.js";
48
48
  import "./chunk-F36C363Y.js";
49
49
  import {
50
50
  EXIT_CODE_NO_RETRY,
package/dist/dotns.d.ts CHANGED
@@ -1,4 +1,8 @@
1
+ import { BootstrapResult } from './personhood/bootstrap.js';
1
2
  import { PolkadotSigner } from 'polkadot-api';
3
+ import './personhood/bind-personal-id.js';
4
+ import './personhood/claim-pgas.js';
5
+ import './personhood/bind-paid-alias.js';
2
6
 
3
7
  interface DotNSConnectOptions {
4
8
  rpc?: string;
@@ -18,6 +22,8 @@ interface DotNSConnectOptions {
18
22
  autoAccountMapping?: boolean;
19
23
  nativeToEthRatio?: bigint;
20
24
  contracts?: Record<string, string>;
25
+ /** Optional environment ID (e.g. "paseo-next-v2"). Used to gate environment-specific preflight advice. */
26
+ environmentId?: string;
21
27
  }
22
28
  interface OwnershipResult {
23
29
  owned: boolean;
@@ -104,6 +110,29 @@ declare const ProofOfPersonhoodStatus: {
104
110
  readonly Reserved: 3;
105
111
  };
106
112
  declare function convertToHexString(value: unknown): string;
113
+ declare function formatContractDryRunFailure(gasEstimate: {
114
+ revertData?: string;
115
+ revertFlags?: bigint;
116
+ gasConsumed?: {
117
+ referenceTime: bigint;
118
+ proofSize: bigint;
119
+ };
120
+ gasRequired?: {
121
+ referenceTime: bigint;
122
+ proofSize: bigint;
123
+ };
124
+ storageDeposit?: bigint;
125
+ }, context: {
126
+ contractAddress: string;
127
+ functionName?: string;
128
+ signerSubstrateAddress: string;
129
+ signerEvmAddress?: string;
130
+ value: bigint;
131
+ encodedData: string;
132
+ args?: unknown[];
133
+ contracts?: Record<string, string>;
134
+ }): string;
135
+ declare function __formatContractDryRunFailureForTest(gasEstimate: Parameters<typeof formatContractDryRunFailure>[0], context: Parameters<typeof formatContractDryRunFailure>[1]): string;
107
136
  declare const DOT_NODE: `0x${string}`;
108
137
  declare function convertWeiToNative(weiValue: bigint): bigint;
109
138
  declare function computeDomainTokenId(label: string): bigint;
@@ -161,6 +190,21 @@ declare class ReviveClientWrapper {
161
190
  contracts?: Record<string, string>;
162
191
  }): Promise<string>;
163
192
  }
193
+ type AliasAccountState = "not-bound" | "bound-likely-stale" | "wrong-context" | "bound-fresh";
194
+ interface AliasAccountClassification {
195
+ state: AliasAccountState;
196
+ storedContextHex?: string;
197
+ paid?: boolean;
198
+ revision?: number;
199
+ }
200
+ /**
201
+ * Format a user-facing remediation message for the "no personhood" preflight failure.
202
+ * Pure function — unit-testable without a chain connection.
203
+ *
204
+ * On paseo-next-v2 testnets we can give actionable advice based on alias state.
205
+ * On other environments we fall back to the generic "contact DotNS team" message.
206
+ */
207
+ declare function formatPersonhoodRemediation(state: AliasAccountClassification, environmentId: string | null): string;
164
208
  declare class DotNS {
165
209
  client: any | null;
166
210
  clientWrapper: ReviveClientWrapper | null;
@@ -173,6 +217,7 @@ declare class DotNS {
173
217
  private _usesExternalSigner;
174
218
  private _contracts;
175
219
  private _nativeToEthRatio;
220
+ private _environmentId;
176
221
  constructor();
177
222
  connect(options?: DotNSConnectOptions): Promise<this>;
178
223
  ensureMappedAccountReady(autoAccountMapping?: boolean): Promise<void>;
@@ -180,6 +225,12 @@ declare class DotNS {
180
225
  ensureConnected(): void;
181
226
  private _testnetCache;
182
227
  isTestnet(): Promise<boolean>;
228
+ /**
229
+ * Classify the AliasAccounts state for a substrate address.
230
+ * Only called on paseo-next-v2 testnets inside the preflight's NoStatus branch.
231
+ * Returns "not-bound" if the chain is unreachable (safe fallback to generic advice).
232
+ */
233
+ private classifyAliasAccountState;
183
234
  readFreeBalance(ss58: string): Promise<bigint>;
184
235
  attemptTestnetTopUp(recipientSs58: string, targetAmount: bigint): Promise<{
185
236
  source: "Alice" | "Bob";
@@ -230,8 +281,30 @@ declare class DotNS {
230
281
  label: string;
231
282
  owner: string;
232
283
  }>;
284
+ /**
285
+ * Reprove a stale DotNS alias binding.
286
+ * Opens a People-chain client internally, builds the ring proof, and submits
287
+ * reprove_alias_account on AH. Use when the alias exists but the ring root
288
+ * has advanced past the stored revision.
289
+ *
290
+ * Requires a mnemonic — the DotNS instance must have been connected with one.
291
+ */
292
+ reprove(mnemonic: string): Promise<{
293
+ oldRevision: number;
294
+ newRevision: number;
295
+ blockHash: string;
296
+ }>;
297
+ /**
298
+ * Run the personhood bootstrap flow for this DotNS signer.
299
+ * Idempotent: each step is gated on chain state being "still needs doing".
300
+ * Does NOT auto-run from preflight — call explicitly.
301
+ *
302
+ * Throws RecognizeRequiredError if the account hasn't been recognized by the
303
+ * personhood faucet (https://sudo.personhood.dev/personhood-faucet).
304
+ */
305
+ bootstrap(mnemonic: string): Promise<BootstrapResult>;
233
306
  disconnect(): void;
234
307
  }
235
308
  declare const dotns: DotNS;
236
309
 
237
- export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, type DotnsSuccessAction, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertToHexString, convertWeiToNative, countTrailingDigits, dotns, feeFloorFor, fetchNonce, fmtPas, isCommitmentMature, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
310
+ export { type AliasAccountClassification, type AliasAccountState, CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, type DotnsSuccessAction, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, __formatContractDryRunFailureForTest, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertToHexString, convertWeiToNative, countTrailingDigits, dotns, feeFloorFor, fetchNonce, fmtPas, formatPersonhoodRemediation, isCommitmentMature, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
package/dist/dotns.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  TX_TIMEOUT_MS,
15
15
  TX_WALL_CLOCK_CEILING_MS,
16
16
  WS_HEARTBEAT_TIMEOUT_MS,
17
+ __formatContractDryRunFailureForTest,
17
18
  canRegister,
18
19
  classifyDotnsLabel,
19
20
  classifyTxRetryDecision,
@@ -25,6 +26,7 @@ import {
25
26
  feeFloorFor,
26
27
  fetchNonce,
27
28
  fmtPas,
29
+ formatPersonhoodRemediation,
28
30
  isCommitmentMature,
29
31
  parseDomainName,
30
32
  parseProofOfPersonhoodStatus,
@@ -34,10 +36,10 @@ import {
34
36
  stripTrailingDigits,
35
37
  validateDomainLabel,
36
38
  verifyNonceAdvanced
37
- } from "./chunk-VTTN4BX7.js";
38
- import "./chunk-4TS6R26J.js";
39
- import "./chunk-2VNGK2MU.js";
40
- import "./chunk-G2P5UIPX.js";
39
+ } from "./chunk-CIXT75OF.js";
40
+ import "./chunk-WVCIU6WM.js";
41
+ import "./chunk-WNUWAA6F.js";
42
+ import "./chunk-XWA3NPMX.js";
41
43
  export {
42
44
  CONNECTION_TIMEOUT_MS,
43
45
  CONTRACTS,
@@ -54,6 +56,7 @@ export {
54
56
  TX_TIMEOUT_MS,
55
57
  TX_WALL_CLOCK_CEILING_MS,
56
58
  WS_HEARTBEAT_TIMEOUT_MS,
59
+ __formatContractDryRunFailureForTest,
57
60
  canRegister,
58
61
  classifyDotnsLabel,
59
62
  classifyTxRetryDecision,
@@ -65,6 +68,7 @@ export {
65
68
  feeFloorFor,
66
69
  fetchNonce,
67
70
  fmtPas,
71
+ formatPersonhoodRemediation,
68
72
  isCommitmentMature,
69
73
  parseDomainName,
70
74
  parseProofOfPersonhoodStatus,
@@ -18,6 +18,7 @@ interface IncrementalStats {
18
18
  probeFailedMetadata: number;
19
19
  recycledCids: number;
20
20
  retentionPeriodBlocks: number;
21
+ bytesProbePresent: number;
21
22
  bytesSkipped: number;
22
23
  bytesUploaded: number;
23
24
  chunksTotal: number;
@@ -43,6 +44,7 @@ interface ComputeStatsInput {
43
44
  probeResults: ChunkProbeResult[];
44
45
  prevChunks: Record<string, ManifestChunkEntry>;
45
46
  retentionPeriodBlocks: number;
47
+ bytesProbePresent: number;
46
48
  bytesSkipped: number;
47
49
  bytesUploaded: number;
48
50
  chunksTotal: number;
@@ -59,7 +61,7 @@ interface ComputeStatsInput {
59
61
  tier2FallbackCount: number;
60
62
  }
61
63
  declare function computeStats(input: ComputeStatsInput): IncrementalStats;
62
- declare function telemetryAttributes(s: IncrementalStats): Record<string, string>;
64
+ declare function telemetryAttributes(s: IncrementalStats): Record<string, string | number>;
63
65
  declare function renderSummary(s: IncrementalStats): string;
64
66
 
65
67
  export { type ComputeStatsInput, type IncrementalStats, computeStats, renderSummary, telemetryAttributes };
@@ -2,7 +2,7 @@ import {
2
2
  computeStats,
3
3
  renderSummary,
4
4
  telemetryAttributes
5
- } from "./chunk-MJTQOXBC.js";
5
+ } from "./chunk-LEYQOOWC.js";
6
6
  export {
7
7
  computeStats,
8
8
  renderSummary,
package/dist/index.d.ts CHANGED
@@ -13,3 +13,7 @@ export { shouldMirrorToPaseoNextV2 } from './mirror.js';
13
13
  import 'multiformats/cid';
14
14
  import 'polkadot-api';
15
15
  import './errors.js';
16
+ import './personhood/bootstrap.js';
17
+ import './personhood/bind-personal-id.js';
18
+ import './personhood/claim-pgas.js';
19
+ import './personhood/bind-paid-alias.js';