@jinn-network/client 0.1.5 → 0.1.6-canary.0b4ff7f9
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 +98 -0
- package/dist/adapters/mech/adapter.js +7 -7
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/ipfs-pinfile.d.ts +22 -0
- package/dist/adapters/mech/ipfs-pinfile.js +54 -0
- package/dist/adapters/mech/ipfs-pinfile.js.map +1 -0
- package/dist/adapters/mech/ipfs.d.ts +1 -0
- package/dist/adapters/mech/ipfs.js +24 -1
- package/dist/adapters/mech/ipfs.js.map +1 -1
- package/dist/api/bootstrap-endpoint.js +2 -0
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/discovery-endpoint.d.ts +18 -0
- package/dist/api/discovery-endpoint.js +65 -0
- package/dist/api/discovery-endpoint.js.map +1 -0
- package/dist/api/fleet-build.d.ts +7 -0
- package/dist/api/fleet-build.js +6 -1
- package/dist/api/fleet-build.js.map +1 -1
- package/dist/api/harness-readiness-endpoint.d.ts +13 -0
- package/dist/api/harness-readiness-endpoint.js +15 -0
- package/dist/api/harness-readiness-endpoint.js.map +1 -0
- package/dist/api/hermes-doctor-endpoint.d.ts +26 -0
- package/dist/api/hermes-doctor-endpoint.js +29 -0
- package/dist/api/hermes-doctor-endpoint.js.map +1 -0
- package/dist/api/server.d.ts +21 -0
- package/dist/api/server.js +22 -0
- package/dist/api/server.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/cli/commands/create.d.ts +5 -3
- package/dist/cli/commands/create.js +101 -36
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/solver-nets.d.ts +19 -0
- package/dist/cli/commands/solver-nets.js +140 -2
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/solver-plugins-publish.d.ts +31 -0
- package/dist/cli/commands/solver-plugins-publish.js +169 -0
- package/dist/cli/commands/solver-plugins-publish.js.map +1 -0
- package/dist/cli/commands/solver-plugins-revoke.d.ts +15 -0
- package/dist/cli/commands/solver-plugins-revoke.js +91 -0
- package/dist/cli/commands/solver-plugins-revoke.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +50 -6
- package/dist/cli/commands/solver-plugins.js +205 -68
- package/dist/cli/commands/solver-plugins.js.map +1 -1
- package/dist/config.d.ts +27 -0
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -1
- package/dist/conformance/checks/hash-signature.js +6 -2
- package/dist/conformance/checks/hash-signature.js.map +1 -1
- package/dist/conformance/checks/payload.js +4 -2
- package/dist/conformance/checks/payload.js.map +1 -1
- package/dist/conformance/checks/verdict.d.ts +10 -10
- package/dist/conformance/checks/verdict.js +16 -15
- package/dist/conformance/checks/verdict.js.map +1 -1
- package/dist/conformance/harness.d.ts +1 -1
- package/dist/conformance/harness.js +16 -9
- package/dist/conformance/harness.js.map +1 -1
- package/dist/conformance/types.d.ts +10 -3
- package/dist/conformance/types.js.map +1 -1
- package/dist/corpus/acquire.d.ts +1 -3
- package/dist/corpus/acquire.js.map +1 -1
- package/dist/corpus/envelope-projection.d.ts +1 -1
- package/dist/corpus/envelope-projection.js +14 -7
- package/dist/corpus/envelope-projection.js.map +1 -1
- package/dist/corpus/index.d.ts +2 -1
- package/dist/corpus/index.js.map +1 -1
- package/dist/corpus/prediction-brier-scoreboard-report.js +1 -1
- package/dist/corpus/prediction-brier-scoreboard-report.js.map +1 -1
- package/dist/corpus/prediction-brier-scoreboard.js +3 -1
- package/dist/corpus/prediction-brier-scoreboard.js.map +1 -1
- package/dist/corpus/types.d.ts +2 -2
- package/dist/daemon/daemon.d.ts +17 -1
- package/dist/daemon/daemon.js +15 -0
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/freeze-fence.js +6 -3
- package/dist/daemon/freeze-fence.js.map +1 -1
- package/dist/daemon/readiness-gate.d.ts +30 -0
- package/dist/daemon/readiness-gate.js +31 -0
- package/dist/daemon/readiness-gate.js.map +1 -0
- package/dist/dashboard/assets/{index-D_NMfDfV.css → index-B4sTrvQD.css} +1 -1
- package/dist/dashboard/assets/index-C5j0ZJWS.js +140 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/http.js +121 -0
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.js +11 -0
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +112 -0
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.js +9 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/agent-wallet-binding.d.ts +20 -1
- package/dist/earning/agent-wallet-binding.js +54 -16
- package/dist/earning/agent-wallet-binding.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +55 -0
- package/dist/earning/bootstrap.js +376 -20
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/store.js +48 -1
- package/dist/earning/store.js.map +1 -1
- package/dist/earning/types.d.ts +30 -0
- package/dist/earning/types.js +37 -0
- package/dist/earning/types.js.map +1 -1
- package/dist/erc8004/abis.d.ts +64 -0
- package/dist/erc8004/abis.js +48 -0
- package/dist/erc8004/abis.js.map +1 -1
- package/dist/erc8004/plugin-registry.d.ts +102 -0
- package/dist/erc8004/plugin-registry.js +165 -0
- package/dist/erc8004/plugin-registry.js.map +1 -0
- package/dist/harnesses/engine/engine.js +15 -3
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/envelope-assembly.d.ts +2 -2
- package/dist/harnesses/engine/envelope-assembly.js +4 -2
- package/dist/harnesses/engine/envelope-assembly.js.map +1 -1
- package/dist/harnesses/freeze.d.ts +4 -1
- package/dist/harnesses/freeze.js +12 -2
- package/dist/harnesses/freeze.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction/index.d.ts +4 -1
- package/dist/harnesses/impls/claude-mcp-prediction/index.js +7 -2
- package/dist/harnesses/impls/claude-mcp-prediction/index.js.map +1 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.d.ts +4 -1
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js +7 -2
- package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js.map +1 -1
- package/dist/harnesses/impls/evaluation-context.d.ts +15 -4
- package/dist/harnesses/impls/evaluation-context.js +24 -8
- package/dist/harnesses/impls/evaluation-context.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/adapter.d.ts +34 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js +184 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +18 -0
- package/dist/harnesses/impls/hermes-agent/bootstrap.js +231 -0
- package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +49 -0
- package/dist/harnesses/impls/hermes-agent/config-builder.js +104 -0
- package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +30 -0
- package/dist/harnesses/impls/hermes-agent/harness.js +52 -0
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/index.d.ts +5 -0
- package/dist/harnesses/impls/hermes-agent/index.js +7 -0
- package/dist/harnesses/impls/hermes-agent/index.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/prompt.d.ts +15 -0
- package/dist/harnesses/impls/hermes-agent/prompt.js +37 -0
- package/dist/harnesses/impls/hermes-agent/prompt.js.map +1 -0
- package/dist/harnesses/impls/index.d.ts +6 -0
- package/dist/harnesses/impls/index.js +17 -4
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-code.js +13 -34
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -0
- package/dist/harnesses/impls/learner/adapters/codex-workspace.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/harness.d.ts +9 -3
- package/dist/harnesses/impls/{claude-code-learner → learner}/harness.js +24 -1
- package/dist/harnesses/impls/learner/harness.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/harvest.js +15 -3
- package/dist/harnesses/impls/learner/harvest.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/index.d.ts +5 -5
- package/dist/harnesses/impls/{claude-code-learner → learner}/index.js +4 -4
- package/dist/harnesses/impls/learner/index.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/plugin-path.d.ts +4 -4
- package/dist/harnesses/impls/{claude-code-learner → learner}/plugin-path.js +7 -7
- package/dist/harnesses/impls/learner/plugin-path.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/restoration-patch.js +3 -1
- package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -0
- package/dist/harnesses/impls/learner/test-utils/fake-plugin-outputs.js.map +1 -0
- package/dist/harnesses/impls/learner/test-utils/noop-adapter.js.map +1 -0
- package/dist/harnesses/impls/{claude-code-learner → learner}/types.d.ts +12 -2
- package/dist/harnesses/impls/learner/types.js.map +1 -0
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.js +13 -12
- package/dist/harnesses/impls/portfolio-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js +7 -7
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.d.ts +3 -3
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js +7 -6
- package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js.map +1 -1
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.js +1 -1
- package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -1
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js +11 -10
- package/dist/harnesses/impls/prediction-v0-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/prediction-v1-evaluator/index.js +11 -10
- package/dist/harnesses/impls/prediction-v1-evaluator/index.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +1 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +10 -2
- 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 +24 -5
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +104 -4
- 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 +9 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +25 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
- package/dist/harnesses/names.d.ts +1 -0
- package/dist/harnesses/names.js +3 -0
- package/dist/harnesses/names.js.map +1 -1
- package/dist/harnesses/readiness-registry.d.ts +48 -0
- package/dist/harnesses/readiness-registry.js +136 -0
- package/dist/harnesses/readiness-registry.js.map +1 -0
- package/dist/harnesses/types.d.ts +7 -0
- package/dist/main.d.ts +14 -0
- package/dist/main.js +70 -35
- package/dist/main.js.map +1 -1
- package/dist/mcp/server.js +14 -13
- package/dist/mcp/server.js.map +1 -1
- package/dist/preflight/claude-auth.d.ts +18 -0
- package/dist/preflight/claude-auth.js +38 -0
- package/dist/preflight/claude-auth.js.map +1 -1
- package/dist/scripts/donation-consumption-acceptance.js +1 -1
- package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
- package/dist/scripts/swe-rebench-v2-known-bad.json +12 -0
- package/dist/scripts/swe-rebench-v2-seed-pool.json +26 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.d.ts +52 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js +76 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js.map +1 -0
- package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +38 -12
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +136 -27
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +6 -0
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +1 -0
- package/dist/solver-types/swe-rebench-v2.js +19 -6
- package/dist/solver-types/swe-rebench-v2.js.map +1 -1
- package/dist/store/store.js +12 -4
- package/dist/store/store.js.map +1 -1
- package/dist/templates/plugins/runtime-plugin/.mcp.json.tmpl +8 -0
- package/dist/templates/plugins/runtime-plugin/README.md.tmpl +30 -0
- package/dist/templates/plugins/runtime-plugin/gitignore.tmpl +3 -0
- package/dist/templates/plugins/runtime-plugin/jinn.plugin.json.tmpl +21 -0
- package/dist/templates/plugins/runtime-plugin/mcp/server.mjs.tmpl +33 -0
- package/dist/templates/plugins/runtime-plugin/package.json.tmpl +15 -0
- package/dist/templates/plugins/runtime-plugin/test/plugin.test.ts.tmpl +35 -0
- package/dist/templates/plugins/runtime-plugin/tsconfig.json.tmpl +11 -0
- package/dist/templates/plugins/solver-type-plugin/README.md.tmpl +35 -0
- package/dist/templates/plugins/solver-type-plugin/gitignore.tmpl +3 -0
- package/dist/templates/plugins/solver-type-plugin/jinn.plugin.json.tmpl +11 -0
- package/dist/templates/plugins/solver-type-plugin/package.json.tmpl +15 -0
- package/dist/templates/plugins/solver-type-plugin/skills/example/SKILL.md.tmpl +10 -0
- package/dist/templates/plugins/solver-type-plugin/test/plugin.test.ts.tmpl +25 -0
- package/dist/templates/plugins/solver-type-plugin/tsconfig.json.tmpl +11 -0
- package/dist/types/envelope.d.ts +28 -21
- package/dist/types/envelope.js +8 -3
- package/dist/types/envelope.js.map +1 -1
- package/dist/types/payloads/index.d.ts +2 -2
- package/dist/types/payloads/index.js +13 -12
- package/dist/types/payloads/index.js.map +1 -1
- package/dist/types/payloads/portfolio-v0.d.ts +60 -10
- package/dist/types/payloads/portfolio-v0.js +16 -6
- package/dist/types/payloads/portfolio-v0.js.map +1 -1
- package/dist/types/payloads/prediction-apy-v0.d.ts +52 -10
- package/dist/types/payloads/prediction-apy-v0.js +16 -6
- package/dist/types/payloads/prediction-apy-v0.js.map +1 -1
- package/dist/types/payloads/prediction-v0.d.ts +49 -10
- package/dist/types/payloads/prediction-v0.js +16 -6
- package/dist/types/payloads/prediction-v0.js.map +1 -1
- package/dist/vendor/@jinn-network/sdk/dist/payloads/prediction-v1.d.ts +45 -6
- package/dist/vendor/@jinn-network/sdk/dist/payloads/prediction-v1.js +16 -6
- package/dist/x402/handler.js +51 -20
- package/dist/x402/handler.js.map +1 -1
- package/package.json +8 -3
- package/plugins/swe-rebench-v2-diffmin/.claude-plugin/plugin.json +5 -0
- package/plugins/swe-rebench-v2-diffmin/.mcp.json +8 -0
- package/plugins/swe-rebench-v2-diffmin/README.md +69 -0
- package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +12 -0
- package/plugins/swe-rebench-v2-diffmin/mcp/diff-stats-server.mjs +72 -0
- package/plugins/swe-rebench-v2-diffmin/mcp/diff-stats.mjs +48 -0
- package/plugins/swe-rebench-v2-diffmin/package.json +19 -0
- package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +116 -0
- package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +126 -0
- package/plugins/swe-rebench-v2-diffmin/test/diff-stats.test.ts +62 -0
- package/plugins/swe-rebench-v2-diffmin/test/manifest.test.ts +53 -0
- package/plugins/swe-rebench-v2-diffmin/tsconfig.json +12 -0
- package/plugins/swe-rebench-v2-runtime/README.md +13 -0
- package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +7 -3
- package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +6 -17
- package/templates/plugins/runtime-plugin/.mcp.json.tmpl +8 -0
- package/templates/plugins/runtime-plugin/README.md.tmpl +30 -0
- package/templates/plugins/runtime-plugin/gitignore.tmpl +3 -0
- package/templates/plugins/runtime-plugin/jinn.plugin.json.tmpl +21 -0
- package/templates/plugins/runtime-plugin/mcp/server.mjs.tmpl +33 -0
- package/templates/plugins/runtime-plugin/package.json.tmpl +15 -0
- package/templates/plugins/runtime-plugin/test/plugin.test.ts.tmpl +35 -0
- package/templates/plugins/runtime-plugin/tsconfig.json.tmpl +11 -0
- package/templates/plugins/solver-type-plugin/README.md.tmpl +35 -0
- package/templates/plugins/solver-type-plugin/gitignore.tmpl +3 -0
- package/templates/plugins/solver-type-plugin/jinn.plugin.json.tmpl +11 -0
- package/templates/plugins/solver-type-plugin/package.json.tmpl +15 -0
- package/templates/plugins/solver-type-plugin/skills/example/SKILL.md.tmpl +10 -0
- package/templates/plugins/solver-type-plugin/test/plugin.test.ts.tmpl +25 -0
- package/templates/plugins/solver-type-plugin/tsconfig.json.tmpl +11 -0
- package/dist/dashboard/assets/index-BjtltOGc.js +0 -76
- package/dist/harnesses/impls/claude-code-learner/adapters/claude-code.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/adapters/codex-code.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/adapters/codex-workspace.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/harness.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/harvest.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/index.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/plugin-path.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/restoration-patch.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/test-utils/fake-plugin-outputs.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/test-utils/noop-adapter.js.map +0 -1
- package/dist/harnesses/impls/claude-code-learner/types.js.map +0 -1
- package/dist/preflight/claude-required.d.ts +0 -8
- package/dist/preflight/claude-required.js +0 -17
- package/dist/preflight/claude-required.js.map +0 -1
- /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/claude-code.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/claude-code.js +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-code.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-workspace.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-workspace.js +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/harvest.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/restoration-patch.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/fake-plugin-outputs.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/fake-plugin-outputs.js +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/noop-adapter.d.ts +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/noop-adapter.js +0 -0
- /package/dist/harnesses/impls/{claude-code-learner → learner}/types.js +0 -0
- /package/plugins/{claude-code-learner → learner}/.claude-plugin/plugin.json +0 -0
- /package/plugins/{claude-code-learner → learner}/.codex-plugin/plugin.json +0 -0
- /package/plugins/{claude-code-learner → learner}/AGENTS.md +0 -0
- /package/plugins/{claude-code-learner → learner}/CLAUDE.md +0 -0
- /package/plugins/{claude-code-learner → learner}/README.md +0 -0
- /package/plugins/{claude-code-learner → learner}/hooks/hooks.json +0 -0
- /package/plugins/{claude-code-learner → learner}/hooks/session-start +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/SKILL.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/analyst-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/consolidator-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/explorer-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/planner-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/promoter-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/step-worker-prompt.md +0 -0
- /package/plugins/{claude-code-learner → learner}/skills/learn/strategist-prompt.md +0 -0
|
@@ -45,6 +45,16 @@ export interface FleetBootstrapperOptions {
|
|
|
45
45
|
* testnet funding an explicit operator action.
|
|
46
46
|
*/
|
|
47
47
|
autoTestnetFaucet?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Max in-process attempts for the ERC-8004 Safe-binding step (jinn-mono-h74p).
|
|
50
|
+
* Defaults to 3. Tests pass small values to keep retry budgets predictable.
|
|
51
|
+
*/
|
|
52
|
+
safeBindingMaxAttempts?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Delay between Safe-binding retries (jinn-mono-h74p). Defaults to 3000 ms
|
|
55
|
+
* (~1.5 Base Sepolia blocks). Tests pass 0 to skip the sleep entirely.
|
|
56
|
+
*/
|
|
57
|
+
safeBindingRetryDelayMs?: number;
|
|
48
58
|
}
|
|
49
59
|
export declare class FleetBootstrapper {
|
|
50
60
|
private readonly store;
|
|
@@ -60,6 +70,8 @@ export declare class FleetBootstrapper {
|
|
|
60
70
|
private readonly faucetLoopTimeoutMs;
|
|
61
71
|
private readonly now;
|
|
62
72
|
private readonly autoTestnetFaucet;
|
|
73
|
+
private readonly safeBindingMaxAttempts;
|
|
74
|
+
private readonly safeBindingRetryDelayMs;
|
|
63
75
|
constructor(options?: FleetBootstrapperOptions);
|
|
64
76
|
getStatus(): Promise<FleetState>;
|
|
65
77
|
/**
|
|
@@ -83,6 +95,43 @@ export declare class FleetBootstrapper {
|
|
|
83
95
|
* IdentityCard's "binding pending" chip on Overview.
|
|
84
96
|
*/
|
|
85
97
|
retryAgentBindingFor(serviceIndex: number, password: string): Promise<FleetState>;
|
|
98
|
+
/**
|
|
99
|
+
* Stage 1 — Identity (universal). Walks: wallet → predict Safe (from
|
|
100
|
+
* HD-index-1 agent EOA) → ETH funding gate → deploy Safe → mint agentId
|
|
101
|
+
* + setAgentWallet via ERC-1271. Idempotent and re-entrant. Does NOT
|
|
102
|
+
* touch service rows or staking — those belong to Stage 2.
|
|
103
|
+
*
|
|
104
|
+
* Fleet-level fields written:
|
|
105
|
+
* - fleet_safe_address (after predict)
|
|
106
|
+
* - fleet_agent_id, fleet_identity_registry, fleet_stage='stage1'
|
|
107
|
+
* (after mint + bind)
|
|
108
|
+
*
|
|
109
|
+
* Funding gate: requires ETH on the master EOA only (no OLAS). On testnet,
|
|
110
|
+
* the existing CDP faucet loop drains as usual when `autoTestnetFaucet`
|
|
111
|
+
* is enabled.
|
|
112
|
+
*
|
|
113
|
+
* See docs/superpowers/specs/2026-05-13-plug-in-builder-entry-point-design.md §5.1.
|
|
114
|
+
*/
|
|
115
|
+
ensureStage1(password: string): Promise<FleetBootstrapResult>;
|
|
116
|
+
/**
|
|
117
|
+
* Stage 1 + Stage 2 — full operator bootstrap. Calls `ensureStage1`
|
|
118
|
+
* first; on success, walks Stage 2 per service. Builder-only users who
|
|
119
|
+
* have completed Stage 1 and call this method later begin Stage 2 from
|
|
120
|
+
* `awaiting_stake` for the first service row (created lazily here).
|
|
121
|
+
*
|
|
122
|
+
* Two-Safe topology in standard mode: `fleet_safe_address !==
|
|
123
|
+
* services[0].safe_address` because Stage 2's `distributor.stake()`
|
|
124
|
+
* creates its own Safe. In self-bond mode the two converge (both
|
|
125
|
+
* derived from HD-index-1).
|
|
126
|
+
*
|
|
127
|
+
* See docs/superpowers/specs/2026-05-13-plug-in-builder-entry-point-design.md §5.1.
|
|
128
|
+
*/
|
|
129
|
+
ensureStage1And2(password: string): Promise<FleetBootstrapResult>;
|
|
130
|
+
/**
|
|
131
|
+
* Back-compat alias. Existing call sites in `client/src/cli/commands/bootstrap.ts`
|
|
132
|
+
* and `client/src/cli/commands/fleet-scale.ts` continue to call `bootstrap()`;
|
|
133
|
+
* forwarding to `ensureStage1And2` preserves their semantics without churn.
|
|
134
|
+
*/
|
|
86
135
|
bootstrap(password: string): Promise<FleetBootstrapResult>;
|
|
87
136
|
/**
|
|
88
137
|
* If the master is only slightly above the minimum, warn about gas runway (heuristic days).
|
|
@@ -90,6 +139,12 @@ export declare class FleetBootstrapper {
|
|
|
90
139
|
private warnMasterEthRunway;
|
|
91
140
|
private ensureMasterWallet;
|
|
92
141
|
private loadExistingMnemonic;
|
|
142
|
+
/** Deterministic Safe predict from the HD-index-1 agent EOA. */
|
|
143
|
+
private stepFleetSafePredict;
|
|
144
|
+
/** Deploy the predicted fleet Safe. Funds the agent EOA from master if needed. */
|
|
145
|
+
private stepFleetSafeDeploy;
|
|
146
|
+
/** Mint the fleet agentId + bind Safe via setAgentWallet (ERC-1271). */
|
|
147
|
+
private stepFleetIdentityRegister;
|
|
93
148
|
private bootstrapService;
|
|
94
149
|
/**
|
|
95
150
|
* Compare persisted per-service state to registry/staking/Safe bytecode and patch store
|
|
@@ -15,7 +15,7 @@ import { formatBootstrapOperatorMessage, isJinnDebug, } from '../operator-errors
|
|
|
15
15
|
import { reconcileServiceAgainstChain, } from './reconcile.js';
|
|
16
16
|
import { previousSafeBeingAbandoned, sweepOrphanedServiceFunds, } from './orphan-sweep.js';
|
|
17
17
|
import { DEFAULT_FAUCET_LOOP_TIMEOUT_MS, computeFaucetDripCap, requestTestnetFunding, } from './faucet.js';
|
|
18
|
-
import { flattenErrorMessage, viemSendTransactionWithRetry, waitForTransactionReceiptWithRetry, } from '../tx-retry.js';
|
|
18
|
+
import { flattenErrorMessage, sleep, viemSendTransactionWithRetry, waitForTransactionReceiptWithRetry, } from '../tx-retry.js';
|
|
19
19
|
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';
|
|
@@ -29,6 +29,28 @@ const STANDARD_MASTER_BOOTSTRAP_MULTIPLIER = 2n;
|
|
|
29
29
|
const DEFAULT_MASTER_ETH_DAILY_WEI = 1000000000000000n;
|
|
30
30
|
/** Warn when ETH above the minimum would last fewer than this many days at the daily estimate. */
|
|
31
31
|
const MASTER_ETH_RUNWAY_WARN_DAYS = 7n;
|
|
32
|
+
/**
|
|
33
|
+
* Safe → ERC-8004 agent NFT binding retry (jinn-mono-h74p).
|
|
34
|
+
*
|
|
35
|
+
* Empirical observation against fresh Base Sepolia 1/1 Safes: the first
|
|
36
|
+
* `IdentityRegistry.setAgentWallet` attempt reverts with a generic
|
|
37
|
+
* "Execution reverted for an unknown reason" — but the same Safe + same
|
|
38
|
+
* agentId + a freshly-signed message a few seconds later succeeds. The
|
|
39
|
+
* race window is likely freshly-deployed-Safe state lag on the public RPC
|
|
40
|
+
* (the simulator can't read the Safe's storage yet in the same block /
|
|
41
|
+
* eventual-consistency between sibling RPC nodes). A short bounded retry
|
|
42
|
+
* makes the operator-visible behaviour deterministic instead of relying on
|
|
43
|
+
* the "daemon exits → operator restarts → resume at safe_binding_pending"
|
|
44
|
+
* accidental safety net (which goes away when jinn-mono-vh74.2 removes the
|
|
45
|
+
* Claude-auth post-bootstrap exit gate).
|
|
46
|
+
*
|
|
47
|
+
* Defaults: 3 attempts × 3 s delay = at most ~6 s of in-process retry budget
|
|
48
|
+
* before falling through to the existing `safe_binding_pending` persisted
|
|
49
|
+
* state. Real (non-transient) failures still surface — just with a slightly
|
|
50
|
+
* higher latency tax for the diagnostic.
|
|
51
|
+
*/
|
|
52
|
+
const DEFAULT_SAFE_BINDING_MAX_ATTEMPTS = 3;
|
|
53
|
+
const DEFAULT_SAFE_BINDING_RETRY_DELAY_MS = 3_000;
|
|
32
54
|
export class FleetBootstrapper {
|
|
33
55
|
store;
|
|
34
56
|
config;
|
|
@@ -43,6 +65,8 @@ export class FleetBootstrapper {
|
|
|
43
65
|
faucetLoopTimeoutMs;
|
|
44
66
|
now;
|
|
45
67
|
autoTestnetFaucet;
|
|
68
|
+
safeBindingMaxAttempts;
|
|
69
|
+
safeBindingRetryDelayMs;
|
|
46
70
|
constructor(options = {}) {
|
|
47
71
|
this.store = new FleetStateStore(options.earningDir);
|
|
48
72
|
this.chain = options.chain ?? 'base';
|
|
@@ -55,6 +79,10 @@ export class FleetBootstrapper {
|
|
|
55
79
|
this.now = options.now ?? Date.now;
|
|
56
80
|
this.autoTestnetFaucet =
|
|
57
81
|
options.autoTestnetFaucet ?? this.env['JINN_DISABLE_TESTNET_FAUCET'] !== '1';
|
|
82
|
+
this.safeBindingMaxAttempts =
|
|
83
|
+
options.safeBindingMaxAttempts ?? DEFAULT_SAFE_BINDING_MAX_ATTEMPTS;
|
|
84
|
+
this.safeBindingRetryDelayMs =
|
|
85
|
+
options.safeBindingRetryDelayMs ?? DEFAULT_SAFE_BINDING_RETRY_DELAY_MS;
|
|
58
86
|
const dailyOpt = options.masterEthDailyEstimateWei;
|
|
59
87
|
this.masterEthDailyEstimateWei =
|
|
60
88
|
dailyOpt !== undefined
|
|
@@ -112,16 +140,145 @@ export class FleetBootstrapper {
|
|
|
112
140
|
const mnemonic = await this.loadExistingMnemonic(state, password);
|
|
113
141
|
return this.stepRegisterAgent(state, mnemonic, serviceIndex);
|
|
114
142
|
}
|
|
115
|
-
|
|
116
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Stage 1 — Identity (universal). Walks: wallet → predict Safe (from
|
|
145
|
+
* HD-index-1 agent EOA) → ETH funding gate → deploy Safe → mint agentId
|
|
146
|
+
* + setAgentWallet via ERC-1271. Idempotent and re-entrant. Does NOT
|
|
147
|
+
* touch service rows or staking — those belong to Stage 2.
|
|
148
|
+
*
|
|
149
|
+
* Fleet-level fields written:
|
|
150
|
+
* - fleet_safe_address (after predict)
|
|
151
|
+
* - fleet_agent_id, fleet_identity_registry, fleet_stage='stage1'
|
|
152
|
+
* (after mint + bind)
|
|
153
|
+
*
|
|
154
|
+
* Funding gate: requires ETH on the master EOA only (no OLAS). On testnet,
|
|
155
|
+
* the existing CDP faucet loop drains as usual when `autoTestnetFaucet`
|
|
156
|
+
* is enabled.
|
|
157
|
+
*
|
|
158
|
+
* See docs/superpowers/specs/2026-05-13-plug-in-builder-entry-point-design.md §5.1.
|
|
159
|
+
*/
|
|
160
|
+
async ensureStage1(password) {
|
|
161
|
+
// Legacy keystore migration (same as bootstrap()).
|
|
117
162
|
if (!this.store.hasMnemonicKeystore() && this.store.hasLegacyKeystore()) {
|
|
118
163
|
await this.store.migrateLegacyFiles();
|
|
119
164
|
}
|
|
120
165
|
let state = await this.store.load(this.chain);
|
|
166
|
+
// Short-circuit if Stage 1 is already complete (or beyond).
|
|
167
|
+
if (state.fleet_stage === 'stage1' || state.fleet_stage === 'stage1_and_2') {
|
|
168
|
+
// Even when stage marker says complete, fleet identity may be empty for
|
|
169
|
+
// pre-j07 operators (`stage1_and_2` is set by the migration for
|
|
170
|
+
// services-complete-but-no-agent_id operators). In that case we leave
|
|
171
|
+
// Stage 1 alone — the legacy backfill in main.ts handles those rows
|
|
172
|
+
// and a future ensureStage1 call after backfill will promote.
|
|
173
|
+
return {
|
|
174
|
+
ok: true,
|
|
175
|
+
fleet_state: state,
|
|
176
|
+
message: state.fleet_agent_id !== null
|
|
177
|
+
? `Stage 1 already complete (fleet_agent_id=${state.fleet_agent_id}, fleet_safe=${state.fleet_safe_address}).`
|
|
178
|
+
: 'Stage 1 marker present but fleet identity is empty (legacy operator). Skipping.',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
121
181
|
try {
|
|
122
|
-
// Phase 1: Master wallet setup
|
|
123
182
|
state = await this.ensureMasterWallet(state, password);
|
|
124
|
-
//
|
|
183
|
+
// Stage 1 funding gate — ETH only (no OLAS). Self-bond Stage 1 needs:
|
|
184
|
+
// master ETH for the agent-funding transfer + agent ETH for Safe deploy
|
|
185
|
+
// + Safe deploy gas + ERC-8004 register + setAgentWallet (two agent EOA
|
|
186
|
+
// txs through the IdentityRegistry contract). 0.005 ETH is the
|
|
187
|
+
// configured `minEoaGasEth` floor; bump by 2x for safety.
|
|
188
|
+
const requiredMasterEth = this.config.minEoaGasEth * STANDARD_MASTER_BOOTSTRAP_MULTIPLIER;
|
|
189
|
+
const masterAddress = state.master_address;
|
|
190
|
+
const masterBalance = await this.publicClient.getBalance({
|
|
191
|
+
address: masterAddress,
|
|
192
|
+
});
|
|
193
|
+
if (masterBalance < requiredMasterEth) {
|
|
194
|
+
const shortfall = requiredMasterEth - masterBalance;
|
|
195
|
+
return {
|
|
196
|
+
ok: false,
|
|
197
|
+
fleet_state: state,
|
|
198
|
+
message: `Your master wallet needs more ETH (currently ${formatEther(masterBalance)} ETH, need ${formatEther(shortfall)} ETH more) to complete Stage 1. Please send ETH to: ${masterAddress}`,
|
|
199
|
+
funding: {
|
|
200
|
+
master_address: masterAddress,
|
|
201
|
+
eth_required: shortfall.toString(),
|
|
202
|
+
eth_balance: masterBalance.toString(),
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const mnemonic = await this.loadExistingMnemonic(state, password);
|
|
207
|
+
// Step 1: predict fleet Safe from HD-index-1 agent EOA.
|
|
208
|
+
if (!state.fleet_safe_address) {
|
|
209
|
+
state = await this.stepFleetSafePredict(state, mnemonic);
|
|
210
|
+
}
|
|
211
|
+
// Step 2: deploy fleet Safe if bytecode absent.
|
|
212
|
+
const safeCode = await this.publicClient.getCode({
|
|
213
|
+
address: getAddress(state.fleet_safe_address),
|
|
214
|
+
});
|
|
215
|
+
if (safeCode === undefined || safeCode === '0x') {
|
|
216
|
+
state = await this.stepFleetSafeDeploy(state, mnemonic);
|
|
217
|
+
}
|
|
218
|
+
// Step 3: mint agentId + bind Safe via setAgentWallet.
|
|
219
|
+
if (!state.fleet_agent_id) {
|
|
220
|
+
state = await this.stepFleetIdentityRegister(state, mnemonic);
|
|
221
|
+
}
|
|
222
|
+
else if (state.fleet_stage !== 'stage1' && state.fleet_stage !== 'stage1_and_2') {
|
|
223
|
+
// Identity was minted but stage marker is stale; advance it.
|
|
224
|
+
state = await this.store.patchFleet({ fleet_stage: 'stage1' });
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
ok: true,
|
|
228
|
+
fleet_state: state,
|
|
229
|
+
message: `Stage 1 complete. fleet_agent_id=${state.fleet_agent_id}, fleet_safe=${state.fleet_safe_address}.`,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
const { summary, hint, rawMessage } = formatBootstrapOperatorMessage(error);
|
|
234
|
+
const userMessage = hint !== undefined ? `${summary}\nHint: ${hint}` : summary;
|
|
235
|
+
if (this.debug) {
|
|
236
|
+
console.error(`[fleet-bootstrap] ensureStage1 failed:`, error);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.error(`[fleet-bootstrap] ${summary}`);
|
|
240
|
+
if (hint !== undefined)
|
|
241
|
+
console.error(`Hint: ${hint}`);
|
|
242
|
+
if (rawMessage && rawMessage !== summary) {
|
|
243
|
+
console.error(`[fleet-bootstrap] raw: ${rawMessage.split('\n')[0]}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
ok: false,
|
|
248
|
+
fleet_state: state,
|
|
249
|
+
message: userMessage,
|
|
250
|
+
rawErrorMessage: rawMessage,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Stage 1 + Stage 2 — full operator bootstrap. Calls `ensureStage1`
|
|
256
|
+
* first; on success, walks Stage 2 per service. Builder-only users who
|
|
257
|
+
* have completed Stage 1 and call this method later begin Stage 2 from
|
|
258
|
+
* `awaiting_stake` for the first service row (created lazily here).
|
|
259
|
+
*
|
|
260
|
+
* Two-Safe topology in standard mode: `fleet_safe_address !==
|
|
261
|
+
* services[0].safe_address` because Stage 2's `distributor.stake()`
|
|
262
|
+
* creates its own Safe. In self-bond mode the two converge (both
|
|
263
|
+
* derived from HD-index-1).
|
|
264
|
+
*
|
|
265
|
+
* See docs/superpowers/specs/2026-05-13-plug-in-builder-entry-point-design.md §5.1.
|
|
266
|
+
*/
|
|
267
|
+
async ensureStage1And2(password) {
|
|
268
|
+
// Stage 1 first — establishes fleet identity. Short-circuits if already done.
|
|
269
|
+
const stage1Result = await this.ensureStage1(password);
|
|
270
|
+
if (!stage1Result.ok) {
|
|
271
|
+
return stage1Result;
|
|
272
|
+
}
|
|
273
|
+
// Original bootstrap body — copied verbatim from the previous bootstrap()
|
|
274
|
+
// method, with two changes:
|
|
275
|
+
// (a) the legacy-keystore migration and master-wallet-ensure are no-ops
|
|
276
|
+
// because ensureStage1 already ran them.
|
|
277
|
+
// (b) at the end, if any service reached `complete`/`safe_binding_pending`
|
|
278
|
+
// we advance `fleet_stage` to `'stage1_and_2'`.
|
|
279
|
+
let state = stage1Result.fleet_state;
|
|
280
|
+
try {
|
|
281
|
+
// Phase 1b: Check master funding for the full operator path.
|
|
125
282
|
const masterAddress = state.master_address;
|
|
126
283
|
let masterBalance = await this.publicClient.getBalance({ address: masterAddress });
|
|
127
284
|
// Self-bond mode needs much more ETH than standard mode because the master
|
|
@@ -291,6 +448,11 @@ export class FleetBootstrapper {
|
|
|
291
448
|
const nextIndex = nextFleetServiceIndex(state.services);
|
|
292
449
|
state = await this.bootstrapService(state, mnemonic, nextIndex);
|
|
293
450
|
}
|
|
451
|
+
// Advance fleet_stage to 'stage1_and_2' if any service is operational.
|
|
452
|
+
const anyOperationalAfter = state.services.some(s => isOperationalServiceStep(s.step));
|
|
453
|
+
if (anyOperationalAfter && state.fleet_stage !== 'stage1_and_2') {
|
|
454
|
+
state = await this.store.patchFleet({ fleet_stage: 'stage1_and_2' });
|
|
455
|
+
}
|
|
294
456
|
return {
|
|
295
457
|
ok: true,
|
|
296
458
|
fleet_state: state,
|
|
@@ -322,6 +484,14 @@ export class FleetBootstrapper {
|
|
|
322
484
|
};
|
|
323
485
|
}
|
|
324
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Back-compat alias. Existing call sites in `client/src/cli/commands/bootstrap.ts`
|
|
489
|
+
* and `client/src/cli/commands/fleet-scale.ts` continue to call `bootstrap()`;
|
|
490
|
+
* forwarding to `ensureStage1And2` preserves their semantics without churn.
|
|
491
|
+
*/
|
|
492
|
+
async bootstrap(password) {
|
|
493
|
+
return this.ensureStage1And2(password);
|
|
494
|
+
}
|
|
325
495
|
/**
|
|
326
496
|
* If the master is only slightly above the minimum, warn about gas runway (heuristic days).
|
|
327
497
|
*/
|
|
@@ -382,6 +552,128 @@ export class FleetBootstrapper {
|
|
|
382
552
|
return freshMnemonic;
|
|
383
553
|
}
|
|
384
554
|
}
|
|
555
|
+
// ── Stage 1: fleet-level identity steps (nghf) ────────────────────────
|
|
556
|
+
/** Deterministic Safe predict from the HD-index-1 agent EOA. */
|
|
557
|
+
async stepFleetSafePredict(state, mnemonic) {
|
|
558
|
+
const agentAddress = deriveAgentAddress(mnemonic, 1);
|
|
559
|
+
const agentKey = walletPrivateKeyAtIndex(mnemonic, 1);
|
|
560
|
+
console.error(`[fleet-bootstrap] Stage 1: predicting fleet Safe (owner=${agentAddress})`);
|
|
561
|
+
const { address } = await initPredictedSafe({
|
|
562
|
+
rpcUrl: this.config.rpcUrl,
|
|
563
|
+
signerKey: agentKey,
|
|
564
|
+
owners: [agentAddress],
|
|
565
|
+
threshold: 1,
|
|
566
|
+
});
|
|
567
|
+
void state;
|
|
568
|
+
return this.store.patchFleet({ fleet_safe_address: getAddress(address) });
|
|
569
|
+
}
|
|
570
|
+
/** Deploy the predicted fleet Safe. Funds the agent EOA from master if needed. */
|
|
571
|
+
async stepFleetSafeDeploy(state, mnemonic) {
|
|
572
|
+
const agentAddress = deriveAgentAddress(mnemonic, 1);
|
|
573
|
+
const agentKey = walletPrivateKeyAtIndex(mnemonic, 1);
|
|
574
|
+
const agentSigner = deriveAgentSigner(mnemonic, 1);
|
|
575
|
+
const fleetSafe = state.fleet_safe_address;
|
|
576
|
+
// Fund agent EOA so it can pay for Safe deploy + setAgentWallet gas.
|
|
577
|
+
// 0.01 ETH covers Safe deploy (~250k gas) + register (~80k) + setAgentWallet
|
|
578
|
+
// (~200k) at testnet gas prices comfortably.
|
|
579
|
+
const STAGE1_AGENT_ETH = 10000000000000000n; // 0.01 ETH
|
|
580
|
+
const masterAccount = deriveMasterSigner(mnemonic);
|
|
581
|
+
const masterWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, masterAccount);
|
|
582
|
+
const agentBalance = await this.publicClient.getBalance({
|
|
583
|
+
address: getAddress(agentAddress),
|
|
584
|
+
});
|
|
585
|
+
if (agentBalance < STAGE1_AGENT_ETH) {
|
|
586
|
+
const fundAmount = STAGE1_AGENT_ETH - agentBalance;
|
|
587
|
+
console.error(`[fleet-bootstrap] Stage 1: funding fleet agent EOA with ${fundAmount} wei from master`);
|
|
588
|
+
const fundHash = await viemSendTransactionWithRetry(masterWallet, this.publicClient, {
|
|
589
|
+
account: masterAccount,
|
|
590
|
+
to: addr(agentAddress),
|
|
591
|
+
value: fundAmount,
|
|
592
|
+
});
|
|
593
|
+
await waitForTransactionReceiptWithRetry(this.publicClient, fundHash);
|
|
594
|
+
}
|
|
595
|
+
console.error(`[fleet-bootstrap] Stage 1: deploying fleet Safe at ${fleetSafe}`);
|
|
596
|
+
const { safe } = await initPredictedSafe({
|
|
597
|
+
rpcUrl: this.config.rpcUrl,
|
|
598
|
+
signerKey: agentKey,
|
|
599
|
+
owners: [agentAddress],
|
|
600
|
+
threshold: 1,
|
|
601
|
+
});
|
|
602
|
+
const deployTx = await safe.createSafeDeploymentTransaction();
|
|
603
|
+
const agentWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, agentSigner);
|
|
604
|
+
const deployHash = await viemSendTransactionWithRetry(agentWallet, this.publicClient, {
|
|
605
|
+
account: agentSigner,
|
|
606
|
+
to: deployTx.to,
|
|
607
|
+
value: BigInt(deployTx.value),
|
|
608
|
+
data: deployTx.data,
|
|
609
|
+
});
|
|
610
|
+
const receipt = await waitForTransactionReceiptWithRetry(this.publicClient, deployHash);
|
|
611
|
+
if (receipt.status !== 'success') {
|
|
612
|
+
throw new Error(`Fleet Safe deployment tx failed: ${deployHash}`);
|
|
613
|
+
}
|
|
614
|
+
const deployedCode = await this.publicClient.getCode({
|
|
615
|
+
address: getAddress(fleetSafe),
|
|
616
|
+
});
|
|
617
|
+
if (deployedCode === undefined || deployedCode === '0x') {
|
|
618
|
+
throw new Error(`Fleet Safe deployment succeeded but no code at ${fleetSafe}`);
|
|
619
|
+
}
|
|
620
|
+
console.error(`[fleet-bootstrap] Stage 1: fleet Safe deployed (tx=${deployHash})`);
|
|
621
|
+
return this.store.load(this.chain);
|
|
622
|
+
}
|
|
623
|
+
/** Mint the fleet agentId + bind Safe via setAgentWallet (ERC-1271). */
|
|
624
|
+
async stepFleetIdentityRegister(state, mnemonic) {
|
|
625
|
+
const identityRegistry = this.config.identityRegistry ?? IDENTITY_REGISTRY_ADDRESSES[this.config.chainId];
|
|
626
|
+
if (!identityRegistry) {
|
|
627
|
+
throw new Error(`IdentityRegistry address not configured for chainId=${this.config.chainId}.`);
|
|
628
|
+
}
|
|
629
|
+
const fleetSafe = state.fleet_safe_address;
|
|
630
|
+
const agentSigner = deriveAgentSigner(mnemonic, 1);
|
|
631
|
+
const agentWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, agentSigner);
|
|
632
|
+
// Mint agentId — empty agent URI for v0 (matches stepRegisterAgent §6.1 in spec).
|
|
633
|
+
const registerData = encodeFunctionData({
|
|
634
|
+
abi: IDENTITY_REGISTRY_ABI,
|
|
635
|
+
functionName: 'register',
|
|
636
|
+
args: [''],
|
|
637
|
+
});
|
|
638
|
+
console.error(`[fleet-bootstrap] Stage 1: minting fleet agentId ` +
|
|
639
|
+
`(IdentityRegistry=${identityRegistry}, agentEOA=${agentSigner.address})`);
|
|
640
|
+
const mintTxHash = await viemSendTransactionWithRetry(agentWallet, this.publicClient, {
|
|
641
|
+
account: agentSigner,
|
|
642
|
+
to: addr(identityRegistry),
|
|
643
|
+
data: registerData,
|
|
644
|
+
});
|
|
645
|
+
const mintReceipt = await waitForTransactionReceiptWithRetry(this.publicClient, mintTxHash);
|
|
646
|
+
if (mintReceipt.status !== 'success') {
|
|
647
|
+
throw new Error(`Fleet IdentityRegistry.register() failed: ${mintTxHash}`);
|
|
648
|
+
}
|
|
649
|
+
const fleetAgentId = this.parseAgentIdFromReceipt(mintReceipt, identityRegistry);
|
|
650
|
+
if (fleetAgentId === null) {
|
|
651
|
+
throw new Error(`Fleet IdentityRegistry.register() succeeded but Registered event missing (tx=${mintTxHash})`);
|
|
652
|
+
}
|
|
653
|
+
// Persist agentId IMMEDIATELY so a crash between mint and bind doesn't lose it.
|
|
654
|
+
await this.store.patchFleet({
|
|
655
|
+
fleet_agent_id: fleetAgentId,
|
|
656
|
+
fleet_identity_registry: getAddress(identityRegistry),
|
|
657
|
+
});
|
|
658
|
+
// Bind the Safe via setAgentWallet (ERC-1271).
|
|
659
|
+
console.error(`[fleet-bootstrap] Stage 1: binding fleet Safe ${fleetSafe} to agentId=${fleetAgentId}`);
|
|
660
|
+
const bindResult = await bindAgentWalletToSafe({
|
|
661
|
+
identityRegistryAddress: addr(identityRegistry),
|
|
662
|
+
agentId: BigInt(fleetAgentId),
|
|
663
|
+
safeAddress: addr(fleetSafe),
|
|
664
|
+
agentEoaAccount: agentSigner,
|
|
665
|
+
agentEoaWalletClient: agentWallet,
|
|
666
|
+
publicClient: this.publicClient,
|
|
667
|
+
chainId: this.config.chainId,
|
|
668
|
+
});
|
|
669
|
+
if (!bindResult.ok) {
|
|
670
|
+
const bindErr = bindResult.error;
|
|
671
|
+
throw new Error(`Fleet setAgentWallet failed: ${bindErr.shortMessage}` +
|
|
672
|
+
(bindErr.revertReason ? ` (revert: ${bindErr.revertReason})` : ''));
|
|
673
|
+
}
|
|
674
|
+
console.error(`[fleet-bootstrap] Stage 1: setAgentWallet succeeded (tx=${bindResult.txHash})`);
|
|
675
|
+
return this.store.patchFleet({ fleet_stage: 'stage1' });
|
|
676
|
+
}
|
|
385
677
|
// ── Phase 2: Per-service bootstrap ───────────────────────────────────
|
|
386
678
|
async bootstrapService(state, mnemonic, index) {
|
|
387
679
|
const agentAddress = deriveAgentAddress(mnemonic, index);
|
|
@@ -837,6 +1129,7 @@ export class FleetBootstrapper {
|
|
|
837
1129
|
let svc = (await this.store.load(this.chain)).services.find(s => s.index === index);
|
|
838
1130
|
if (!svc)
|
|
839
1131
|
throw new Error(`Service ${index} not found in state`);
|
|
1132
|
+
const fleetSnapshot = await this.store.load(this.chain);
|
|
840
1133
|
const identityRegistry = this.config.identityRegistry
|
|
841
1134
|
?? IDENTITY_REGISTRY_ADDRESSES[this.config.chainId];
|
|
842
1135
|
if (!identityRegistry) {
|
|
@@ -845,7 +1138,7 @@ export class FleetBootstrapper {
|
|
|
845
1138
|
}
|
|
846
1139
|
const agentSigner = deriveAgentSigner(mnemonic, index);
|
|
847
1140
|
const agentWallet = createJinnWalletClient(this.config.rpcUrl, this.chain, agentSigner);
|
|
848
|
-
// ── Sub-step A: mint NFT (skip if agent_id is already set).
|
|
1141
|
+
// ── Sub-step A: mint NFT (skip if agent_id is already set OR fleet identity exists). ─
|
|
849
1142
|
let agentId;
|
|
850
1143
|
if (svc.agent_id) {
|
|
851
1144
|
console.error(`[fleet-bootstrap] Service ${index}: ERC-8004 agent already registered ` +
|
|
@@ -856,6 +1149,22 @@ export class FleetBootstrapper {
|
|
|
856
1149
|
step: svc.step === 'safe_binding_pending' ? 'safe_binding_pending' : 'agent_registered',
|
|
857
1150
|
});
|
|
858
1151
|
}
|
|
1152
|
+
else if (fleetSnapshot.fleet_agent_id) {
|
|
1153
|
+
// nghf: reuse the fleet-level agentId minted by ensureStage1 instead of
|
|
1154
|
+
// minting a second one. This collapses the "one agentId per user"
|
|
1155
|
+
// invariant in spec §5.1 for the standard-mode two-Safe topology.
|
|
1156
|
+
console.error(`[fleet-bootstrap] Service ${index}: reusing fleet agentId=${fleetSnapshot.fleet_agent_id} ` +
|
|
1157
|
+
`(no second mint needed).`);
|
|
1158
|
+
agentId = fleetSnapshot.fleet_agent_id;
|
|
1159
|
+
svc = await this.firstServiceUpdate(index, {
|
|
1160
|
+
agent_id: fleetSnapshot.fleet_agent_id,
|
|
1161
|
+
agent_uri: '',
|
|
1162
|
+
identity_registry_address: fleetSnapshot.fleet_identity_registry ?? getAddress(identityRegistry),
|
|
1163
|
+
agent_registered_tx: null,
|
|
1164
|
+
step: 'agent_registered',
|
|
1165
|
+
error: null,
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
859
1168
|
else {
|
|
860
1169
|
// v0: empty agentURI. The richer agent card (per §6 of the spec) is
|
|
861
1170
|
// future work — operators may later call `setAgentURI`.
|
|
@@ -924,32 +1233,79 @@ export class FleetBootstrapper {
|
|
|
924
1233
|
step: 'safe_binding_pending',
|
|
925
1234
|
error: null,
|
|
926
1235
|
});
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1236
|
+
// Combined h74p (retry-on-transient-throw) + hjex.4 (Result-typed
|
|
1237
|
+
// structured errors) policy:
|
|
1238
|
+
// - bindAgentWalletToSafe now returns a BindAgentWalletOutcome
|
|
1239
|
+
// (ok=true | ok=false with structured SafeBindingError).
|
|
1240
|
+
// - A returned Result.ok=false is a deterministic contract revert —
|
|
1241
|
+
// don't retry; record the structured diagnostic.
|
|
1242
|
+
// - A *thrown* exception is the freshly-deployed-Safe RPC race
|
|
1243
|
+
// window h74p targets — retry up to safeBindingMaxAttempts with a
|
|
1244
|
+
// small delay; if every attempt throws we fall through to a plain
|
|
1245
|
+
// reason log (no structured fields available).
|
|
1246
|
+
const maxAttempts = Math.max(1, this.safeBindingMaxAttempts);
|
|
1247
|
+
let bindResult;
|
|
1248
|
+
let lastBindError;
|
|
1249
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1250
|
+
try {
|
|
1251
|
+
bindResult = await bindAgentWalletToSafe({
|
|
1252
|
+
identityRegistryAddress: addr(identityRegistry),
|
|
1253
|
+
agentId: BigInt(agentId),
|
|
1254
|
+
safeAddress: addr(safeAddress),
|
|
1255
|
+
agentEoaAccount: agentSigner,
|
|
1256
|
+
agentEoaWalletClient: agentWallet,
|
|
1257
|
+
publicClient: this.publicClient,
|
|
1258
|
+
chainId: this.config.chainId,
|
|
1259
|
+
});
|
|
1260
|
+
break;
|
|
1261
|
+
}
|
|
1262
|
+
catch (err) {
|
|
1263
|
+
lastBindError = err;
|
|
1264
|
+
if (attempt < maxAttempts) {
|
|
1265
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1266
|
+
console.error(`[fleet-bootstrap] Service ${index}: setAgentWallet attempt ` +
|
|
1267
|
+
`${attempt}/${maxAttempts} failed (${reason}); retrying in ` +
|
|
1268
|
+
`${this.safeBindingRetryDelayMs}ms...`);
|
|
1269
|
+
if (this.safeBindingRetryDelayMs > 0) {
|
|
1270
|
+
await sleep(this.safeBindingRetryDelayMs);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
if (bindResult?.ok === true) {
|
|
937
1276
|
console.error(`[fleet-bootstrap] Service ${index}: setAgentWallet succeeded ` +
|
|
938
|
-
`(tx=${
|
|
1277
|
+
`(tx=${bindResult.txHash}, safe=${safeAddress}).`);
|
|
939
1278
|
svc = await this.firstServiceUpdate(index, {
|
|
940
1279
|
safe_bound_to_agent: true,
|
|
941
1280
|
step: 'complete',
|
|
942
1281
|
error: null,
|
|
1282
|
+
error_revert_reason: null,
|
|
1283
|
+
error_short_message: null,
|
|
943
1284
|
});
|
|
944
1285
|
}
|
|
945
|
-
|
|
946
|
-
const
|
|
1286
|
+
else if (bindResult && !bindResult.ok) {
|
|
1287
|
+
const bindErr = bindResult.error;
|
|
947
1288
|
console.error(`[fleet-bootstrap] Service ${index}: setAgentWallet failed; continuing with ` +
|
|
948
|
-
`safe_bound_to_agent=false (${
|
|
1289
|
+
`safe_bound_to_agent=false (${bindErr.shortMessage}` +
|
|
1290
|
+
`${bindErr.revertReason ? `, revert: ${bindErr.revertReason}` : ''}).`);
|
|
1291
|
+
svc = await this.firstServiceUpdate(index, {
|
|
1292
|
+
safe_bound_to_agent: false,
|
|
1293
|
+
step: 'safe_binding_pending',
|
|
1294
|
+
error: `safe_binding_failed: ${bindErr.shortMessage}`,
|
|
1295
|
+
error_revert_reason: bindErr.revertReason,
|
|
1296
|
+
error_short_message: bindErr.shortMessage,
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
else {
|
|
1300
|
+
const reason = lastBindError instanceof Error ? lastBindError.message : String(lastBindError);
|
|
1301
|
+
console.error(`[fleet-bootstrap] Service ${index}: setAgentWallet failed after ` +
|
|
1302
|
+
`${maxAttempts} attempts; continuing with safe_bound_to_agent=false (${reason}).`);
|
|
949
1303
|
svc = await this.firstServiceUpdate(index, {
|
|
950
1304
|
safe_bound_to_agent: false,
|
|
951
1305
|
step: 'safe_binding_pending',
|
|
952
1306
|
error: `safe_binding_failed: ${reason}`,
|
|
1307
|
+
error_revert_reason: null,
|
|
1308
|
+
error_short_message: null,
|
|
953
1309
|
});
|
|
954
1310
|
}
|
|
955
1311
|
}
|