@jinn-network/client 0.1.6 → 0.1.7-canary.17a8ecb8
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/README.md +67 -1
- 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 +268 -57
- 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 +6 -2
- package/dist/adapters/mech/safe.js +32 -11
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +6 -1
- package/dist/adapters/mech/types.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/activity-events-endpoint.d.ts +14 -0
- package/dist/api/activity-events-endpoint.js +59 -0
- package/dist/api/activity-events-endpoint.js.map +1 -0
- 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.d.ts +1 -2
- package/dist/api/bootstrap-endpoint.js +49 -1
- 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 +14 -0
- package/dist/api/gather-status.js +494 -19
- 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 +22 -17
- package/dist/api/launcher-status.js +13 -11
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/launcher-tasks.d.ts +1 -1
- package/dist/api/launcher-tasks.js +12 -8
- package/dist/api/launcher-tasks.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 +72 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +16 -0
- package/dist/api/setup-endpoints.js +89 -135
- 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 +112 -0
- package/dist/api/status-build.js +98 -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 +101 -15
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
- package/dist/cli/commands/solver-plugins-block.js +118 -0
- package/dist/cli/commands/solver-plugins-block.js.map +1 -0
- package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
- package/dist/cli/commands/solver-plugins-feedback.js +262 -0
- package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
- package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
- package/dist/cli/commands/solver-plugins-read.js +259 -0
- package/dist/cli/commands/solver-plugins-read.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +35 -0
- package/dist/cli/commands/solver-plugins.js +399 -2
- package/dist/cli/commands/solver-plugins.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 +101 -11
- 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 +10 -1
- package/dist/cli/task-native-readiness.js +30 -6
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +273 -235
- package/dist/config.js +305 -114
- 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 +22 -0
- package/dist/daemon/daemon.js +156 -23
- 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/gate-logger.d.ts +9 -0
- package/dist/daemon/gate-logger.js +2 -0
- package/dist/daemon/gate-logger.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/readiness-gate.d.ts +1 -4
- package/dist/daemon/readiness-gate.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/daemon/spend-cap-gate.d.ts +40 -0
- package/dist/daemon/spend-cap-gate.js +46 -0
- package/dist/daemon/spend-cap-gate.js.map +1 -0
- package/dist/dashboard/assets/index-8yHQgi7p.js +345 -0
- package/dist/dashboard/assets/index-BOBhJ76-.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 +37 -11
- 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 +21 -6
- package/dist/earning/viem-clients.d.ts +11 -4
- package/dist/earning/viem-clients.js +14 -5
- package/dist/earning/viem-clients.js.map +1 -1
- 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/events/types.d.ts +2 -2
- 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 +118 -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 +88 -4
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +143 -22
- 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 +413 -111
- package/dist/main.js.map +1 -1
- package/dist/observability/emit-event.d.ts +3 -2
- package/dist/observability/emit-event.js +22 -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/preflight/rpc-network.d.ts +40 -0
- package/dist/preflight/rpc-network.js +67 -1
- package/dist/preflight/rpc-network.js.map +1 -1
- 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/rpc/transport.d.ts +109 -0
- package/dist/rpc/transport.js +220 -0
- package/dist/rpc/transport.js.map +1 -0
- package/dist/scripts/donation-consumption-acceptance.js +7 -28
- package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
- 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.d.ts +1 -2
- package/dist/solver-nets/prediction-operator-ux.js +90 -47
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +20 -1
- package/dist/solver-nets/registry.js +38 -25
- 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-pool.d.ts +9 -2
- package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
- package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
- 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 +94 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +305 -39
- 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 +237 -95
- 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/spend/credential.d.ts +8 -0
- package/dist/spend/credential.js +30 -0
- package/dist/spend/credential.js.map +1 -0
- package/dist/spend/daemon-config.d.ts +13 -0
- package/dist/spend/daemon-config.js +24 -0
- package/dist/spend/daemon-config.js.map +1 -0
- package/dist/spend/pricing.d.ts +16 -0
- package/dist/spend/pricing.js +26 -0
- package/dist/spend/pricing.js.map +1 -0
- package/dist/spend/record.d.ts +13 -0
- package/dist/spend/record.js +30 -0
- package/dist/spend/record.js.map +1 -0
- package/dist/spend/usage.d.ts +27 -0
- package/dist/spend/usage.js +113 -0
- package/dist/spend/usage.js.map +1 -0
- package/dist/store/store.d.ts +43 -0
- package/dist/store/store.js +236 -7
- 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/trajectory/transcript-parsers/types.d.ts +8 -8
- package/dist/tx-retry.d.ts +166 -19
- package/dist/tx-retry.js +310 -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 +30 -12
- package/dist/dashboard/assets/index-DOlzFN8a.css +0 -32
- package/dist/dashboard/assets/index-NkZ7CTAT.js +0 -140
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Best-effort status collection for GET /v1/status (RPC + earning store + SQLite).
|
|
3
3
|
*/
|
|
4
|
-
import { createPublicClient, http } from 'viem';
|
|
4
|
+
import { createPublicClient, getAddress, http, parseAbiItem } from 'viem';
|
|
5
5
|
import { existsSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { base, baseSepolia } from 'viem/chains';
|
|
8
|
+
import { isOverSpendCap } from '../daemon/spend-cap-gate.js';
|
|
8
9
|
import { FleetStateStore } from '../earning/store.js';
|
|
9
|
-
import { getChainConfig } from '../earning/contracts.js';
|
|
10
|
+
import { DEFAULT_TESTNET_ARTIFACTS, getChainConfig, loadJinnMviConfig, } from '../earning/contracts.js';
|
|
11
|
+
import { createJinnL1PublicClient } from '../earning/viem-clients.js';
|
|
10
12
|
import { stage1MinMasterEth } from '../earning/bootstrap.js';
|
|
11
13
|
import { JINN_STAKING_ABI } from '../earning/jinn-rewards.js';
|
|
12
14
|
import { displayFleetServiceIndex } from '../earning/fleet-display-index.js';
|
|
13
|
-
import { assembleStatusV1, resolveMasterDailyEstimateWei, } from './status-build.js';
|
|
15
|
+
import { assembleStatusV1, pendingTjinnStatus, TJINN_PUBLIC_INVALID_SAFE_ERROR, TJINN_PUBLIC_PARTIAL_ERROR, TJINN_PUBLIC_READ_ERROR, resolveMasterDailyEstimateWei, } from './status-build.js';
|
|
14
16
|
import { listStolasClaimTargets } from '../earning/stolas-claim.js';
|
|
15
17
|
import { gatherPortfolioV0Status, DEFAULT_ENGINE_WORKING_DIR_ROOT, } from './portfolio-v0-build.js';
|
|
16
18
|
import { gatherPredictionV1Status, } from './prediction-v1-build.js';
|
|
17
19
|
import { gatherTaskRunsStatus } from './task-runs-build.js';
|
|
18
20
|
import { buildPredictionOperatorStatus, } from '../solver-nets/prediction-operator-ux.js';
|
|
21
|
+
import { findJoinedByName, rolesFromJoinedConfig, solverTypeFromJoinedContract, } from '../solver-nets/registry.js';
|
|
19
22
|
const ERC20_BALANCE_OF_ABI = [
|
|
20
23
|
{
|
|
21
24
|
type: 'function',
|
|
@@ -25,6 +28,81 @@ const ERC20_BALANCE_OF_ABI = [
|
|
|
25
28
|
outputs: [{ name: '', type: 'uint256' }],
|
|
26
29
|
},
|
|
27
30
|
];
|
|
31
|
+
const JINN_DISTRIBUTOR_CLAIMED_ABI = [
|
|
32
|
+
{
|
|
33
|
+
type: 'function',
|
|
34
|
+
name: 'totalClaimedOperator',
|
|
35
|
+
stateMutability: 'view',
|
|
36
|
+
inputs: [{ name: 'serviceId', type: 'uint256' }],
|
|
37
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* `Claimed` event item for `getLogs({ event, args })`. Matches the
|
|
42
|
+
* Solidity signature in
|
|
43
|
+
* `contracts/src/jinn/distribution/JinnDistributor.sol` so the operator
|
|
44
|
+
* 24h-minted sum can be computed without a separate indexer.
|
|
45
|
+
*/
|
|
46
|
+
const JINN_DISTRIBUTOR_CLAIMED_EVENT = parseAbiItem('event Claimed(uint256 indexed serviceId, address indexed multisig, uint256 operatorMinted, uint256 daoMinted, uint256 totalEntitledOperator, uint256 totalEntitledDao)');
|
|
47
|
+
const TJINN_BALANCE_CACHE_TTL_MS = 30_000;
|
|
48
|
+
const TJINN_BALANCE_TIMEOUT_MS = 6_000;
|
|
49
|
+
/**
|
|
50
|
+
* Approximate Sepolia blocks per 24 hours. The chain produces a block every
|
|
51
|
+
* ~12s; 86_400 / 12 = 7_200. We pad to 7_500 to absorb the occasional
|
|
52
|
+
* slower block and keep the window comfortably within the common 10k-block
|
|
53
|
+
* `eth_getLogs` cap.
|
|
54
|
+
*/
|
|
55
|
+
const SEPOLIA_BLOCKS_PER_24H = 7500n;
|
|
56
|
+
/**
|
|
57
|
+
* tJINN token address + chain id resolved from the bundled JINN MVI L1
|
|
58
|
+
* deployment artifact — the single source of truth. Used only when the caller
|
|
59
|
+
* (`main.ts`) does not thread explicit values through `StatusGatherConfig`
|
|
60
|
+
* (e.g. test callers, sqlite-only introspection without config). Lazy + cached
|
|
61
|
+
* so the artifact read happens at most once per process.
|
|
62
|
+
*/
|
|
63
|
+
let cachedTjinnArtifactIdentity;
|
|
64
|
+
function defaultTjinnIdentity() {
|
|
65
|
+
if (!cachedTjinnArtifactIdentity) {
|
|
66
|
+
let tokenAddress;
|
|
67
|
+
let chainId;
|
|
68
|
+
try {
|
|
69
|
+
const mvi = loadJinnMviConfig({ l1ArtifactPath: DEFAULT_TESTNET_ARTIFACTS.jinnMviL1 });
|
|
70
|
+
tokenAddress = mvi.jinn;
|
|
71
|
+
chainId = mvi.l1ChainId;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Fall through to the hard defaults below if the artifact is unreadable.
|
|
75
|
+
}
|
|
76
|
+
cachedTjinnArtifactIdentity = {
|
|
77
|
+
tokenAddress: tokenAddress ?? '0x0bc0B2f733bF4229FD58Baaac5ebFEf2AEc83C4A',
|
|
78
|
+
chainId: chainId ?? 11155111,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return cachedTjinnArtifactIdentity;
|
|
82
|
+
}
|
|
83
|
+
function resolveTjinnIdentity(status) {
|
|
84
|
+
const fallback = defaultTjinnIdentity();
|
|
85
|
+
return {
|
|
86
|
+
tokenAddress: status?.tjinnTokenAddress ?? fallback.tokenAddress,
|
|
87
|
+
chainId: status?.tjinnChainId ?? fallback.chainId,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** Fill a fresh errors Map with `TJINN_PUBLIC_READ_ERROR` for every key. */
|
|
91
|
+
function errorsForAllKeys(keys) {
|
|
92
|
+
const errors = new Map();
|
|
93
|
+
for (const key of keys) {
|
|
94
|
+
errors.set(key, TJINN_PUBLIC_READ_ERROR);
|
|
95
|
+
}
|
|
96
|
+
return errors;
|
|
97
|
+
}
|
|
98
|
+
function errorsForAllServiceIds(serviceIds) {
|
|
99
|
+
const errors = new Map();
|
|
100
|
+
for (const serviceId of serviceIds) {
|
|
101
|
+
errors.set(serviceId, TJINN_PUBLIC_READ_ERROR);
|
|
102
|
+
}
|
|
103
|
+
return errors;
|
|
104
|
+
}
|
|
105
|
+
const tjinnBalanceCache = new Map();
|
|
28
106
|
function readDaemonRuntime(earningDir) {
|
|
29
107
|
if (!earningDir)
|
|
30
108
|
return undefined;
|
|
@@ -62,6 +140,24 @@ export function invalidatePredictionOperatorStatusCache(config) {
|
|
|
62
140
|
function chainKey(network) {
|
|
63
141
|
return network === 'testnet' ? 'base-sepolia' : 'base';
|
|
64
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Derive the SolverNet name to use for the prediction operator diagnostic.
|
|
145
|
+
*
|
|
146
|
+
* Priority: (1) first joined entry's `name` field, (2) first joined entry's
|
|
147
|
+
* manifestCid, (3) fallback `'prediction'`.
|
|
148
|
+
*
|
|
149
|
+
* Post-issue-#421 the legacy `solverNets` config block has been retired; the
|
|
150
|
+
* operator's participation choices live in `joinedSolverNets` keyed by
|
|
151
|
+
* manifestCid.
|
|
152
|
+
*/
|
|
153
|
+
function derivePredictionSolverNetName(config) {
|
|
154
|
+
const joinedEntries = Object.entries(config.joinedSolverNets ?? {});
|
|
155
|
+
if (joinedEntries.length > 0) {
|
|
156
|
+
const [cid, entry] = joinedEntries[0];
|
|
157
|
+
return entry.name ?? cid;
|
|
158
|
+
}
|
|
159
|
+
return 'prediction';
|
|
160
|
+
}
|
|
65
161
|
function predictionOperatorCacheKey(configPath, name) {
|
|
66
162
|
return `${configPath}\0${name}`;
|
|
67
163
|
}
|
|
@@ -77,41 +173,42 @@ async function getCachedPredictionOperatorStatus(config, configPath, name) {
|
|
|
77
173
|
// gather-status only runs inside a live daemon; the operator-status
|
|
78
174
|
// surface should reflect that (Issue #86 §1: drop the vacuous
|
|
79
175
|
// "start the daemon" copy when the daemon is already running).
|
|
80
|
-
cached = buildPredictionOperatorStatus({ config, configPath,
|
|
176
|
+
cached = buildPredictionOperatorStatus({ config, configPath, daemonRunning: true })
|
|
81
177
|
.catch((error) => predictionOperatorUnavailable(config, configPath, name, errorMessage(error)));
|
|
82
178
|
byKey.set(key, cached);
|
|
83
179
|
}
|
|
84
180
|
return cached;
|
|
85
181
|
}
|
|
86
182
|
function predictionOperatorUnavailable(config, configPath, name, message) {
|
|
87
|
-
|
|
183
|
+
// Resolve the matching joined entry by display name (or manifestCid) so
|
|
184
|
+
// the diagnostic can still surface the operator's configured roles when
|
|
185
|
+
// possible.
|
|
186
|
+
const joined = findJoinedByName(config.joinedSolverNets, name);
|
|
88
187
|
const diagnostic = {
|
|
89
188
|
code: 'prediction_operator_status_unavailable',
|
|
90
189
|
severity: 'error',
|
|
91
190
|
message,
|
|
92
191
|
nextAction: {
|
|
93
|
-
description: 'Inspect Prediction SolverNet configuration and restart the daemon after fixing it.',
|
|
94
|
-
|
|
192
|
+
description: 'Inspect Prediction SolverNet configuration via Operator > SolverNets and restart the daemon after fixing it.',
|
|
193
|
+
url: '/operator#solvernets',
|
|
95
194
|
},
|
|
96
195
|
};
|
|
97
196
|
// Roles are best-effort: an unavailable status path means the daemon
|
|
98
|
-
// could not load the SolverNet, so we surface whatever the operator
|
|
99
|
-
//
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
? rawRoles.filter((r) => r === 'solving' || r === 'evaluating')
|
|
103
|
-
: [];
|
|
197
|
+
// could not load the SolverNet, so we surface whatever the operator
|
|
198
|
+
// joined.
|
|
199
|
+
const netRoles = joined ? rolesFromJoinedConfig(joined) : [];
|
|
200
|
+
const solverType = (joined && solverTypeFromJoinedContract(joined)) ?? 'prediction.v1';
|
|
104
201
|
return {
|
|
105
202
|
kind: 'prediction.v1.operatorStatus',
|
|
106
203
|
ok: false,
|
|
107
204
|
configPath,
|
|
108
205
|
solverNet: {
|
|
109
206
|
name,
|
|
110
|
-
enabled:
|
|
111
|
-
solverType
|
|
207
|
+
enabled: joined ? netRoles.length > 0 : false,
|
|
208
|
+
solverType,
|
|
112
209
|
roles: netRoles,
|
|
113
|
-
harness:
|
|
114
|
-
taskGeneratorEnabled:
|
|
210
|
+
harness: joined?.harness,
|
|
211
|
+
taskGeneratorEnabled: false,
|
|
115
212
|
},
|
|
116
213
|
runtimePlugins: [],
|
|
117
214
|
diagnostics: [diagnostic],
|
|
@@ -163,6 +260,8 @@ function predictionV1Unavailable(operator, operatorError) {
|
|
|
163
260
|
solutions: 0,
|
|
164
261
|
verdicts: 0,
|
|
165
262
|
failed: 0,
|
|
263
|
+
settledFailed: 0,
|
|
264
|
+
localErrors: 0,
|
|
166
265
|
},
|
|
167
266
|
latest: {
|
|
168
267
|
taskAt: null,
|
|
@@ -177,6 +276,158 @@ function predictionV1Unavailable(operator, operatorError) {
|
|
|
177
276
|
function errorMessage(error) {
|
|
178
277
|
return error instanceof Error ? error.message : String(error);
|
|
179
278
|
}
|
|
279
|
+
function tJinnBalanceCacheKey(ethereumRpcUrl, distributorAddress, safeKeys, serviceIds) {
|
|
280
|
+
return [
|
|
281
|
+
ethereumRpcUrl,
|
|
282
|
+
distributorAddress ?? '',
|
|
283
|
+
[...safeKeys].sort().join(','),
|
|
284
|
+
[...serviceIds].sort((a, b) => a - b).join(','),
|
|
285
|
+
].join('\0');
|
|
286
|
+
}
|
|
287
|
+
function timeoutError(message) {
|
|
288
|
+
const error = new Error(message);
|
|
289
|
+
error.name = 'TimeoutError';
|
|
290
|
+
return error;
|
|
291
|
+
}
|
|
292
|
+
function withTimeout(promise, timeoutMs, message) {
|
|
293
|
+
return new Promise((resolve, reject) => {
|
|
294
|
+
const timer = setTimeout(() => reject(timeoutError(message)), timeoutMs);
|
|
295
|
+
promise
|
|
296
|
+
.then(resolve, reject)
|
|
297
|
+
.finally(() => clearTimeout(timer));
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
async function readTjinnBalances(ethereumRpcUrl, tokenAddress, distributorAddress, expectedChainId, safeToAddress, serviceIds) {
|
|
301
|
+
const safeEntries = [...safeToAddress.entries()];
|
|
302
|
+
const client = createJinnL1PublicClient(ethereumRpcUrl, 'sepolia');
|
|
303
|
+
const chainId = await client.getChainId();
|
|
304
|
+
const balances = new Map();
|
|
305
|
+
const operatorClaimedByService = new Map();
|
|
306
|
+
const operatorMintedLast24hByService = new Map();
|
|
307
|
+
if (chainId !== expectedChainId) {
|
|
308
|
+
return {
|
|
309
|
+
chainId,
|
|
310
|
+
balances,
|
|
311
|
+
operatorClaimedByService,
|
|
312
|
+
operatorMintedLast24hByService,
|
|
313
|
+
errors: errorsForAllKeys(safeToAddress.keys()),
|
|
314
|
+
claimedErrors: errorsForAllServiceIds(serviceIds),
|
|
315
|
+
claimedLast24hError: TJINN_PUBLIC_READ_ERROR,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
const errors = new Map();
|
|
319
|
+
// Single multicall3 round-trip (Sepolia has multicall3). `allowFailure: true`
|
|
320
|
+
// preserves the per-Safe partial-failure handling — a failed entry yields a
|
|
321
|
+
// `{ status: 'failure' }` result rather than rejecting the whole batch.
|
|
322
|
+
const results = await client.multicall({
|
|
323
|
+
allowFailure: true,
|
|
324
|
+
contracts: safeEntries.map(([, safeAddress]) => ({
|
|
325
|
+
address: tokenAddress,
|
|
326
|
+
abi: ERC20_BALANCE_OF_ABI,
|
|
327
|
+
functionName: 'balanceOf',
|
|
328
|
+
args: [safeAddress],
|
|
329
|
+
})),
|
|
330
|
+
});
|
|
331
|
+
for (let i = 0; i < results.length; i++) {
|
|
332
|
+
const result = results[i];
|
|
333
|
+
const key = safeEntries[i]?.[0];
|
|
334
|
+
if (!key)
|
|
335
|
+
continue;
|
|
336
|
+
if (result.status === 'success') {
|
|
337
|
+
balances.set(key, result.result.toString());
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
errors.set(key, TJINN_PUBLIC_READ_ERROR);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
const claimedErrors = new Map();
|
|
344
|
+
if (distributorAddress && serviceIds.length > 0) {
|
|
345
|
+
const claimedResults = await client.multicall({
|
|
346
|
+
allowFailure: true,
|
|
347
|
+
contracts: serviceIds.map((serviceId) => ({
|
|
348
|
+
address: distributorAddress,
|
|
349
|
+
abi: JINN_DISTRIBUTOR_CLAIMED_ABI,
|
|
350
|
+
functionName: 'totalClaimedOperator',
|
|
351
|
+
args: [BigInt(serviceId)],
|
|
352
|
+
})),
|
|
353
|
+
});
|
|
354
|
+
for (let i = 0; i < claimedResults.length; i++) {
|
|
355
|
+
const serviceId = serviceIds[i];
|
|
356
|
+
if (serviceId === undefined)
|
|
357
|
+
continue;
|
|
358
|
+
const result = claimedResults[i];
|
|
359
|
+
if (result.status === 'success') {
|
|
360
|
+
operatorClaimedByService.set(serviceId, result.result.toString());
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
claimedErrors.set(serviceId, TJINN_PUBLIC_READ_ERROR);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
let claimedLast24hError = null;
|
|
368
|
+
if (distributorAddress && serviceIds.length > 0) {
|
|
369
|
+
try {
|
|
370
|
+
const latest = await client.getBlockNumber();
|
|
371
|
+
const fromBlock = latest > SEPOLIA_BLOCKS_PER_24H ? latest - SEPOLIA_BLOCKS_PER_24H : 0n;
|
|
372
|
+
const logs = await client.getLogs({
|
|
373
|
+
address: distributorAddress,
|
|
374
|
+
event: JINN_DISTRIBUTOR_CLAIMED_EVENT,
|
|
375
|
+
args: { serviceId: serviceIds.map((id) => BigInt(id)) },
|
|
376
|
+
fromBlock,
|
|
377
|
+
toBlock: latest,
|
|
378
|
+
});
|
|
379
|
+
const sums = new Map();
|
|
380
|
+
for (const log of logs) {
|
|
381
|
+
const args = log.args;
|
|
382
|
+
if (args.serviceId === undefined || args.operatorMinted === undefined)
|
|
383
|
+
continue;
|
|
384
|
+
const id = Number(args.serviceId);
|
|
385
|
+
sums.set(id, (sums.get(id) ?? 0n) + args.operatorMinted);
|
|
386
|
+
}
|
|
387
|
+
for (const serviceId of serviceIds) {
|
|
388
|
+
operatorMintedLast24hByService.set(serviceId, (sums.get(serviceId) ?? 0n).toString());
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
claimedLast24hError = TJINN_PUBLIC_READ_ERROR;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
chainId,
|
|
397
|
+
balances,
|
|
398
|
+
operatorClaimedByService,
|
|
399
|
+
operatorMintedLast24hByService,
|
|
400
|
+
errors,
|
|
401
|
+
claimedErrors,
|
|
402
|
+
claimedLast24hError,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
async function getCachedTjinnBalances(ethereumRpcUrl, tokenAddress, distributorAddress, expectedChainId, safeToAddress, serviceIds) {
|
|
406
|
+
const safeKeys = [...safeToAddress.keys()].sort();
|
|
407
|
+
const sortedServiceIds = [...serviceIds].sort((a, b) => a - b);
|
|
408
|
+
const cacheKey = tJinnBalanceCacheKey(ethereumRpcUrl, distributorAddress, safeKeys, sortedServiceIds);
|
|
409
|
+
const now = Date.now();
|
|
410
|
+
const cached = tjinnBalanceCache.get(cacheKey);
|
|
411
|
+
if (cached && cached.expiresAt > now) {
|
|
412
|
+
return cached.promise;
|
|
413
|
+
}
|
|
414
|
+
const promise = withTimeout(readTjinnBalances(ethereumRpcUrl, tokenAddress, distributorAddress, expectedChainId, safeToAddress, sortedServiceIds), TJINN_BALANCE_TIMEOUT_MS, 'tJINN balance collection timed out').catch(() => {
|
|
415
|
+
return {
|
|
416
|
+
chainId: expectedChainId,
|
|
417
|
+
balances: new Map(),
|
|
418
|
+
operatorClaimedByService: new Map(),
|
|
419
|
+
operatorMintedLast24hByService: new Map(),
|
|
420
|
+
errors: errorsForAllKeys(safeKeys),
|
|
421
|
+
claimedErrors: errorsForAllServiceIds(sortedServiceIds),
|
|
422
|
+
claimedLast24hError: TJINN_PUBLIC_READ_ERROR,
|
|
423
|
+
};
|
|
424
|
+
});
|
|
425
|
+
tjinnBalanceCache.set(cacheKey, {
|
|
426
|
+
expiresAt: now + TJINN_BALANCE_CACHE_TTL_MS,
|
|
427
|
+
promise,
|
|
428
|
+
});
|
|
429
|
+
return promise;
|
|
430
|
+
}
|
|
180
431
|
async function sumPendingStakingRewards(rpcUrl, network, fleet) {
|
|
181
432
|
const targets = listStolasClaimTargets(fleet.services);
|
|
182
433
|
if (targets.length === 0) {
|
|
@@ -228,6 +479,158 @@ async function sumPendingStakingRewards(rpcUrl, network, fleet) {
|
|
|
228
479
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
229
480
|
}
|
|
230
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Resolve the public error string for a tJINN status with at least one error.
|
|
484
|
+
*
|
|
485
|
+
* Flattened from a 3-deep nested ternary into guard clauses:
|
|
486
|
+
* - partial success (some balances read) → PARTIAL
|
|
487
|
+
* - only invalid-Safe errors → INVALID_SAFE
|
|
488
|
+
* - otherwise (RPC read failures) → READ_ERROR
|
|
489
|
+
*
|
|
490
|
+
* Caller must only invoke this when `hasInvalidSafe || hasReadError` is true.
|
|
491
|
+
*/
|
|
492
|
+
function tjinnPublicError(opts) {
|
|
493
|
+
if (opts.hasAnyBalance)
|
|
494
|
+
return TJINN_PUBLIC_PARTIAL_ERROR;
|
|
495
|
+
if (opts.hasInvalidSafe && !opts.hasReadError)
|
|
496
|
+
return TJINN_PUBLIC_INVALID_SAFE_ERROR;
|
|
497
|
+
return TJINN_PUBLIC_READ_ERROR;
|
|
498
|
+
}
|
|
499
|
+
async function gatherTjinnStatus(ethereumRpcUrl, tokenAddress, distributorAddress, chainId, fleet) {
|
|
500
|
+
if (!fleet) {
|
|
501
|
+
return pendingTjinnStatus(tokenAddress, chainId);
|
|
502
|
+
}
|
|
503
|
+
const services = [];
|
|
504
|
+
const safeToAddress = new Map();
|
|
505
|
+
const serviceIds = new Set();
|
|
506
|
+
for (const svc of fleet.services) {
|
|
507
|
+
const index = displayFleetServiceIndex(svc);
|
|
508
|
+
const serviceId = svc.service_id ?? null;
|
|
509
|
+
if (serviceId !== null) {
|
|
510
|
+
serviceIds.add(serviceId);
|
|
511
|
+
}
|
|
512
|
+
const safeAddress = svc.safe_address;
|
|
513
|
+
if (!safeAddress) {
|
|
514
|
+
services.push({
|
|
515
|
+
index,
|
|
516
|
+
serviceId,
|
|
517
|
+
safeAddress: null,
|
|
518
|
+
balanceWei: null,
|
|
519
|
+
operatorClaimedWei: null,
|
|
520
|
+
state: 'pending',
|
|
521
|
+
error: null,
|
|
522
|
+
});
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
try {
|
|
526
|
+
const checksum = getAddress(safeAddress);
|
|
527
|
+
const key = checksum.toLowerCase();
|
|
528
|
+
services.push({
|
|
529
|
+
index,
|
|
530
|
+
serviceId,
|
|
531
|
+
safeAddress: checksum,
|
|
532
|
+
balanceWei: null,
|
|
533
|
+
operatorClaimedWei: null,
|
|
534
|
+
state: 'pending',
|
|
535
|
+
error: null,
|
|
536
|
+
});
|
|
537
|
+
safeToAddress.set(key, checksum);
|
|
538
|
+
}
|
|
539
|
+
catch {
|
|
540
|
+
services.push({
|
|
541
|
+
index,
|
|
542
|
+
serviceId,
|
|
543
|
+
safeAddress,
|
|
544
|
+
balanceWei: null,
|
|
545
|
+
operatorClaimedWei: null,
|
|
546
|
+
state: 'error',
|
|
547
|
+
error: TJINN_PUBLIC_INVALID_SAFE_ERROR,
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const safeCount = safeToAddress.size;
|
|
552
|
+
if (safeCount === 0) {
|
|
553
|
+
const invalid = services.find((svc) => svc.state === 'error')?.error;
|
|
554
|
+
return pendingTjinnStatus(tokenAddress, chainId, {
|
|
555
|
+
state: invalid ? 'error' : 'pending',
|
|
556
|
+
safeCount,
|
|
557
|
+
services,
|
|
558
|
+
error: invalid ?? null,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
if (!ethereumRpcUrl) {
|
|
562
|
+
return pendingTjinnStatus(tokenAddress, chainId, { safeCount, services });
|
|
563
|
+
}
|
|
564
|
+
const snapshot = await getCachedTjinnBalances(ethereumRpcUrl, tokenAddress, distributorAddress, chainId, safeToAddress, [...serviceIds]);
|
|
565
|
+
let total = 0n;
|
|
566
|
+
for (const balance of snapshot.balances.values()) {
|
|
567
|
+
total += BigInt(balance);
|
|
568
|
+
}
|
|
569
|
+
const allClaimedReadsAvailable = !!distributorAddress &&
|
|
570
|
+
serviceIds.size > 0 &&
|
|
571
|
+
snapshot.claimedErrors.size === 0 &&
|
|
572
|
+
[...serviceIds].every((serviceId) => snapshot.operatorClaimedByService.has(serviceId));
|
|
573
|
+
let operatorClaimedWei = null;
|
|
574
|
+
if (allClaimedReadsAvailable) {
|
|
575
|
+
let claimedTotal = 0n;
|
|
576
|
+
for (const serviceId of serviceIds) {
|
|
577
|
+
claimedTotal += BigInt(snapshot.operatorClaimedByService.get(serviceId) ?? '0');
|
|
578
|
+
}
|
|
579
|
+
operatorClaimedWei = claimedTotal.toString();
|
|
580
|
+
}
|
|
581
|
+
// 24h-window sum: null when the log query errored or there are no services.
|
|
582
|
+
let operatorMintedLast24hWei = null;
|
|
583
|
+
if (!!distributorAddress &&
|
|
584
|
+
serviceIds.size > 0 &&
|
|
585
|
+
snapshot.claimedLast24hError === null) {
|
|
586
|
+
let last24hTotal = 0n;
|
|
587
|
+
for (const serviceId of serviceIds) {
|
|
588
|
+
last24hTotal += BigInt(snapshot.operatorMintedLast24hByService.get(serviceId) ?? '0');
|
|
589
|
+
}
|
|
590
|
+
operatorMintedLast24hWei = last24hTotal.toString();
|
|
591
|
+
}
|
|
592
|
+
const hasInvalidSafe = services.some((svc) => svc.error === TJINN_PUBLIC_INVALID_SAFE_ERROR);
|
|
593
|
+
const hasReadError = snapshot.errors.size > 0;
|
|
594
|
+
const hasAnyError = hasInvalidSafe || hasReadError;
|
|
595
|
+
const hasAnyBalance = snapshot.balances.size > 0;
|
|
596
|
+
const publicError = hasAnyError
|
|
597
|
+
? tjinnPublicError({ hasInvalidSafe, hasReadError, hasAnyBalance })
|
|
598
|
+
: null;
|
|
599
|
+
return pendingTjinnStatus(tokenAddress, snapshot.chainId, {
|
|
600
|
+
state: hasAnyError ? 'error' : 'ready',
|
|
601
|
+
safeBalanceWei: hasAnyBalance ? total.toString() : null,
|
|
602
|
+
operatorClaimedWei,
|
|
603
|
+
operatorMintedLast24hWei,
|
|
604
|
+
safeCount,
|
|
605
|
+
services: services.map((svc) => {
|
|
606
|
+
const operatorClaimedForService = svc.serviceId !== null
|
|
607
|
+
? (snapshot.operatorClaimedByService.get(svc.serviceId) ?? null)
|
|
608
|
+
: null;
|
|
609
|
+
if (!svc.safeAddress)
|
|
610
|
+
return { ...svc, operatorClaimedWei: operatorClaimedForService };
|
|
611
|
+
if (svc.state === 'error')
|
|
612
|
+
return { ...svc, operatorClaimedWei: operatorClaimedForService };
|
|
613
|
+
const key = svc.safeAddress.toLowerCase();
|
|
614
|
+
const balance = snapshot.balances.get(key);
|
|
615
|
+
if (balance !== undefined) {
|
|
616
|
+
return {
|
|
617
|
+
...svc,
|
|
618
|
+
state: 'ready',
|
|
619
|
+
balanceWei: balance,
|
|
620
|
+
operatorClaimedWei: operatorClaimedForService,
|
|
621
|
+
error: null,
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
return {
|
|
625
|
+
...svc,
|
|
626
|
+
state: 'error',
|
|
627
|
+
operatorClaimedWei: operatorClaimedForService,
|
|
628
|
+
error: snapshot.errors.get(key) ?? TJINN_PUBLIC_READ_ERROR,
|
|
629
|
+
};
|
|
630
|
+
}),
|
|
631
|
+
error: publicError,
|
|
632
|
+
});
|
|
633
|
+
}
|
|
231
634
|
function hasUsefulCacheValues(entry, isAgentRole) {
|
|
232
635
|
if (isAgentRole)
|
|
233
636
|
return entry.nativeWei != null;
|
|
@@ -350,6 +753,7 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
350
753
|
}));
|
|
351
754
|
const lastRewardClaimTickAt = store.getConfigValue('last_reward_claim_tick_at');
|
|
352
755
|
const daily = resolveMasterDailyEstimateWei(status?.masterEthDailyEstimateWei, status?.pollIntervalMs ?? 5000);
|
|
756
|
+
const tjinnIdentity = resolveTjinnIdentity(status);
|
|
353
757
|
// portfolio.v0 lifecycle data — best-effort, never throws
|
|
354
758
|
let portfolioV0;
|
|
355
759
|
try {
|
|
@@ -369,7 +773,8 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
369
773
|
let predictionOperatorError;
|
|
370
774
|
if (status?.config) {
|
|
371
775
|
try {
|
|
372
|
-
const
|
|
776
|
+
const solverNetName = derivePredictionSolverNetName(status.config);
|
|
777
|
+
const raw = await getCachedPredictionOperatorStatus(status.config, status.configPath ?? '<default>', solverNetName);
|
|
373
778
|
predictionOperator = narrowOperatorStatusForApi(raw);
|
|
374
779
|
}
|
|
375
780
|
catch (error) {
|
|
@@ -410,6 +815,9 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
410
815
|
serviceBalances: {},
|
|
411
816
|
pendingByService: {},
|
|
412
817
|
claimedByService: store.getClaimedRewardsByService(),
|
|
818
|
+
tjinnTokenAddress: tjinnIdentity.tokenAddress,
|
|
819
|
+
tjinnChainId: tjinnIdentity.chainId,
|
|
820
|
+
tjinnDistributorAddress: status?.tjinnDistributorAddress,
|
|
413
821
|
};
|
|
414
822
|
if (!status) {
|
|
415
823
|
return { ...baseRaw, hintsScope: 'sqlite_only' };
|
|
@@ -424,6 +832,11 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
424
832
|
testnetMechDeploymentPath: status.testnetMechDeploymentPath,
|
|
425
833
|
testnetStolasDeploymentPath: status.testnetStolasDeploymentPath,
|
|
426
834
|
});
|
|
835
|
+
// Start the Sepolia tJINN read up front so it overlaps the Base-RPC fan-out
|
|
836
|
+
// below for free. `gatherTjinnStatus` is internally error-safe (it catches
|
|
837
|
+
// and returns a snapshot), so the promise never rejects — it is awaited at
|
|
838
|
+
// the point its result is assigned to `raw.tJinn`.
|
|
839
|
+
const tJinnPromise = gatherTjinnStatus(status.network === 'testnet' ? status.config?.ethereumRpcUrl : undefined, tjinnIdentity.tokenAddress, status.tjinnDistributorAddress, tjinnIdentity.chainId, fleet);
|
|
427
840
|
const raw = {
|
|
428
841
|
...baseRaw,
|
|
429
842
|
fleet,
|
|
@@ -503,6 +916,51 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
503
916
|
else {
|
|
504
917
|
raw.pendingRewardsError = pr.error;
|
|
505
918
|
}
|
|
919
|
+
// Eviction state + inactivity — best-effort; never blocks the rest of status assembly.
|
|
920
|
+
try {
|
|
921
|
+
const evictedByServiceIndex = {};
|
|
922
|
+
const inactivityByServiceIndex = {};
|
|
923
|
+
await Promise.all(fleet.services.map(async (svc) => {
|
|
924
|
+
const serviceId = svc.service_id;
|
|
925
|
+
const stakingProxy = svc.staking_address;
|
|
926
|
+
if (!serviceId || !stakingProxy)
|
|
927
|
+
return;
|
|
928
|
+
const di = displayFleetServiceIndex(svc);
|
|
929
|
+
try {
|
|
930
|
+
const [state, info] = await Promise.all([
|
|
931
|
+
client.readContract({
|
|
932
|
+
address: stakingProxy,
|
|
933
|
+
abi: JINN_STAKING_ABI,
|
|
934
|
+
functionName: 'getStakingState',
|
|
935
|
+
args: [BigInt(serviceId)],
|
|
936
|
+
}),
|
|
937
|
+
client.readContract({
|
|
938
|
+
address: stakingProxy,
|
|
939
|
+
abi: JINN_STAKING_ABI,
|
|
940
|
+
functionName: 'getServiceInfo',
|
|
941
|
+
args: [BigInt(serviceId)],
|
|
942
|
+
}).catch(() => null),
|
|
943
|
+
]);
|
|
944
|
+
// getStakingState returns uint8; 2 = Evicted enum value
|
|
945
|
+
evictedByServiceIndex[di] = Number(state) === 2;
|
|
946
|
+
// getServiceInfo returns a struct — inactivity is seconds of accumulated inactivity
|
|
947
|
+
if (info != null) {
|
|
948
|
+
const inactivity = info.inactivity;
|
|
949
|
+
if (typeof inactivity === 'bigint') {
|
|
950
|
+
inactivityByServiceIndex[di] = Number(inactivity);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
catch {
|
|
955
|
+
// Transient RPC errors: skip silently; evicted defaults to false
|
|
956
|
+
}
|
|
957
|
+
}));
|
|
958
|
+
raw.evictedByServiceIndex = evictedByServiceIndex;
|
|
959
|
+
raw.inactivityByServiceIndex = inactivityByServiceIndex;
|
|
960
|
+
}
|
|
961
|
+
catch {
|
|
962
|
+
// Non-fatal: staking state reads should not prevent status from returning
|
|
963
|
+
}
|
|
506
964
|
}
|
|
507
965
|
if (fleet) {
|
|
508
966
|
const per = {};
|
|
@@ -520,10 +978,27 @@ export async function gatherGatheredStatusRaw(store, status) {
|
|
|
520
978
|
raw.serviceBalanceErrors = bal.errorsByDisplay;
|
|
521
979
|
}
|
|
522
980
|
}
|
|
981
|
+
// The tJINN read started up front (overlapping the Base-RPC fan-out). It is
|
|
982
|
+
// awaited here, as late as possible — after ALL other awaited Base-chain work
|
|
983
|
+
// — so the up-to-4s tJINN timeout never serializes the Base fan-out behind it.
|
|
984
|
+
// `gatherTjinnStatus` is internally error-safe, so a plain await is safe.
|
|
985
|
+
raw.tJinn = await tJinnPromise;
|
|
523
986
|
return raw;
|
|
524
987
|
}
|
|
525
988
|
export async function gatherStatusForApi(store, status) {
|
|
526
989
|
const raw = await gatherGatheredStatusRaw(store, status);
|
|
527
|
-
|
|
990
|
+
const body = assembleStatusV1(raw);
|
|
991
|
+
const caps = status?.spendCaps;
|
|
992
|
+
if (caps && Object.keys(caps).length > 0) {
|
|
993
|
+
const now = new Date();
|
|
994
|
+
const resetsAt = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)).toISOString();
|
|
995
|
+
body.spend = {
|
|
996
|
+
credentials: Object.entries(caps).map(([credentialId, capUsd]) => {
|
|
997
|
+
const spentTodayUsd = store.spentTodayMicros(credentialId, now) / 1_000_000;
|
|
998
|
+
return { credentialId, capUsd, spentTodayUsd, paused: isOverSpendCap(spentTodayUsd, capUsd), resetsAt };
|
|
999
|
+
}),
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
return body;
|
|
528
1003
|
}
|
|
529
1004
|
//# sourceMappingURL=gather-status.js.map
|