@parity/product-deploy 0.8.3-rc.6 → 0.8.3-rc.7

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 (59) hide show
  1. package/bin/bulletin-deploy +33 -7
  2. package/dist/allocations-B65Is4Md.d.ts +97 -0
  3. package/dist/auth/index.d.ts +7 -0
  4. package/dist/auth/index.js +25 -0
  5. package/dist/auth/vendor/index.d.ts +32 -0
  6. package/dist/auth/vendor/index.js +26 -0
  7. package/dist/auth/vendor/ui/index.d.ts +15 -0
  8. package/dist/auth/vendor/ui/index.js +10 -0
  9. package/dist/auth-DkRZBK-T.d.ts +122 -0
  10. package/dist/auth-config.d.ts +39 -0
  11. package/dist/auth-config.js +20 -0
  12. package/dist/bug-report.js +4 -4
  13. package/dist/chunk-327NAPBD.js +52 -0
  14. package/dist/chunk-7DGFJC6E.js +379 -0
  15. package/dist/{chunk-6XDIJYDO.js → chunk-BI5SDZMM.js} +2 -2
  16. package/dist/{chunk-22CE57IY.js → chunk-C2DA2PRC.js} +1 -1
  17. package/dist/{chunk-YUIBBHS2.js → chunk-HEKCOME3.js} +1 -1
  18. package/dist/chunk-JQKKMUCT.js +0 -0
  19. package/dist/{chunk-3TOFKDMY.js → chunk-OBCWAZQE.js} +1 -1
  20. package/dist/{chunk-L5Z3TJD7.js → chunk-OCKCB72S.js} +6 -6
  21. package/dist/{chunk-LX77LVIM.js → chunk-OPMGKRYY.js} +17 -3
  22. package/dist/chunk-RIRDBSBG.js +36 -0
  23. package/dist/{chunk-Y7F57J2T.js → chunk-TDPH6Y3G.js} +602 -383
  24. package/dist/{chunk-M6DM2NUT.js → chunk-W4MILLXD.js} +8 -2
  25. package/dist/{chunk-3ASTLJSZ.js → chunk-XYBMCFIX.js} +2 -2
  26. package/dist/chunk-probe.js +3 -3
  27. package/dist/commands/login.d.ts +28 -0
  28. package/dist/commands/login.js +63 -0
  29. package/dist/commands/logout.d.ts +21 -0
  30. package/dist/commands/logout.js +37 -0
  31. package/dist/commands/whoami.d.ts +22 -0
  32. package/dist/commands/whoami.js +47 -0
  33. package/dist/deploy.d.ts +40 -3
  34. package/dist/deploy.js +17 -8
  35. package/dist/dotns.js +3 -3
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +13 -12
  38. package/dist/manifest/publish.js +10 -9
  39. package/dist/memory-report.js +2 -2
  40. package/dist/merkle.d.ts +3 -1
  41. package/dist/merkle.js +9 -8
  42. package/dist/personhood/bind-paid-alias.js +3 -3
  43. package/dist/personhood/bind-personal-id.js +2 -2
  44. package/dist/personhood/bootstrap.js +16 -16
  45. package/dist/personhood/claim-pgas.js +2 -2
  46. package/dist/personhood/people-client.js +3 -3
  47. package/dist/personhood/proof-validity.js +2 -2
  48. package/dist/personhood/reprove.js +5 -5
  49. package/dist/run-state.js +1 -1
  50. package/dist/signer-CriGqahj.d.ts +35 -0
  51. package/dist/storage-signer.d.ts +38 -0
  52. package/dist/storage-signer.js +28 -0
  53. package/dist/telemetry.d.ts +1 -1
  54. package/dist/telemetry.js +2 -2
  55. package/dist/version-check.js +3 -3
  56. package/package.json +17 -3
  57. package/dist/{chunk-LHLCPDGL.js → chunk-7URNKK6J.js} +3 -3
  58. package/dist/{chunk-7Y7RDOGT.js → chunk-EATOPQFR.js} +5 -5
  59. package/dist/{chunk-SLE4P6MO.js → chunk-EJI3MX4G.js} +3 -3
