@jinn-network/client 0.1.6-canary.fb9c8196 → 0.1.6

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 (76) hide show
  1. package/dist/api/bootstrap-endpoint.js +0 -45
  2. package/dist/api/bootstrap-endpoint.js.map +1 -1
  3. package/dist/api/fleet-build.d.ts +0 -1
  4. package/dist/api/fleet-build.js +1 -2
  5. package/dist/api/fleet-build.js.map +1 -1
  6. package/dist/api/gather-status.js +1 -68
  7. package/dist/api/gather-status.js.map +1 -1
  8. package/dist/api/hermes-doctor-endpoint.d.ts +0 -10
  9. package/dist/api/hermes-doctor-endpoint.js +23 -30
  10. package/dist/api/hermes-doctor-endpoint.js.map +1 -1
  11. package/dist/api/setup-endpoints.d.ts +0 -16
  12. package/dist/api/setup-endpoints.js +0 -28
  13. package/dist/api/setup-endpoints.js.map +1 -1
  14. package/dist/api/status-build.d.ts +0 -14
  15. package/dist/api/status-build.js +18 -23
  16. package/dist/api/status-build.js.map +1 -1
  17. package/dist/build-info.json +4 -4
  18. package/dist/build-meta.json +1 -1
  19. package/dist/cli/commands/solver-nets.js +9 -24
  20. package/dist/cli/commands/solver-nets.js.map +1 -1
  21. package/dist/config.d.ts +0 -9
  22. package/dist/config.js +0 -7
  23. package/dist/config.js.map +1 -1
  24. package/dist/daemon/daemon.d.ts +0 -8
  25. package/dist/daemon/daemon.js +0 -17
  26. package/dist/daemon/daemon.js.map +1 -1
  27. package/dist/dashboard/assets/{index-CarzUepP.css → index-DOlzFN8a.css} +1 -1
  28. package/dist/dashboard/assets/index-NkZ7CTAT.js +140 -0
  29. package/dist/dashboard/index.html +2 -2
  30. package/dist/earning/bootstrap.d.ts +0 -59
  31. package/dist/earning/bootstrap.js +41 -139
  32. package/dist/earning/bootstrap.js.map +1 -1
  33. package/dist/earning/contracts.d.ts +0 -12
  34. package/dist/earning/contracts.js +0 -7
  35. package/dist/earning/contracts.js.map +1 -1
  36. package/dist/earning/funding-plan.js.map +1 -1
  37. package/dist/earning/jinn-rewards.d.ts +0 -46
  38. package/dist/earning/jinn-rewards.js +0 -32
  39. package/dist/earning/jinn-rewards.js.map +1 -1
  40. package/dist/earning/testnet-setup-migration.d.ts +0 -12
  41. package/dist/earning/testnet-setup-migration.js +1 -17
  42. package/dist/earning/testnet-setup-migration.js.map +1 -1
  43. package/dist/earning/types.d.ts +0 -15
  44. package/dist/harnesses/impls/hermes-agent/harness.d.ts +1 -23
  45. package/dist/harnesses/impls/hermes-agent/harness.js +0 -49
  46. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
  47. package/dist/harnesses/impls/index.d.ts +0 -2
  48. package/dist/harnesses/impls/index.js +1 -5
  49. package/dist/harnesses/impls/index.js.map +1 -1
  50. package/dist/main.js +30 -204
  51. package/dist/main.js.map +1 -1
  52. package/dist/operator-errors.d.ts +0 -7
  53. package/dist/operator-errors.js +1 -13
  54. package/dist/operator-errors.js.map +1 -1
  55. package/dist/solver-nets/prediction-operator-ux.js +3 -24
  56. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  57. package/dist/solver-nets/registry.d.ts +0 -1
  58. package/dist/solver-nets/registry.js +1 -1
  59. package/dist/solver-nets/registry.js.map +1 -1
  60. package/package.json +1 -1
  61. package/dist/api/setup-retry-endpoint.d.ts +0 -19
  62. package/dist/api/setup-retry-endpoint.js +0 -32
  63. package/dist/api/setup-retry-endpoint.js.map +0 -1
  64. package/dist/daemon/eviction-loop.d.ts +0 -40
  65. package/dist/daemon/eviction-loop.js +0 -67
  66. package/dist/daemon/eviction-loop.js.map +0 -1
  67. package/dist/dashboard/assets/index-C_QnE4YV.js +0 -140
  68. package/dist/harnesses/cost-estimates.d.ts +0 -145
  69. package/dist/harnesses/cost-estimates.js +0 -297
  70. package/dist/harnesses/cost-estimates.js.map +0 -1
  71. package/dist/restart-daemon.d.ts +0 -71
  72. package/dist/restart-daemon.js +0 -82
  73. package/dist/restart-daemon.js.map +0 -1
  74. package/dist/setup/halt-mode.d.ts +0 -14
  75. package/dist/setup/halt-mode.js +0 -17
  76. package/dist/setup/halt-mode.js.map +0 -1
