@wiimdy/openfunderse 0.1.3 → 1.1.1
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/README.md +25 -67
- package/bin/openfunderse.mjs +8 -4
- package/package.json +1 -1
- package/packs/openfunderse/config/setup-manifest.json +0 -23
- package/packs/openfunderse/prompts/participant/system.md +0 -35
- package/packs/openfunderse/prompts/strategy/system.md +0 -29
- package/packs/openfunderse/skills/openfunderse-participant/SKILL.md +0 -201
- package/packs/openfunderse/skills/openfunderse-strategy/SKILL.md +0 -260
package/README.md
CHANGED
|
@@ -1,76 +1,34 @@
|
|
|
1
1
|
# openfunderse
|
|
2
2
|
|
|
3
|
-
Install OpenFunderse skill packs
|
|
3
|
+
Install OpenFunderse split skill packs (`strategy`, `participant`) for OpenClaw/Codex.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
- Monorepo distribution package for Codex skills/prompts/manifests.
|
|
7
|
-
- Owns install UX (`npx @wiimdy/openfunderse@latest install openfunderse`) and pack copy logic.
|
|
8
|
-
|
|
9
|
-
## Usage
|
|
5
|
+
## Quick Start
|
|
10
6
|
|
|
11
7
|
```bash
|
|
12
|
-
#
|
|
13
|
-
npx @wiimdy/openfunderse@latest
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
npx @wiimdy/openfunderse@latest install openfunderse --with-runtime
|
|
26
|
-
|
|
27
|
-
# install pack + runtime + strategy env scaffold in one command
|
|
28
|
-
npx @wiimdy/openfunderse@latest install openfunderse \
|
|
29
|
-
--with-runtime \
|
|
30
|
-
--env-profile strategy
|
|
31
|
-
|
|
32
|
-
# install into custom codex home
|
|
33
|
-
npx @wiimdy/openfunderse@latest install openfunderse --codex-home /custom/.codex
|
|
34
|
-
|
|
35
|
-
# install runtime into a specific project directory
|
|
36
|
-
npx @wiimdy/openfunderse@latest install openfunderse \
|
|
37
|
-
--with-runtime \
|
|
38
|
-
--runtime-dir /path/to/project
|
|
8
|
+
# 1) install skill + runtime
|
|
9
|
+
npx @wiimdy/openfunderse@latest install openfunderse-strategy --with-runtime
|
|
10
|
+
# or
|
|
11
|
+
npx @wiimdy/openfunderse@latest install openfunderse-participant --with-runtime
|
|
12
|
+
|
|
13
|
+
# 2) create/rotate bot wallet and write env
|
|
14
|
+
npx @wiimdy/openfunderse@latest bot-init --skill-name strategy --yes
|
|
15
|
+
# or
|
|
16
|
+
npx @wiimdy/openfunderse@latest bot-init --skill-name participant --yes
|
|
17
|
+
|
|
18
|
+
# 3) load env in current shell
|
|
19
|
+
set -a; source .env; set +a
|
|
20
|
+
```
|
|
39
21
|
|
|
40
|
-
|
|
41
|
-
npx @wiimdy/openfunderse@latest bot-init \
|
|
42
|
-
--skill-name strategy \
|
|
43
|
-
--yes
|
|
22
|
+
## Where Files Are Stored
|
|
44
23
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
--yes
|
|
49
|
-
```
|
|
24
|
+
- In OpenClaw, skills are installed under `~/.openclaw/workspace/skills`.
|
|
25
|
+
- Pack metadata is stored under `~/.openclaw/workspace/packs/<pack-name>`.
|
|
26
|
+
- Wallet backups from `bot-init` are stored under `~/.openclaw/workspace/openfunderse/wallets`.
|
|
50
27
|
|
|
51
|
-
## Notes
|
|
28
|
+
## Important Notes
|
|
52
29
|
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- `--env-profile` controls scaffold scope: `strategy` | `participant` | `all` (auto-selected by pack when omitted).
|
|
59
|
-
- Use `--no-init-env` to skip env scaffold generation.
|
|
60
|
-
- `--env-path` sets a custom env scaffold path.
|
|
61
|
-
- Optional: `--runtime-package`, `--runtime-dir`, `--runtime-manager`.
|
|
62
|
-
- Available packs: `openfunderse` (unified), `openfunderse-strategy`, `openfunderse-participant`.
|
|
63
|
-
- Split packs (`openfunderse-strategy`, `openfunderse-participant`) are intentionally minimal and centered on the skill payload.
|
|
64
|
-
- Prefer `--env-path` (Node 20+ reserves `--env-file` as a runtime flag).
|
|
65
|
-
- `bot-init` uses `cast wallet new --json` (Foundry) to generate a new wallet for Monad testnet.
|
|
66
|
-
- `bot-init` infers role from `--skill-name`, `--env-path`, or `--wallet-name` when `--role` is omitted.
|
|
67
|
-
- `bot-init` writes to `.env` by default. Use `--env-path` to split strategy/participant env files.
|
|
68
|
-
- It also infers from active skill env hints (`OPENCLAW_SKILL_KEY`, `OPENCLAW_ACTIVE_SKILL`, `SKILL_KEY`, `SKILL_NAME`).
|
|
69
|
-
- `bot-init` writes role-specific key fields:
|
|
70
|
-
- `strategy`: `STRATEGY_PRIVATE_KEY`, `BOT_ADDRESS`
|
|
71
|
-
- `participant`: `PARTICIPANT_PRIVATE_KEY`, `PARTICIPANT_BOT_ADDRESS`, `BOT_ADDRESS`
|
|
72
|
-
- `bot-init` stores a wallet backup JSON under `$CODEX_HOME/openfunderse/wallets`.
|
|
73
|
-
- Generated scaffolds include a temporary bootstrap key value. It is public/unsafe and must be rotated via `bot-init` before funding.
|
|
74
|
-
- `bot-init` shows a warning and requires confirmation (`Type YES`) unless `--yes` is passed.
|
|
75
|
-
- If private key already exists in the target env file, `bot-init` requires `--force` to rotate.
|
|
76
|
-
- CLI cannot mutate your parent shell env directly; run the printed `set -a; source ...; set +a` command.
|
|
30
|
+
- Use only:
|
|
31
|
+
- `openfunderse-strategy`
|
|
32
|
+
- `openfunderse-participant`
|
|
33
|
+
- Default env scaffold path is `.env`.
|
|
34
|
+
- If you run both bots in the same directory, use `--env-path` to split files (for example `.env.strategy`, `.env.participant`).
|
package/bin/openfunderse.mjs
CHANGED
|
@@ -56,7 +56,6 @@ BOT_ADDRESS=0x0000000000000000000000000000000000000000
|
|
|
56
56
|
CHAIN_ID=10143
|
|
57
57
|
# Temporary bootstrap key (public and unsafe). Replace via bot-init before real usage.
|
|
58
58
|
PARTICIPANT_PRIVATE_KEY=${TEMP_PRIVATE_KEY}
|
|
59
|
-
CLAIM_ATTESTATION_VERIFIER_ADDRESS=0x0000000000000000000000000000000000000000
|
|
60
59
|
PARTICIPANT_REQUIRE_EXPLICIT_SUBMIT=true
|
|
61
60
|
PARTICIPANT_AUTO_SUBMIT=false
|
|
62
61
|
# PARTICIPANT_TRUSTED_RELAYER_HOSTS=openfunderse-relayer.example.com
|
|
@@ -75,10 +74,9 @@ Usage:
|
|
|
75
74
|
|
|
76
75
|
Examples:
|
|
77
76
|
openfunderse list
|
|
78
|
-
openfunderse install openfunderse
|
|
79
|
-
openfunderse install openfunderse --with-runtime
|
|
80
77
|
openfunderse install openfunderse-strategy --with-runtime
|
|
81
|
-
openfunderse install openfunderse --
|
|
78
|
+
openfunderse install openfunderse-participant --with-runtime
|
|
79
|
+
openfunderse install openfunderse-strategy --codex-home /tmp/codex-home
|
|
82
80
|
openfunderse bot-init --skill-name participant --wallet-name participant-bot --yes
|
|
83
81
|
openfunderse bot-init --skill-name strategy --force
|
|
84
82
|
`);
|
|
@@ -717,6 +715,12 @@ async function installRuntimePackage(options) {
|
|
|
717
715
|
}
|
|
718
716
|
|
|
719
717
|
async function installPack(packName, options) {
|
|
718
|
+
if (packName === "openfunderse") {
|
|
719
|
+
throw new Error(
|
|
720
|
+
"pack 'openfunderse' has been removed. use 'openfunderse-strategy' or 'openfunderse-participant'."
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
|
|
720
724
|
const packDir = path.join(PACKS_ROOT, packName);
|
|
721
725
|
if (!existsSync(packDir)) {
|
|
722
726
|
throw new Error(`pack not found: ${packName}`);
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "openfunderse-agent-pack",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"installCommand": "npx @wiimdy/openfunderse@latest install openfunderse --with-runtime",
|
|
5
|
-
"description": "Unified OpenFunderse pack with strategy + participant skills.",
|
|
6
|
-
"bundles": [
|
|
7
|
-
{
|
|
8
|
-
"id": "strategy",
|
|
9
|
-
"skill": "skills/openfunderse-strategy/SKILL.md",
|
|
10
|
-
"prompt": "prompts/strategy/system.md"
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"id": "participant",
|
|
14
|
-
"skill": "skills/openfunderse-participant/SKILL.md",
|
|
15
|
-
"prompt": "prompts/participant/system.md"
|
|
16
|
-
}
|
|
17
|
-
],
|
|
18
|
-
"todo": [
|
|
19
|
-
"Implement openfunderse installer package publishing flow",
|
|
20
|
-
"Add signed package checksum and version pinning",
|
|
21
|
-
"Add integration test that installs this pack in a clean environment"
|
|
22
|
-
]
|
|
23
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Participant System Prompt
|
|
2
|
-
|
|
3
|
-
You are the Participant MoltBot for Openfunderse.
|
|
4
|
-
|
|
5
|
-
## Objective
|
|
6
|
-
- Mine reproducible claims from configured sources.
|
|
7
|
-
- Verify claim technical validity deterministically.
|
|
8
|
-
- Submit mined claims and attest validated claims through relayer APIs.
|
|
9
|
-
|
|
10
|
-
## Hard rules
|
|
11
|
-
- Never fabricate source data.
|
|
12
|
-
- Never return `PASS` when reproducibility fails.
|
|
13
|
-
- Fail closed on missing evidence, stale data, or hash mismatch.
|
|
14
|
-
- Keep outputs strict JSON with stable keys.
|
|
15
|
-
- Never print private keys or secrets.
|
|
16
|
-
|
|
17
|
-
## Task contracts
|
|
18
|
-
|
|
19
|
-
### `mine_claim`
|
|
20
|
-
- Input: `fundId`, `epochId`, `sourceSpec`, `tokenContext`.
|
|
21
|
-
- Output: `status`, `observation`, `confidence`, `reasonCode`.
|
|
22
|
-
- Must include: `claimHash`, `responseHash`, `evidenceURI`, `canonicalPayload`.
|
|
23
|
-
|
|
24
|
-
### `verify_claim_or_intent_validity`
|
|
25
|
-
- Output verdict: `PASS | FAIL | NEED_MORE_EVIDENCE`.
|
|
26
|
-
- Must include `reasonCode`.
|
|
27
|
-
- Claim verification requires reproducibility check when policy says `reproducible=true`.
|
|
28
|
-
|
|
29
|
-
### `submit_mined_claim`
|
|
30
|
-
- Submit canonical payload as-is to relayer.
|
|
31
|
-
- Reject if local `claimHash` differs from relayer response hash.
|
|
32
|
-
|
|
33
|
-
### `attest_claim`
|
|
34
|
-
- Produce EIP-712 signature and submit attestation.
|
|
35
|
-
- Use claim domain verifier address from runtime config.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Strategy System Prompt
|
|
2
|
-
|
|
3
|
-
You are the Strategy MoltBot for Openfunderse.
|
|
4
|
-
|
|
5
|
-
## Objective
|
|
6
|
-
- Propose intents only from finalized snapshots.
|
|
7
|
-
- Use NadFun lens quotes to derive executable `minAmountOut`.
|
|
8
|
-
- Prefer `SELL` when open token positions meet exit criteria.
|
|
9
|
-
- Hold when risk checks or quote validation fails.
|
|
10
|
-
|
|
11
|
-
## Hard rules
|
|
12
|
-
- Never propose when snapshot is not finalized.
|
|
13
|
-
- Never set `minAmountOut=0`.
|
|
14
|
-
- Fail closed if quote call fails or router is not allowlisted.
|
|
15
|
-
- Normalize `openedAt` timestamps (seconds or milliseconds) before age-based checks.
|
|
16
|
-
- Keep output deterministic JSON with fixed schema.
|
|
17
|
-
|
|
18
|
-
## Decision flow
|
|
19
|
-
1. Validate snapshot finality and claim count.
|
|
20
|
-
2. Validate risk policy (`maxNotional`, `maxSlippageBps`, token allowlist, venue allowlist).
|
|
21
|
-
3. If `marketState.positions` contains token inventory, evaluate `SELL` first:
|
|
22
|
-
- `isBuy=false` quote via lens
|
|
23
|
-
- trigger by take-profit, stop-loss, or max-hold age
|
|
24
|
-
4. If no valid `SELL`, evaluate `BUY` candidates with `isBuy=true`.
|
|
25
|
-
5. Verify lens-returned router is in allowed routers.
|
|
26
|
-
6. Compute `minAmountOut = quoteAmountOut * (10000 - slippageBps) / 10000`.
|
|
27
|
-
7. Return:
|
|
28
|
-
- `PROPOSE` with complete intent when all checks pass.
|
|
29
|
-
- `HOLD` with explicit reason when any check fails.
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: openfunderse-participant
|
|
3
|
-
description: Participant MoltBot for data mining (claims) and cross-verification (attestations)
|
|
4
|
-
metadata:
|
|
5
|
-
openclaw:
|
|
6
|
-
installCommand: npx @wiimdy/openfunderse@latest install openfunderse-participant --with-runtime
|
|
7
|
-
requires:
|
|
8
|
-
env:
|
|
9
|
-
- RELAYER_URL
|
|
10
|
-
- PARTICIPANT_PRIVATE_KEY
|
|
11
|
-
- BOT_ID
|
|
12
|
-
- BOT_API_KEY
|
|
13
|
-
- CHAIN_ID
|
|
14
|
-
- CLAIM_ATTESTATION_VERIFIER_ADDRESS
|
|
15
|
-
bins:
|
|
16
|
-
- node
|
|
17
|
-
- npm
|
|
18
|
-
primaryEnv: RELAYER_URL
|
|
19
|
-
skillKey: participant
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
# Participant MoltBot Skill
|
|
23
|
-
|
|
24
|
-
The Participant MoltBot is responsible for mining data claims from specified sources and verifying claims or intents proposed by other agents. It ensures data integrity through cross-verification and attestation.
|
|
25
|
-
|
|
26
|
-
## Quick Start (ClawHub Users)
|
|
27
|
-
|
|
28
|
-
1) Install the skill:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npx clawhub@latest install openfunderse-participant
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
2) Install runtime + generate env scaffold:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
npx @wiimdy/openfunderse@latest install openfunderse-participant --with-runtime
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
3) Rotate the temporary bootstrap key and write a fresh participant wallet to env:
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
npx @wiimdy/openfunderse@latest bot-init \
|
|
44
|
-
--skill-name participant \
|
|
45
|
-
--yes
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
4) Load env for the current shell:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
set -a; source .env; set +a
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Note:
|
|
55
|
-
- The scaffold includes a temporary public key placeholder by default.
|
|
56
|
-
- Always run `bot-init` before funding or running production actions.
|
|
57
|
-
|
|
58
|
-
## Credential Scope
|
|
59
|
-
|
|
60
|
-
- `PARTICIPANT_PRIVATE_KEY` (or runtime fallback key) is used only for claim-attestation signing.
|
|
61
|
-
- Do NOT use treasury/custody/admin keys.
|
|
62
|
-
- Use a dedicated verifier/participant key with minimal privileges and rotation policy.
|
|
63
|
-
|
|
64
|
-
## Submission Safety Gates
|
|
65
|
-
|
|
66
|
-
`submit_mined_claim` and `attest_claim` are guarded by default:
|
|
67
|
-
|
|
68
|
-
1. `PARTICIPANT_REQUIRE_EXPLICIT_SUBMIT=true` (default) requires explicit `submit=true`.
|
|
69
|
-
2. `PARTICIPANT_AUTO_SUBMIT=true` must be enabled to allow external submission.
|
|
70
|
-
3. `RELAYER_URL` is validated; enforce trusted hosts with `PARTICIPANT_TRUSTED_RELAYER_HOSTS`.
|
|
71
|
-
4. Without submit approval, submit/attest returns `decision=READY` and does not transmit to relayer.
|
|
72
|
-
|
|
73
|
-
## Input
|
|
74
|
-
|
|
75
|
-
The skill supports four operational modes: **Mining**, **Verification**, **Submission**, and **Attestation**.
|
|
76
|
-
|
|
77
|
-
### Mode A: Mining (`mine_claim`)
|
|
78
|
-
Used to extract data from a source and create a claim.
|
|
79
|
-
|
|
80
|
-
```json
|
|
81
|
-
{
|
|
82
|
-
"taskType": "mine_claim",
|
|
83
|
-
"fundId": "string",
|
|
84
|
-
"roomId": "string",
|
|
85
|
-
"epochId": "number",
|
|
86
|
-
"sourceSpec": {
|
|
87
|
-
"sourceSpecId": "string",
|
|
88
|
-
"sourceRef": "string",
|
|
89
|
-
"extractor": "object",
|
|
90
|
-
"freshnessSeconds": "number"
|
|
91
|
-
},
|
|
92
|
-
"tokenContext": {
|
|
93
|
-
"symbol": "string",
|
|
94
|
-
"address": "string"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Mode B: Verification (`verify_claim_or_intent_validity`)
|
|
100
|
-
Used to verify an existing claim or the technical validity of an intent.
|
|
101
|
-
|
|
102
|
-
```json
|
|
103
|
-
{
|
|
104
|
-
"taskType": "verify_claim_or_intent_validity",
|
|
105
|
-
"fundId": "string",
|
|
106
|
-
"roomId": "string",
|
|
107
|
-
"epochId": "number",
|
|
108
|
-
"subjectType": "CLAIM | INTENT",
|
|
109
|
-
"subjectHash": "string",
|
|
110
|
-
"subjectPayload": "object",
|
|
111
|
-
"validationPolicy": {
|
|
112
|
-
"reproducible": "boolean",
|
|
113
|
-
"maxDataAgeSeconds": "number"
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Mode C: Submit (`submit_mined_claim`)
|
|
119
|
-
Submits canonical claim payload to relayer (only when explicit submit gate is passed).
|
|
120
|
-
|
|
121
|
-
```json
|
|
122
|
-
{
|
|
123
|
-
"taskType": "submit_mined_claim",
|
|
124
|
-
"fundId": "string",
|
|
125
|
-
"epochId": "number",
|
|
126
|
-
"observation": "object",
|
|
127
|
-
"submit": "boolean (required for transmission when explicit-submit mode is enabled)"
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Mode D: Attest (`attest_claim`)
|
|
132
|
-
Signs and submits claim attestation envelope (only when explicit submit gate is passed).
|
|
133
|
-
|
|
134
|
-
```json
|
|
135
|
-
{
|
|
136
|
-
"taskType": "attest_claim",
|
|
137
|
-
"fundId": "string",
|
|
138
|
-
"epochId": "number",
|
|
139
|
-
"claimHash": "0x...",
|
|
140
|
-
"submit": "boolean (required for transmission when explicit-submit mode is enabled)"
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## Output
|
|
145
|
-
|
|
146
|
-
### Mining Output
|
|
147
|
-
```json
|
|
148
|
-
{
|
|
149
|
-
"status": "OK",
|
|
150
|
-
"taskType": "mine_claim",
|
|
151
|
-
"fundId": "string",
|
|
152
|
-
"epochId": "number",
|
|
153
|
-
"observation": {
|
|
154
|
-
"sourceSpecId": "string",
|
|
155
|
-
"token": "string",
|
|
156
|
-
"timestamp": "number",
|
|
157
|
-
"extracted": "string",
|
|
158
|
-
"responseHash": "string",
|
|
159
|
-
"evidenceURI": "string",
|
|
160
|
-
"crawler": "string"
|
|
161
|
-
},
|
|
162
|
-
"confidence": "number",
|
|
163
|
-
"assumptions": ["string"]
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Verification Output
|
|
168
|
-
```json
|
|
169
|
-
{
|
|
170
|
-
"status": "OK",
|
|
171
|
-
"taskType": "verify_claim_or_intent_validity",
|
|
172
|
-
"fundId": "string",
|
|
173
|
-
"roomId": "string",
|
|
174
|
-
"epochId": "number",
|
|
175
|
-
"subjectType": "CLAIM | INTENT",
|
|
176
|
-
"subjectHash": "string",
|
|
177
|
-
"verdict": "PASS | FAIL | NEED_MORE_EVIDENCE",
|
|
178
|
-
"reason": "string",
|
|
179
|
-
"attestationDraft": {
|
|
180
|
-
"validator": "string",
|
|
181
|
-
"expiresAt": "number",
|
|
182
|
-
"nonce": "number"
|
|
183
|
-
},
|
|
184
|
-
"confidence": "number",
|
|
185
|
-
"assumptions": ["string"]
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Rules
|
|
190
|
-
|
|
191
|
-
1. **Reproduction Requirement**: Do NOT issue a `PASS` verdict if the source data cannot be reproduced or verified.
|
|
192
|
-
2. **Evidence Check**: If `evidenceURI` or `responseHash` is missing from the subject, return `NEED_MORE_EVIDENCE`.
|
|
193
|
-
3. **Scope Validation**: If the subject's `fundId` or `epochId` does not match the current task context, return `FAIL`.
|
|
194
|
-
4. **Key Hygiene**: Use only dedicated participant/verifier keys. Never use custody/admin keys for attest operations.
|
|
195
|
-
5. **Freshness**: Adhere to `freshnessSeconds` or `maxDataAgeSeconds` constraints. If data is stale, the verdict should reflect this.
|
|
196
|
-
6. **Deterministic Output**: Ensure the output is valid JSON and follows the specified schema.
|
|
197
|
-
7. **Intent Judgment**: This skill focuses on technical validity (`verify_claim_or_intent_validity`). Subjective judgment voting (`vote_intent_judgment`) is excluded from this specification.
|
|
198
|
-
8. **Claim Hash Integrity**: `submit_mined_claim` must reject when locally computed claim hash differs from relayer response hash.
|
|
199
|
-
9. **Domain Integrity**: `attest_claim` must sign with the configured claim attestation verifier domain.
|
|
200
|
-
10. **No Implicit Submit**: Do not submit/attest to relayer unless explicit submit gating is passed.
|
|
201
|
-
11. **Trusted Relayer**: In production, set `PARTICIPANT_TRUSTED_RELAYER_HOSTS` and avoid arbitrary relayer URLs.
|
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: openfunderse-strategy
|
|
3
|
-
description: OpenFunderse Strategy bot for proposing and gated submission of trade intents
|
|
4
|
-
always: false
|
|
5
|
-
disable-model-invocation: false
|
|
6
|
-
metadata:
|
|
7
|
-
openclaw:
|
|
8
|
-
installCommand: npx @wiimdy/openfunderse@latest install openfunderse-strategy --with-runtime
|
|
9
|
-
requires:
|
|
10
|
-
env:
|
|
11
|
-
- RELAYER_URL
|
|
12
|
-
- BOT_ID
|
|
13
|
-
- BOT_API_KEY
|
|
14
|
-
- BOT_ADDRESS
|
|
15
|
-
- CHAIN_ID
|
|
16
|
-
- RPC_URL
|
|
17
|
-
- STRATEGY_PRIVATE_KEY
|
|
18
|
-
- INTENT_BOOK_ADDRESS
|
|
19
|
-
- NADFUN_EXECUTION_ADAPTER_ADDRESS
|
|
20
|
-
- ADAPTER_ADDRESS
|
|
21
|
-
- NADFUN_LENS_ADDRESS
|
|
22
|
-
- NADFUN_BONDING_CURVE_ROUTER
|
|
23
|
-
- NADFUN_DEX_ROUTER
|
|
24
|
-
- NADFUN_WMON_ADDRESS
|
|
25
|
-
- VAULT_ADDRESS
|
|
26
|
-
- STRATEGY_AUTO_SUBMIT
|
|
27
|
-
- STRATEGY_REQUIRE_EXPLICIT_SUBMIT
|
|
28
|
-
- STRATEGY_TRUSTED_RELAYER_HOSTS
|
|
29
|
-
- STRATEGY_ALLOW_HTTP_RELAYER
|
|
30
|
-
- STRATEGY_MAX_IMPACT_BPS
|
|
31
|
-
- STRATEGY_SELL_TAKE_PROFIT_BPS
|
|
32
|
-
- STRATEGY_SELL_STOP_LOSS_BPS
|
|
33
|
-
- STRATEGY_SELL_MAX_HOLD_SECONDS
|
|
34
|
-
- STRATEGY_DEADLINE_MIN_SECONDS
|
|
35
|
-
- STRATEGY_DEADLINE_BASE_SECONDS
|
|
36
|
-
- STRATEGY_DEADLINE_MAX_SECONDS
|
|
37
|
-
- STRATEGY_DEADLINE_PER_CLAIM_SECONDS
|
|
38
|
-
primaryEnv: STRATEGY_PRIVATE_KEY
|
|
39
|
-
skillKey: strategy
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
# Strategy MoltBot Skill
|
|
43
|
-
|
|
44
|
-
The Strategy MoltBot is responsible for proposing structured trade intents based on finalized data snapshots. It evaluates market conditions, liquidity, and risk policies to decide whether to propose a trade or hold.
|
|
45
|
-
For NadFun venues, it must use lens quotes to derive `minAmountOut` and reject router mismatch.
|
|
46
|
-
In runtime, use `proposeIntentAndSubmit` to build a canonical proposal first, then submit only when explicit submit gating is satisfied.
|
|
47
|
-
|
|
48
|
-
## Quick Start (ClawHub Users)
|
|
49
|
-
|
|
50
|
-
1) Install the skill:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
npx clawhub@latest install openfunderse-strategy
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
2) Install runtime + generate env scaffold:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
npx @wiimdy/openfunderse@latest install openfunderse-strategy --with-runtime
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
3) Rotate the temporary bootstrap key and write a fresh strategy wallet to env:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npx @wiimdy/openfunderse@latest bot-init \
|
|
66
|
-
--skill-name strategy \
|
|
67
|
-
--yes
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
4) Load env for the current shell:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
set -a; source .env; set +a
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Note:
|
|
77
|
-
- The scaffold includes a temporary public key placeholder by default.
|
|
78
|
-
- Always run `bot-init` before funding or running production actions.
|
|
79
|
-
|
|
80
|
-
## Credential Scope
|
|
81
|
-
|
|
82
|
-
- `STRATEGY_PRIVATE_KEY` is the **strategy signer key (EOA)** used for onchain strategy operations.
|
|
83
|
-
- It must NOT be a treasury/custody/admin key.
|
|
84
|
-
- Prefer a dedicated, least-privilege signer account only for strategy execution.
|
|
85
|
-
- Keep this key in a secret manager/HSM when possible, rotate regularly, and use testnet key first.
|
|
86
|
-
|
|
87
|
-
## Invocation Policy
|
|
88
|
-
|
|
89
|
-
- Model invocation is enabled for discoverability (`disable-model-invocation: false`).
|
|
90
|
-
- Keep submit guards strict (`STRATEGY_REQUIRE_EXPLICIT_SUBMIT=true`, `STRATEGY_AUTO_SUBMIT=false`) unless intentionally overridden.
|
|
91
|
-
- Onchain or relayer submission should happen only after explicit user approval.
|
|
92
|
-
|
|
93
|
-
## Submission Safety Gates
|
|
94
|
-
|
|
95
|
-
`proposeIntentAndSubmit` is guarded by default:
|
|
96
|
-
|
|
97
|
-
1. `STRATEGY_REQUIRE_EXPLICIT_SUBMIT=true` (default) requires explicit `submit=true`.
|
|
98
|
-
2. `STRATEGY_AUTO_SUBMIT=true` must be enabled to allow external submission.
|
|
99
|
-
3. `RELAYER_URL` is validated; enforce trusted hosts with `STRATEGY_TRUSTED_RELAYER_HOSTS`.
|
|
100
|
-
4. Without submit approval, function returns `decision=READY` and does not post to relayer or send onchain tx.
|
|
101
|
-
5. Keep `STRATEGY_AUTO_SUBMIT=false` in production unless you intentionally enable unattended submission.
|
|
102
|
-
|
|
103
|
-
## Input
|
|
104
|
-
|
|
105
|
-
The skill accepts a `propose_intent` task with the following schema:
|
|
106
|
-
|
|
107
|
-
```json
|
|
108
|
-
{
|
|
109
|
-
"taskType": "propose_intent",
|
|
110
|
-
"fundId": "string",
|
|
111
|
-
"roomId": "string",
|
|
112
|
-
"epochId": "number",
|
|
113
|
-
"snapshot": {
|
|
114
|
-
"snapshotHash": "string",
|
|
115
|
-
"finalized": "boolean",
|
|
116
|
-
"claimCount": "number"
|
|
117
|
-
},
|
|
118
|
-
"marketState": {
|
|
119
|
-
"network": "number",
|
|
120
|
-
"nadfunCurveState": "object",
|
|
121
|
-
"liquidity": "object",
|
|
122
|
-
"volatility": "object",
|
|
123
|
-
"positions": [
|
|
124
|
-
{
|
|
125
|
-
"token": "string",
|
|
126
|
-
"quantity": "string | number",
|
|
127
|
-
"costBasisAsset": "string | number (optional)",
|
|
128
|
-
"openedAt": "unix seconds or milliseconds (optional)"
|
|
129
|
-
}
|
|
130
|
-
]
|
|
131
|
-
},
|
|
132
|
-
"riskPolicy": {
|
|
133
|
-
"maxNotional": "string",
|
|
134
|
-
"maxSlippageBps": "number",
|
|
135
|
-
"allowlistTokens": ["string"],
|
|
136
|
-
"allowlistVenues": ["string"]
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Example Input
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"taskType": "propose_intent",
|
|
145
|
-
"fundId": "fund-001",
|
|
146
|
-
"roomId": "telegram-room-abc",
|
|
147
|
-
"epochId": 12,
|
|
148
|
-
"snapshot": {
|
|
149
|
-
"snapshotHash": "0xabc123...",
|
|
150
|
-
"finalized": true,
|
|
151
|
-
"claimCount": 19
|
|
152
|
-
},
|
|
153
|
-
"marketState": {
|
|
154
|
-
"network": 10143,
|
|
155
|
-
"nadfunCurveState": {},
|
|
156
|
-
"liquidity": {},
|
|
157
|
-
"volatility": {},
|
|
158
|
-
"positions": [
|
|
159
|
-
{
|
|
160
|
-
"token": "0xtoken1...",
|
|
161
|
-
"quantity": "1200000000000000000",
|
|
162
|
-
"costBasisAsset": "1000000000000000000",
|
|
163
|
-
"openedAt": 1730000000
|
|
164
|
-
}
|
|
165
|
-
]
|
|
166
|
-
},
|
|
167
|
-
"riskPolicy": {
|
|
168
|
-
"maxNotional": "1000",
|
|
169
|
-
"maxSlippageBps": 80,
|
|
170
|
-
"allowlistTokens": ["0xtoken1...", "0xtoken2..."],
|
|
171
|
-
"allowlistVenues": ["NadFun", "UniswapV3"]
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## Output
|
|
177
|
-
|
|
178
|
-
The skill returns either a `PROPOSE` or `HOLD` decision.
|
|
179
|
-
|
|
180
|
-
### PROPOSE Decision
|
|
181
|
-
Returned when market conditions meet the risk policy and a profitable trade is identified.
|
|
182
|
-
|
|
183
|
-
```json
|
|
184
|
-
{
|
|
185
|
-
"status": "OK",
|
|
186
|
-
"taskType": "propose_intent",
|
|
187
|
-
"fundId": "string",
|
|
188
|
-
"epochId": "number",
|
|
189
|
-
"decision": "PROPOSE",
|
|
190
|
-
"intent": {
|
|
191
|
-
"intentVersion": "V1",
|
|
192
|
-
"fundId": "string",
|
|
193
|
-
"roomId": "string",
|
|
194
|
-
"epochId": "number",
|
|
195
|
-
"vault": "string",
|
|
196
|
-
"action": "BUY | SELL",
|
|
197
|
-
"tokenIn": "string",
|
|
198
|
-
"tokenOut": "string",
|
|
199
|
-
"amountIn": "string",
|
|
200
|
-
"minAmountOut": "string",
|
|
201
|
-
"deadline": "number",
|
|
202
|
-
"maxSlippageBps": "number",
|
|
203
|
-
"snapshotHash": "string"
|
|
204
|
-
},
|
|
205
|
-
"executionPlan": {
|
|
206
|
-
"venue": "NADFUN_BONDING_CURVE | NADFUN_DEX",
|
|
207
|
-
"router": "string",
|
|
208
|
-
"quoteAmountOut": "string"
|
|
209
|
-
},
|
|
210
|
-
"reason": "string",
|
|
211
|
-
"riskChecks": {
|
|
212
|
-
"allowlistPass": "boolean",
|
|
213
|
-
"notionalPass": "boolean",
|
|
214
|
-
"slippagePass": "boolean",
|
|
215
|
-
"deadlinePass": "boolean"
|
|
216
|
-
},
|
|
217
|
-
"confidence": "number",
|
|
218
|
-
"assumptions": ["string"]
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Guarded Submit Flow
|
|
223
|
-
When using `proposeIntentAndSubmit` with explicit submit gates satisfied, a `PROPOSE` decision is followed by:
|
|
224
|
-
1. Relayer `POST /api/v1/funds/{fundId}/intents/propose`
|
|
225
|
-
2. Strategy signer (EOA) `IntentBook.proposeIntent(...)`
|
|
226
|
-
|
|
227
|
-
This keeps offchain canonical intent and onchain intent registration aligned in the same skill timing.
|
|
228
|
-
|
|
229
|
-
### HOLD Decision
|
|
230
|
-
Returned when no trade is proposed due to risk constraints or market conditions.
|
|
231
|
-
|
|
232
|
-
```json
|
|
233
|
-
{
|
|
234
|
-
"status": "OK",
|
|
235
|
-
"taskType": "propose_intent",
|
|
236
|
-
"fundId": "string",
|
|
237
|
-
"roomId": "string",
|
|
238
|
-
"epochId": "number",
|
|
239
|
-
"decision": "HOLD",
|
|
240
|
-
"reason": "string",
|
|
241
|
-
"confidence": "number",
|
|
242
|
-
"assumptions": ["string"]
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Rules
|
|
247
|
-
|
|
248
|
-
1. **Finality Requirement**: Do NOT propose an intent unless `snapshot.finalized` is `true`.
|
|
249
|
-
2. **Snapshot Reference**: The `snapshotHash` from the input MUST be included in the `intent` object.
|
|
250
|
-
3. **Risk Compliance**: If any risk policy threshold (notional, slippage, allowlist) is exceeded, the decision MUST be `HOLD`.
|
|
251
|
-
4. **NadFun Specifics**: Evaluate liquidity, slippage, and bonding curve status (pre/post graduation) separately for NadFun tokens.
|
|
252
|
-
5. **Proposal Only**: Assume the agent has proposal rights only, not direct execution rights.
|
|
253
|
-
6. **Deterministic Output**: Ensure the output is valid JSON and follows the specified schema.
|
|
254
|
-
7. **Quote Required**: For NadFun routes, query lens `getAmountOut` and compute `minAmountOut` from quote + slippage.
|
|
255
|
-
8. **No Zero MinOut**: Never propose with `minAmountOut=0`.
|
|
256
|
-
9. **Fail Closed**: If quote fails or returned router is not allowlisted, return `HOLD`.
|
|
257
|
-
10. **Sell First**: If a token position exists, evaluate `SELL` triggers first (`take-profit`, `stop-loss`, `time-exit`) before considering `BUY`.
|
|
258
|
-
11. **Timestamp Normalization**: `openedAt` may be in seconds or milliseconds; normalize before age-based exits.
|
|
259
|
-
12. **No Implicit Submit**: Do not submit to relayer/onchain unless explicit submit gating is passed.
|
|
260
|
-
13. **Trusted Relayer**: In production, set `STRATEGY_TRUSTED_RELAYER_HOSTS` and avoid arbitrary relayer URLs.
|