@jinn-network/client 0.1.6 → 0.1.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.
- package/CHANGELOG.md +33 -0
- package/deployments/deployment-jinn-mvi-l1-sepolia-fast.json +23 -4
- package/deployments/deployment-jinn-mvi-l1-sepolia.json +23 -4
- package/deployments/deployment-jinn-mvi-l2-baseSepolia.json +5 -4
- package/dist/adapters/mech/adapter.d.ts +38 -1
- package/dist/adapters/mech/adapter.js +241 -54
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +17 -4
- package/dist/adapters/mech/contracts.js +8 -2
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/safe-revert.d.ts +20 -0
- package/dist/adapters/mech/safe-revert.js +12 -4
- package/dist/adapters/mech/safe-revert.js.map +1 -1
- package/dist/adapters/mech/safe.d.ts +5 -1
- package/dist/adapters/mech/safe.js +27 -8
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/verdict-code.d.ts +1 -0
- package/dist/adapters/mech/verdict-code.js +18 -0
- package/dist/adapters/mech/verdict-code.js.map +1 -1
- package/dist/api/admin-endpoint.d.ts +15 -3
- package/dist/api/admin-endpoint.js +24 -2
- package/dist/api/admin-endpoint.js.map +1 -1
- package/dist/api/bootstrap-endpoint.js +49 -0
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/codex-doctor-endpoint.d.ts +73 -0
- package/dist/api/codex-doctor-endpoint.js +177 -0
- package/dist/api/codex-doctor-endpoint.js.map +1 -0
- package/dist/api/discovery-endpoint.d.ts +1 -0
- package/dist/api/discovery-endpoint.js +26 -0
- package/dist/api/discovery-endpoint.js.map +1 -1
- package/dist/api/fleet-build.d.ts +1 -0
- package/dist/api/fleet-build.js +2 -1
- package/dist/api/fleet-build.js.map +1 -1
- package/dist/api/gather-status.d.ts +11 -0
- package/dist/api/gather-status.js +400 -4
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +117 -0
- package/dist/api/hermes-doctor-endpoint.js +229 -23
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/launcher-status.d.ts +21 -16
- package/dist/api/launcher-status.js +2 -1
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +10 -0
- package/dist/api/portfolio-v0-build.js +24 -5
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/prediction-v1-build.d.ts +10 -0
- package/dist/api/prediction-v1-build.js +7 -1
- package/dist/api/prediction-v1-build.js.map +1 -1
- package/dist/api/server.d.ts +31 -1
- package/dist/api/server.js +68 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +16 -0
- package/dist/api/setup-endpoints.js +78 -4
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/setup-retry-endpoint.d.ts +19 -0
- package/dist/api/setup-retry-endpoint.js +32 -0
- package/dist/api/setup-retry-endpoint.js.map +1 -0
- package/dist/api/solvernets-endpoints.d.ts +8 -0
- package/dist/api/solvernets-endpoints.js +71 -43
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +72 -0
- package/dist/api/status-build.js +73 -18
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/task-run-routing.d.ts +7 -0
- package/dist/api/task-run-routing.js +12 -0
- package/dist/api/task-run-routing.js.map +1 -0
- package/dist/api/task-runs-build.d.ts +21 -0
- package/dist/api/task-runs-build.js +14 -1
- package/dist/api/task-runs-build.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/chain-read-errors.d.ts +10 -0
- package/dist/chain-read-errors.js +15 -0
- package/dist/chain-read-errors.js.map +1 -1
- package/dist/cli/commands/auth.js +1 -1
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/create.js +3 -2
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +2 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/rewards.js +11 -7
- package/dist/cli/commands/rewards.js.map +1 -1
- package/dist/cli/commands/solver-nets.js +24 -9
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tasks.js +86 -9
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/update.d.ts +10 -0
- package/dist/cli/commands/update.js +36 -0
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/introspection-context.js +5 -0
- package/dist/cli/introspection-context.js.map +1 -1
- package/dist/cli/task-native-readiness.d.ts +3 -1
- package/dist/cli/task-native-readiness.js +28 -6
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +106 -5
- package/dist/config.js +97 -18
- package/dist/config.js.map +1 -1
- package/dist/daemon/checkpoint-loop.d.ts +48 -0
- package/dist/daemon/checkpoint-loop.js +76 -0
- package/dist/daemon/checkpoint-loop.js.map +1 -0
- package/dist/daemon/creator.d.ts +1 -1
- package/dist/daemon/creator.js +7 -3
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +19 -0
- package/dist/daemon/daemon.js +68 -1
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/eviction-loop.d.ts +40 -0
- package/dist/daemon/eviction-loop.js +67 -0
- package/dist/daemon/eviction-loop.js.map +1 -0
- package/dist/daemon/jinn-claim-loop-wiring.d.ts +33 -0
- package/dist/daemon/jinn-claim-loop-wiring.js +40 -0
- package/dist/daemon/jinn-claim-loop-wiring.js.map +1 -0
- package/dist/daemon/jinn-claim-loop.d.ts +24 -17
- package/dist/daemon/jinn-claim-loop.js +77 -23
- package/dist/daemon/jinn-claim-loop.js.map +1 -1
- package/dist/daemon/skip-log-dedup.d.ts +69 -0
- package/dist/daemon/skip-log-dedup.js +106 -0
- package/dist/daemon/skip-log-dedup.js.map +1 -0
- package/dist/dashboard/assets/index-BUlE8F3Y.js +330 -0
- package/dist/dashboard/assets/index-blqc7eqq.css +32 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/factory.d.ts +17 -5
- package/dist/discovery/factory.js +46 -18
- package/dist/discovery/factory.js.map +1 -1
- package/dist/discovery/http.js +142 -3
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.d.ts +5 -0
- package/dist/discovery/onchain.js +407 -15
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +45 -1
- package/dist/discovery/types.js +8 -10
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.d.ts +7 -0
- package/dist/discovery/with-fallback.js +10 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +92 -1
- package/dist/earning/bootstrap.js +203 -63
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +14 -0
- package/dist/earning/contracts.js +17 -5
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/funding-plan.js +27 -18
- package/dist/earning/funding-plan.js.map +1 -1
- package/dist/earning/jinn-rewards.d.ts +46 -0
- package/dist/earning/jinn-rewards.js +32 -0
- package/dist/earning/jinn-rewards.js.map +1 -1
- package/dist/earning/safe-adapter.d.ts +2 -0
- package/dist/earning/safe-adapter.js +26 -12
- package/dist/earning/safe-adapter.js.map +1 -1
- package/dist/earning/store.d.ts +8 -0
- package/dist/earning/store.js.map +1 -1
- package/dist/earning/testnet-setup-migration.d.ts +12 -0
- package/dist/earning/testnet-setup-migration.js +27 -1
- package/dist/earning/testnet-setup-migration.js.map +1 -1
- package/dist/earning/types.d.ts +15 -0
- package/dist/erc8004/reputation.d.ts +8 -0
- package/dist/erc8004/reputation.js +22 -3
- package/dist/erc8004/reputation.js.map +1 -1
- package/dist/harnesses/cost-estimates.d.ts +145 -0
- package/dist/harnesses/cost-estimates.js +297 -0
- package/dist/harnesses/cost-estimates.js.map +1 -0
- package/dist/harnesses/engine/engine.d.ts +72 -0
- package/dist/harnesses/engine/engine.js +105 -8
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/persistence.d.ts +51 -1
- package/dist/harnesses/engine/persistence.js +118 -5
- package/dist/harnesses/engine/persistence.js.map +1 -1
- package/dist/harnesses/engine/work-dir-reaper.d.ts +65 -0
- package/dist/harnesses/engine/work-dir-reaper.js +100 -0
- package/dist/harnesses/engine/work-dir-reaper.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js +40 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +20 -0
- package/dist/harnesses/impls/hermes-agent/bootstrap.js +40 -6
- package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +59 -1
- package/dist/harnesses/impls/hermes-agent/harness.js +104 -0
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
- package/dist/harnesses/impls/index.d.ts +7 -0
- package/dist/harnesses/impls/index.js +16 -1
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +38 -4
- package/dist/harnesses/impls/learner/harness.js +96 -2
- package/dist/harnesses/impls/learner/harness.js.map +1 -1
- package/dist/harnesses/impls/learner/plugin-path.d.ts +0 -13
- package/dist/harnesses/impls/learner/plugin-path.js +35 -15
- package/dist/harnesses/impls/learner/plugin-path.js.map +1 -1
- package/dist/harnesses/impls/learner/types.d.ts +11 -0
- package/dist/harnesses/impls/stub.d.ts +58 -0
- package/dist/harnesses/impls/stub.js +89 -0
- package/dist/harnesses/impls/stub.js.map +1 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +69 -50
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +178 -93
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.d.ts +12 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +121 -7
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +15 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +54 -4
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.d.ts +6 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js.map +1 -1
- package/dist/harnesses/readiness-registry.js +9 -1
- package/dist/harnesses/readiness-registry.js.map +1 -1
- package/dist/main.js +371 -82
- package/dist/main.js.map +1 -1
- package/dist/observability/emit-event.d.ts +1 -1
- package/dist/observability/emit-event.js.map +1 -1
- package/dist/operator-errors.d.ts +7 -0
- package/dist/operator-errors.js +13 -1
- package/dist/operator-errors.js.map +1 -1
- package/dist/plugins/learner/.claude-plugin/plugin.json +9 -0
- package/dist/plugins/learner/.codex-plugin/plugin.json +39 -0
- package/dist/plugins/learner/AGENTS.md +40 -0
- package/dist/plugins/learner/CLAUDE.md +33 -0
- package/dist/plugins/learner/README.md +59 -0
- package/dist/plugins/learner/hooks/hooks.json +16 -0
- package/dist/plugins/learner/hooks/session-start +38 -0
- package/dist/plugins/learner/skills/learn/SKILL.md +412 -0
- package/dist/plugins/learner/skills/learn/analyst-prompt.md +68 -0
- package/dist/plugins/learner/skills/learn/consolidator-prompt.md +94 -0
- package/dist/plugins/learner/skills/learn/explorer-prompt.md +53 -0
- package/dist/plugins/learner/skills/learn/planner-prompt.md +87 -0
- package/dist/plugins/learner/skills/learn/promoter-prompt.md +113 -0
- package/dist/plugins/learner/skills/learn/step-worker-prompt.md +47 -0
- package/dist/plugins/learner/skills/learn/strategist-prompt.md +85 -0
- package/dist/restart-daemon.d.ts +90 -0
- package/dist/restart-daemon.js +95 -0
- package/dist/restart-daemon.js.map +1 -0
- package/dist/setup/halt-mode.d.ts +14 -0
- package/dist/setup/halt-mode.js +17 -0
- package/dist/setup/halt-mode.js.map +1 -0
- package/dist/solver-nets/prediction-operator-ux.js +43 -3
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +1 -0
- package/dist/solver-nets/registry.js +1 -1
- package/dist/solver-nets/registry.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-pool-cache.d.ts +58 -0
- package/dist/solver-types/_swe-rebench-v2-pool-cache.js +87 -0
- package/dist/solver-types/_swe-rebench-v2-pool-cache.js.map +1 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.d.ts +1 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js +10 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +65 -0
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +243 -26
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +22 -7
- package/dist/solver-types/swe-rebench-v2-auto.js +45 -20
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +13 -2
- package/dist/solver-types/swe-rebench-v2.js +233 -94
- package/dist/solver-types/swe-rebench-v2.js.map +1 -1
- package/dist/solvernets/daemon-init.d.ts +10 -2
- package/dist/solvernets/daemon-init.js +22 -2
- package/dist/solvernets/daemon-init.js.map +1 -1
- package/dist/solvernets/launched-record-dispatcher.js +35 -7
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/solvernets/store.d.ts +5 -0
- package/dist/solvernets/store.js +1 -0
- package/dist/solvernets/store.js.map +1 -1
- package/dist/store/store.d.ts +15 -0
- package/dist/store/store.js +118 -3
- package/dist/store/store.js.map +1 -1
- package/dist/tasks/sources.d.ts +18 -1
- package/dist/tasks/sources.js +33 -5
- package/dist/tasks/sources.js.map +1 -1
- package/dist/tx-retry.d.ts +151 -19
- package/dist/tx-retry.js +286 -32
- package/dist/tx-retry.js.map +1 -1
- package/dist/types/payloads/prediction-apy-v0.d.ts +5 -5
- package/dist/types/payloads/prediction-v0.d.ts +5 -5
- package/dist/types/task-document.d.ts +392 -0
- package/dist/types/task-document.js +10 -0
- package/dist/types/task-document.js.map +1 -1
- package/dist/types/task.d.ts +28 -0
- package/dist/util/extract-tx-hash.d.ts +14 -0
- package/dist/util/extract-tx-hash.js +19 -0
- package/dist/util/extract-tx-hash.js.map +1 -0
- package/dist/vendor/@jinn-network/sdk/dist/contracts.js +1 -1
- package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.d.ts +3 -0
- package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.js +1 -0
- package/package.json +29 -12
- package/dist/dashboard/assets/index-DOlzFN8a.css +0 -32
- package/dist/dashboard/assets/index-NkZ7CTAT.js +0 -140
|
@@ -145,6 +145,36 @@ export interface DiscoveryAPI {
|
|
|
145
145
|
* `undefined` if no lifecycle events have been recorded for it yet.
|
|
146
146
|
*/
|
|
147
147
|
getLifecycleStatus(manifestCid: string): Promise<SolverNetLifecycleStatus | undefined>;
|
|
148
|
+
/**
|
|
149
|
+
* Returns the number of distinct operators that have *ever* claimed a task
|
|
150
|
+
* on the SolverNet identified by `manifestCid` — i.e. the count of unique
|
|
151
|
+
* `attempt.operator` Safe addresses across every task whose
|
|
152
|
+
* `manifestDigest === keccak256(manifestCid)`, **including tasks that are
|
|
153
|
+
* now finalized or refunded**.
|
|
154
|
+
*
|
|
155
|
+
* This is an *ever-participated* signal, not a "currently active" one. The
|
|
156
|
+
* count never filters on task lifecycle state: the on-chain backing reads
|
|
157
|
+
* raw `TaskAttemptCreated` logs, which carry no finalized/refunded flag, so
|
|
158
|
+
* the only count consistent across all three backings (HTTP / embedded /
|
|
159
|
+
* on-chain) is the all-time distinct-operator total. Treat it as "operators
|
|
160
|
+
* who have participated at least once", not "operators participating today".
|
|
161
|
+
*
|
|
162
|
+
* It is the protocol-observable participation signal: a "join" in the
|
|
163
|
+
* operator app is purely a local config write (`joinedSolverNets[<cid>]`,
|
|
164
|
+
* see `spec/2026-05-05-solvernet-creation-and-launch.md` §12) and leaves no
|
|
165
|
+
* on-chain footprint. An operator only becomes visible to the network once
|
|
166
|
+
* they claim a task — `TaskAttemptCreated` is the first on-chain event tied
|
|
167
|
+
* to (operator, SolverNet). This method therefore counts *participating*
|
|
168
|
+
* operators (operators who have claimed at least one task), which is the
|
|
169
|
+
* only honest cross-operator count derivable from the indexer / chain.
|
|
170
|
+
*
|
|
171
|
+
* Task pagination is hard-capped (`MAX_OPERATOR_COUNT_TASK_PAGES` in each
|
|
172
|
+
* backing) so a pathological task volume cannot turn this into an unbounded
|
|
173
|
+
* scan; on a SolverNet beyond the cap the count is a lower bound.
|
|
174
|
+
*
|
|
175
|
+
* Returns `0` when no operator has attempted a task on the SolverNet yet.
|
|
176
|
+
*/
|
|
177
|
+
getSolverNetOperatorCount(manifestCid: string): Promise<number>;
|
|
148
178
|
/**
|
|
149
179
|
* Returns envelope refs matching the query. Refs only — byte retrieval is
|
|
150
180
|
* done by the corpus library on demand.
|
|
@@ -200,7 +230,21 @@ export interface DiscoveryAPI {
|
|
|
200
230
|
* The `withFallback` wrapper catches this class (plus network-shaped errors)
|
|
201
231
|
* and routes to the floor implementation for the duration of the outage.
|
|
202
232
|
*/
|
|
233
|
+
/**
|
|
234
|
+
* Machine-readable reason a discovery read failed. `rpc_rate_limited` is the
|
|
235
|
+
* one branch callers act on distinctly: it means the configured RPC endpoint
|
|
236
|
+
* returned a 429 (or otherwise rate-limited the daemon), which — on the shared
|
|
237
|
+
* default RPC — is an operator-actionable condition ("add your own key"), not
|
|
238
|
+
* an indexer outage. Any other transport failure is left untyped (`undefined`).
|
|
239
|
+
*/
|
|
240
|
+
export type DiscoveryUnavailableCode = 'rpc_rate_limited';
|
|
203
241
|
export declare class DiscoveryUnavailableError extends Error {
|
|
204
242
|
readonly cause?: unknown;
|
|
205
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Typed reason, when one can be classified — currently only
|
|
245
|
+
* `rpc_rate_limited`, surfaced end-to-end so the operator UI can render a
|
|
246
|
+
* distinct "your RPC is throttled" message instead of a generic failure.
|
|
247
|
+
*/
|
|
248
|
+
readonly code?: DiscoveryUnavailableCode;
|
|
249
|
+
constructor(message: string, cause?: unknown, code?: DiscoveryUnavailableCode);
|
|
206
250
|
}
|
package/dist/discovery/types.js
CHANGED
|
@@ -9,21 +9,19 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Spec: spec/2026-05-11-discovery-api-and-shared-indexer.md §5.
|
|
11
11
|
*/
|
|
12
|
-
// ── Error ────────────────────────────────────────────────────────────────────
|
|
13
|
-
/**
|
|
14
|
-
* Thrown by a DiscoveryAPI implementation when it is temporarily unable to
|
|
15
|
-
* serve a request — e.g. indexer unreachable, embedded Ponder still syncing,
|
|
16
|
-
* hosted subgraph 5xx.
|
|
17
|
-
*
|
|
18
|
-
* The `withFallback` wrapper catches this class (plus network-shaped errors)
|
|
19
|
-
* and routes to the floor implementation for the duration of the outage.
|
|
20
|
-
*/
|
|
21
12
|
export class DiscoveryUnavailableError extends Error {
|
|
22
13
|
cause;
|
|
23
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Typed reason, when one can be classified — currently only
|
|
16
|
+
* `rpc_rate_limited`, surfaced end-to-end so the operator UI can render a
|
|
17
|
+
* distinct "your RPC is throttled" message instead of a generic failure.
|
|
18
|
+
*/
|
|
19
|
+
code;
|
|
20
|
+
constructor(message, cause, code) {
|
|
24
21
|
super(message);
|
|
25
22
|
this.name = 'DiscoveryUnavailableError';
|
|
26
23
|
this.cause = cause;
|
|
24
|
+
this.code = code;
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
27
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkRH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAChC,KAAK,CAAW;IAClC;;;;OAIG;IACM,IAAI,CAA4B;IAEzC,YAAY,OAAe,EAAE,KAAe,EAAE,IAA+B;QAC3E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -12,6 +12,13 @@
|
|
|
12
12
|
* operators can see why their daemon is running slowly. After the window
|
|
13
13
|
* elapses the wrapper probes the primary again on the next call.
|
|
14
14
|
*
|
|
15
|
+
* NOTE (2026-05-23): this wrapper is no longer engaged by default. The
|
|
16
|
+
* factory installs it only when `discovery.fallbackToOnchain === true` (an
|
|
17
|
+
* explicit opt-in). Without the opt-in, indexer outages propagate as
|
|
18
|
+
* DiscoveryUnavailableError so the operator-app surfaces them rather than the
|
|
19
|
+
* daemon silently storming shared RPC. The wrapper itself is unchanged for
|
|
20
|
+
* operators who still want it.
|
|
21
|
+
*
|
|
15
22
|
* Spec: spec/2026-05-11-discovery-api-and-shared-indexer.md §9.3.
|
|
16
23
|
*/
|
|
17
24
|
import type { DiscoveryAPI } from './types.js';
|
|
@@ -12,6 +12,13 @@
|
|
|
12
12
|
* operators can see why their daemon is running slowly. After the window
|
|
13
13
|
* elapses the wrapper probes the primary again on the next call.
|
|
14
14
|
*
|
|
15
|
+
* NOTE (2026-05-23): this wrapper is no longer engaged by default. The
|
|
16
|
+
* factory installs it only when `discovery.fallbackToOnchain === true` (an
|
|
17
|
+
* explicit opt-in). Without the opt-in, indexer outages propagate as
|
|
18
|
+
* DiscoveryUnavailableError so the operator-app surfaces them rather than the
|
|
19
|
+
* daemon silently storming shared RPC. The wrapper itself is unchanged for
|
|
20
|
+
* operators who still want it.
|
|
21
|
+
*
|
|
15
22
|
* Spec: spec/2026-05-11-discovery-api-and-shared-indexer.md §9.3.
|
|
16
23
|
*/
|
|
17
24
|
import { DiscoveryUnavailableError } from './types.js';
|
|
@@ -145,6 +152,9 @@ export function withFallback(primary, floor, opts = {}) {
|
|
|
145
152
|
getLifecycleStatus(manifestCid) {
|
|
146
153
|
return dispatch(() => primary.getLifecycleStatus(manifestCid), () => floor.getLifecycleStatus(manifestCid));
|
|
147
154
|
},
|
|
155
|
+
getSolverNetOperatorCount(manifestCid) {
|
|
156
|
+
return dispatch(() => primary.getSolverNetOperatorCount(manifestCid), () => floor.getSolverNetOperatorCount(manifestCid));
|
|
157
|
+
},
|
|
148
158
|
queryEnvelopes(query) {
|
|
149
159
|
return dispatch(() => primary.queryEnvelopes(query), () => floor.queryEnvelopes(query));
|
|
150
160
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-fallback.js","sourceRoot":"","sources":["../../src/discovery/with-fallback.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"with-fallback.js","sourceRoot":"","sources":["../../src/discovery/with-fallback.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,78 @@
|
|
|
4
4
|
* Phase 1 (master): generate mnemonic → fund master EOA
|
|
5
5
|
* Phase 2 (per-service): derive agent → stake → deploy mech
|
|
6
6
|
*/
|
|
7
|
-
import type { FleetState, FleetBootstrapResult } from './types.js';
|
|
7
|
+
import type { FleetState, FleetBootstrapResult, StakingMode } 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
|
+
* Used by {@link stage1MinMasterEth} to size the Stage 1 master gas budget.
|
|
20
|
+
*
|
|
21
|
+
* Single source of truth: imported by funding-plan.ts.
|
|
22
|
+
*/
|
|
23
|
+
export declare const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
24
|
+
/**
|
|
25
|
+
* Self-bond mode needs much more ETH per service than standard mode because
|
|
26
|
+
* the master funds the agent which then pays for: Safe deploy, 5 service
|
|
27
|
+
* registry txs (create, activate, register, deploy, stake), and mech deploy.
|
|
28
|
+
* Roughly 15 txs at varying gas costs. 0.03 ETH per service is a safe
|
|
29
|
+
* estimate. Single source of truth: imported by funding-plan.ts.
|
|
30
|
+
*/
|
|
31
|
+
export declare const SELF_BOND_ETH_PER_SERVICE = 30000000000000000n;
|
|
32
|
+
/**
|
|
33
|
+
* Single source of truth for the master-ETH cold-start funding gate.
|
|
34
|
+
*
|
|
35
|
+
* Both the mutating bootstrapper ({@link FleetBootstrapper.ensureStage1And2})
|
|
36
|
+
* and the read-only funding plan (`planFleetFunding` in funding-plan.ts) route
|
|
37
|
+
* through this helper, so a migration-wiped fleet computes an identical
|
|
38
|
+
* required-ETH gate in both views. Re-implementing the gate inline at either
|
|
39
|
+
* call site is the u34i cross-module invariant-drift hazard — do not do it.
|
|
40
|
+
*
|
|
41
|
+
* Standard-mode gate has three branches:
|
|
42
|
+
* 1. `standardFleetAlreadyComplete` — fleet already has its full target of
|
|
43
|
+
* operational services and no deprecated-setup migration is pending →
|
|
44
|
+
* `0n` (nothing to fund).
|
|
45
|
+
* 2. `preStage1` — no fleet identity yet (`fleet_stage === 'none'` or no
|
|
46
|
+
* fleet state at all) → the Stage 1 gate from {@link stage1MinMasterEth},
|
|
47
|
+
* which covers the master → agent transfer plus the master's own gas
|
|
48
|
+
* reserve. See jinn-mono-u34i.
|
|
49
|
+
* 3. otherwise — the Stage 2 master gas budget: `minEoaGasEth` (stake gas)
|
|
50
|
+
* plus a per-extra-service top-up transfer for services 2..N.
|
|
51
|
+
*
|
|
52
|
+
* Self-bond mode is a flat `SELF_BOND_ETH_PER_SERVICE × targetServices`
|
|
53
|
+
* regardless of stage.
|
|
54
|
+
*
|
|
55
|
+
* @param services Persisted service states
|
|
56
|
+
* @param minEoaGasEth Configured minimum EOA gas target (wei)
|
|
57
|
+
* @param pendingSetupMigration True when a deprecated testnet setup is
|
|
58
|
+
* detected — suppresses the `standardFleetAlreadyComplete` short-circuit so a
|
|
59
|
+
* migration-wiped fleet is correctly treated as needing funding. Both call
|
|
60
|
+
* sites MUST pass this so the bootstrapper gate and the funding-plan view
|
|
61
|
+
* agree for migration-wiped fleets.
|
|
62
|
+
* @param targetServices How many services the fleet is aiming for
|
|
63
|
+
* @param stakingMode `'standard'` (default) or `'self-bond'`
|
|
64
|
+
* @param preStage1 True when fleet identity is not yet provisioned —
|
|
65
|
+
* selects the Stage 1 gate. The bootstrapper passes `false` here because it
|
|
66
|
+
* only computes this gate *after* `ensureStage1` succeeds.
|
|
67
|
+
*/
|
|
68
|
+
export declare function computeRequiredMasterEth({ services, minEoaGasEth, pendingSetupMigration, targetServices, stakingMode, preStage1, }: {
|
|
69
|
+
services: Array<{
|
|
70
|
+
service_id?: number | null | undefined;
|
|
71
|
+
step?: string;
|
|
72
|
+
}>;
|
|
73
|
+
minEoaGasEth: bigint;
|
|
74
|
+
pendingSetupMigration?: boolean;
|
|
75
|
+
targetServices?: number;
|
|
76
|
+
stakingMode?: StakingMode;
|
|
77
|
+
preStage1?: boolean;
|
|
78
|
+
}): bigint;
|
|
9
79
|
/** Master ETH required to FINISH the whole bootstrap from a fresh start (not
|
|
10
80
|
* just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
|
|
11
81
|
* the read-side funding-plan, gather-status, and the panel faucet target
|
|
@@ -286,3 +356,24 @@ export declare class FleetBootstrapper {
|
|
|
286
356
|
}
|
|
287
357
|
/** @deprecated Use FleetBootstrapper */
|
|
288
358
|
export declare const EarningBootstrapper: typeof FleetBootstrapper;
|
|
359
|
+
export interface RecoverEvictedServiceOptions {
|
|
360
|
+
/** Display index of the service (used only for log messages). */
|
|
361
|
+
serviceDisplayIndex: number;
|
|
362
|
+
serviceId: number;
|
|
363
|
+
stakingAddress: string;
|
|
364
|
+
distributorAddress: string;
|
|
365
|
+
rpcUrl: string;
|
|
366
|
+
chain: JinnOnchainNetwork;
|
|
367
|
+
mnemonic: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
|
|
371
|
+
*
|
|
372
|
+
* Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
|
|
373
|
+
* from the in-process `EvictionLoop` without requiring a full bootstrapper
|
|
374
|
+
* context (jinn-mono-hjex.3).
|
|
375
|
+
*
|
|
376
|
+
* The caller is responsible for advancing the local service step back to
|
|
377
|
+
* `mech_deployed` after this returns (just like the bootstrapper resume path does).
|
|
378
|
+
*/
|
|
379
|
+
export declare function recoverEvictedService(opts: RecoverEvictedServiceOptions): Promise<void>;
|
|
@@ -20,11 +20,95 @@ 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';
|
|
23
24
|
import { rpcHostForDisplay } from '../preflight/rpc-network.js';
|
|
24
25
|
import { detectDeprecatedTestnetSetup, migrateDeprecatedTestnetSetup, } from './testnet-setup-migration.js';
|
|
25
26
|
const addr = (value) => getAddress(value);
|
|
26
27
|
const SAFE_TOKEN_BOOTSTRAP_MULTIPLIER = 2n;
|
|
27
|
-
|
|
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
|
+
* Used by {@link stage1MinMasterEth} to size the Stage 1 master gas budget.
|
|
38
|
+
*
|
|
39
|
+
* Single source of truth: imported by funding-plan.ts.
|
|
40
|
+
*/
|
|
41
|
+
export const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
42
|
+
/**
|
|
43
|
+
* Self-bond mode needs much more ETH per service than standard mode because
|
|
44
|
+
* the master funds the agent which then pays for: Safe deploy, 5 service
|
|
45
|
+
* registry txs (create, activate, register, deploy, stake), and mech deploy.
|
|
46
|
+
* Roughly 15 txs at varying gas costs. 0.03 ETH per service is a safe
|
|
47
|
+
* estimate. Single source of truth: imported by funding-plan.ts.
|
|
48
|
+
*/
|
|
49
|
+
export const SELF_BOND_ETH_PER_SERVICE = 30000000000000000n; // 0.03 ETH
|
|
50
|
+
/**
|
|
51
|
+
* Single source of truth for the master-ETH cold-start funding gate.
|
|
52
|
+
*
|
|
53
|
+
* Both the mutating bootstrapper ({@link FleetBootstrapper.ensureStage1And2})
|
|
54
|
+
* and the read-only funding plan (`planFleetFunding` in funding-plan.ts) route
|
|
55
|
+
* through this helper, so a migration-wiped fleet computes an identical
|
|
56
|
+
* required-ETH gate in both views. Re-implementing the gate inline at either
|
|
57
|
+
* call site is the u34i cross-module invariant-drift hazard — do not do it.
|
|
58
|
+
*
|
|
59
|
+
* Standard-mode gate has three branches:
|
|
60
|
+
* 1. `standardFleetAlreadyComplete` — fleet already has its full target of
|
|
61
|
+
* operational services and no deprecated-setup migration is pending →
|
|
62
|
+
* `0n` (nothing to fund).
|
|
63
|
+
* 2. `preStage1` — no fleet identity yet (`fleet_stage === 'none'` or no
|
|
64
|
+
* fleet state at all) → the Stage 1 gate from {@link stage1MinMasterEth},
|
|
65
|
+
* which covers the master → agent transfer plus the master's own gas
|
|
66
|
+
* reserve. See jinn-mono-u34i.
|
|
67
|
+
* 3. otherwise — the Stage 2 master gas budget: `minEoaGasEth` (stake gas)
|
|
68
|
+
* plus a per-extra-service top-up transfer for services 2..N.
|
|
69
|
+
*
|
|
70
|
+
* Self-bond mode is a flat `SELF_BOND_ETH_PER_SERVICE × targetServices`
|
|
71
|
+
* regardless of stage.
|
|
72
|
+
*
|
|
73
|
+
* @param services Persisted service states
|
|
74
|
+
* @param minEoaGasEth Configured minimum EOA gas target (wei)
|
|
75
|
+
* @param pendingSetupMigration True when a deprecated testnet setup is
|
|
76
|
+
* detected — suppresses the `standardFleetAlreadyComplete` short-circuit so a
|
|
77
|
+
* migration-wiped fleet is correctly treated as needing funding. Both call
|
|
78
|
+
* sites MUST pass this so the bootstrapper gate and the funding-plan view
|
|
79
|
+
* agree for migration-wiped fleets.
|
|
80
|
+
* @param targetServices How many services the fleet is aiming for
|
|
81
|
+
* @param stakingMode `'standard'` (default) or `'self-bond'`
|
|
82
|
+
* @param preStage1 True when fleet identity is not yet provisioned —
|
|
83
|
+
* selects the Stage 1 gate. The bootstrapper passes `false` here because it
|
|
84
|
+
* only computes this gate *after* `ensureStage1` succeeds.
|
|
85
|
+
*/
|
|
86
|
+
export function computeRequiredMasterEth({ services, minEoaGasEth, pendingSetupMigration = false, targetServices = 1, stakingMode = 'standard', preStage1 = false, }) {
|
|
87
|
+
if (stakingMode !== 'standard') {
|
|
88
|
+
return SELF_BOND_ETH_PER_SERVICE * BigInt(targetServices);
|
|
89
|
+
}
|
|
90
|
+
// Reconciled `standardFleetAlreadyComplete` — a single definition replacing
|
|
91
|
+
// the three historic inline variants. Adopts the strictest of them (the
|
|
92
|
+
// FleetBootstrapper variant): the fleet must have at least `targetServices`
|
|
93
|
+
// rows AND every row must be operational AND no deprecated-setup migration
|
|
94
|
+
// may be pending. A migration-wiped fleet (which sets
|
|
95
|
+
// `pendingSetupMigration`) is therefore never short-circuited to `0n`.
|
|
96
|
+
const standardFleetAlreadyComplete = services.length >= targetServices &&
|
|
97
|
+
services.every(s => s.step !== undefined && isOperationalServiceStep(s.step)) &&
|
|
98
|
+
!pendingSetupMigration;
|
|
99
|
+
if (standardFleetAlreadyComplete)
|
|
100
|
+
return 0n;
|
|
101
|
+
if (preStage1) {
|
|
102
|
+
// Stage 1 gate: master → agent transfer (STAGE1_AGENT_ETH) + the master's
|
|
103
|
+
// own gas reserve, plus per-extra-service transfers. See jinn-mono-u34i.
|
|
104
|
+
return stage1MinMasterEth({ minEoaGasEth }, targetServices);
|
|
105
|
+
}
|
|
106
|
+
// Stage 2 master gas budget — covers distributor.stake() (~0.003 ETH at
|
|
107
|
+
// typical 6 gwei Base Sepolia) plus per-extra-service top-up transfers.
|
|
108
|
+
// Service 1 piggybacks on HD-1's Stage 1 funding, so the base term is a
|
|
109
|
+
// single `minEoaGasEth` (not `× 2`). See jinn-mono-u34i.
|
|
110
|
+
return minEoaGasEth + minEoaGasEth * BigInt(Math.max(0, targetServices - 1));
|
|
111
|
+
}
|
|
28
112
|
/** Master ETH required to FINISH the whole bootstrap from a fresh start (not
|
|
29
113
|
* just to enter Stage 1). Centralized so the daemon's ensureStage1 gate,
|
|
30
114
|
* the read-side funding-plan, gather-status, and the panel faucet target
|
|
@@ -389,12 +473,8 @@ export class FleetBootstrapper {
|
|
|
389
473
|
// Phase 1b: Check master funding for the full operator path.
|
|
390
474
|
const masterAddress = state.master_address;
|
|
391
475
|
let masterBalance = await this.publicClient.getBalance({ address: masterAddress });
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
// (create, activate, register, deploy, stake), and mech deploy. Roughly
|
|
395
|
-
// 15 txs at varying gas costs. 0.03 ETH per service is a safe estimate.
|
|
396
|
-
// On re-runs, include ETH already held by funded agents/safes in the total.
|
|
397
|
-
const SELF_BOND_ETH_PER_SERVICE = 30000000000000000n; // 0.03 ETH
|
|
476
|
+
// On re-runs, include ETH already held by funded agents/safes in the
|
|
477
|
+
// total for self-bond mode.
|
|
398
478
|
let systemEth = masterBalance;
|
|
399
479
|
if (this.stakingMode === 'self-bond') {
|
|
400
480
|
for (const svc of state.services) {
|
|
@@ -416,26 +496,20 @@ export class FleetBootstrapper {
|
|
|
416
496
|
stakingMode: this.stakingMode,
|
|
417
497
|
currentStakingContract: this.config.stakingContract,
|
|
418
498
|
}).services.length > 0;
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
// exceeded the post-Stage-1 master balance at the operator-facing
|
|
434
|
-
// 0.020 ETH budget by ~127k gwei of Stage 1 gas burn, causing a
|
|
435
|
-
// second funding prompt.
|
|
436
|
-
: this.config.minEoaGasEth +
|
|
437
|
-
this.config.minEoaGasEth * BigInt(Math.max(0, this.targetServices - 1)))
|
|
438
|
-
: SELF_BOND_ETH_PER_SERVICE * BigInt(this.targetServices);
|
|
499
|
+
// Single source of truth: the master-ETH gate is computed by
|
|
500
|
+
// `computeRequiredMasterEth` (defined above), the same helper the
|
|
501
|
+
// read-only `planFleetFunding` view routes through. Re-deriving it inline
|
|
502
|
+
// here is the u34i cross-module invariant-drift hazard. `ensureStage1And2`
|
|
503
|
+
// only reaches this point AFTER `ensureStage1` has succeeded, so the
|
|
504
|
+
// fleet is always past Stage 1 — `preStage1` is `false`.
|
|
505
|
+
const requiredMasterEth = computeRequiredMasterEth({
|
|
506
|
+
services: state.services,
|
|
507
|
+
minEoaGasEth: this.config.minEoaGasEth,
|
|
508
|
+
pendingSetupMigration,
|
|
509
|
+
targetServices: this.targetServices,
|
|
510
|
+
stakingMode: this.stakingMode,
|
|
511
|
+
preStage1: false,
|
|
512
|
+
});
|
|
439
513
|
const autoFaucetEnabled = this.autoTestnetFaucet;
|
|
440
514
|
// Re-sum system ETH (master + agent/safe balances for self-bond mode).
|
|
441
515
|
// Hoisted so the drip loop below can refresh cheaply.
|
|
@@ -578,7 +652,7 @@ export class FleetBootstrapper {
|
|
|
578
652
|
};
|
|
579
653
|
}
|
|
580
654
|
catch (error) {
|
|
581
|
-
const { summary, hint, rawMessage } = formatBootstrapOperatorMessage(error);
|
|
655
|
+
const { summary, hint, rawMessage, category } = formatBootstrapOperatorMessage(error);
|
|
582
656
|
const userMessage = hint !== undefined ? `${summary}\nHint: ${hint}` : summary;
|
|
583
657
|
if (this.debug) {
|
|
584
658
|
console.error(`[fleet-bootstrap] Bootstrap failed:`, error);
|
|
@@ -594,11 +668,21 @@ export class FleetBootstrapper {
|
|
|
594
668
|
console.error(`[fleet-bootstrap] raw: ${rawMessage.split('\n')[0]}`);
|
|
595
669
|
}
|
|
596
670
|
}
|
|
671
|
+
// Extract a tx hash embedded in the error message by the on-chain revert
|
|
672
|
+
// paths (format: "...tx failed for service N: 0x<hash>" or
|
|
673
|
+
// "...tx reverted: 0x<hash>"). Surfaced in the fatal envelope so the SPA
|
|
674
|
+
// can render a block-explorer link. jinn-mono-hjex reviewer fix.
|
|
675
|
+
const txHashMatch = /(0x[a-fA-F0-9]{64})/.exec(rawMessage);
|
|
676
|
+
const txHash = txHashMatch ? txHashMatch[1] : null;
|
|
597
677
|
return {
|
|
598
678
|
ok: false,
|
|
599
679
|
fleet_state: state,
|
|
600
680
|
message: userMessage,
|
|
601
681
|
rawErrorMessage: rawMessage,
|
|
682
|
+
// Preserve the structured category so the error envelope in main.ts
|
|
683
|
+
// can surface it in `details.category` for SPA consumers. jinn-mono-hjex.6
|
|
684
|
+
...(category !== undefined ? { errorCategory: category } : {}),
|
|
685
|
+
...(txHash !== null ? { txHash } : {}),
|
|
602
686
|
};
|
|
603
687
|
}
|
|
604
688
|
}
|
|
@@ -1044,6 +1128,39 @@ export class FleetBootstrapper {
|
|
|
1044
1128
|
return this.store.updateService(index, { step: 'staked' });
|
|
1045
1129
|
}
|
|
1046
1130
|
}
|
|
1131
|
+
// Pre-stake precondition: if migration cleared service_id but kept agent_address,
|
|
1132
|
+
// check the EOA is not already registered on-chain as an agent instance. If it is,
|
|
1133
|
+
// calling stake() again would revert with AgentInstanceRegistered (selector 0x631695bd)
|
|
1134
|
+
// and there is nothing useful the operator can do without rotating the agent EOA.
|
|
1135
|
+
// Fail fast with a typed error instead of letting the contract revert.
|
|
1136
|
+
//
|
|
1137
|
+
// ServiceRegistryL2 exposes the `mapAgentInstanceOperators(address) → address` mapping:
|
|
1138
|
+
// it returns the operator address that registered the given agent instance, or the
|
|
1139
|
+
// zero address when no operator has bound that instance. A non-zero return means the
|
|
1140
|
+
// EOA is already bound. (There is no `mapAgentInstances(address) → uint256` getter on
|
|
1141
|
+
// the deployed registry — an earlier draft of this guard referenced one and was a
|
|
1142
|
+
// permanent no-op.)
|
|
1143
|
+
if (svc.agent_address && svc.service_id === null && this.config.serviceRegistry) {
|
|
1144
|
+
let alreadyBound = false;
|
|
1145
|
+
try {
|
|
1146
|
+
const boundOperator = (await this.publicClient.readContract({
|
|
1147
|
+
address: getAddress(this.config.serviceRegistry),
|
|
1148
|
+
abi: SERVICE_REGISTRY_L2_ABI,
|
|
1149
|
+
functionName: 'mapAgentInstanceOperators',
|
|
1150
|
+
args: [getAddress(svc.agent_address)],
|
|
1151
|
+
}));
|
|
1152
|
+
alreadyBound = boundOperator !== '0x0000000000000000000000000000000000000000';
|
|
1153
|
+
}
|
|
1154
|
+
catch {
|
|
1155
|
+
// Registry read failure is non-fatal — proceed and let stake() surface
|
|
1156
|
+
// the error if the agent really is bound.
|
|
1157
|
+
}
|
|
1158
|
+
if (alreadyBound) {
|
|
1159
|
+
throw new Error(`agent_already_bound: agent EOA ${svc.agent_address} is already registered as an agent instance on-chain. ` +
|
|
1160
|
+
`The previous setup retirement may have been incomplete. ` +
|
|
1161
|
+
`Contact support or rotate the agent EOA to continue.`);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1047
1164
|
// Fresh distributor stake() creates a new on-chain service. If state still
|
|
1048
1165
|
// references an old Safe (e.g. hand-edited JSON), sweep it before replacing.
|
|
1049
1166
|
if (svc.service_id === null && svc.safe_address && state.master_address) {
|
|
@@ -1109,42 +1226,19 @@ export class FleetBootstrapper {
|
|
|
1109
1226
|
const svc = state.services.find(s => s.index === index);
|
|
1110
1227
|
const serviceId = svc.service_id;
|
|
1111
1228
|
const stakingAddress = this.stakingAddressForService(svc);
|
|
1112
|
-
|
|
1113
|
-
//
|
|
1114
|
-
//
|
|
1115
|
-
//
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1229
|
+
const di = displayFleetServiceIndex(svc);
|
|
1230
|
+
// Delegate to the standalone exported helper (shared with EvictionLoop /
|
|
1231
|
+
// the dashboard "Re-stake now" CTA). This eliminates the duplicate
|
|
1232
|
+
// implementation (jinn-mono-hjex.3).
|
|
1233
|
+
await recoverEvictedService({
|
|
1234
|
+
serviceDisplayIndex: di,
|
|
1235
|
+
serviceId,
|
|
1236
|
+
stakingAddress: stakingAddress,
|
|
1237
|
+
distributorAddress: this.config.distributorAddress,
|
|
1238
|
+
rpcUrl: this.config.rpcUrl,
|
|
1239
|
+
chain: this.chain,
|
|
1240
|
+
mnemonic,
|
|
1122
1241
|
});
|
|
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})`);
|
|
1148
1242
|
// Service is now Staked again with the same service_id, safe_address, and mech_address.
|
|
1149
1243
|
// Step back to `mech_deployed` so the resume loop advances through
|
|
1150
1244
|
// `stepRegisterAgent` (idempotent — short-circuits if `agent_id` is
|
|
@@ -1897,4 +1991,50 @@ export class FleetBootstrapper {
|
|
|
1897
1991
|
}
|
|
1898
1992
|
/** @deprecated Use FleetBootstrapper */
|
|
1899
1993
|
export const EarningBootstrapper = FleetBootstrapper;
|
|
1994
|
+
/**
|
|
1995
|
+
* Re-stake an evicted service by calling `distributor.reStake(stakingProxy, serviceId)`.
|
|
1996
|
+
*
|
|
1997
|
+
* Extracted from `FleetBootstrapper.recoverEvictedService` so it can be called
|
|
1998
|
+
* from the in-process `EvictionLoop` without requiring a full bootstrapper
|
|
1999
|
+
* context (jinn-mono-hjex.3).
|
|
2000
|
+
*
|
|
2001
|
+
* The caller is responsible for advancing the local service step back to
|
|
2002
|
+
* `mech_deployed` after this returns (just like the bootstrapper resume path does).
|
|
2003
|
+
*/
|
|
2004
|
+
export async function recoverEvictedService(opts) {
|
|
2005
|
+
const { serviceDisplayIndex, serviceId, stakingAddress, distributorAddress, rpcUrl, chain, mnemonic, } = opts;
|
|
2006
|
+
const masterAccount = deriveMasterSigner(mnemonic);
|
|
2007
|
+
const publicClient = createJinnPublicClient(rpcUrl, chain);
|
|
2008
|
+
const masterWallet = createJinnWalletClient(rpcUrl, chain, masterAccount);
|
|
2009
|
+
const reStakeData = encodeFunctionData({
|
|
2010
|
+
abi: STOLAS_DISTRIBUTOR_ABI,
|
|
2011
|
+
functionName: 'reStake',
|
|
2012
|
+
args: [addr(stakingAddress), BigInt(serviceId)],
|
|
2013
|
+
});
|
|
2014
|
+
console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: calling distributor.reStake() for evicted service ${serviceId}`);
|
|
2015
|
+
let reStakeHash;
|
|
2016
|
+
try {
|
|
2017
|
+
reStakeHash = await viemSendTransactionWithRetry(masterWallet, publicClient, {
|
|
2018
|
+
account: masterAccount,
|
|
2019
|
+
to: addr(distributorAddress),
|
|
2020
|
+
data: reStakeData,
|
|
2021
|
+
gas: 1500000n,
|
|
2022
|
+
});
|
|
2023
|
+
}
|
|
2024
|
+
catch (err) {
|
|
2025
|
+
const message = flattenErrorMessage(err);
|
|
2026
|
+
if (isUnauthorizedAccountError(message)) {
|
|
2027
|
+
throw new Error(`Service ${serviceDisplayIndex} (service_id ${serviceId}) is evicted on the staking proxy, but master EOA ` +
|
|
2028
|
+
`${masterAccount.address} is not authorized to reStake it. ` +
|
|
2029
|
+
`Verify JINN_EARNING_DIR and JINN_PASSWORD derive the original master EOA for this service. ` +
|
|
2030
|
+
`reStake revert: ${message}`);
|
|
2031
|
+
}
|
|
2032
|
+
throw err;
|
|
2033
|
+
}
|
|
2034
|
+
const receipt = await waitForTransactionReceiptWithRetry(publicClient, reStakeHash);
|
|
2035
|
+
if (receipt.status !== 'success') {
|
|
2036
|
+
throw new Error(`reStake failed for service ${serviceDisplayIndex}: ${reStakeHash}`);
|
|
2037
|
+
}
|
|
2038
|
+
console.error(`[eviction-recovery] Service ${serviceDisplayIndex}: reStake confirmed (tx: ${reStakeHash})`);
|
|
2039
|
+
}
|
|
1900
2040
|
//# sourceMappingURL=bootstrap.js.map
|