@@ -10,8 +10,8 @@
10
10
  href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@400;500;600&display=swap"
11
11
  rel="stylesheet"
12
12
  />
13
- <script type="module" crossorigin src="/assets/index-C_QnE4YV.js"></script>
14
- <link rel="stylesheet" crossorigin href="/assets/index-CarzUepP.css">
13
+ <script type="module" crossorigin src="/assets/index-NkZ7CTAT.js"></script>
14
+ <link rel="stylesheet" crossorigin href="/assets/index-DOlzFN8a.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
@@ -6,44 +6,6 @@
6
6
  */
7
7
  import type { FleetState, FleetBootstrapResult } from './types.js';
8
8
  import { requestTestnetFunding } from './faucet.js';
9
- import { type JinnOnchainNetwork } from './viem-clients.js';
10
- /**
11
- * 2× cold-start headroom for master ETH target on a fresh bootstrap.
12
- *
13
- * Gas accounting for a single standard-mode service on first run:
14
- * ~1.3M gas for the Safe deploy + stake + mech (at 2 gwei ≈ 0.0026 ETH)
15
- * + 0.002 ETH Safe seed (sent to the Safe so it can pay mech fees)
16
- * ≈ 0.0046 ETH minimum; 2× gives ≈ 0.009–0.010 ETH — the bootstrap
17
- * `minEoaGasEth` default.
18
- *
19
- * The multiplier only applies when no service has a persisted `service_id`
20
- * on-chain (i.e. the fleet is truly cold — OR migration-wiped, where
21
- * services exist in shape but lost their on-chain anchor). Once any service
22
- * has committed a `service_id`, the fleet is past the cold-start cliff and
23
- * 1× suffices.
24
- *
25
- * Single source of truth: imported by funding-plan.ts.
26
- */
27
- export declare const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
28
- /**
29
- * Compute the required master ETH gate for the standard staking mode.
30
- *
31
- * @param services Persisted service states
32
- * @param minEoaGasEth Configured minimum EOA gas target (wei)
33
- * @param standardMultiplier Cold-start multiplier (defaults to {@link STANDARD_MASTER_BOOTSTRAP_MULTIPLIER})
34
- * @param pendingSetupMigration True when deprecated testnet setup detected
35
- * @param targetServices How many services the fleet is aiming for
36
- */
37
- export declare function computeRequiredMasterEth({ services, minEoaGasEth, standardMultiplier, pendingSetupMigration, targetServices, }: {
38
- services: Array<{
39
- service_id: number | null | undefined;
40
- step?: string;
41
- }>;
42
- minEoaGasEth: bigint;
43
- standardMultiplier?: bigint;
44
- pendingSetupMigration?: boolean;
45
- targetServices?: number;
46
- }): bigint;
47
9
  /** Master ETH required to FINISH the whole bootstrap from a fresh start (not
48
10
  * just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
49
11
  * the read-side funding-plan, gather-status, and the panel faucet target
@@ -324,24 +286,3 @@ export declare class FleetBootstrapper {
324
286
  }
325
287
  /** @deprecated Use FleetBootstrapper */
