bulletin-deploy 0.10.1-dev.0 → 0.11.0-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 (40) hide show
  1. package/bin/bulletin-deploy +42 -10
  2. package/dist/auth-config.js +3 -3
  3. package/dist/bug-report.js +4 -4
  4. package/dist/{chunk-TE5ILRKP.js → chunk-4PLUBND7.js} +1 -1
  5. package/dist/{chunk-H73WL3JM.js → chunk-5SWXGBOO.js} +10 -5
  6. package/dist/{chunk-LDMBTCMO.js → chunk-7H6UYIDE.js} +14 -1
  7. package/dist/{chunk-UCRSE6CA.js → chunk-BJXJ7ZLD.js} +1 -1
  8. package/dist/{chunk-WWHAWJ6W.js → chunk-CW6GFAEF.js} +2 -2
  9. package/dist/{chunk-R74IZLP4.js → chunk-IMHVYM7Q.js} +1 -1
  10. package/dist/{chunk-Q5JW6NOW.js → chunk-TXJ6KQWM.js} +55 -10
  11. package/dist/{chunk-VHW7K7JW.js → chunk-U2JW2FSV.js} +6 -11
  12. package/dist/chunk-UWAZDGBT.js +78 -0
  13. package/dist/{chunk-XZXMZ2EN.js → chunk-VJNXVT3F.js} +122 -91
  14. package/dist/{chunk-Y3GVAWTH.js → chunk-XCK7YHBD.js} +1 -1
  15. package/dist/chunk-probe.js +3 -3
  16. package/dist/commands/login.js +22 -21
  17. package/dist/commands/logout.js +7 -7
  18. package/dist/commands/transfer.js +3 -3
  19. package/dist/commands/whoami.js +3 -3
  20. package/dist/deploy-actors.d.ts +84 -3
  21. package/dist/deploy-actors.js +12 -35
  22. package/dist/deploy.d.ts +30 -4
  23. package/dist/deploy.js +13 -9
  24. package/dist/dotns.d.ts +42 -2
  25. package/dist/dotns.js +3 -3
  26. package/dist/index.js +21 -17
  27. package/dist/manifest/publish.js +14 -10
  28. package/dist/memory-report.js +2 -2
  29. package/dist/merkle.js +13 -9
  30. package/dist/personhood/bootstrap.js +6 -6
  31. package/dist/personhood/people-client.js +3 -3
  32. package/dist/run-state.js +1 -1
  33. package/dist/sss-allowance-cache.js +4 -4
  34. package/dist/storage-signer.js +13 -9
  35. package/dist/suppress-localstorage-warning.d.ts +2 -0
  36. package/dist/suppress-localstorage-warning.js +7 -0
  37. package/dist/telemetry.d.ts +9 -1
  38. package/dist/telemetry.js +6 -2
  39. package/dist/version-check.js +3 -3
  40. package/package.json +6 -11
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  preflightSssAllowance
3
- } from "./chunk-Y3GVAWTH.js";
3
+ } from "./chunk-XCK7YHBD.js";
4
4
  import {
5
5
  statementSigningAccount
6
6
  } from "./chunk-GRPLHUYC.js";
@@ -29,21 +29,27 @@ import {
29
29
  classifyFile,
30
30
  parseManifest
31
31
  } from "./chunk-S7EM5VMW.js";
32
- import {
33
- DOT_PRODUCT_ID,
34
- STALE_SESSION_MESSAGE,
35
- getPeopleChainEndpoints,
36
- hasPersistedSession
37
- } from "./chunk-TE5ILRKP.js";
38
32
  import {
39
33
  setDeployContext
40
- } from "./chunk-H73WL3JM.js";
34
+ } from "./chunk-5SWXGBOO.js";
41
35
  import {
42
36
  probeChunks
43
- } from "./chunk-R74IZLP4.js";
37
+ } from "./chunk-IMHVYM7Q.js";
44
38
  import {
45
39
  packSection
46
40
  } from "./chunk-C2TS5MER.js";
41
+ import {
42
+ resolveStorageSigner
43
+ } from "./chunk-UWAZDGBT.js";
44
+ import {
45
+ createSlotAccountSigner,
46
+ requestResourceAllocation
47
+ } from "./chunk-5FLTDWWP.js";
48
+ import {
49
+ STALE_SESSION_MESSAGE,
50
+ getPeopleChainEndpoints,
51
+ hasPersistedSession
52
+ } from "./chunk-4PLUBND7.js";
47
53
  import {
48
54
  CLI_NAME
49
55
  } from "./chunk-TSPERKUS.js";