@@ -0,0 +1,379 @@
1
+ // src/auth/vendor/auth.ts
2
+ import { readdir, unlink } from "fs/promises";
3
+ import { homedir } from "os";
4
+ import { join } from "path";
5
+ import { deriveH160, ss58Encode } from "@parity/product-sdk-address";
6
+ import {
7
+ createTerminalAdapter,
8
+ waitForSessions,
9
+ renderQrCode
10
+ } from "@parity/product-sdk-terminal";
11
+
12
+ // src/auth/vendor/sessionSigner.ts
13
+ import { deriveProductAccountPublicKey } from "@parity/product-sdk-keys";
14
+ var INCOMPLETE_SESSION_MESSAGE = 'Stored login session is missing the root account public key. Run "logout" and then "login" to pair again.';
15
+ function sessionRootPublicKey(session) {
16
+ const rootAccountId = session.rootAccountId;
17
+ const publicKey = rootAccountId ? new Uint8Array(rootAccountId) : new Uint8Array();
18
+ if (publicKey.length !== 32) {
19
+ throw new Error(INCOMPLETE_SESSION_MESSAGE);
20
+ }
21
+ return publicKey;
22
+ }
23
+ function deriveProductPublicKey(rootAccountId, ref) {
24
+ return deriveProductAccountPublicKey(rootAccountId, ref.productId, ref.derivationIndex);
25
+ }
26
+ function createSessionSigner(session, ref) {
27
+ const publicKey = deriveProductPublicKey(sessionRootPublicKey(session), ref);
28
+ const productAccountId = [ref.productId, ref.derivationIndex];
29
+ const signTx = async (callData, signedExtensions, _metadata, _atBlockNumber) => {
30
+ const genesisHash = signedExtensions["CheckGenesis"]?.additionalSigned ?? new Uint8Array(32);
31
+ const extensions = Object.entries(signedExtensions).map(([id, { value, additionalSigned }]) => ({
32
+ id,
33
+ extra: value,
34
+ additionalSigned
35
+ }));
36
+ const result = await session.createTransaction({
37
+ payload: {
38
+ tag: "v1",
39
+ value: {
40
+ signer: productAccountId,
41
+ genesisHash,
42
+ callData,
43
+ extensions,
44
+ txExtVersion: 0
45
+ }
46
+ }
47
+ });
48
+ if (result.isErr()) {
49
+ throw new Error(`Mobile signing rejected: ${result.error.message}`);
50
+ }
51
+ return result.value;
52
+ };
53
+ const signBytes = async (data) => {
54
+ const result = await session.signRaw({
55
+ productAccountId,
56
+ data: { tag: "Bytes", value: data }
57
+ });
58
+ if (result.isErr()) {
59
+ throw new Error(`Mobile signing rejected: ${result.error.message}`);
60
+ }
61
+ return result.value.signature;
62
+ };
63
+ return { publicKey, signTx, signBytes };
64
+ }
65
+
66
+ // src/auth/vendor/allocations.ts
67
+ var DEFAULT_RESOURCES = [
68
+ { tag: "BulletInAllowance", value: void 0 },
69
+ { tag: "StatementStoreAllowance", value: void 0 },
70
+ // derivation index 0 = the default product account.
71
+ { tag: "SmartContractAllowance", value: 0 }
72
+ ];
73
+ async function requestResourceAllocation(session, productId, resources = DEFAULT_RESOURCES, onExisting = "Ignore") {
74
+ const result = await session.requestResourceAllocation({
75
+ callingProductId: productId,
76
+ resources,
77
+ onExisting
78
+ });
79
+ if (result.isErr()) {
80
+ throw new Error(`Resource allocation request failed: ${result.error.message}`);
81
+ }
82
+ return result.value;
83
+ }
84
+ function summarizeOutcomes(outcomes, resources) {
85
+ const granted = [];
86
+ const rejected = [];
87
+ const unavailable = [];
88
+ outcomes.forEach((outcome, i) => {
89
+ const resource = resources[i];
90
+ if (!resource) return;
91
+ if (outcome.tag === "Allocated") granted.push(resource);
92
+ else if (outcome.tag === "Rejected") rejected.push(resource);
93
+ else unavailable.push(resource);
94
+ });
95
+ return { granted, rejected, unavailable };
96
+ }
97
+
98
+ // src/auth/vendor/auth.ts
99
+ var QR_TIMEOUT_MS = 6e4;
100
+ function createAuthClient(config) {
101
+ const ref = { productId: config.productId, derivationIndex: config.derivationIndex };
102
+ function createAdapter() {
103
+ return createTerminalAdapter({
104
+ appId: config.dappId,
105
+ metadataUrl: config.metadataUrl,
106
+ endpoints: config.peopleEndpoints
107
+ });
108
+ }
109
+ function deriveSessionAddresses(session) {
110
+ const rootBytes = sessionRootPublicKey(session);
111
+ const productPubkey = deriveProductPublicKey(rootBytes, ref);
112
+ return {
113
+ rootAddress: ss58Encode(rootBytes),
114
+ productAddress: ss58Encode(productPubkey),
115
+ productH160: deriveH160(productPubkey)
116
+ };
117
+ }
118
+ function createSigner(session) {
119
+ return createSessionSigner(session, ref);
120
+ }
121
+ function sessionRemoteAddress(session) {
122
+ const raw = session.remoteAccount?.accountId;
123
+ const accountId = raw ? new Uint8Array(raw) : new Uint8Array();
124
+ return accountId.length === 32 ? ss58Encode(accountId) : null;
125
+ }
126
+ function sessionLogoutAddress(session) {
127
+ try {
128
+ return deriveSessionAddresses(session).productAddress;
129
+ } catch {
130
+ return sessionRemoteAddress(session) ?? "(stored session)";
131
+ }
132
+ }
133
+ async function connect() {
134
+ const adapter = createAdapter();
135
+ const sessions = await waitForSessions(adapter);
136
+ if (sessions.length > 0) {
137
+ const addresses = deriveSessionAddresses(sessions[0]);
138
+ return { kind: "existing", address: addresses.productAddress, addresses };
139
+ }
140
+ const authPromise = adapter.sso.authenticate();
141
+ try {
142
+ const qrCode = await Promise.race([
143
+ new Promise((resolve) => {
144
+ let done = false;
145
+ let unsub;
146
+ unsub = adapter.sso.pairingStatus.subscribe(async (status) => {
147
+ if (status.step === "pairing" && !done) {
148
+ done = true;
149
+ unsub?.();
150
+ resolve(await renderQrCode(status.payload));
151
+ }
152
+ });
153
+ }),
154
+ new Promise(
155
+ (_, reject) => setTimeout(
156
+ () => reject(
157
+ new Error(
158
+ `Login service did not respond within ${Math.round(
159
+ QR_TIMEOUT_MS / 1e3
160
+ )}s \u2014 try again`
161
+ )
162
+ ),
163
+ QR_TIMEOUT_MS
164
+ )
165
+ )
166
+ ]);
167
+ return { kind: "qr", qrCode, login: { adapter, authPromise } };
168
+ } catch (err) {
169
+ adapter.destroy().catch(() => {
170
+ });
171
+ throw err;
172
+ }
173
+ }
174
+ async function waitForLogin({ adapter, authPromise }, onStatus) {
175
+ onStatus({ step: "waiting" });
176
+ const unsubPairing = adapter.sso.pairingStatus.subscribe((status) => {
177
+ if (status.step === "finished") {
178
+ onStatus({ step: "paired" });
179
+ } else if (status.step === "pending") {
180
+ onStatus({ step: "pending", stage: status.stage });
181
+ } else if (status.step === "pairingError") {
182
+ onStatus({ step: "error", message: status.message });
183
+ }
184
+ });
185
+ let authenticated = false;
186
+ let address = null;
187
+ try {
188
+ const result = await authPromise;
189
+ result.match(
190
+ (session) => {
191
+ if (session) {
192
+ authenticated = true;
193
+ }
194
+ },
195
+ (error) => {
196
+ onStatus({ step: "error", message: error.message });
197
+ }
198
+ );
199
+ if (authenticated) {
200
+ const sessions = await waitForSessions(adapter, 3e3);
201
+ if (sessions.length > 0) {
202
+ const addresses = deriveSessionAddresses(sessions[0]);
203
+ address = addresses.productAddress;
204
+ onStatus({ step: "success", address, addresses });
205
+ } else {
206
+ onStatus({
207
+ step: "error",
208
+ message: "Login succeeded but the local session was not available"
209
+ });
210
+ }
211
+ }
212
+ } finally {
213
+ unsubPairing();
214
+ }
215
+ return address;
216
+ }
217
+ async function getSessionSigner() {
218
+ const adapter = createAdapter();
219
+ const sessions = await waitForSessions(adapter, 3e3);
220
+ if (sessions.length === 0) {
221
+ adapter.destroy().catch(() => {
222
+ });
223
+ return null;
224
+ }
225
+ const session = sessions[0];
226
+ const signer = createSigner(session);
227
+ const addresses = deriveSessionAddresses(session);
228
+ let destroyed = false;
229
+ const destroy = () => {
230
+ if (destroyed) return;
231
+ destroyed = true;
232
+ adapter.destroy().catch(() => {
233
+ });
234
+ };
235
+ return {
236
+ address: addresses.productAddress,
237
+ addresses,
238
+ signer,
239
+ userSession: session,
240
+ destroy
241
+ };
242
+ }
243
+ async function requestAllocation(session, resources = DEFAULT_RESOURCES, onExisting = "Ignore") {
244
+ return requestResourceAllocation(session, config.productId, resources, onExisting);
245
+ }
246
+ async function findSession() {
247
+ const adapter = createAdapter();
248
+ const sessions = await waitForSessions(adapter, 3e3);
249
+ if (sessions.length === 0) {
250
+ try {
251
+ await adapter.destroy();
252
+ } catch {
253
+ }
254
+ return null;
255
+ }
256
+ const session = sessions[0];
257
+ const address = sessionLogoutAddress(session);
258
+ return { adapter, address, session };
259
+ }
260
+ async function waitForLogout(handle, onStatus) {
261
+ const { adapter, address, session } = handle;
262
+ try {
263
+ onStatus({ step: "disconnecting", address });
264
+ const result = await adapter.sessions.disconnect(session);
265
+ if (result.isOk()) {
266
+ await clearLocalAppStorage();
267
+ onStatus({ step: "success", address });
268
+ return;
269
+ }
270
+ const reason = result.error.message || "remote unreachable";
271
+ await clearLocalAppStorage();
272
+ onStatus({ step: "partial", address, reason });
273
+ } catch (err) {
274
+ const reason = err instanceof Error ? err.message : String(err);
275
+ try {
276
+ await clearLocalAppStorage();
277
+ onStatus({ step: "partial", address, reason });
278
+ } catch (cleanupErr) {
279
+ const msg = cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr);
280
+ onStatus({ step: "error", message: msg });
281
+ }
282
+ } finally {
283
+ try {
284
+ await adapter.destroy();
285
+ } catch {
286
+ }
287
+ }
288
+ }
289
+ async function clearLocalAppStorage(dir = join(homedir(), ".polkadot-apps")) {
290
+ let entries;
291
+ try {
292
+ entries = await readdir(dir, { withFileTypes: true });
293
+ } catch {
294
+ return;
295
+ }
296
+ const prefix = `${config.dappId}_`;
297
+ await Promise.all(
298
+ entries.filter((entry) => entry.isFile() && entry.name.startsWith(prefix)).map(
299
+ (entry) => unlink(join(dir, entry.name)).catch(() => {
300
+ })
301
+ )
302
+ );
303
+ }
304
+ return {
305
+ connect,
306
+ waitForLogin,
307
+ getSessionSigner,
308
+ findSession,
309
+ waitForLogout,
310
+ requestAllocation,
311
+ clearLocalAppStorage
312
+ };
313
+ }
314
+
315
+ // src/auth/vendor/signer.ts
316
+ import { ss58Encode as ss58Encode2 } from "@parity/product-sdk-address";
317
+ import { createDevSigner, getDevPublicKey } from "@parity/product-sdk-tx";
318
+ import { seedToAccount } from "@parity/product-sdk-keys";
319
+ var SignerNotAvailableError = class extends Error {
320
+ constructor() {
321
+ super('No signer available. Run "login" to sign in, or pass --suri //Alice for dev.');
322
+ this.name = "SignerNotAvailableError";
323
+ }
324
+ };
325
+ var DEV_NAMES = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Ferdie"];
326
+ function parseDevAccountName(suri) {
327
+ const name = suri.replace(/^\/\//, "");
328
+ return DEV_NAMES.find((n) => n.toLowerCase() === name.toLowerCase()) ?? null;
329
+ }
330
+ async function resolveSigner(authClient, options) {
331
+ if (options?.suri) {
332
+ const devName = parseDevAccountName(options.suri);
333
+ if (devName) {
334
+ return {
335
+ signer: createDevSigner(devName),
336
+ address: ss58Encode2(getDevPublicKey(devName)),
337
+ source: "dev",
338
+ destroy() {
339
+ }
340
+ };
341
+ }
342
+ const sepIdx = options.suri.indexOf("//");
343
+ const mnemonic = (sepIdx === -1 ? options.suri : options.suri.slice(0, sepIdx)).trim();
344
+ const path = sepIdx === -1 ? "" : options.suri.slice(sepIdx);
345
+ try {
346
+ const account = seedToAccount(mnemonic, path);
347
+ return {
348
+ signer: account.signer,
349
+ address: ss58Encode2(account.publicKey),
350
+ source: "dev",
351
+ destroy() {
352
+ }
353
+ };
354
+ } catch {
355
+ throw new Error(
356
+ `Unrecognized SURI "${options.suri}". Expected a dev name (${DEV_NAMES.join(", ")}) or a BIP-39 mnemonic.`
357
+ );
358
+ }
359
+ }
360
+ const session = await authClient.getSessionSigner();
361
+ if (session) {
362
+ return { ...session, source: "session" };
363
+ }
364
+ throw new SignerNotAvailableError();
365
+ }
366
+
367
+ export {
368
+ INCOMPLETE_SESSION_MESSAGE,
369
+ sessionRootPublicKey,
370
+ deriveProductPublicKey,
371
+ createSessionSigner,
372
+ DEFAULT_RESOURCES,
373
+ requestResourceAllocation,
374
+ summarizeOutcomes,
375
+ createAuthClient,
376
+ SignerNotAvailableError,
377
+ parseDevAccountName,
378
+ resolveSigner
379
+ };
@@ -2,11 +2,11 @@ import {
2
2
  classifyErrorArea,
3
3
  isInteractive,
4
4
  promptYesNo
5
- } from "./chunk-YUIBBHS2.js";
5
+ } from "./chunk-HEKCOME3.js";
6
6
  import {
7
7
  VERSION,
8
8
  getCurrentSentryTraceId
9
- } from "./chunk-M6DM2NUT.js";
9
+ } from "./chunk-W4MILLXD.js";
10
10
 