326
288
  export declare const EarningBootstrapper: typeof FleetBootstrapper;
327
- export interface RecoverEvictedServiceOptions {
328
- /** Display index of the service (used only for log messages). */
329
- serviceDisplayIndex: number;
330
- serviceId: number;
331
- stakingAddress: string;
332
- distributorAddress: string;
333
- rpcUrl: string;
334
- chain: JinnOnchainNetwork;
335
- mnemonic: string;
336
- }
337
- /**
338
- * Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
339
- *
340
- * Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
341
- * from the in-process `EvictionLoop` without requiring a full bootstrapper
342
- * context (jinn-mono-hjex.3).
343
- *
344
- * The caller is responsible for advancing the local service step back to
345
- * `mech_deployed` after this returns (just like the bootstrapper resume path does).
346
- */
347
- export declare function recoverEvictedService(opts: RecoverEvictedServiceOptions): Promise<void>;
@@ -20,51 +20,11 @@ import { isUnauthorizedAccountError } from '../errors/unauthorized-account.js';
20
20
  import { createJinnPublicClient, createJinnWalletClient } from './viem-clients.js';
21
21
  import { isTransientEthReadError } from '../chain-read-errors.js';
22
22
  import { nextFleetServiceIndex } from './next-service-index.js';
23
- import { displayFleetServiceIndex } from './fleet-display-index.js';
24
23
  import { rpcHostForDisplay } from '../preflight/rpc-network.js';
25
24
  import { detectDeprecatedTestnetSetup, migrateDeprecatedTestnetSetup, } from './testnet-setup-migration.js';
26
25
  const addr = (value) => getAddress(value);
27
26
  const SAFE_TOKEN_BOOTSTRAP_MULTIPLIER = 2n;