@@ -56,7 +62,7 @@ import {
56
62
  parseDomainName,
57
63
  popStatusName,
58
64
  verifyNonceAdvanced
59
- } from "./chunk-Q5JW6NOW.js";
65
+ } from "./chunk-TXJ6KQWM.js";
60
66
  import {
61
67
  derivePoolAccounts,
62
68
  detectTestnet,
@@ -78,7 +84,7 @@ import {
78
84
  truncateAddress,
79
85
  withDeploySpan,
80
86
  withSpan
81
- } from "./chunk-LDMBTCMO.js";
87
+ } from "./chunk-7H6UYIDE.js";
82
88
  import {
83
89
  DEFAULT_ENV_ID,
84
90
  getPopSelfServeConfig,
@@ -601,8 +607,11 @@ function isPhoneSignerActive(options) {
601
607
  function shouldHandoverName(opts) {
602
608
  return !!opts.transferTo && opts.registeredFresh;
603
609
  }
604
- function formatStorageSignerLine(slotAddress, failReason) {
605
- if (slotAddress) return ` Storage signer: allowance slot ${slotAddress}`;
610
+ function formatStorageSignerLine(slotAddress, failReason, owned) {
611
+ if (slotAddress) {
612
+ const prefix = owned ? "your allowance slot" : "allowance slot";
613
+ return ` Storage signer: ${prefix} ${slotAddress}`;
614
+ }
606
615
  return ` Storage signer: pool fallback (${failReason ?? "no session"})`;
607
616
  }
608
617
  function selectStorageReconnect(options) {
@@ -936,7 +945,18 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
936
945
  }
937
946
  console.log(` Cache check: ${confirmedCount} confirmed, ${tier2Fallback} missing${tier2Fallback > 0 ? " (will upload)" : ""}`);
938
947
  }
939
- const assignedNonces = assignDenseNonces(stored, startNonce);
948
+ let assignedNonces = assignDenseNonces(stored, startNonce);
949
+ const doReconnectAndRebase = async () => {
950
+ const prevSS58 = ss58;
951
+ await doReconnect();
952
+ const currentNonce = await _fetchNonce(BULLETIN_ENDPOINTS, ss58);
953
+ const changed = ss58 !== prevSS58;
954
+ if (changed) {
955
+ assignedNonces = assignDenseNonces(stored, currentNonce);
956
+ startNonce = currentNonce;
957
+ }
958
+ return { changed, currentNonce };
959
+ };
940
960
  const uploadTotal = stored.filter((s) => s === null).length;
941
961
  let uploadEmitted = 0;
942
962
  const nonceAdvanceIndices = /* @__PURE__ */ new Set();
@@ -979,18 +999,19 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
979
999
  const failures = results.map((r, j) => r.status === "rejected" ? { index: batchIndices[j], chunkData: batchChunks[j], error: r.reason } : null).filter(Boolean);
980
1000
  const needsReconnect = failures.some((f) => isConnectionError(f.error));
981
1001
  if (needsReconnect && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
982
- await doReconnect();
983
- const currentNonce = await _fetchNonce(BULLETIN_ENDPOINTS, ss58);
984
- for (const idx of batchIndices) {
985
- const chunkNonce = assignedNonces.get(idx);
986
- if (chunkNonce !== void 0 && chunkNonce < currentNonce && stored[idx] === null) {
987
- console.log(` Chunk ${idx + 1}: nonce ${chunkNonce} consumed (current=${currentNonce}), treating as included`);
988
- stored[idx] = { cid: createCID(chunks[idx], CID_CONFIG.codec, 18), len: chunks[idx].length, viaFallback: true };
989
- nonceAdvanceIndices.add(idx);
990
- assignedNonces.delete(idx);
1002
+ const { changed, currentNonce } = await doReconnectAndRebase();
1003
+ if (!changed) {
1004
+ for (const idx of batchIndices) {
1005
+ const chunkNonce = assignedNonces.get(idx);
1006
+ if (chunkNonce !== void 0 && chunkNonce < currentNonce && stored[idx] === null) {
1007
+ console.log(` Chunk ${idx + 1}: nonce ${chunkNonce} consumed (current=${currentNonce}), treating as included`);
1008
+ stored[idx] = { cid: createCID(chunks[idx], CID_CONFIG.codec, 18), len: chunks[idx].length, viaFallback: true };
1009
+ nonceAdvanceIndices.add(idx);
1010
+ assignedNonces.delete(idx);
1011
+ }
991
1012
  }
1013
+ startNonce = Math.max(startNonce, currentNonce);
992
1014
  }
993
- startNonce = Math.max(startNonce, currentNonce);
994
1015
  if (failures.some((f) => stored[f.index] === null)) {
995
1016
  continue;
996
1017
  }
@@ -1017,9 +1038,10 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
1017
1038
  const retryDelay = Math.min(RETRY_BASE_DELAY_MS * Math.pow(2, attempt - 1), RETRY_MAX_DELAY_MS);
1018
1039
  console.log(` Retrying chunk ${fail.index + 1} (attempt ${attempt}/${MAX_CHUNK_RETRIES}) in ${(retryDelay / 1e3).toFixed(0)}s...`);
1019
1040
  await new Promise((r) => setTimeout(r, retryDelay));
1041
+ let perRetryChanged = false;
1020
1042
  if (isConnectionError(fail.error) && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
1021
1043
  try {
1022
- await doReconnect();
1044
+ ({ changed: perRetryChanged } = await doReconnectAndRebase());
1023
1045
  } catch (reconnectErr) {
1024
1046
  console.log(` Reconnect failed: ${reconnectErr.message?.slice(0, 80)}`);
1025
1047
  break;
@@ -1028,7 +1050,7 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
1028
1050
  try {
1029
1051
  const currentNonce = await _fetchNonce(BULLETIN_ENDPOINTS, ss58);
1030
1052
  const originalNonce = assignedNonces.get(fail.index);
1031
- if (originalNonce !== void 0 && originalNonce < currentNonce) {
1053
+ if (!perRetryChanged && originalNonce !== void 0 && originalNonce < currentNonce) {
1032
1054
  console.log(` Chunk ${fail.index + 1}: nonce ${originalNonce} consumed (current=${currentNonce}), treating as included`);
1033
1055
  stored[fail.index] = { cid: createCID(fail.chunkData, CID_CONFIG.codec, 18), len: fail.chunkData.length, viaFallback: true };
1034
1056
  nonceAdvanceIndices.add(fail.index);
@@ -1083,6 +1105,10 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
1083
1105
  collision_count: missingResults.length
1084
1106
  });
1085
1107
  }
1108
+ if (wsHaltDetected && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
1109
+ wsHaltDetected = false;
1110
+ await doReconnect();
1111
+ }
1086
1112
  let reuploadCount = 0;
1087
1113
  for (const m of missingResults) {
1088
1114
  const idx = cidToIndex.get(m.cid);
@@ -1095,6 +1121,12 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
1095
1121
  reuploadCount++;
1096
1122
  break;
1097
1123
  } catch (e) {
1124
+ if (isConnectionError(e) && reconnect && reconnectionsUsed < MAX_RECONNECTIONS) {
1125
+ try {
1126
+ await doReconnect();
1127
+ } catch {
1128
+ }
1129
+ }
1098
1130
  if (attempt === MAX_REPROBE_RETRIES) {
1099
1131
  throw new Error(`Nonce-collision re-upload of chunk ${idx + 1} failed after ${MAX_REPROBE_RETRIES} attempts: ${e.message?.slice(0, 100)}`);
1100
1132
  }
@@ -1652,33 +1684,46 @@ async function storeDirectoryV2(directoryPath, opts = {}) {
1652
1684
  const roundSuffix = round > 1 ? ` (round ${round}/${GRANDPA_REUPLOAD_MAX_ROUNDS}, retry after fork)` : "";
1653
1685
  console.log(` ${missingCids.size} chunks still missing after wait \u2014 re-uploading${roundSuffix}`);
1654
1686
  const reuploadList = [...missingCids];
1655
- for (let i = 0; i < reuploadList.length; i++) {
1656
- const cid = reuploadList[i];
1657
- const freshNonce = await fetchNonceFn(BULLETIN_ENDPOINTS, phaseALiveProvider.ss58);
1658
- if (cid === storageCid) {
1659
- const rootTx = phaseALiveProvider.unsafeApi.tx.TransactionStorage.store_with_cid_config({
1660
- cid: { codec: BigInt(112), hashing: toHashingEnum(rootHashCode) },
1661
- data: rootDagBytes
1662
- });
1663
- await watchTransaction(rootTx, phaseALiveProvider.signer, { mortality: { mortal: true, period: 256 }, nonce: freshNonce }, () => storageCid, {
1664
- label: "root-reupload",
1665
- rpc: BULLETIN_ENDPOINTS,
1666
- senderSS58: phaseALiveProvider.ss58,
1667
- expectedNonce: freshNonce,
1668
- timeoutMs: CHUNK_TIMEOUT_MS,
1669
- fetchNonce: phaseALiveProvider.fetchNonce
1670
- });
1671
- } else {
1672
- const chunkBytes = phaseBChunkByCid.get(cid);
1673
- if (!chunkBytes) {
1674
- throw new Error(
1675
- `Deploy verification failed: chunk ${cid.slice(0, 20)}\u2026 missing at finalised head and its bytes are not in phaseB.chunks (cannot re-upload). This indicates an internal state issue.`
1676
- );
1687
+ try {
1688
+ for (let i = 0; i < reuploadList.length; i++) {
1689
+ const cid = reuploadList[i];
1690
+ const freshNonce = await fetchNonceFn(BULLETIN_ENDPOINTS, phaseALiveProvider.ss58);
1691
+ if (cid === storageCid) {
1692
+ const rootTx = phaseALiveProvider.unsafeApi.tx.TransactionStorage.store_with_cid_config({
1693
+ cid: { codec: BigInt(112), hashing: toHashingEnum(rootHashCode) },
1694
+ data: rootDagBytes
1695
+ });
1696
+ await watchTransaction(rootTx, phaseALiveProvider.signer, { mortality: { mortal: true, period: 256 }, nonce: freshNonce }, () => storageCid, {
1697
+ label: "root-reupload",
1698
+ rpc: BULLETIN_ENDPOINTS,
1699
+ senderSS58: phaseALiveProvider.ss58,
1700
+ expectedNonce: freshNonce,
1701
+ timeoutMs: CHUNK_TIMEOUT_MS,
1702
+ fetchNonce: phaseALiveProvider.fetchNonce
1703
+ });
1704
+ } else {
1705
+ const chunkBytes = phaseBChunkByCid.get(cid);
1706
+ if (!chunkBytes) {
1707
+ throw new Error(
1708
+ `Deploy verification failed: chunk ${cid.slice(0, 20)}\u2026 missing at finalised head and its bytes are not in phaseB.chunks (cannot re-upload). This indicates an internal state issue.`
1709
+ );
1710
+ }
1711
+ await storeChunk(phaseALiveProvider.unsafeApi, phaseALiveProvider.signer, chunkBytes, freshNonce, phaseALiveProvider.ss58, { fetchNonce: phaseALiveProvider.fetchNonce });
1677
1712
  }
1678
- await storeChunk(phaseALiveProvider.unsafeApi, phaseALiveProvider.signer, chunkBytes, freshNonce, phaseALiveProvider.ss58, { fetchNonce: phaseALiveProvider.fetchNonce });
1713
+ reuploadCount++;
1714
+ console.log(` [${i + 1}/${reuploadList.length}] re-uploaded ${cid.slice(0, 20)}\u2026 (nonce ${freshNonce})`);
1679
1715
  }
1680
- reuploadCount++;
1681
- console.log(` [${i + 1}/${reuploadList.length}] re-uploaded ${cid.slice(0, 20)}\u2026 (nonce ${freshNonce})`);
1716
+ } catch (e) {
1717
+ if (isConnectionError(e) && phaseALiveProvider.reconnect) {
1718
+ try {
1719
+ phaseALiveProvider.client.destroy();
1720
+ } catch {
1721
+ }
1722
+ const fresh = await phaseALiveProvider.reconnect();
1723
+ phaseALiveProvider = { ...phaseALiveProvider, ...fresh };
1724
+ continue;
1725
+ }
1726
+ throw e;
1682
1727
  }
1683
1728
  const reuploadStart = Date.now();
1684
1729
  while (Date.now() - reuploadStart < GRANDPA_REUPLOAD_TIMEOUT_MS && missingCids.size > 0) {
@@ -2038,29 +2083,28 @@ async function deploy(content, domainName = null, options = {}) {
2038
2083
  }
2039
2084
  }
2040
2085
  if (!options.storageSigner) {
2041
- let storageLine = null;
2042
- try {
2043
- if (resolvedUserSession?.userSession && resolvedUserSession?.adapter) {
2044
- const { ss58Encode } = await import("@parity/product-sdk-address");
2045
- const signerResult = await resolvedUserSession.adapter.allowance.getBulletinSigner(
2046
- resolvedUserSession.userSession.id,
2047
- DOT_PRODUCT_ID
2048
- );
2049
- if (signerResult.isOk()) {
2050
- const slotSigner = signerResult.value;
2051
- const slotAddress = ss58Encode(slotSigner.publicKey);
2052
- options = { ...options, storageSigner: slotSigner, storageSignerAddress: slotAddress };
2053
- storageLine = formatStorageSignerLine(slotAddress);
2054
- } else {
2055
- storageLine = formatStorageSignerLine(null, signerResult.error.reason);
2086
+ const { ss58Encode } = await import("@parity/product-sdk-address");
2087
+ const slotResult = await resolveStorageSigner(
2088
+ resolvedUserSession ?? null,
2089
+ {
2090
+ getBulletinSigner: (sessionId, productId, adapter) => adapter.allowance.getBulletinSigner(sessionId, productId),
2091
+ requestResourceAllocation,
2092
+ createSlotAccountSigner,
2093
+ ss58Encode: (pk) => ss58Encode(pk),
2094
+ promptBeforeAllocation: () => {
2095
+ console.log(
2096
+ `
2097
+ \u26A0 Your account has no Bulletin allowance. Approve one on your phone to deploy with your own account, or press Ctrl-C to use the shared pool.`
2098
+ );
2056
2099
  }
2057
- } else {
2058
- storageLine = formatStorageSignerLine(null);
2059
2100
  }
2060
- } catch {
2061
- storageLine = formatStorageSignerLine(null, "error");
2101
+ );
2102
+ if (slotResult) {
2103
+ options = { ...options, storageSigner: slotResult.signer, storageSignerAddress: slotResult.slotAddress };
2104
+ console.log(formatStorageSignerLine(slotResult.slotAddress, void 0, slotResult.owned));
2105
+ } else {
2106
+ console.log(formatStorageSignerLine(null, resolvedUserSession ? "no allowance" : void 0));
2062
2107
  }
2063
- if (storageLine) console.log(storageLine);
2064
2108
  }
2065
2109
  initTelemetry();
2066
2110
  const randomSuffix = Math.floor(Math.random() * 100).toString().padStart(2, "0");
@@ -2173,17 +2217,7 @@ async function deploy(content, domainName = null, options = {}) {
2173
2217
  }
2174
2218
  if (phoneSignerActive) {
2175
2219
  const steps = computePhoneSigningSteps(dotnsPreflight, preflightPublishNeeded);
2176
- if (steps.length === 1) {
2177
- console.log(`
2178
- Have your phone ready \u2014 1 signature needed (${steps[0].toLowerCase()})`);
2179
- } else if (steps.length > 1) {
2180
- const display = steps.flatMap(
2181
- (s, i) => s === "Register" && steps[i - 1] === "Commitment" ? ["(wait)", s] : [s]
2182
- );
2183
- console.log(`
2184
- Have your phone ready \u2014 ${steps.length} signatures needed`);
2185
- console.log(` ${display.map((s) => s.toLowerCase()).join(" \xB7 ")}`);
2186
- }
2220
+ options.onPhoneSignaturePlan?.(steps);
2187
2221
  }
2188
2222
  provider = await reconnect();
2189
2223
  const providerWithReconnect = { ...provider, reconnect };
@@ -2392,13 +2426,10 @@ Have your phone ready \u2014 ${steps.length} signatures needed`);
2392
2426
  };
2393
2427
  await ownerDotns.connect({
2394
2428
  ...resolveDotnsConnectOptions({ ...options, signer: owner.signer, signerAddress: owner.address }, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit),
2395
- onPhoneSigningRequired: (label) => console.log(`
2396
- Check your phone \u2192 ${label}`)
2429
+ confirmPhoneReady: options.confirmPhoneReady
2397
2430
  });
2398
2431
  const willPublish = !!(options.publish && parsed && preflightPublishNeeded !== false);
2399
- console.log(willPublish ? `
2400
- Have your phone ready \u2014 2 signatures needed (link content \xB7 publish)` : `
2401
- Have your phone ready \u2014 1 signature needed (link content)`);
2432
+ ownerDotns.setPhoneSignatureTotal(willPublish ? 2 : 1);
2402
2433
  const contenthashHex2 = `0x${encodeContenthash(cid)}`;
2403
2434
  await ownerDotns.setContenthash(name, contenthashHex2, { feeAsset: "pgas" });
2404
2435
  if (willPublish) await publish(ownerDotns, parsed, options.failOnPublishError);
@@ -2407,11 +2438,11 @@ Have your phone ready \u2014 1 signature needed (link content)`);
2407
2438
  const dotns = new DotNS();
2408
2439
  await dotns.connect({
2409
2440
  ...resolveDotnsConnectOptions(options, envAssetHub, envAutoAccountMapping, envContracts, envNativeToEthRatio, envId, envPopSelfServe, envRegisterStorageDeposit),
2410
- // Per-step "check your phone" reminder — only for a phone-backed signer
2411
- // (see phoneSignerActive); a transfer-mode local worker signs locally.
2412
- ...phoneSignerActive ? { onPhoneSigningRequired: (label) => console.log(`
2413
- Check your phone \u2192 ${label}`) } : {}
2441
+ confirmPhoneReady: options.confirmPhoneReady
2414
2442
  });
2443
+ if (phoneSignerActive) {
2444
+ dotns.setPhoneSignatureTotal(computePhoneSigningSteps(dotnsPreflight, preflightPublishNeeded).length);
2445
+ }
2415
2446
  let registeredFresh = false;
2416
2447
  if (parsed?.isSubdomain) {
2417
2448
  const { owned, owner } = await dotns.checkSubdomainOwnership(parsed.sublabel, parsed.parentLabel);
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-GRPLHUYC.js";
4
4
  import {
5
5
  DOT_DAPP_ID
6
- } from "./chunk-TE5ILRKP.js";
6
+ } from "./chunk-4PLUBND7.js";
7
7
 
8
8
  // src/sss-allowance-cache.ts
9
9
  import { mkdir, readFile, writeFile, unlink } from "fs/promises";
@@ -5,9 +5,9 @@ import {
5
5
  _decodeStorageValue,
6
6
  _resetProbeSession,
7
7
  probeChunks
8
- } from "./chunk-R74IZLP4.js";
9
- import "./chunk-LDMBTCMO.js";
10
- import "./chunk-VHW7K7JW.js";
8
+ } from "./chunk-IMHVYM7Q.js";
9
+ import "./chunk-7H6UYIDE.js";
10
+ import "./chunk-U2JW2FSV.js";
11
11
  export {
12
12
  ChainProbeCrossValidationError,
13
13
  ChainProbeMetadataError,
@@ -1,23 +1,12 @@
1
1
  import {
2
2
  startSpinner
3
3
  } from "../chunk-J7CYVTAW.js";
4
- import "../chunk-JQKKMUCT.js";
5
- import {
6
- BULLETIN_RESOURCE,
7
- DEFAULT_RESOURCES,
8
- createSlotAccountSigner,
9
- requestResourceAllocation,
10
- summarizeOutcomes
11
- } from "../chunk-5FLTDWWP.js";
12
- import {
13
- renderLoginStatus
14
- } from "../chunk-RIRDBSBG.js";
15
4
  import {
16
5
  waitForBulletinAuthorization
17
- } from "../chunk-XZXMZ2EN.js";
6
+ } from "../chunk-VJNXVT3F.js";
18
7
  import {
19
8
  preflightSssAllowance
20
- } from "../chunk-Y3GVAWTH.js";
9
+ } from "../chunk-XCK7YHBD.js";
21
10
  import {
22
11
  statementSigningAccount
23
12
  } from "../chunk-GRPLHUYC.js";
@@ -26,24 +15,36 @@ import "../chunk-IW3X2MJF.js";
26
15
  import "../chunk-KOSF5FDO.js";
27
16
  import "../chunk-J3NIXHZZ.js";
28
17
  import "../chunk-S7EM5VMW.js";
18
+ import "../chunk-5SWXGBOO.js";
19
+ import "../chunk-BJXJ7ZLD.js";
20
+ import "../chunk-IMHVYM7Q.js";
21
+ import "../chunk-C2TS5MER.js";
22
+ import "../chunk-UWAZDGBT.js";
23
+ import "../chunk-JQKKMUCT.js";
24
+ import {
25
+ BULLETIN_RESOURCE,
26
+ DEFAULT_RESOURCES,
27
+ createSlotAccountSigner,
28
+ requestResourceAllocation,
29
+ summarizeOutcomes
30
+ } from "../chunk-5FLTDWWP.js";
31
+ import {
32
+ renderLoginStatus
33
+ } from "../chunk-RIRDBSBG.js";
29
34
  import {
30
35
  DOT_PRODUCT_ID,
31
36
  getAuthClient,
32
37
  getPeopleChainEndpoints,
33
38
  resolveBulletinEndpoints
34
- } from "../chunk-TE5ILRKP.js";
35
- import "../chunk-H73WL3JM.js";
36
- import "../chunk-UCRSE6CA.js";
37
- import "../chunk-R74IZLP4.js";
38
- import "../chunk-C2TS5MER.js";
39
+ } from "../chunk-4PLUBND7.js";
39
40
  import {
40
41
  CLI_NAME
41
42
  } from "../chunk-TSPERKUS.js";
42
- import "../chunk-Q5JW6NOW.js";
43
+ import "../chunk-TXJ6KQWM.js";
43
44
  import "../chunk-SI2ZUOYD.js";
44
45
  import "../chunk-4IUTMHVB.js";
45
- import "../chunk-LDMBTCMO.js";
46
- import "../chunk-VHW7K7JW.js";
46
+ import "../chunk-7H6UYIDE.js";
47
+ import "../chunk-U2JW2FSV.js";
47
48
  import {
48
49
  loadEnvironments
49
50
  } from "../chunk-QRKI6MMK.js";
@@ -1,18 +1,18 @@
1
+ import {
2
+ clearSssAllowanceCache
3
+ } from "../chunk-XCK7YHBD.js";
4
+ import "../chunk-GRPLHUYC.js";
1
5
  import "../chunk-JQKKMUCT.js";
2
6
  import "../chunk-5FLTDWWP.js";
3
7
  import {
4
8
  renderLogoutStatus
5
9
  } from "../chunk-RIRDBSBG.js";
6
- import {
7
- clearSssAllowanceCache
8
- } from "../chunk-Y3GVAWTH.js";
9
- import "../chunk-GRPLHUYC.js";
10
10
  import {
11
11
  getAuthClient
12
- } from "../chunk-TE5ILRKP.js";
12
+ } from "../chunk-4PLUBND7.js";
13
13
  import "../chunk-TSPERKUS.js";
14
- import "../chunk-LDMBTCMO.js";
15
- import "../chunk-VHW7K7JW.js";
14
+ import "../chunk-7H6UYIDE.js";
15
+ import "../chunk-U2JW2FSV.js";
16
16
  import "../chunk-QRKI6MMK.js";
17
17
  import "../chunk-ZOC4GITL.js";
18
18
 
@@ -4,11 +4,11 @@ import {
4
4
  import {
5
5
  DEFAULT_MNEMONIC,
6
6
  DotNS
7
- } from "../chunk-Q5JW6NOW.js";
7
+ } from "../chunk-TXJ6KQWM.js";
8
8
  import "../chunk-SI2ZUOYD.js";
9
9
  import "../chunk-4IUTMHVB.js";
10
- import "../chunk-LDMBTCMO.js";
11
- import "../chunk-VHW7K7JW.js";
10
+ import "../chunk-7H6UYIDE.js";
11
+ import "../chunk-U2JW2FSV.js";
12
12
  import {
13
13
  getPopSelfServeConfig,
14
14
  loadEnvironments,
@@ -2,12 +2,12 @@ import {
2
2
  STALE_SESSION_MESSAGE,
3
3
  getAuthClient,
4
4
  hasPersistedSession
5
- } from "../chunk-TE5ILRKP.js";
5
+ } from "../chunk-4PLUBND7.js";
6
6
  import {
7
7
  CLI_NAME
8
8
  } from "../chunk-TSPERKUS.js";
9
- import "../chunk-LDMBTCMO.js";
10
- import "../chunk-VHW7K7JW.js";
9
+ import "../chunk-7H6UYIDE.js";
10
+ import "../chunk-U2JW2FSV.js";
11
11
  import "../chunk-QRKI6MMK.js";
12
12
  import "../chunk-ZOC4GITL.js";
13
13
 
@@ -1,8 +1,8 @@
1
1
  import { A as AuthClient } from './auth-CA_YKtM2.js';
2
+ import { PolkadotSigner } from 'polkadot-api';
2
3
  import { R as ResolvedSigner } from './signer-Duup0hgQ.js';
4
+ import { A as AllocatableResource } from './allocations-CEPeZr6T.js';
3
5
  import '@parity/product-sdk-terminal';
4
- import 'polkadot-api';
5
- import './allocations-CEPeZr6T.js';
6
6
  import '@parity/product-sdk-tx';
7
7
 
8
8
  declare class MainnetDefaultWorkerError extends Error {
@@ -20,5 +20,86 @@ interface ResolveDeployActorsOptions {
20
20
  sessionPresent: boolean;
21
21
  }
22
22
  declare function resolveDeployActors(authClient: AuthClient, { suri, transferEnabled, isTestnet, sessionPresent }: ResolveDeployActorsOptions): Promise<DeployActors>;
23
+ /**
24
+ * Result returned by resolveStorageSigner when a Bulletin slot signer was found.
25
+ *
26
+ * `owned` is true when the slot comes from the user's own session (cache-hit or
27
+ * freshly allocated via step-4 prompt). It is used by formatStorageSignerLine to
28
+ * distinguish "your allowance slot" (owned) from "allowance slot" (explicitly
29
+ * injected by a programmatic caller).
30
+ */
31
+ interface StorageSignerResult {
32
+ signer: PolkadotSigner;
33
+ slotAddress: string;
34
+ /** true when the slot comes from the user's own session (not a pre-injected slot). */
35
+ owned: true;
36
+ }
37
+ /**
38
+ * Injectable dependencies for resolveStorageSigner.
39
+ * All fields are optional — defaults are used when not provided (deploy path).
40
+ * Injecting stubs lets unit tests drive every branch without a real adapter.
41
+ */
42
+ interface StorageSignerDeps {
43
+ /**
44
+ * Calls adapter.allowance.getBulletinSigner(sessionId, productId).
45
+ * Returns an Ok/Err result (product-sdk shape).
46
+ */
47
+ getBulletinSigner: (sessionId: string, productId: string, adapter: any) => Promise<{
48
+ isOk(): boolean;
49
+ isErr(): boolean;
50
+ value?: PolkadotSigner;
51
+ error?: {
52
+ reason: string;
53
+ };
54
+ }>;
55
+ /**
56
+ * Triggers a phone prompt to allocate the BulletInAllowance resource.
57
+ * Returns AllocationOutcome[] — one per resource in order.
58
+ */
59
+ requestResourceAllocation: (userSession: any, adapter: any, resources: AllocatableResource[]) => Promise<{
60
+ tag: string;
61
+ value?: unknown;
62
+ }[]>;
63
+ /**
64
+ * Read the cached slot account signer written by requestResourceAllocation.
65
+ * Returns null on a miss (graceful fallback).
66
+ */
67
+ createSlotAccountSigner?: (adapter: any, resource: AllocatableResource) => Promise<PolkadotSigner | null>;
68
+ /** Encode a public key as SS58. */
69
+ ss58Encode: (publicKey: Uint8Array) => string;
70
+ /**
71
+ * Called BEFORE requestResourceAllocation to print the user-facing prompt.
72
+ * Should print the "check your phone" warning so the user knows what's coming.
73
+ * Ctrl-C will interrupt the subsequent requestResourceAllocation call directly.
74
+ */
75
+ promptBeforeAllocation: () => void;
76
+ }
77
+ /**
78
+ * Resolve a user-owned Bulletin slot signer from the active session.
79
+ *
80
+ * Implements steps 3–4 of the storage-signer precedence:
81
+ * 3. Cache-hit: adapter.allowance.getBulletinSigner(sessionId) → slot signer.
82
+ * 4. Cache-miss (NotAvailable / Rejected): prompt then requestResourceAllocation
83
+ * ([BulletInAllowance]) → newly-allocated slot signer.
84
+ * 5. Fall through: returns null → caller falls back to pool.
85
+ *
86
+ * Non-goals: explicit storageSigner / signer / mnemonic paths — those are handled
87
+ * upstream by selectStorageReconnect. This function only handles session-derived slots.
88
+ *
89
+ * Layer-3 isolation is preserved: when `session` is null (no session file on disk,
90
+ * no --suri), this function returns null immediately without touching the SSO stack.
91
+ *
92
+ * @param session The resolved session object from resolveDeployActors (or null when
93
+ * no session is present). Must have { userSession, adapter } shape.
94
+ * @param deps Injectable dependencies for testing. Production callers pass
95
+ * undefined to use the real auth functions.
96
+ * @returns A { signer, slotAddress, owned: true } result or null (→ pool).
97
+ */
98
+ declare function resolveStorageSigner(session: {
99
+ userSession: {
100
+ id: string;
101
+ };
102
+ adapter: any;
103
+ } | null | undefined, deps: StorageSignerDeps): Promise<StorageSignerResult | null>;
23
104
 
24
- export { type DeployActors, MainnetDefaultWorkerError, type ResolveDeployActorsOptions, resolveDeployActors };
105
+ export { type DeployActors, MainnetDefaultWorkerError, type ResolveDeployActorsOptions, type StorageSignerDeps, type StorageSignerResult, resolveDeployActors, resolveStorageSigner };
@@ -1,45 +1,22 @@
1
- import "./chunk-JQKKMUCT.js";
2
1
  import {
3
- resolveSigner
4
- } from "./chunk-5FLTDWWP.js";
2
+ MainnetDefaultWorkerError,
3
+ resolveDeployActors,
4
+ resolveStorageSigner
5
+ } from "./chunk-UWAZDGBT.js";
6
+ import "./chunk-JQKKMUCT.js";
7
+ import "./chunk-5FLTDWWP.js";
5
8
  import "./chunk-RIRDBSBG.js";
9
+ import "./chunk-4PLUBND7.js";
6
10
  import "./chunk-TSPERKUS.js";
7
- import {
8
- DEFAULT_MNEMONIC
9
- } from "./chunk-Q5JW6NOW.js";
11
+ import "./chunk-TXJ6KQWM.js";
10
12
  import "./chunk-SI2ZUOYD.js";
11
13
  import "./chunk-4IUTMHVB.js";
12
- import "./chunk-LDMBTCMO.js";
13
- import "./chunk-VHW7K7JW.js";
14
+ import "./chunk-7H6UYIDE.js";
15
+ import "./chunk-U2JW2FSV.js";
14
16
  import "./chunk-QRKI6MMK.js";
15
17
  import "./chunk-ZOC4GITL.js";
16
-
17
- // src/deploy-actors.ts
18
- var DEFAULT_WORKER_SURI = DEFAULT_MNEMONIC;
19
- var MainnetDefaultWorkerError = class extends Error {
20
- constructor() {
21
- super(
22
- "Refusing to default the deploy worker to Alice on a non-testnet environment. Pass --mnemonic <a funded, sufficiently-verified key> to do the transfer flow, or --no-transfer-to-signedin-user to sign directly with your mobile session."
23
- );
24
- this.name = "MainnetDefaultWorkerError";
25
- }
26
- };
27
- async function resolveDeployActors(authClient, { suri, transferEnabled, isTestnet, sessionPresent }) {
28
- if (sessionPresent && transferEnabled) {
29
- if (!suri && !isTestnet) throw new MainnetDefaultWorkerError();
30
- const worker2 = await resolveSigner(authClient, { suri: suri ?? DEFAULT_WORKER_SURI });
31
- const handle = await authClient.getSessionSigner();
32
- if (!handle) throw new Error("transfer mode active but no session resolved; pass --no-transfer-to-signedin-user.");
33
- try {
34
- return { worker: worker2, recipientH160: handle.addresses.productH160 };
35
- } finally {
36
- handle.destroy();
37
- }
38
- }
39
- const worker = await resolveSigner(authClient, { suri });
40
- return { worker };
41
- }
42
18
  export {
43
19
  MainnetDefaultWorkerError,
44
- resolveDeployActors
20
+ resolveDeployActors,
21
+ resolveStorageSigner
45
22
  };