11
11
  // src/bug-report.ts
12
12
  import { execSync, execFileSync } from "child_process";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  captureWarning
3
- } from "./chunk-M6DM2NUT.js";
3
+ } from "./chunk-W4MILLXD.js";
4
4
 
5
5
  // src/chunk-probe.ts
6
6
  import { Twox128, Blake2128Concat, decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-M6DM2NUT.js";
3
+ } from "./chunk-W4MILLXD.js";
4
4
 
5
5
  // src/version-check.ts
6
6
  import { execSync, execFileSync } from "child_process";
File without changes
@@ -8,7 +8,7 @@ import {
8
8
  setDeploySentryTag,
9
9
  truncateAddress,
10
10
  withSpan
11
- } from "./chunk-M6DM2NUT.js";
11
+ } from "./chunk-W4MILLXD.js";
12
12
  import {
13
13
  validateContractAddresses
14
14
  } from "./chunk-5K3RI5C2.js";
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  buildAliasProofMessage,
3
3
  getProofValidAtSec
4
- } from "./chunk-SLE4P6MO.js";
4
+ } from "./chunk-EJI3MX4G.js";
5
+ import {
6
+ bytesToHex,
7
+ encodeMembers,
8
+ hexToBytes
9
+ } from "./chunk-ZYVGHDMU.js";
5
10
  import {
6
11
  PEOPLE_MEMBER_IDENTIFIER_HEX,
7
12
  PGAS_ASSET_ID,
8
13
  PGAS_ASSET_LOCATION,
9
14
  PROOF_BYTES
10
15
  } from "./chunk-SI2ZUOYD.js";
