@jinn-network/client 0.1.1 → 0.1.2-canary.d6e72dfd
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 +14 -0
- package/CONTRIBUTING.md +123 -0
- package/README.md +210 -37
- package/deployments/deployment-claim-registry-baseSepolia.json +13 -0
- package/deployments/deployment-jinn-testnet-faucet-baseSepolia-fast.json +15 -0
- package/dist/adapters/claim-registry/abi.d.ts +127 -0
- package/dist/adapters/claim-registry/abi.js +93 -0
- package/dist/adapters/claim-registry/abi.js.map +1 -0
- package/dist/adapters/claim-registry/client.d.ts +89 -0
- package/dist/adapters/claim-registry/client.js +205 -0
- package/dist/adapters/claim-registry/client.js.map +1 -0
- package/dist/adapters/mech/adapter.d.ts +1 -0
- package/dist/adapters/mech/adapter.js +75 -41
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +2 -0
- package/dist/adapters/mech/contracts.js +57 -7
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/ipfs.d.ts +8 -0
- package/dist/adapters/mech/ipfs.js +12 -0
- package/dist/adapters/mech/ipfs.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +20 -46
- package/dist/adapters/mech/types.js +16 -35
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/api/gather-status.d.ts +1 -0
- package/dist/api/gather-status.js +33 -1
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +81 -0
- package/dist/api/portfolio-v0-build.js +141 -0
- package/dist/api/portfolio-v0-build.js.map +1 -0
- package/dist/api/portfolio-v0-doctor.d.ts +37 -0
- package/dist/api/portfolio-v0-doctor.js +123 -0
- package/dist/api/portfolio-v0-doctor.js.map +1 -0
- package/dist/api/rewards-build.js +1 -1
- package/dist/api/rewards-build.js.map +1 -1
- package/dist/api/status-build.d.ts +7 -0
- package/dist/api/status-build.js +1 -0
- package/dist/api/status-build.js.map +1 -1
- package/dist/bin/jinn-mcp.d.ts +0 -12
- package/dist/bin/jinn-mcp.js +5 -14
- package/dist/bin/jinn-mcp.js.map +1 -1
- package/dist/build-meta.json +1 -1
- package/dist/cli/commands/auth.js +115 -25
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/bootstrap.js +1 -0
- package/dist/cli/commands/bootstrap.js.map +1 -1
- package/dist/cli/commands/doctor.js +130 -14
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/fleet-scale.js +1 -0
- package/dist/cli/commands/fleet-scale.js.map +1 -1
- package/dist/cli/commands/fund-requirements.js +2 -0
- package/dist/cli/commands/fund-requirements.js.map +1 -1
- package/dist/cli/commands/intents.d.ts +17 -0
- package/dist/cli/commands/intents.js +489 -0
- package/dist/cli/commands/intents.js.map +1 -0
- package/dist/cli/commands/keys-backup.js +13 -11
- package/dist/cli/commands/keys-backup.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +3 -0
- package/dist/cli/commands/mcp.js +19 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/plugin-install.js +8 -4
- package/dist/cli/commands/plugin-install.js.map +1 -1
- package/dist/cli/commands/quickstart.js +60 -4
- package/dist/cli/commands/quickstart.js.map +1 -1
- package/dist/cli/commands/rewards.js +27 -1
- package/dist/cli/commands/rewards.js.map +1 -1
- package/dist/cli/commands/submit-intent.js +108 -5
- package/dist/cli/commands/submit-intent.js.map +1 -1
- package/dist/cli/commands/version.js +1 -0
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/cli/deployment-digest.js +5 -0
- package/dist/cli/deployment-digest.js.map +1 -1
- package/dist/cli/execution-context.js +1 -0
- package/dist/cli/execution-context.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/intent-registry-access.d.ts +64 -0
- package/dist/cli/intent-registry-access.js +187 -0
- package/dist/cli/intent-registry-access.js.map +1 -0
- package/dist/cli/introspection-context.js +1 -0
- package/dist/cli/introspection-context.js.map +1 -1
- package/dist/cli/password.d.ts +21 -9
- package/dist/cli/password.js +45 -24
- package/dist/cli/password.js.map +1 -1
- package/dist/config.d.ts +110 -8
- package/dist/config.js +41 -12
- package/dist/config.js.map +1 -1
- package/dist/daemon/creator.d.ts +7 -1
- package/dist/daemon/creator.js +38 -3
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +43 -0
- package/dist/daemon/daemon.js +87 -2
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +2 -1
- package/dist/earning/bootstrap.js +72 -4
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +10 -0
- package/dist/earning/contracts.js +24 -0
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/jinn-rewards.d.ts +9 -0
- package/dist/earning/jinn-rewards.js +7 -0
- package/dist/earning/jinn-rewards.js.map +1 -1
- package/dist/intents/prediction-apy-v0-auto.d.ts +11 -0
- package/dist/intents/prediction-apy-v0-auto.js +46 -0
- package/dist/intents/prediction-apy-v0-auto.js.map +1 -0
- package/dist/intents/prediction-apy-v0-template.d.ts +8 -0
- package/dist/intents/prediction-apy-v0-template.js +22 -0
- package/dist/intents/prediction-apy-v0-template.js.map +1 -0
- package/dist/intents/prediction-v0-auto.d.ts +53 -0
- package/dist/intents/prediction-v0-auto.js +84 -0
- package/dist/intents/prediction-v0-auto.js.map +1 -0
- package/dist/intents/prediction-v0-template.d.ts +65 -0
- package/dist/intents/prediction-v0-template.js +125 -0
- package/dist/intents/prediction-v0-template.js.map +1 -0
- package/dist/main.js +149 -1
- package/dist/main.js.map +1 -1
- package/dist/mcp/operator-server.d.ts +1 -1
- package/dist/mcp/operator-server.js +1 -1
- package/dist/preflight/claude-auth.d.ts +12 -1
- package/dist/preflight/claude-auth.js +21 -3
- package/dist/preflight/claude-auth.js.map +1 -1
- package/dist/restorer/engine/canonical-json.d.ts +18 -0
- package/dist/restorer/engine/canonical-json.js +59 -0
- package/dist/restorer/engine/canonical-json.js.map +1 -0
- package/dist/restorer/engine/claim.d.ts +69 -0
- package/dist/restorer/engine/claim.js +104 -0
- package/dist/restorer/engine/claim.js.map +1 -0
- package/dist/restorer/engine/delivery.d.ts +52 -0
- package/dist/restorer/engine/delivery.js +63 -0
- package/dist/restorer/engine/delivery.js.map +1 -0
- package/dist/restorer/engine/engine.d.ts +203 -0
- package/dist/restorer/engine/engine.js +753 -0
- package/dist/restorer/engine/engine.js.map +1 -0
- package/dist/restorer/engine/manifest-assembly.d.ts +67 -0
- package/dist/restorer/engine/manifest-assembly.js +79 -0
- package/dist/restorer/engine/manifest-assembly.js.map +1 -0
- package/dist/restorer/engine/packaging.d.ts +87 -0
- package/dist/restorer/engine/packaging.js +350 -0
- package/dist/restorer/engine/packaging.js.map +1 -0
- package/dist/restorer/engine/persistence.d.ts +170 -0
- package/dist/restorer/engine/persistence.js +381 -0
- package/dist/restorer/engine/persistence.js.map +1 -0
- package/dist/restorer/engine/recovery.d.ts +22 -0
- package/dist/restorer/engine/recovery.js +24 -0
- package/dist/restorer/engine/recovery.js.map +1 -0
- package/dist/restorer/engine/registry.d.ts +62 -0
- package/dist/restorer/engine/registry.js +73 -0
- package/dist/restorer/engine/registry.js.map +1 -0
- package/dist/restorer/engine/signing.d.ts +30 -0
- package/dist/restorer/engine/signing.js +39 -0
- package/dist/restorer/engine/signing.js.map +1 -0
- package/dist/restorer/engine/state.d.ts +42 -0
- package/dist/restorer/engine/state.js +87 -0
- package/dist/restorer/engine/state.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.d.ts +64 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js +96 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.d.ts +101 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.js +710 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.d.ts +137 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js +865 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.d.ts +74 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js +74 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.d.ts +97 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js +226 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.d.ts +43 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.js +230 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.d.ts +38 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js +135 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.d.ts +8 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.js +54 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.d.ts +36 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js +137 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.d.ts +82 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.js +6 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.js.map +1 -0
- package/dist/restorer/impls/legacy-claude/index.d.ts +45 -0
- package/dist/restorer/impls/legacy-claude/index.js +71 -0
- package/dist/restorer/impls/legacy-claude/index.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.d.ts +68 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js +117 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.d.ts +49 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js +91 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.d.ts +78 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js +274 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.d.ts +23 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js +49 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.d.ts +25 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js +44 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.d.ts +17 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js +43 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.d.ts +43 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.js +431 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.d.ts +21 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.js +32 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.d.ts +32 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.js +8 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.d.ts +39 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.js +98 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.d.ts +2 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js +7 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.d.ts +4 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.js +2 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +2 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js +7 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.d.ts +39 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js +186 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.d.ts +9 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js +20 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js +2 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.d.ts +29 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.js +94 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.d.ts +8 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.js +41 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.js +2 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.d.ts +20 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js +66 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.d.ts +9 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js +23 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.d.ts +3 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js +13 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js +93 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.d.ts +5 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js +20 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.d.ts +33 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.js +208 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.d.ts +8 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.js +15 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.js +2 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/types.d.ts +177 -0
- package/dist/restorer/types.js +7 -0
- package/dist/restorer/types.js.map +1 -0
- package/dist/store/store.d.ts +3 -1
- package/dist/store/store.js +3 -0
- package/dist/store/store.js.map +1 -1
- package/dist/types/desired-state.d.ts +53 -0
- package/dist/types/desired-state.js +20 -0
- package/dist/types/desired-state.js.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.js +4 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/portfolio.d.ts +1000 -0
- package/dist/types/portfolio.js +168 -0
- package/dist/types/portfolio.js.map +1 -0
- package/dist/types/prediction-apy.d.ts +919 -0
- package/dist/types/prediction-apy.js +121 -0
- package/dist/types/prediction-apy.js.map +1 -0
- package/dist/types/prediction.d.ts +925 -0
- package/dist/types/prediction.js +140 -0
- package/dist/types/prediction.js.map +1 -0
- package/dist/venues/aave-v3/addresses.d.ts +6 -0
- package/dist/venues/aave-v3/addresses.js +19 -0
- package/dist/venues/aave-v3/addresses.js.map +1 -0
- package/dist/venues/aave-v3/client.d.ts +81 -0
- package/dist/venues/aave-v3/client.js +97 -0
- package/dist/venues/aave-v3/client.js.map +1 -0
- package/dist/venues/chainlink/client.d.ts +99 -0
- package/dist/venues/chainlink/client.js +130 -0
- package/dist/venues/chainlink/client.js.map +1 -0
- package/dist/venues/chainlink/feeds.d.ts +8 -0
- package/dist/venues/chainlink/feeds.js +9 -0
- package/dist/venues/chainlink/feeds.js.map +1 -0
- package/dist/venues/hyperliquid/account-value.d.ts +30 -0
- package/dist/venues/hyperliquid/account-value.js +30 -0
- package/dist/venues/hyperliquid/account-value.js.map +1 -0
- package/dist/venues/hyperliquid/client.d.ts +63 -0
- package/dist/venues/hyperliquid/client.js +135 -0
- package/dist/venues/hyperliquid/client.js.map +1 -0
- package/dist/venues/hyperliquid/grid.d.ts +36 -0
- package/dist/venues/hyperliquid/grid.js +61 -0
- package/dist/venues/hyperliquid/grid.js.map +1 -0
- package/dist/venues/hyperliquid/types.d.ts +81 -0
- package/dist/venues/hyperliquid/types.js +8 -0
- package/dist/venues/hyperliquid/types.js.map +1 -0
- package/dist/withdraw/run-withdraw-plan.js +2 -0
- package/dist/withdraw/run-withdraw-plan.js.map +1 -1
- package/docker-compose.yml +44 -0
- package/package.json +12 -1
- package/skills/jinn-operator/SKILL.md +85 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec checks for portfolio.v0.eval — §7.4.
|
|
3
|
+
*
|
|
4
|
+
* spec.equity_return_target
|
|
5
|
+
* spec.max_drawdown_constraint
|
|
6
|
+
*
|
|
7
|
+
* FAIL in any spec.* check → verdict FAIL per §7.3.
|
|
8
|
+
*/
|
|
9
|
+
// ── equity_return_target ──────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Check that rederived equityReturnPct >= intent spec's minReturnPct.
|
|
12
|
+
*/
|
|
13
|
+
export function checkEquityReturnTarget(equityReturnPct, minReturnPct) {
|
|
14
|
+
if (equityReturnPct >= minReturnPct) {
|
|
15
|
+
return { name: 'spec.equity_return_target', status: 'PASS' };
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
name: 'spec.equity_return_target',
|
|
19
|
+
status: 'FAIL',
|
|
20
|
+
detail: {
|
|
21
|
+
required: minReturnPct,
|
|
22
|
+
actual: equityReturnPct,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
// ── max_drawdown_constraint ───────────────────────────────────────────────────
|
|
27
|
+
/**
|
|
28
|
+
* Check that rederived maxDrawdownPct <= intent spec's maxDrawdownPct constraint.
|
|
29
|
+
*/
|
|
30
|
+
export function checkMaxDrawdownConstraint(maxDrawdownPct, maxAllowed) {
|
|
31
|
+
if (maxDrawdownPct <= maxAllowed) {
|
|
32
|
+
return { name: 'spec.max_drawdown_constraint', status: 'PASS' };
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
name: 'spec.max_drawdown_constraint',
|
|
36
|
+
status: 'FAIL',
|
|
37
|
+
detail: {
|
|
38
|
+
limit: maxAllowed,
|
|
39
|
+
actual: maxDrawdownPct,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../../src/restorer/impls/portfolio-v0-evaluator/checks/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,iFAAiF;AAEjF;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,eAAuB,EACvB,YAAoB;IAEpB,IAAI,eAAe,IAAI,YAAY,EAAE,CAAC;QACpC,OAAO,EAAE,IAAI,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO;QACL,IAAI,EAAE,2BAA2B;QACjC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE;YACN,QAAQ,EAAE,YAAY;YACtB,MAAM,EAAE,eAAe;SACxB;KACF,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,cAAsB,EACtB,UAAkB;IAElB,IAAI,cAAc,IAAI,UAAU,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,8BAA8B,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAClE,CAAC;IACD,OAAO;QACL,IAAI,EAAE,8BAA8B;QACpC,MAAM,EAAE,MAAM;QACd,MAAM,EAAE;YACN,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,cAAc;SACvB;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* portfolio-v0-evaluator — deterministic verifier for portfolio.v0 manifests.
|
|
3
|
+
*
|
|
4
|
+
* Implements RestorerImpl for spec.kind === "portfolio.v0" && type === "evaluation".
|
|
5
|
+
* No LLM. Pure deterministic verification per spec §7.
|
|
6
|
+
*
|
|
7
|
+
* Architecture decision (T7):
|
|
8
|
+
* The engine (locked) builds portfolio.v0.manifest.v1. The verdict manifest
|
|
9
|
+
* shape is portfolio.v0.eval.manifest.v1 (§5.2). Since the engine cannot be
|
|
10
|
+
* modified, the eval impl assembles and signs the verdict manifest itself,
|
|
11
|
+
* writes it as verdict.json in workingDir, and declares it as an artifact
|
|
12
|
+
* with role "evaluation_verdict". The engine's outer manifest becomes the
|
|
13
|
+
* packaging container; verdict.json is the meaningful payload.
|
|
14
|
+
*
|
|
15
|
+
* Unified-payload model (Task 7):
|
|
16
|
+
* - spec.kind is "portfolio.v0" (same as restoration)
|
|
17
|
+
* - intent.type === "evaluation"
|
|
18
|
+
* - Restorer's manifest is inlined at intent.context.restorationResult (JSON string)
|
|
19
|
+
* - Original intent spec is at intent.spec (PortfolioV0Spec) — no IPFS fetch needed
|
|
20
|
+
* - intent.restorationRequestId carries the on-chain request ID
|
|
21
|
+
*/
|
|
22
|
+
import type { RestorerImpl, RestorationContext, RestorationOutput } from '../../types.js';
|
|
23
|
+
import type { DesiredState } from '../../../types/desired-state.js';
|
|
24
|
+
import type { PortfolioV0EvaluatorConfig } from './types.js';
|
|
25
|
+
export declare class PortfolioV0Evaluator implements RestorerImpl {
|
|
26
|
+
readonly name = "portfolio-v0-evaluator";
|
|
27
|
+
readonly version = "1.0.0";
|
|
28
|
+
private readonly config;
|
|
29
|
+
constructor(config?: PortfolioV0EvaluatorConfig);
|
|
30
|
+
supports(ctx: {
|
|
31
|
+
kind: string;
|
|
32
|
+
type?: 'restoration' | 'evaluation';
|
|
33
|
+
}): boolean;
|
|
34
|
+
canAttempt(intent: DesiredState): Promise<{
|
|
35
|
+
ok: true;
|
|
36
|
+
} | {
|
|
37
|
+
ok: false;
|
|
38
|
+
reason: string;
|
|
39
|
+
}>;
|
|
40
|
+
run(ctx: RestorationContext): Promise<RestorationOutput>;
|
|
41
|
+
private _buildOutput;
|
|
42
|
+
}
|
|
43
|
+
export default PortfolioV0Evaluator;
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* portfolio-v0-evaluator — deterministic verifier for portfolio.v0 manifests.
|
|
3
|
+
*
|
|
4
|
+
* Implements RestorerImpl for spec.kind === "portfolio.v0" && type === "evaluation".
|
|
5
|
+
* No LLM. Pure deterministic verification per spec §7.
|
|
6
|
+
*
|
|
7
|
+
* Architecture decision (T7):
|
|
8
|
+
* The engine (locked) builds portfolio.v0.manifest.v1. The verdict manifest
|
|
9
|
+
* shape is portfolio.v0.eval.manifest.v1 (§5.2). Since the engine cannot be
|
|
10
|
+
* modified, the eval impl assembles and signs the verdict manifest itself,
|
|
11
|
+
* writes it as verdict.json in workingDir, and declares it as an artifact
|
|
12
|
+
* with role "evaluation_verdict". The engine's outer manifest becomes the
|
|
13
|
+
* packaging container; verdict.json is the meaningful payload.
|
|
14
|
+
*
|
|
15
|
+
* Unified-payload model (Task 7):
|
|
16
|
+
* - spec.kind is "portfolio.v0" (same as restoration)
|
|
17
|
+
* - intent.type === "evaluation"
|
|
18
|
+
* - Restorer's manifest is inlined at intent.context.restorationResult (JSON string)
|
|
19
|
+
* - Original intent spec is at intent.spec (PortfolioV0Spec) — no IPFS fetch needed
|
|
20
|
+
* - intent.restorationRequestId carries the on-chain request ID
|
|
21
|
+
*/
|
|
22
|
+
import { writeFileSync } from 'node:fs';
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { keccak256 } from 'viem';
|
|
25
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
26
|
+
import { HyperliquidClient, HL_MAINNET_BASE_URL, HL_TESTNET_BASE_URL } from '../../../venues/hyperliquid/client.js';
|
|
27
|
+
import { bracketGridPoints } from '../../../venues/hyperliquid/grid.js';
|
|
28
|
+
import { canonicalJson } from '../../engine/canonical-json.js';
|
|
29
|
+
import { signCanonical } from '../../engine/signing.js';
|
|
30
|
+
import { RestorationManifestSchema, PortfolioV0IntentSchema, PortfolioV0EligibilitySchema, } from '../../../types/portfolio.js';
|
|
31
|
+
import { equityCurve, maxDrawdownPct as computeMaxDrawdownPct, equityReturnPct as computeEquityReturnPct, closedTradesCount as computeClosedTradesCount, tradedNotionalMultiple as computeTradedNotionalMultiple, } from './canonical-metrics.js';
|
|
32
|
+
import { scoreCalmarV1 } from './score.js';
|
|
33
|
+
import { checkHlReachable, checkPreSnapshotRederivable, checkFillsRederivable, checkPostSnapshotFundingAccrual, } from './checks/availability.js';
|
|
34
|
+
import { checkMinClosedTrades, checkMinTradedNotional } from './checks/eligibility.js';
|
|
35
|
+
import { checkWindowBounds } from './checks/integrity.js';
|
|
36
|
+
import { checkPreSnapshot, checkPostSnapshot, checkFills, checkGatingEquityReturn, checkGatingMaxDrawdown, checkGatingClosedTrades, checkGatingTradedNotional, extractAccountValue, } from './checks/consistency.js';
|
|
37
|
+
import { checkEquityReturnTarget, checkMaxDrawdownConstraint } from './checks/spec.js';
|
|
38
|
+
// ── Verdict derivation per §7.3 ───────────────────────────────────────────────
|
|
39
|
+
function deriveVerdict(checks) {
|
|
40
|
+
// if any "availability.*" FAIL → INDETERMINATE
|
|
41
|
+
const availFail = checks.some((c) => c.name.startsWith('availability.') && c.status === 'FAIL');
|
|
42
|
+
if (availFail)
|
|
43
|
+
return 'INDETERMINATE';
|
|
44
|
+
// if any "eligibility.*" FAIL → REJECTED
|
|
45
|
+
const eligFail = checks.some((c) => c.name.startsWith('eligibility.') && c.status === 'FAIL');
|
|
46
|
+
if (eligFail)
|
|
47
|
+
return 'REJECTED';
|
|
48
|
+
// if any "integrity.*"|"consistency.*"|"spec.*" FAIL → FAIL
|
|
49
|
+
const otherFail = checks.some((c) => (c.name.startsWith('integrity.') ||
|
|
50
|
+
c.name.startsWith('consistency.') ||
|
|
51
|
+
c.name.startsWith('spec.')) &&
|
|
52
|
+
c.status === 'FAIL');
|
|
53
|
+
if (otherFail)
|
|
54
|
+
return 'FAIL';
|
|
55
|
+
return 'PASS';
|
|
56
|
+
}
|
|
57
|
+
// ── Private helpers ───────────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Assemble the unsigned verdict manifest object (no signature field).
|
|
60
|
+
*
|
|
61
|
+
* NOTE: `generatedAt` is intentionally excluded from this object.
|
|
62
|
+
* It is non-deterministic (wall-clock time) and MUST NOT be included
|
|
63
|
+
* in the signed content — two evaluations of the same inputs at different
|
|
64
|
+
* times must produce the same hash. `generatedAt` is added as an unsigned
|
|
65
|
+
* sibling field in _buildOutput after signing.
|
|
66
|
+
*/
|
|
67
|
+
function _assembleUnsignedManifest(params) {
|
|
68
|
+
const { intentCid, onchainCreationTx, onchainCreationBlock, restorationRequestId, intent, checks, verdict, score, targetManifest, rederivPrePayload, rederivFills, rederived, evaluatorSafeAddress, evaluatorAgentEoa, } = params;
|
|
69
|
+
const claimedGating = targetManifest?.gating ?? {
|
|
70
|
+
equityReturnPct: '0',
|
|
71
|
+
maxDrawdownPct: '0',
|
|
72
|
+
closedTradesCount: 0,
|
|
73
|
+
tradedNotionalMultiple: '0',
|
|
74
|
+
};
|
|
75
|
+
const intentProvenance = {
|
|
76
|
+
cid: intentCid,
|
|
77
|
+
onchainCreationTx: onchainCreationTx ?? '0x',
|
|
78
|
+
onchainCreationBlock: onchainCreationBlock,
|
|
79
|
+
requestId: restorationRequestId ?? '0x',
|
|
80
|
+
};
|
|
81
|
+
const rederivPreSnap = rederivPrePayload ?? {
|
|
82
|
+
capturedAt: targetManifest?.preSnapshot.capturedAt ?? 0,
|
|
83
|
+
payload: null,
|
|
84
|
+
};
|
|
85
|
+
const rederivPostSnap = {
|
|
86
|
+
capturedAt: targetManifest?.postSnapshot.capturedAt ?? 0,
|
|
87
|
+
payload: targetManifest?.postSnapshot.payload ?? null,
|
|
88
|
+
};
|
|
89
|
+
const fillsHash = (() => {
|
|
90
|
+
if (!rederivFills)
|
|
91
|
+
return '0x';
|
|
92
|
+
return keccak256(new TextEncoder().encode(canonicalJson(rederivFills)));
|
|
93
|
+
})();
|
|
94
|
+
return {
|
|
95
|
+
schemaVersion: 'portfolio.v0.eval.manifest.v1',
|
|
96
|
+
intent: intentProvenance,
|
|
97
|
+
evaluator: {
|
|
98
|
+
safeAddress: evaluatorSafeAddress,
|
|
99
|
+
agentEoa: evaluatorAgentEoa,
|
|
100
|
+
},
|
|
101
|
+
window: targetManifest?.window ?? intent.window ?? { startTs: 0, endTs: 0 },
|
|
102
|
+
verdict,
|
|
103
|
+
score,
|
|
104
|
+
scoreBasis: 'calmar.v1',
|
|
105
|
+
scoreVersion: 'v1',
|
|
106
|
+
rederived: {
|
|
107
|
+
preSnapshot: rederivPreSnap,
|
|
108
|
+
postSnapshot: rederivPostSnap,
|
|
109
|
+
fills: rederivFills ?? [],
|
|
110
|
+
gating: {
|
|
111
|
+
equityReturnPct: String(rederived?.equityReturn ?? 0),
|
|
112
|
+
maxDrawdownPct: String(rederived?.maxDrawdown ?? 0),
|
|
113
|
+
closedTradesCount: rederived?.closedTrades ?? 0,
|
|
114
|
+
tradedNotionalMultiple: String(rederived?.notional ?? 0),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
claimed: {
|
|
118
|
+
preSnapshot: {
|
|
119
|
+
capturedAt: targetManifest?.preSnapshot.capturedAt ?? 0,
|
|
120
|
+
payload: targetManifest?.preSnapshot.payload ?? null,
|
|
121
|
+
},
|
|
122
|
+
postSnapshot: {
|
|
123
|
+
capturedAt: targetManifest?.postSnapshot.capturedAt ?? 0,
|
|
124
|
+
payload: targetManifest?.postSnapshot.payload ?? null,
|
|
125
|
+
},
|
|
126
|
+
fillsHash,
|
|
127
|
+
fillsCount: targetManifest?.fills.length ?? 0,
|
|
128
|
+
gating: claimedGating,
|
|
129
|
+
},
|
|
130
|
+
checks,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Sign the unsigned manifest or emit empty stub signature if no key or signing fails.
|
|
135
|
+
*/
|
|
136
|
+
async function _signOrStub(unsigned, privateKey, evaluatorAgentEoa, log) {
|
|
137
|
+
const stub = { hash: '0x', sig: '0x' };
|
|
138
|
+
if (!privateKey) {
|
|
139
|
+
return stub;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const account = privateKeyToAccount(privateKey);
|
|
143
|
+
const signerAddr = evaluatorAgentEoa !== '0x0000000000000000000000000000000000000000'
|
|
144
|
+
? evaluatorAgentEoa
|
|
145
|
+
: account.address;
|
|
146
|
+
const result = await signCanonical(unsigned, privateKey, signerAddr);
|
|
147
|
+
return { hash: result.hash, sig: result.sig };
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
log({ level: 'warn', msg: 'portfolio-v0-evaluator: signing failed, emitting unsigned manifest', data: { err } });
|
|
151
|
+
return stub;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Write verdict manifest JSON to workingDir/verdict.json.
|
|
156
|
+
*/
|
|
157
|
+
function _writeVerdictArtifact(workingDir, verdictManifest) {
|
|
158
|
+
const verdictPath = join(workingDir, 'verdict.json');
|
|
159
|
+
writeFileSync(verdictPath, JSON.stringify(verdictManifest, null, 2), 'utf-8');
|
|
160
|
+
}
|
|
161
|
+
// ── PortfolioV0Evaluator ──────────────────────────────────────────────────────
|
|
162
|
+
export class PortfolioV0Evaluator {
|
|
163
|
+
name = 'portfolio-v0-evaluator';
|
|
164
|
+
version = '1.0.0';
|
|
165
|
+
config;
|
|
166
|
+
constructor(config = {}) {
|
|
167
|
+
this.config = config;
|
|
168
|
+
}
|
|
169
|
+
supports(ctx) {
|
|
170
|
+
return ctx.kind === 'portfolio.v0' && ctx.type === 'evaluation';
|
|
171
|
+
}
|
|
172
|
+
async canAttempt(intent) {
|
|
173
|
+
if (intent.spec?.kind !== 'portfolio.v0') {
|
|
174
|
+
return { ok: false, reason: 'spec.kind is not portfolio.v0' };
|
|
175
|
+
}
|
|
176
|
+
if (intent.type !== 'evaluation') {
|
|
177
|
+
return { ok: false, reason: 'DesiredState.type is not evaluation' };
|
|
178
|
+
}
|
|
179
|
+
if (!intent.restorationRequestId) {
|
|
180
|
+
return { ok: false, reason: 'restorationRequestId is required' };
|
|
181
|
+
}
|
|
182
|
+
const restorationResult = intent.context?.['restorationResult'];
|
|
183
|
+
if (typeof restorationResult !== 'string') {
|
|
184
|
+
return { ok: false, reason: 'context.restorationResult (manifest JSON) is required' };
|
|
185
|
+
}
|
|
186
|
+
return { ok: true };
|
|
187
|
+
}
|
|
188
|
+
async run(ctx) {
|
|
189
|
+
const { intent, log } = ctx;
|
|
190
|
+
// ── Step 1: Parse restorer's manifest from inlined context ────────────────
|
|
191
|
+
// The manifest JSON is inlined by MechAdapter.tryCreateEvaluationJob at context.restorationResult.
|
|
192
|
+
// Falls back to an error — crash recovery path not yet implemented.
|
|
193
|
+
let targetManifest;
|
|
194
|
+
let targetIntent;
|
|
195
|
+
let hlPortfolioPeriodFn;
|
|
196
|
+
let hlUserFillsByTimeFn;
|
|
197
|
+
const checks = [];
|
|
198
|
+
const inlined = intent.context?.['restorationResult'];
|
|
199
|
+
if (typeof inlined !== 'string') {
|
|
200
|
+
throw new Error('portfolio-v0-evaluator: restorationResult missing from context; crash recovery path not yet implemented');
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
targetManifest = RestorationManifestSchema.parse(JSON.parse(inlined));
|
|
204
|
+
// The original portfolio.v0 intent is directly at intent.spec — no IPFS fetch needed.
|
|
205
|
+
targetIntent = PortfolioV0IntentSchema.parse(intent);
|
|
206
|
+
// Determine HL client from venue (or use injected test deps)
|
|
207
|
+
if (this.config._testDeps?.hlPortfolioPeriod && this.config._testDeps?.hlUserFillsByTime) {
|
|
208
|
+
hlPortfolioPeriodFn = this.config._testDeps.hlPortfolioPeriod;
|
|
209
|
+
hlUserFillsByTimeFn = this.config._testDeps.hlUserFillsByTime;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
const venue = targetIntent.spec.account.venue;
|
|
213
|
+
const baseUrl = venue === 'hyperliquid-mainnet' ? HL_MAINNET_BASE_URL : HL_TESTNET_BASE_URL;
|
|
214
|
+
const hlClient = new HyperliquidClient(baseUrl);
|
|
215
|
+
hlPortfolioPeriodFn = (user) => hlClient.portfolioPeriod(user, 'allTime');
|
|
216
|
+
hlUserFillsByTimeFn = (user, start, end) => hlClient.userFillsByTime(user, start, end);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
221
|
+
log({ level: 'error', msg: 'portfolio-v0-evaluator: failed to parse manifest/intent', data: { err: msg } });
|
|
222
|
+
// We cannot proceed — return a minimal INDETERMINATE output.
|
|
223
|
+
checks.push({
|
|
224
|
+
name: 'availability.manifest_parseable',
|
|
225
|
+
status: 'FAIL',
|
|
226
|
+
detail: `Failed to parse manifest or intent: ${msg}`,
|
|
227
|
+
});
|
|
228
|
+
return this._buildOutput(ctx, checks, null, null, null, null, null, null, null, null);
|
|
229
|
+
}
|
|
230
|
+
// Extract provenance fields from the parsed manifest + intent
|
|
231
|
+
const intentCid = targetManifest.intent.cid;
|
|
232
|
+
const onchainCreationTx = targetManifest.intent.onchainCreationTx;
|
|
233
|
+
const onchainCreationBlock = targetManifest.intent.onchainCreationBlock;
|
|
234
|
+
const restorationRequestId = intent.restorationRequestId;
|
|
235
|
+
log({ level: 'info', msg: 'portfolio-v0-evaluator: starting evaluation', data: { intentCid, restorationRequestId } });
|
|
236
|
+
const masterAddress = targetIntent.spec.account.masterAddress;
|
|
237
|
+
const { startTs, endTs } = targetManifest.window;
|
|
238
|
+
// ── Step 2: Re-fetch HL data ──────────────────────────────────────────────
|
|
239
|
+
// 2a: Check HL reachability + fetch portfolio grid + fills
|
|
240
|
+
let grid = [];
|
|
241
|
+
let rederivFills = [];
|
|
242
|
+
let startTimeClamped = false;
|
|
243
|
+
let hlReachable = false;
|
|
244
|
+
try {
|
|
245
|
+
const [portfolioResp, fillsResult] = await Promise.all([
|
|
246
|
+
hlPortfolioPeriodFn(masterAddress),
|
|
247
|
+
hlUserFillsByTimeFn(masterAddress, startTs, endTs),
|
|
248
|
+
]);
|
|
249
|
+
grid = portfolioResp?.accountValueHistory ?? [];
|
|
250
|
+
rederivFills = fillsResult.fills;
|
|
251
|
+
startTimeClamped = fillsResult.startTimeClamped;
|
|
252
|
+
hlReachable = true;
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
256
|
+
log({ level: 'error', msg: 'portfolio-v0-evaluator: HL API call failed', data: { err: msg } });
|
|
257
|
+
}
|
|
258
|
+
// ── Availability checks ───────────────────────────────────────────────────
|
|
259
|
+
checks.push(checkHlReachable(hlReachable));
|
|
260
|
+
if (!hlReachable) {
|
|
261
|
+
return this._buildOutput(ctx, checks, null, null, null, null, intentCid, onchainCreationTx, onchainCreationBlock, restorationRequestId);
|
|
262
|
+
}
|
|
263
|
+
const preCapturedAt = targetManifest.preSnapshot.capturedAt;
|
|
264
|
+
const postCapturedAt = targetManifest.postSnapshot.capturedAt;
|
|
265
|
+
checks.push(checkPreSnapshotRederivable(grid, preCapturedAt));
|
|
266
|
+
checks.push(checkFillsRederivable(startTimeClamped));
|
|
267
|
+
const postAccrualCheck = checkPostSnapshotFundingAccrual(postCapturedAt, endTs);
|
|
268
|
+
checks.push(postAccrualCheck);
|
|
269
|
+
// If post-snapshot funding accrual SKIP → downstream consistency is skipped
|
|
270
|
+
const skipPostConsistency = postAccrualCheck.status === 'SKIP';
|
|
271
|
+
// ── Derive pre-snapshot from grid ─────────────────────────────────────────
|
|
272
|
+
const bracket = bracketGridPoints(grid, preCapturedAt);
|
|
273
|
+
let rederivPrePayload = null;
|
|
274
|
+
if (bracket !== null) {
|
|
275
|
+
// Interpolate accountValue at preCapturedAt between the two bracket points
|
|
276
|
+
const [beforeTs, beforeVal] = bracket.before;
|
|
277
|
+
const [afterTs, afterVal] = bracket.after;
|
|
278
|
+
const frac = afterTs > beforeTs ? (preCapturedAt - beforeTs) / (afterTs - beforeTs) : 0;
|
|
279
|
+
const interpolatedValue = parseFloat(beforeVal) + frac * (parseFloat(afterVal) - parseFloat(beforeVal));
|
|
280
|
+
rederivPrePayload = {
|
|
281
|
+
capturedAt: preCapturedAt,
|
|
282
|
+
payload: {
|
|
283
|
+
marginSummary: { accountValue: String(interpolatedValue) },
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
// ── Derive post-snapshot ───────────────────────────────────────────────────
|
|
288
|
+
// For the post-snapshot, we use the claimed value (from the manifest) since
|
|
289
|
+
// HL only returns current state. The §7.7 note says to use the portfolio grid
|
|
290
|
+
// for the pre-snapshot only. For post-snapshot we compare against the live
|
|
291
|
+
// clearinghouse state at the time of evaluation — but since we're post-window,
|
|
292
|
+
// the best we can do is compare fill-derived metrics.
|
|
293
|
+
//
|
|
294
|
+
// To keep things deterministic: rederived post snapshot = claimed post snapshot
|
|
295
|
+
// (we verify internal consistency of the manifest, not post re-fetch).
|
|
296
|
+
const rederivPostPayload = skipPostConsistency
|
|
297
|
+
? null
|
|
298
|
+
: {
|
|
299
|
+
capturedAt: postCapturedAt,
|
|
300
|
+
payload: targetManifest.postSnapshot.payload,
|
|
301
|
+
};
|
|
302
|
+
// ── Compute canonical metrics ─────────────────────────────────────────────
|
|
303
|
+
// Extract accountValues for metric computation
|
|
304
|
+
const claimedPrePayload = targetManifest.preSnapshot.payload;
|
|
305
|
+
const claimedPostPayload = targetManifest.postSnapshot.payload;
|
|
306
|
+
// Use the shared extractor so unified-shape and legacy payloads both work
|
|
307
|
+
// (see `extractAccountValue` in checks/consistency.ts).
|
|
308
|
+
const preValue = (rederivPrePayload ? extractAccountValue(rederivPrePayload.payload) : null)
|
|
309
|
+
?? extractAccountValue(claimedPrePayload)
|
|
310
|
+
?? 0;
|
|
311
|
+
const postValue = extractAccountValue(claimedPostPayload) ?? 0;
|
|
312
|
+
const fillTimes = rederivFills.map((f) => f.time);
|
|
313
|
+
const curve = equityCurve(preCapturedAt, preValue, postCapturedAt, postValue, fillTimes);
|
|
314
|
+
const rederivEquityReturn = computeEquityReturnPct(preValue, postValue);
|
|
315
|
+
const rederivMaxDrawdown = computeMaxDrawdownPct(curve);
|
|
316
|
+
const rederivClosedTrades = computeClosedTradesCount(rederivFills);
|
|
317
|
+
const rederivNotional = computeTradedNotionalMultiple(rederivFills, preValue);
|
|
318
|
+
// ── Integrity checks ──────────────────────────────────────────────────────
|
|
319
|
+
checks.push(checkWindowBounds(preCapturedAt, postCapturedAt, startTs, endTs));
|
|
320
|
+
// ── Eligibility checks ────────────────────────────────────────────────────
|
|
321
|
+
const eligibility = PortfolioV0EligibilitySchema.parse(targetIntent.eligibility ?? {});
|
|
322
|
+
checks.push(checkMinClosedTrades(rederivClosedTrades, eligibility.minClosedTrades));
|
|
323
|
+
checks.push(checkMinTradedNotional(rederivNotional, eligibility.minTradedNotionalMultiple));
|
|
324
|
+
// ── Consistency checks ────────────────────────────────────────────────────
|
|
325
|
+
const claimedGating = targetManifest.gating;
|
|
326
|
+
checks.push(checkPreSnapshot(claimedPrePayload, rederivPrePayload));
|
|
327
|
+
checks.push(checkPostSnapshot(claimedPostPayload, rederivPostPayload));
|
|
328
|
+
checks.push(checkFills(targetManifest.fills, rederivFills));
|
|
329
|
+
checks.push(checkGatingEquityReturn(claimedGating.equityReturnPct, rederivEquityReturn));
|
|
330
|
+
checks.push(checkGatingMaxDrawdown(claimedGating.maxDrawdownPct, rederivMaxDrawdown));
|
|
331
|
+
checks.push(checkGatingClosedTrades(claimedGating.closedTradesCount, rederivClosedTrades));
|
|
332
|
+
checks.push(checkGatingTradedNotional(claimedGating.tradedNotionalMultiple, rederivNotional));
|
|
333
|
+
// ── Spec checks ───────────────────────────────────────────────────────────
|
|
334
|
+
checks.push(checkEquityReturnTarget(rederivEquityReturn, targetIntent.spec.target.minReturnPct));
|
|
335
|
+
checks.push(checkMaxDrawdownConstraint(rederivMaxDrawdown, targetIntent.spec.constraint.maxDrawdownPct));
|
|
336
|
+
// ── Derive verdict ────────────────────────────────────────────────────────
|
|
337
|
+
const rederived = {
|
|
338
|
+
equityReturn: rederivEquityReturn,
|
|
339
|
+
maxDrawdown: rederivMaxDrawdown,
|
|
340
|
+
closedTrades: rederivClosedTrades,
|
|
341
|
+
notional: rederivNotional,
|
|
342
|
+
};
|
|
343
|
+
return this._buildOutput(ctx, checks, targetManifest, rederivPrePayload, rederivFills, rederived, intentCid, onchainCreationTx, onchainCreationBlock, restorationRequestId);
|
|
344
|
+
}
|
|
345
|
+
async _buildOutput(ctx, checks, targetManifest, rederivPrePayload, rederivFills, rederived, intentCid, onchainCreationTx, onchainCreationBlock, restorationRequestId) {
|
|
346
|
+
const { intent, workingDir, log } = ctx;
|
|
347
|
+
// Spec §7.5 funding-accrual edge case: if hl_post_snapshot_rederivable is SKIP,
|
|
348
|
+
// the verdict MUST be INDETERMINATE regardless of other check outcomes.
|
|
349
|
+
// (deriveVerdict() only handles FAIL→INDETERMINATE per §7.3; SKIP needs explicit handling.)
|
|
350
|
+
const postRederivableSkipped = checks.some((c) => c.name === 'availability.hl_post_snapshot_rederivable' && c.status === 'SKIP');
|
|
351
|
+
const verdict = postRederivableSkipped ? 'INDETERMINATE' : deriveVerdict(checks);
|
|
352
|
+
const equityReturn = rederived?.equityReturn ?? 0;
|
|
353
|
+
const maxDrawdown = rederived?.maxDrawdown ?? 0;
|
|
354
|
+
const score = scoreCalmarV1(equityReturn, maxDrawdown, verdict);
|
|
355
|
+
log({ level: 'info', msg: 'portfolio-v0-evaluator: verdict derived', data: { verdict, score, checkCount: checks.length } });
|
|
356
|
+
// Evaluator identity — sourced from constructor config (injected by daemon)
|
|
357
|
+
const evaluatorSafeAddress = (this.config.safeAddress ?? '0x0000000000000000000000000000000000000000');
|
|
358
|
+
const evaluatorAgentEoa = (this.config.agentEoa ?? '0x0000000000000000000000000000000000000000');
|
|
359
|
+
// ── Assemble unsigned verdict manifest ────────────────────────────────────
|
|
360
|
+
// generatedAt is NOT included in the signed content: it is non-deterministic
|
|
361
|
+
// (wall-clock) and must not affect the hash. It is added below after signing.
|
|
362
|
+
const unsigned = _assembleUnsignedManifest({
|
|
363
|
+
intentCid: intentCid ?? '',
|
|
364
|
+
onchainCreationTx: onchainCreationTx ?? '0x',
|
|
365
|
+
onchainCreationBlock: onchainCreationBlock ?? 0,
|
|
366
|
+
restorationRequestId: restorationRequestId ?? '0x',
|
|
367
|
+
intent,
|
|
368
|
+
checks,
|
|
369
|
+
verdict,
|
|
370
|
+
score,
|
|
371
|
+
targetManifest,
|
|
372
|
+
rederivPrePayload,
|
|
373
|
+
rederivFills,
|
|
374
|
+
rederived,
|
|
375
|
+
evaluatorSafeAddress,
|
|
376
|
+
evaluatorAgentEoa,
|
|
377
|
+
});
|
|
378
|
+
// ── Sign or emit stub ─────────────────────────────────────────────────────
|
|
379
|
+
const privateKey = this.config.agentEoaPrivateKey;
|
|
380
|
+
const { hash, sig } = await _signOrStub(unsigned, privateKey, evaluatorAgentEoa, log);
|
|
381
|
+
// generatedAt: unsigned metadata — sits outside the signed envelope.
|
|
382
|
+
// Added after signing so it does not influence the hash.
|
|
383
|
+
const generatedAt = Date.now();
|
|
384
|
+
const verdictManifest = {
|
|
385
|
+
...unsigned,
|
|
386
|
+
generatedAt,
|
|
387
|
+
signature: {
|
|
388
|
+
algo: 'secp256k1',
|
|
389
|
+
signer: evaluatorAgentEoa,
|
|
390
|
+
hash,
|
|
391
|
+
sig,
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
// ── Write verdict.json ────────────────────────────────────────────────────
|
|
395
|
+
_writeVerdictArtifact(workingDir, verdictManifest);
|
|
396
|
+
log({ level: 'info', msg: 'portfolio-v0-evaluator: verdict.json written', data: { path: join(workingDir, 'verdict.json') } });
|
|
397
|
+
// ── Build RestorationOutput ───────────────────────────────────────────────
|
|
398
|
+
const output = {
|
|
399
|
+
venueRef: { name: 'hyperliquid' },
|
|
400
|
+
gating: {
|
|
401
|
+
verdict,
|
|
402
|
+
score,
|
|
403
|
+
scoreBasis: 'calmar.v1',
|
|
404
|
+
scoreVersion: 'v1',
|
|
405
|
+
checkCount: checks.length,
|
|
406
|
+
passCount: checks.filter((c) => c.status === 'PASS').length,
|
|
407
|
+
failCount: checks.filter((c) => c.status === 'FAIL').length,
|
|
408
|
+
skipCount: checks.filter((c) => c.status === 'SKIP').length,
|
|
409
|
+
},
|
|
410
|
+
informational: {
|
|
411
|
+
intentCid: intentCid ?? '',
|
|
412
|
+
equityReturnPct: String(rederived?.equityReturn ?? 0),
|
|
413
|
+
maxDrawdownPct: String(rederived?.maxDrawdown ?? 0),
|
|
414
|
+
closedTradesCount: rederived?.closedTrades ?? 0,
|
|
415
|
+
tradedNotionalMultiple: String(rederived?.notional ?? 0),
|
|
416
|
+
},
|
|
417
|
+
artifacts: [
|
|
418
|
+
{
|
|
419
|
+
path: 'verdict.json',
|
|
420
|
+
role: 'evaluation_verdict',
|
|
421
|
+
metadata: { verdict, score, schemaVersion: 'portfolio.v0.eval.manifest.v1' },
|
|
422
|
+
tags: ['verdict', 'evaluation'],
|
|
423
|
+
access: { kind: 'open' },
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
};
|
|
427
|
+
return output;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
export default PortfolioV0Evaluator;
|
|
431
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/restorer/impls/portfolio-v0-evaluator/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score function for portfolio.v0 evaluation — §7.8.
|
|
3
|
+
*
|
|
4
|
+
* scoreBasis: "calmar.v1"
|
|
5
|
+
* score_calmar_v1 =
|
|
6
|
+
* if verdict != PASS: "0"
|
|
7
|
+
* else:
|
|
8
|
+
* ratio = clamp(equityReturnPct / max(maxDrawdownPct, 1.0%), 0, 10.0)
|
|
9
|
+
* encoded = ratio * 1e17 // range [0, 1e18]
|
|
10
|
+
* encoded as decimal string
|
|
11
|
+
*/
|
|
12
|
+
import type { Verdict } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Compute the calmar.v1 score.
|
|
15
|
+
*
|
|
16
|
+
* @param equityReturnPct Equity return percentage (e.g. 5.0 for +5%)
|
|
17
|
+
* @param maxDrawdownPctVal Max drawdown percentage (e.g. 2.0 for 2%)
|
|
18
|
+
* @param verdict The evaluation verdict
|
|
19
|
+
* @returns Fixed-point string in 1e18 scale; "0" for any non-PASS verdict
|
|
20
|
+
*/
|
|
21
|
+
export declare function scoreCalmarV1(equityReturnPct: number, maxDrawdownPctVal: number, verdict: Verdict): string;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Score function for portfolio.v0 evaluation — §7.8.
|
|
3
|
+
*
|
|
4
|
+
* scoreBasis: "calmar.v1"
|
|
5
|
+
* score_calmar_v1 =
|
|
6
|
+
* if verdict != PASS: "0"
|
|
7
|
+
* else:
|
|
8
|
+
* ratio = clamp(equityReturnPct / max(maxDrawdownPct, 1.0%), 0, 10.0)
|
|
9
|
+
* encoded = ratio * 1e17 // range [0, 1e18]
|
|
10
|
+
* encoded as decimal string
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Compute the calmar.v1 score.
|
|
14
|
+
*
|
|
15
|
+
* @param equityReturnPct Equity return percentage (e.g. 5.0 for +5%)
|
|
16
|
+
* @param maxDrawdownPctVal Max drawdown percentage (e.g. 2.0 for 2%)
|
|
17
|
+
* @param verdict The evaluation verdict
|
|
18
|
+
* @returns Fixed-point string in 1e18 scale; "0" for any non-PASS verdict
|
|
19
|
+
*/
|
|
20
|
+
export function scoreCalmarV1(equityReturnPct, maxDrawdownPctVal, verdict) {
|
|
21
|
+
if (verdict !== 'PASS') {
|
|
22
|
+
return '0';
|
|
23
|
+
}
|
|
24
|
+
const denominator = Math.max(maxDrawdownPctVal, 1.0);
|
|
25
|
+
const ratio = Math.min(Math.max(equityReturnPct / denominator, 0), 10.0);
|
|
26
|
+
// ratio * 1e17 → range [0, 1e18]
|
|
27
|
+
// Use BigInt arithmetic to avoid floating-point precision loss in the
|
|
28
|
+
// fixed-point representation.
|
|
29
|
+
const ratioBig = BigInt(Math.round(ratio * 1e17));
|
|
30
|
+
return ratioBig.toString();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../../src/restorer/impls/portfolio-v0-evaluator/score.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,eAAuB,EACvB,iBAAyB,EACzB,OAAgB;IAEhB,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,WAAW,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAEzE,iCAAiC;IACjC,sEAAsE;IACtE,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IAElD,OAAO,QAAQ,CAAC,QAAQ,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the portfolio-v0-evaluator.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for Check, Verdict, and related types.
|
|
5
|
+
* Import from here instead of declaring locally in each check module.
|
|
6
|
+
*/
|
|
7
|
+
import type { HlFill, HlGridPoint } from '../../../venues/hyperliquid/types.js';
|
|
8
|
+
export type CheckStatus = 'PASS' | 'FAIL' | 'SKIP';
|
|
9
|
+
export interface Check {
|
|
10
|
+
name: string;
|
|
11
|
+
status: CheckStatus;
|
|
12
|
+
detail?: string | Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export type Verdict = 'PASS' | 'FAIL' | 'REJECTED' | 'INDETERMINATE';
|
|
15
|
+
export interface PortfolioV0EvaluatorConfig {
|
|
16
|
+
/** Evaluator Safe multisig address (injected by daemon). */
|
|
17
|
+
safeAddress?: string;
|
|
18
|
+
/** Evaluator agent EOA address (injected by daemon). */
|
|
19
|
+
agentEoa?: string;
|
|
20
|
+
/** Evaluator agent EOA private key (injected by daemon). */
|
|
21
|
+
agentEoaPrivateKey?: string;
|
|
22
|
+
/** Test-only: injectable deps to avoid real network calls. */
|
|
23
|
+
_testDeps?: {
|
|
24
|
+
hlPortfolioPeriod?: (user: string) => Promise<{
|
|
25
|
+
accountValueHistory: HlGridPoint[];
|
|
26
|
+
} | null>;
|
|
27
|
+
hlUserFillsByTime?: (user: string, startTime: number, endTime?: number) => Promise<{
|
|
28
|
+
fills: HlFill[];
|
|
29
|
+
startTimeClamped: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
}
|