28
- /**
29
- * 2× cold-start headroom for master ETH target on a fresh bootstrap.
30
- *
31
- * Gas accounting for a single standard-mode service on first run:
32
- * ~1.3M gas for the Safe deploy + stake + mech (at 2 gwei ≈ 0.0026 ETH)
33
- * + 0.002 ETH Safe seed (sent to the Safe so it can pay mech fees)
34
- * ≈ 0.0046 ETH minimum; 2× gives ≈ 0.009–0.010 ETH — the bootstrap
35
- * `minEoaGasEth` default.
36
- *
37
- * The multiplier only applies when no service has a persisted `service_id`
38
- * on-chain (i.e. the fleet is truly cold — OR migration-wiped, where
39
- * services exist in shape but lost their on-chain anchor). Once any service
40
- * has committed a `service_id`, the fleet is past the cold-start cliff and
41
- * 1× suffices.
42
- *
43
- * Single source of truth: imported by funding-plan.ts.
44
- */
45
- export const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
46
- /**
47
- * Compute the required master ETH gate for the standard staking mode.
48
- *
49
- * @param services Persisted service states
50
- * @param minEoaGasEth Configured minimum EOA gas target (wei)
51
- * @param standardMultiplier Cold-start multiplier (defaults to {@link STANDARD_MASTER_BOOTSTRAP_MULTIPLIER})
52
- * @param pendingSetupMigration True when deprecated testnet setup detected
53
- * @param targetServices How many services the fleet is aiming for
54
- */
55
- export function computeRequiredMasterEth({ services, minEoaGasEth, standardMultiplier = STANDARD_MASTER_BOOTSTRAP_MULTIPLIER, pendingSetupMigration = false, targetServices = 1, }) {
56
- const completedCount = services.filter(s => s.step !== undefined && isOperationalServiceStep(s.step)).length;
57
- const standardFleetAlreadyComplete = !pendingSetupMigration && completedCount >= targetServices;
58
- if (standardFleetAlreadyComplete)
59
- return 0n;
60
- // "Cold in liability" = no service has an on-chain anchor yet.
61
- // This includes:
62
- // 1. Fresh fleet (services array is empty)
63
- // 2. Migration-wiped fleet (services exist in shape but service_id === null)
64
- // Apply the 2× headroom multiplier in both cases.
65
- const hasPersistedOnChain = services.some(s => s.service_id != null);
66
- return minEoaGasEth * (hasPersistedOnChain ? 1n : standardMultiplier);
67
- }
27
+ const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
68
28
  /** Master ETH required to FINISH the whole bootstrap from a fresh start (not
69
29
  * just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
70
30
  * the read-side funding-plan, gather-status, and the panel faucet target
@@ -456,10 +416,11 @@ export class FleetBootstrapper {
456
416
  stakingMode: this.stakingMode,
457
417
  currentStakingContract: this.config.stakingContract,
458
418
  }).services.length > 0;
419
+ const completedCountBeforeFunding = state.services.filter(s => isOperationalServiceStep(s.step)).length;
459
420
  const standardFleetAlreadyComplete = this.stakingMode === 'standard' &&
460
- state.services.length >= this.targetServices &&
461
- state.services.every(svc => svc.step !== undefined && isOperationalServiceStep(svc.step)) &&
462
- !pendingSetupMigration;
421
+ !pendingSetupMigration &&
422
+ completedCountBeforeFunding >= this.targetServices;
423
+ const standardFleetHasInProgressServices = this.stakingMode === 'standard' && state.services.length > 0;
463
424
  const requiredMasterEth = this.stakingMode === 'standard'
464
425
  ? (standardFleetAlreadyComplete
465
426
  ? 0n
@@ -617,7 +578,7 @@ export class FleetBootstrapper {
617
578
  };
618
579
  }
619
580
  catch (error) {
620
- const { summary, hint, rawMessage, category } = formatBootstrapOperatorMessage(error);
581
+ const { summary, hint, rawMessage } = formatBootstrapOperatorMessage(error);
621
582
  const userMessage = hint !== undefined ? `${summary}\nHint: ${hint}` : summary;
622
583
  if (this.debug) {
623
584
  console.error(`[fleet-bootstrap] Bootstrap failed:`, error);
@@ -633,21 +594,11 @@ export class FleetBootstrapper {
633
594
  console.error(`[fleet-bootstrap] raw: ${rawMessage.split('\n')[0]}`);
634
595
  }
635
596
  }
636
- // Extract a tx hash embedded in the error message by the on-chain revert
637
- // paths (format: "...tx failed for service N: 0x<hash>" or
638
- // "...tx reverted: 0x<hash>"). Surfaced in the fatal envelope so the SPA
639
- // can render a block-explorer link. jinn-mono-hjex reviewer fix.
640
- const txHashMatch = /(0x[a-fA-F0-9]{64})/.exec(rawMessage);
641
- const txHash = txHashMatch ? txHashMatch[1] : null;
642
597
  return {
643
598
  ok: false,
644
599
  fleet_state: state,
645
600
  message: userMessage,
646
601
  rawErrorMessage: rawMessage,
647
- // Preserve the structured category so the error envelope in main.ts
648
- // can surface it in `details.category` for SPA consumers. jinn-mono-hjex.6
649
- ...(category !== undefined ? { errorCategory: category } : {}),
650
- ...(txHash !== null ? { txHash } : {}),
651
602
  };
652
603
  }
653
604
  }
@@ -1093,32 +1044,6 @@ export class FleetBootstrapper {
1093
1044
  return this.store.updateService(index, { step: 'staked' });
1094
1045
  }
1095
1046
  }
1096
- // Pre-stake precondition: if migration cleared service_id but kept agent_address,
1097
- // check the EOA is not already registered on-chain as an agent instance. If it is,
1098
- // calling stake() again would revert with AgentInstanceRegistered (selector 0x631695bd)
1099
- // and there is nothing useful the operator can do without rotating the agent EOA.
1100
- // Fail fast with a typed error instead of letting the contract revert.
1101
- if (svc.agent_address && svc.service_id === null && this.config.serviceRegistry) {
1102
- let alreadyBound = false;
1103
- try {
1104
- const boundServiceId = (await this.publicClient.readContract({
1105
- address: getAddress(this.config.serviceRegistry),
1106
- abi: SERVICE_REGISTRY_L2_ABI,
1107
- functionName: 'mapAgentInstances',
1108
- args: [getAddress(svc.agent_address)],
1109
- }));
1110
- alreadyBound = boundServiceId > 0n;
1111
- }
1112
- catch {
1113
- // Registry read failure is non-fatal — proceed and let stake() surface
1114
- // the error if the agent really is bound.
1115
- }
1116
- if (alreadyBound) {
1117
- throw new Error(`agent_already_bound: agent EOA ${svc.agent_address} is already registered as an agent instance on-chain. ` +
1118
- `The previous setup retirement may have been incomplete. ` +
1119
- `Contact support or rotate the agent EOA to continue.`);
1120
- }
1121
- }
1122
1047
  // Fresh distributor stake() creates a new on-chain service. If state still
1123
1048
  // references an old Safe (e.g. hand-edited JSON), sweep it before replacing.
1124
1049
  if (svc.service_id === null && svc.safe_address && state.master_address) {
@@ -1184,19 +1109,42 @@ export class FleetBootstrapper {
1184
1109
  const svc = state.services.find(s => s.index === index);
1185
1110
  const serviceId = svc.service_id;
1186
1111
  const stakingAddress = this.stakingAddressForService(svc);
1187
- const di = displayFleetServiceIndex(svc);
1188
- // Delegate to the standalone exported helper (shared with EvictionLoop /
1189
- // the dashboard "Re-stake now" CTA). This eliminates the duplicate
1190
- // implementation (jinn-mono-hjex.3).
1191
- await recoverEvictedService({
1192
- serviceDisplayIndex: di,
1193
- serviceId,
1194
- stakingAddress: stakingAddress,
1195
- distributorAddress: this.config.distributorAddress,
1196
- rpcUrl: this.config.rpcUrl,
1197
- chain: this.chain,
1198
- mnemonic,
1112
+ // `reStake()` is operator-scoped: the master EOA must match the
1113
+ // distributor's recorded `mapServiceIdCuratingAgents[serviceId]` entry.
1114
+ // If it doesn't, the operator is likely using the wrong earning dir or
1115
+ // password, or the service needs owner / managing-agent recovery.
1116
+ const masterAccount = deriveMasterSigner(mnemonic);
1117
+ const masterWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, masterAccount);
1118
+ const reStakeData = encodeFunctionData({
1119
+ abi: STOLAS_DISTRIBUTOR_ABI,
1120
+ functionName: 'reStake',
1121
+ args: [stakingAddress, BigInt(serviceId)],
1199
1122
  });
1123
+ console.error(`[fleet-bootstrap] Service ${index}: calling distributor.reStake() for evicted service ${serviceId}`);
1124
+ let reStakeHash;
1125
+ try {
1126
+ reStakeHash = await viemSendTransactionWithRetry(masterWallet, this.publicClient, {
1127
+ account: masterAccount,
1128
+ to: addr(this.config.distributorAddress),
1129
+ data: reStakeData,
1130
+ gas: 1500000n,
1131
+ });
1132
+ }
1133
+ catch (err) {
1134
+ const message = flattenErrorMessage(err);
1135
+ if (isUnauthorizedAccountError(message)) {
1136
+ throw new Error(`Service ${index} (service_id ${serviceId}) is evicted on the staking proxy, but master EOA ${masterAccount.address} is not authorized to reStake it. ` +
1137
+ `The distributor only permits the recorded service operator, a managing agent, or the owner. ` +
1138
+ `Verify JINN_EARNING_DIR and JINN_PASSWORD derive the original master EOA for this service, then re-run jinn bootstrap; otherwise request owner / managing-agent recovery or abandon-and-rebootstrap. ` +
1139
+ `reStake revert: ${message}`);
1140
+ }
1141
+ throw err;
1142
+ }
1143
+ const receipt = await waitForTransactionReceiptWithRetry(this.publicClient, reStakeHash);
1144
+ if (receipt.status !== 'success') {
1145
+ throw new Error(`reStake failed for service ${index}: ${reStakeHash}`);
1146
+ }
1147
+ console.error(`[fleet-bootstrap] Service ${index}: reStake confirmed (tx: ${reStakeHash})`);
1200
1148
  // Service is now Staked again with the same service_id, safe_address, and mech_address.
1201
1149
  // Step back to `mech_deployed` so the resume loop advances through
1202
1150
  // `stepRegisterAgent` (idempotent — short-circuits if `agent_id` is
@@ -1949,50 +1897,4 @@ export class FleetBootstrapper {
1949
1897
  }
1950
1898
  /** @deprecated Use FleetBootstrapper */