11
- import {
12
- bytesToHex,
13
- encodeMembers,
14
- hexToBytes
15
- } from "./chunk-ZYVGHDMU.js";
16
16
 
17
17
  // src/personhood/bind-paid-alias.ts
18
18
  import { getSs58AddressInfo, Binary } from "polkadot-api";
@@ -6,7 +6,7 @@ import * as path from "path";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@parity/product-deploy",
9
- version: "0.8.3-rc.6",
9
+ version: "0.8.3-rc.7",
10
10
  private: false,
11
11
  repository: {
12
12
  type: "git",
@@ -49,10 +49,10 @@ var package_default = {
49
49
  "tools/release-retry-wrapper.mjs"
50
50
  ],
51
51
  scripts: {
52
- 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/personhood/encoding.ts src/personhood/hashing.ts src/personhood/constants.ts src/personhood/member-key.ts src/personhood/people-client.ts src/personhood/proof-validity.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 src/personhood/chain-prereqs.ts src/manifest/types.ts src/manifest/schema.ts src/manifest/byte-budget.ts src/manifest/config-load.ts src/manifest/publish.ts --format esm --dts --clean --target node22",
52
+ 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/personhood/encoding.ts src/personhood/hashing.ts src/personhood/constants.ts src/personhood/member-key.ts src/personhood/people-client.ts src/personhood/proof-validity.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 src/personhood/chain-prereqs.ts src/manifest/types.ts src/manifest/schema.ts src/manifest/byte-budget.ts src/manifest/config-load.ts src/manifest/publish.ts src/auth/index.ts src/auth/vendor/index.ts src/auth/vendor/ui/index.ts src/auth-config.ts src/commands/login.ts src/commands/logout.ts src/commands/whoami.ts src/storage-signer.ts --format esm --dts --clean --target node22",
53
53
  "refresh-environments": "node scripts/refresh-environments.mjs",
54
54
  prepare: "npm run build",
55
- 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/chunk-sharing-report.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js",
55
+ 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/chunk-sharing-report.test.js test/product-manifest.test.js test/cache-savings-totals.test.js test/error-pattern-signature.test.js test/exit-codes.test.js test/probe-env-health.test.js test/e2e-chain-calls.test.js test/auth-config.test.js test/whoami.test.js test/login.test.js test/logout.test.js test/auth-resolve.test.js",
56
56
  "test:e2e": "npm run build && node --test test/e2e.test.js",
57
57
  "test:e2e:smoke": "bash scripts/e2e-pass.sh smoke",
58
58
  "test:e2e:pr": "bash scripts/e2e-pass.sh pr",
@@ -63,6 +63,10 @@ var package_default = {
63
63
  "@ipld/car": "^5.4.3",
64
64
  "@ipld/dag-pb": "^4.1.3",
65
65
  "@noble/hashes": "^1.7.2",
66
+ "@parity/product-sdk-address": "^0.1.1",
67
+ "@parity/product-sdk-keys": "^0.3.0",
68
+ "@parity/product-sdk-terminal": "^0.2.1",
69
+ "@parity/product-sdk-tx": "^0.2.4",
66
70
  "@polkadot-api/metadata-builders": "^0.14.2",
67
71
  "@polkadot-api/substrate-bindings": "^0.20.2",
68
72
  "@polkadot-labs/hdkd": "^0.0.28",
@@ -82,8 +86,18 @@ var package_default = {
82
86
  "@types/node": "^22.0.0",
83
87
  tsup: "^8.5.0",
84
88
  typescript: "^5.9.3",
89
+ vitest: "^3.0.0",
85
90
  ws: "^8.20.1"
86
91
  },
92
+ overrides: {
93
+ "@polkadot-api/json-rpc-provider": "^0.2.0",
94
+ "@novasamatech/host-api": "0.7.9-4",
95
+ "@novasamatech/host-papp": "0.7.9-4",
96
+ "@novasamatech/product-sdk": "0.7.9-4",
97
+ "@novasamatech/scale": "0.7.9-4",
98
+ "@novasamatech/statement-store": "0.7.9-4",
99
+ "@novasamatech/storage-adapter": "0.7.9-4"
100
+ },
87
101
  minimumVersion: "0.5.6",
88
102
  engines: {
89
103
  node: ">=22"
@@ -0,0 +1,36 @@
1
+ // src/auth/vendor/ui/qr.ts
2
+ import { renderQrCode } from "@parity/product-sdk-terminal";
3
+
4
+ // src/auth/vendor/ui/status.ts
5
+ function renderLoginStatus(status) {
6
+ switch (status.step) {
7
+ case "waiting":
8
+ return "Waiting for you to scan the QR code with your phone\u2026";
9
+ case "paired":
10
+ return "Paired \u2014 finishing sign-in\u2026";
11
+ case "pending":
12
+ return `Working: ${status.stage}\u2026`;
13
+ case "success":
14
+ return `Signed in as ${status.address}`;
15
+ case "error":
16
+ return `Sign-in failed: ${status.message}`;
17
+ }
18
+ }
19
+ function renderLogoutStatus(status) {
20
+ switch (status.step) {
21
+ case "disconnecting":
22
+ return `Signing out ${status.address}\u2026`;
23
+ case "success":
24
+ return `Signed out ${status.address}`;
25
+ case "partial":
26
+ return `Signed out locally (${status.address}); the phone was not notified: ${status.reason}`;
27
+ case "error":
28
+ return `Sign-out error: ${status.message}`;
29
+ }
30
+ }
31
+
32
+ export {
33
+ renderQrCode,
34
+ renderLoginStatus,
35
+ renderLogoutStatus
36
+ };