1951
1899
  export const EarningBootstrapper = FleetBootstrapper;
1952
- /**
1953
- * Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
1954
- *
1955
- * Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
1956
- * from the in-process `EvictionLoop` without requiring a full bootstrapper
1957
- * context (jinn-mono-hjex.3).
1958
- *
1959
- * The caller is responsible for advancing the local service step back to
1960
- * `mech_deployed` after this returns (just like the bootstrapper resume path does).
1961
- */
1962
- export async function recoverEvictedService(opts) {
1963
- const { serviceDisplayIndex, serviceId, stakingAddress, distributorAddress, rpcUrl, chain, mnemonic, } = opts;
1964
- const masterAccount = deriveMasterSigner(mnemonic);
1965
- const publicClient = createJinnPublicClient(rpcUrl, chain);
1966
- const masterWallet = createJinnWalletClient(rpcUrl, chain, masterAccount);
1967
- const reStakeData = encodeFunctionData({
1968
- abi: STOLAS_DISTRIBUTOR_ABI,
1969
- functionName: 'reStake',
1970
- args: [addr(stakingAddress), BigInt(serviceId)],
1971
- });
1972
- console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: calling distributor.reStake() for evicted service ${serviceId}`);
1973
- let reStakeHash;
1974
- try {
1975
- reStakeHash = await viemSendTransactionWithRetry(masterWallet, publicClient, {
1976
- account: masterAccount,
1977
- to: addr(distributorAddress),
1978
- data: reStakeData,
1979
- gas: 1500000n,
1980
- });
1981
- }
1982
- catch (err) {
1983
- const message = flattenErrorMessage(err);
1984
- if (isUnauthorizedAccountError(message)) {
1985
- throw new Error(`Service ${serviceDisplayIndex} (service_id ${serviceId}) is evicted on the staking proxy, but master EOA ` +
1986
- `${masterAccount.address} is not authorized to reStake it. ` +
1987
- `Verify JINN_EARNING_DIR and JINN_PASSWORD derive the original master EOA for this service. ` +
1988
- `reStake revert: ${message}`);
1989
- }
1990
- throw err;
1991
- }
1992
- const receipt = await waitForTransactionReceiptWithRetry(publicClient, reStakeHash);
1993
- if (receipt.status !== 'success') {
1994
- throw new Error(`reStake failed for service ${serviceDisplayIndex}: ${reStakeHash}`);
1995
- }
1996
- console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: reStake confirmed (tx: ${reStakeHash})`);
1997
- }
1998
1900
  //# sourceMappingURL=bootstrap.js.map