@kaleidorg/mind 0.8.1 → 0.10.0
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 +7 -5
- package/dist/bitrefill/index.d.ts +4 -0
- package/dist/bitrefill/index.d.ts.map +1 -0
- package/dist/bitrefill/index.js +3 -0
- package/dist/bitrefill/index.js.map +1 -0
- package/dist/capabilities.d.ts +3 -3
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +4 -4
- package/dist/capabilities.js.map +1 -1
- package/dist/engine/answer.d.ts +37 -0
- package/dist/engine/answer.d.ts.map +1 -0
- package/dist/engine/answer.js +35 -0
- package/dist/engine/answer.js.map +1 -0
- package/dist/engine.d.ts +9 -3
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +159 -175
- package/dist/engine.js.map +1 -1
- package/dist/evidence.d.ts +1 -1
- package/dist/evidence.d.ts.map +1 -1
- package/dist/flashnet/index.d.ts +5 -0
- package/dist/flashnet/index.d.ts.map +1 -0
- package/dist/flashnet/index.js +4 -0
- package/dist/flashnet/index.js.map +1 -0
- package/dist/guards.d.ts.map +1 -1
- package/dist/guards.js +20 -0
- package/dist/guards.js.map +1 -1
- package/dist/index.d.ts +7 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -28
- package/dist/index.js.map +1 -1
- package/dist/kaleidoswap/contract.d.ts +7 -0
- package/dist/kaleidoswap/contract.d.ts.map +1 -1
- package/dist/kaleidoswap/contract.js +71 -17
- package/dist/kaleidoswap/contract.js.map +1 -1
- package/dist/kaleidoswap/index.d.ts +8 -0
- package/dist/kaleidoswap/index.d.ts.map +1 -0
- package/dist/kaleidoswap/index.js +7 -0
- package/dist/kaleidoswap/index.js.map +1 -0
- package/dist/knowledge/index.d.ts +9 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +6 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/lsps1/index.d.ts +4 -0
- package/dist/lsps1/index.d.ts.map +1 -0
- package/dist/lsps1/index.js +3 -0
- package/dist/lsps1/index.js.map +1 -0
- package/dist/providers/types.d.ts +3 -3
- package/dist/providers/types.js +3 -3
- package/dist/qvac/index.d.ts +0 -1
- package/dist/qvac/index.d.ts.map +1 -1
- package/dist/qvac/index.js +0 -1
- package/dist/qvac/index.js.map +1 -1
- package/dist/qvac/provider.d.ts +9 -9
- package/dist/qvac/provider.d.ts.map +1 -1
- package/dist/qvac/provider.js +115 -109
- package/dist/qvac/provider.js.map +1 -1
- package/dist/qvac/stream.d.ts +4 -3
- package/dist/qvac/stream.d.ts.map +1 -1
- package/dist/qvac/stream.js.map +1 -1
- package/dist/qvac/voice.d.ts +1 -1
- package/dist/recipe/asset-send.js +1 -1
- package/dist/recipe/asset-send.js.map +1 -1
- package/dist/submarine/index.d.ts +5 -0
- package/dist/submarine/index.d.ts.map +1 -0
- package/dist/submarine/index.js +4 -0
- package/dist/submarine/index.js.map +1 -0
- package/dist/testing/mock-wallet.d.ts.map +1 -1
- package/dist/testing/mock-wallet.js +6 -0
- package/dist/testing/mock-wallet.js.map +1 -1
- package/dist/tools/in-process.d.ts +2 -2
- package/dist/tools/in-process.js +2 -2
- package/dist/wallet/contract.d.ts +5 -0
- package/dist/wallet/contract.d.ts.map +1 -1
- package/dist/wallet/contract.js +39 -6
- package/dist/wallet/contract.js.map +1 -1
- package/package.json +32 -2
- package/scripts/snapshot-mcp-tools.mjs +38 -0
- package/skills/README.md +98 -64
- package/skills/bitrefill/SKILL.md +30 -157
- package/skills/channel-manager/SKILL.md +31 -52
- package/skills/flashnet-swaps/SKILL.md +24 -150
- package/skills/kaleido-node/SKILL.md +25 -55
- package/skills/kaleido-trading/SKILL.md +28 -172
- package/skills/kaleido-trading/references/assets.md +4 -4
- package/skills/kaleido-trading/references/atomic.md +5 -7
- package/skills/merchant-finder/SKILL.md +25 -108
- package/skills/paid-data/SKILL.md +25 -58
- package/skills/portfolio-manager/SKILL.md +26 -60
- package/skills/rgb-lightning-node/SKILL.md +37 -255
- package/skills/rgb-lightning-node/references/channels.md +34 -0
- package/skills/spark-wallet/SKILL.md +26 -228
- package/skills/submarine-swaps/SKILL.md +19 -37
- package/skills/wallet-assistant/SKILL.md +26 -44
- package/src/bitrefill/index.ts +13 -0
- package/src/capabilities.ts +7 -7
- package/src/context/context.test.ts +2 -2
- package/src/engine/answer.ts +66 -0
- package/src/engine.ts +185 -194
- package/src/evidence.ts +1 -1
- package/src/flashnet/index.ts +14 -0
- package/src/funnel.mind.test.ts +6 -5
- package/src/guards.test.ts +12 -0
- package/src/guards.ts +20 -0
- package/src/index.ts +11 -107
- package/src/kaleidoswap/contract.test.ts +32 -3
- package/src/kaleidoswap/contract.ts +65 -17
- package/src/kaleidoswap/index.ts +20 -0
- package/src/knowledge/index.ts +14 -0
- package/src/lsps1/index.ts +13 -0
- package/src/providers/types.ts +3 -3
- package/src/qvac/index.ts +0 -8
- package/src/qvac/provider.test.ts +17 -17
- package/src/qvac/provider.ts +33 -31
- package/src/qvac/stream.ts +4 -3
- package/src/qvac/voice.ts +1 -1
- package/src/recipe/asset-send.ts +1 -1
- package/src/recipe/recipe.test.ts +1 -1
- package/src/skills/catalog.test.ts +215 -0
- package/src/skills/mcp-tools.snapshot.json +1938 -0
- package/src/submarine/index.ts +17 -0
- package/src/testing/mock-wallet.ts +6 -0
- package/src/tools/in-process.ts +2 -2
- package/src/wallet/contract.test.ts +20 -1
- package/src/wallet/contract.ts +36 -6
- package/dist/qvac/delegate.d.ts +0 -50
- package/dist/qvac/delegate.d.ts.map +0 -1
- package/dist/qvac/delegate.js +0 -53
- package/dist/qvac/delegate.js.map +0 -1
- package/skills/dca/SKILL.md +0 -48
- package/skills/kaleido-lsps/SKILL.md +0 -131
- package/skills/liquidity-optimizer/SKILL.md +0 -91
- package/src/qvac/delegate.test.ts +0 -68
- package/src/qvac/delegate.ts +0 -73
|
@@ -1,117 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: merchant-finder
|
|
3
|
-
description: "Find
|
|
3
|
+
description: "Find places that accept Bitcoin (shops, restaurants, cafes, bars, ATMs) near the user or in a named city, from live BTC Map data."
|
|
4
4
|
tools: find_merchant_locations, search_knowledge
|
|
5
|
-
|
|
5
|
+
requires-tools: find_merchant_locations
|
|
6
|
+
triggers: merchant, merchants, shop, shops, store, restaurant, restaurants, cafe, cafes, coffee, bar, bars, atm, atms, near me, nearby, where can i spend, accept bitcoin, pizza, food, eat, btcmap, bitcoin map
|
|
6
7
|
metadata:
|
|
7
8
|
author: kaleidoswap
|
|
8
|
-
version: "0.
|
|
9
|
+
version: "0.4.0"
|
|
9
10
|
homepage: "https://btcmap.org"
|
|
10
11
|
---
|
|
11
|
-
|
|
12
12
|
# Merchant finder
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
conservatively. When in doubt, pass FEWER fields rather than guessing. The
|
|
36
|
-
tool and the live data (plus any RAG hits you also fetch) are the source of
|
|
37
|
-
truth — your job is to get the right starting call and then reason over
|
|
38
|
-
what comes back.
|
|
39
|
-
|
|
40
|
-
## Using your understanding (the model is meant to help here)
|
|
41
|
-
|
|
42
|
-
- Translate vague or natural language into the best minimal call:
|
|
43
|
-
- "coffee near the station", "grab a bite", "something to eat" → `query: "coffee"` or `"food"` / `"pizza"` (or leave descriptive terms in `query`); consider `category: "cafe"` or `"restaurant"` only when it clearly fits one of the allowed values.
|
|
44
|
-
- "near me for lunch" or "around here" → start with empty or just a broad `query`; let the device location do the work. You may infer a reasonable city from prior turns ("you mentioned Lugano earlier") and pass `near_address`.
|
|
45
|
-
- "ATMs or shops that take lightning" → `query: "atm"` or separate calls, or put "atm shop lightning" in `query`.
|
|
46
|
-
- "the cheaper ones", "with websites", "open late", "good for dinner" → use the tool first (possibly broad), then in the same or follow-up turn use the returned list + any other context/memory to filter, rank or describe. Do not fabricate entries.
|
|
47
|
-
- **Critical for currency terms**: "where can I spend sats in turin", "bitcoin merchants in X", "places that accept crypto" are generic spend requests. **Do not** put "sats", "btc", "bitcoin", "spend" into `query` or invent a `category` (e.g. "shop"). Use only `near_address` (or empty). Putting currency words in query almost always returns zero results because the data source already only contains Bitcoin-accepting places.
|
|
48
|
-
|
|
49
|
-
- Multi-turn and post-processing: After the merchant search tool returns a list you may (and should) reason over it: rank by distance or relevance to the user's phrasing, surface `phone`/`website`/`opening_hours` when present, note accepts_lightning, suggest next actions ("want directions or to check one?"), or combine with `search_knowledge` / memory results if merchants have been ingested for the area.
|
|
50
|
-
|
|
51
|
-
- Hybrid live + RAG: If a `search_knowledge` tool is available and a merchant corpus is loaded, you can use both the live finder (for freshness + distance) and search for background on an area or previously-seen places. Present live results as the actionable list.
|
|
52
|
-
|
|
53
|
-
- Context is fair game for *formulating the call or summarizing results* (e.g. previous city mentioned, user's preference for Lightning). It is never a substitute for calling the tool for the actual current list of places.
|
|
54
|
-
|
|
55
|
-
## How to call the tool
|
|
56
|
-
|
|
57
|
-
1. **Start with the merchant search tool.** Map the user's words to fields using the guidance above. The schema accepts:
|
|
58
|
-
|
|
59
|
-
- `query` — free-text the user effectively named or implied (e.g. "coffee", "pizza", "food", "tapas", "atm"). Good place for terms that don't match a strict category. **Omit entirely** for generic "spend sats", "where can I spend", "merchants", "places to spend bitcoin", or "accept crypto". **Never** put "sats", "sat", "bitcoin", "btc", "crypto", "spend", or similar currency/verb terms here — the data source is already Bitcoin-only and this will usually return zero results.
|
|
60
|
-
|
|
61
|
-
- `category` — **exactly one** of the allowed values when it fits cleanly: `restaurant`, `cafe`, `bar`, `shop`, `grocery`, `lodging`, `atm`. Leave empty otherwise. **For any generic "spend sats / where can I spend bitcoin / merchants in X" request, leave category empty.** Do not guess a category just because the user wants to spend. Generic nouns like "merchant", "place", "store" belong in `query` (or omitted), never as the category.
|
|
62
|
-
|
|
63
|
-
- `near_address` — city / neighborhood / address when the user named a place instead of (or in addition to) "near me". The host will geocode it.
|
|
64
|
-
|
|
65
|
-
- `radius_km` — only when the user gave a specific distance ("within 2 km"). Default (5 km) is already reasonable for a city; the backend applies a sensible bound.
|
|
66
|
-
|
|
67
|
-
- `limit` — only when the user named a count (1–20).
|
|
68
|
-
|
|
69
|
-
Positive examples (using understanding):
|
|
70
|
-
- "where can I spend btc near me" → use the tool with `{}`
|
|
71
|
-
- "where can I spend sats in turin" → use the tool with `{ near_address: "Turin" }` ← generic spend → minimal args, no query, no category
|
|
72
|
-
- "where can I spend btc in Lugano" → use the tool with `{ near_address: "Lugano" }`
|
|
73
|
-
- "cafes in Lisbon" → use the tool with `{ category: "cafe", near_address: "Lisbon" }`
|
|
74
|
-
- "pizza places in Switzerland that take bitcoin" → use the tool with `{ query: "pizza", near_address: "Switzerland" }`
|
|
75
|
-
- "lightning bars in NYC, within 2 km" → use the tool with `{ category: "bar", near_address: "New York", radius_km: 2 }`
|
|
76
|
-
- "coffee near the station" or "grab a bite around here" → use the tool with `{ query: "coffee" }` or `{ query: "food" }` (let location come from device or prior context)
|
|
77
|
-
- "ATMs or shops that take sats in the center" → first use the tool with `query: "atm shop"` + appropriate near_address; then reason over results.
|
|
78
|
-
|
|
79
|
-
Things that are still wrong (schema or data reasons):
|
|
80
|
-
- `category: "merchant"` or `"place"` (invalid per schema).
|
|
81
|
-
- `query: "sats"`, `"btc"`, `"bitcoin"`, or any currency/spend verb (the dataset is already Bitcoin-only; these filters return nothing or almost nothing useful. "Spend sats" is a generic merchant request, not a filter term).
|
|
82
|
-
- Guessing a tiny `radius_km` the user never mentioned (results will be empty).
|
|
83
|
-
- Inventing a `category` (like "shop") for a completely generic "where can I spend sats" query — use no category and let the data speak.
|
|
84
|
-
- Adding constraints the user did not name when a minimal call would have returned more relevant places.
|
|
85
|
-
|
|
86
|
-
**Real bad example that causes zero results**:
|
|
87
|
-
- "where can I spend sats in turin" → bad: use query "sats" + category "shop"
|
|
88
|
-
( "sats" in query + guessed category over-filters everything; correct is just the near_address or nothing).
|
|
89
|
-
|
|
90
|
-
2. **Present the results.** Each row carries:
|
|
91
|
-
- `name`, `category`, `address`
|
|
92
|
-
- `distance_m` when present — show in metres or km
|
|
93
|
-
- `accepts_bitcoin` / `accepts_lightning` — relevant because Lightning is
|
|
94
|
-
fastest for small payments
|
|
95
|
-
- `phone`, `website`, `opening_hours` when present — surface if asked or relevant
|
|
96
|
-
|
|
97
|
-
3. **Handling failures.** If the tool returns `{success:false, error}`, relay
|
|
98
|
-
the error as-is and stop. Common cases:
|
|
99
|
-
- "Merchant search is unavailable…" → the host has no BTC Map adapter.
|
|
100
|
-
- "Could not locate \"X\"…" → geocoding failed; ask the user for a nearby
|
|
101
|
-
city or check the spelling.
|
|
102
|
-
- "Could not determine your location…" → no `near_address` was passed and
|
|
103
|
-
the device has no GPS / default location.
|
|
104
|
-
|
|
105
|
-
Do NOT retry with invented data, and do NOT pretend you know merchants in
|
|
106
|
-
the area. There is no offline fallback — a failure means no data.
|
|
107
|
-
|
|
108
|
-
## Reply style
|
|
109
|
-
|
|
110
|
-
- **List, don't fabricate.** Show the merchants the tool actually returned (first ~5–8 is fine for long lists), one line each. You may add a short prose lead or helpful follow-up ("These are sorted by distance. The first two have websites.") but the names, categories, addresses and distances must come from the tool result in this turn.
|
|
111
|
-
- One line per merchant (example):
|
|
112
|
-
`Name — category, address (X m away, accepts: lightning, onchain)`.
|
|
113
|
-
- If zero merchants: say so plainly. Suggest widening radius or trying a `near_address`. Do not invent alternatives.
|
|
114
|
-
- When `precise_location` is false for a "near me" result, mention the fallback area that was used.
|
|
115
|
-
- After showing the list you are free to reason, rank, or ask a clarifying follow-up using the data + conversation context.
|
|
116
|
-
|
|
117
|
-
**Remember**: the live merchant search tool (plus any RAG merchant documents you also search) are the only sources of place information. Your value is excellent intent → arg mapping on the way in, and helpful reasoning / presentation on the way out. Do not name the tool in your user-facing reply.
|
|
14
|
+
Every place in a reply comes from `find_merchant_locations` in this turn. The
|
|
15
|
+
data is already Bitcoin-only.
|
|
16
|
+
|
|
17
|
+
## Do
|
|
18
|
+
- Pass the fewest arguments that express the request:
|
|
19
|
+
- `near_address` when the user names a place; omit it for "near me".
|
|
20
|
+
- `category` only for a clear venue type: `restaurant`, `cafe`, `bar`,
|
|
21
|
+
`shop`, `grocery`, `lodging`, `atm`.
|
|
22
|
+
- `query` for a food or name ("pizza", "coffee"). Never "sats", "btc",
|
|
23
|
+
"bitcoin" or "spend".
|
|
24
|
+
- `radius_km` / `limit` only when the user gave a distance or count.
|
|
25
|
+
- List the results, one line each: name, category, address, distance, and
|
|
26
|
+
whether Lightning is accepted. Up to about 8.
|
|
27
|
+
- `{success:false, error}` → relay the error and stop.
|
|
28
|
+
- `search_knowledge` may add background from a loaded merchant corpus.
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
- "Where can I spend sats in Turin?" → `find_merchant_locations {"near_address":"Turin"}`
|
|
32
|
+
- "Cafes in Lisbon" → `find_merchant_locations {"category":"cafe","near_address":"Lisbon"}`
|
|
33
|
+
- "Pizza near me that takes bitcoin" → `find_merchant_locations {"query":"pizza"}`
|
|
34
|
+
- "Bitcoin ATMs within 2 km" → `find_merchant_locations {"category":"atm","radius_km":2}`
|
|
@@ -1,65 +1,32 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: paid-data
|
|
3
|
-
description: Fetch
|
|
4
|
-
tools: fetch_paid_resource, search_paid_apis, mpp_request_challenge, mpp_parse_challenge_header,
|
|
5
|
-
triggers: premium, paid, l402, mpp, 402,
|
|
3
|
+
description: "Fetch data behind an HTTP 402 Lightning paywall (L402 or MPP): paid feeds, pay-per-call APIs, unlockable resources, and finding paid APIs in the 402index registry."
|
|
4
|
+
tools: fetch_paid_resource, search_paid_apis, mpp_request_challenge, mpp_parse_challenge_header, rln_mpp_pay, spark_mpp_pay, mpp_submit_credential, l402_request_challenge, l402_fetch_resource
|
|
5
|
+
triggers: premium, paid, l402, mpp, 402, paywall, pay per call, paid api, gated, unlock
|
|
6
6
|
metadata:
|
|
7
7
|
author: kaleidoswap
|
|
8
|
-
version: "0.
|
|
8
|
+
version: "0.3.0"
|
|
9
9
|
---
|
|
10
|
-
|
|
11
10
|
# Paid data
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
→ { paid, payment_hash, preimage?, credential: "<JSON string>" }
|
|
35
|
-
|
|
36
|
-
3. mpp_submit_credential({ url, credential }) ← pass credential verbatim
|
|
37
|
-
→ { ok, status, data, receipt }
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Finish all three before `expires_at` (~60 s); a credential is single-use, so
|
|
41
|
-
restart from step 1 if it expires. Keep the `receipt` as proof of payment.
|
|
42
|
-
|
|
43
|
-
- **Discovery:** `search_paid_apis({ query, protocol?, health: "healthy" })`
|
|
44
|
-
lists registered endpoints with their price; pick a healthy one, then run the
|
|
45
|
-
flow on its `url`.
|
|
46
|
-
- **Own fetch:** with a `WWW-Authenticate` header already in hand, use
|
|
47
|
-
`mpp_parse_challenge_header({ url, www_authenticate })` instead of step 1.
|
|
48
|
-
- **Legacy L402-only servers:** `l402_request_challenge` /
|
|
49
|
-
`l402_fetch_resource`. Prefer the `mpp_*` tools; they handle both.
|
|
50
|
-
- **Sessions:** `intent: "session"` challenges allow pay-once, then cheap
|
|
51
|
-
repeat calls. Not every server offers them; fall back to `charge`.
|
|
52
|
-
|
|
53
|
-
| Error | Meaning | Fix |
|
|
54
|
-
|---|---|---|
|
|
55
|
-
| `Expected HTTP 402` | URL is not payment-gated | Fetch it normally |
|
|
56
|
-
| `payment failed` | Route or balance problem | Check balances; try `spark_mpp_pay` |
|
|
57
|
-
| `401 after submit` | Bad or reused credential | Redo steps 1–3 |
|
|
58
|
-
| `challenge expired` | Too slow between steps | Restart from step 1 |
|
|
59
|
-
|
|
60
|
-
## Rules
|
|
61
|
-
|
|
62
|
-
1. Show `amount_sats` before paying; ask for a yes above 1,000 sats.
|
|
63
|
-
2. Only pay challenges for URLs the user asked for.
|
|
64
|
-
3. Stop after two failures in a row and report; don't loop.
|
|
65
|
-
4. Dry run: report the price and what you would fetch; never pay.
|
|
12
|
+
A server answers 402 with a Lightning invoice; you pay it and present the proof.
|
|
13
|
+
Use whichever tools are available.
|
|
14
|
+
|
|
15
|
+
## Do
|
|
16
|
+
- In-app: `fetch_paid_resource` with the `url` pays small invoices (capped by the host)
|
|
17
|
+
and returns the data. A declined payment is the answer; don't retry.
|
|
18
|
+
- kaleido-mcp, three steps before `expires_at` (~60 s):
|
|
19
|
+
1. `mpp_request_challenge` (`url`) → `challenge_id`, `invoice`, `amount_sats`.
|
|
20
|
+
2. `rln_mpp_pay` (`invoice`, `challenge_id`) (or `spark_mpp_pay`, same args) →
|
|
21
|
+
`credential`.
|
|
22
|
+
3. `mpp_submit_credential` (`url`, `credential`) with the credential unchanged.
|
|
23
|
+
- Show `amount_sats` before paying; ask for a yes above 1,000 sats. Pay only
|
|
24
|
+
for URLs the user asked for. Stop after two failures.
|
|
25
|
+
- Find APIs: `search_paid_apis` (`query`, `health: "healthy"`), then run the flow on
|
|
26
|
+
the chosen `url`.
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
- "Get the premium feed at https://api.example.com/feed" → `mpp_request_challenge {"url":"https://api.example.com/feed"}`
|
|
30
|
+
- "Pay that challenge" → `rln_mpp_pay {"invoice":"<invoice>","challenge_id":"<challenge_id>"}`
|
|
31
|
+
- "Any paid weather APIs?" → `search_paid_apis {"query":"weather","health":"healthy"}`
|
|
32
|
+
- In-app → `fetch_paid_resource {"url":"https://api.example.com/feed"}`
|
|
@@ -1,67 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: portfolio-manager
|
|
3
|
-
description: "
|
|
4
|
-
tools: rln_get_balances, rln_list_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_atomic_init,
|
|
5
|
-
|
|
3
|
+
description: "Portfolio across BTC, USDT and XAUT: holdings and allocation, drift versus targets, rebalancing and recurring DCA buys through KaleidoSwap atomic swaps. Runs the scheduled rebalance, DCA and daily summary tasks."
|
|
4
|
+
tools: rln_get_balances, rln_list_assets, get_price, get_market_data, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_atomic_init, rln_atomic_taker, rln_get_node_info, kaleidoswap_atomic_execute, kaleidoswap_atomic_status
|
|
5
|
+
requires-tools: kaleidoswap_get_quote
|
|
6
|
+
triggers: portfolio, allocation, rebalance, drift, target, weighting, holdings, dca, dollar cost average, recurring buy, average in, accumulate, daily summary
|
|
6
7
|
metadata:
|
|
7
8
|
author: kaleidoswap
|
|
8
|
-
version: "0.
|
|
9
|
+
version: "0.2.0"
|
|
9
10
|
---
|
|
10
|
-
|
|
11
11
|
# Portfolio manager
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
display fields the tools return; only convert sats↔USD with the live BTC
|
|
35
|
-
price.
|
|
36
|
-
3. **Compare to targets.** Targets come in the task parameters (e.g.
|
|
37
|
-
`BTC 70 / USDT 20 / XAUT 10`). Compute each asset's current weight and its
|
|
38
|
-
drift = current − target.
|
|
39
|
-
4. **Decide.** If the largest drift exceeds the threshold, the over-weight asset
|
|
40
|
-
sells into the most under-weight asset. One swap per run — smallest trade
|
|
41
|
-
that brings the worst drift back inside the band.
|
|
42
|
-
5. **Quote.** `kaleidoswap_get_quote(from, to, amount)` for that single leg.
|
|
43
|
-
6. **Execute** (only when `dry_run` is false and the size is within limits): the
|
|
44
|
-
atomic swap recipe drives `kaleidoswap_atomic_init` → `_execute`; then poll
|
|
45
|
-
`kaleidoswap_atomic_status`.
|
|
46
|
-
|
|
47
|
-
## Asset codes (canonical)
|
|
48
|
-
|
|
49
|
-
`BTC` (satoshis), `USDT` (not `USD`), `XAUT` (not `XAU`/gold).
|
|
50
|
-
|
|
51
|
-
## Scheduled (background) runs
|
|
52
|
-
|
|
53
|
-
When run by the `rebalance` loop, after deciding, return STRICT JSON only:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
{"task":"rebalance","timestamp":"<ISO8601>","action":"rebalance|noop","dry_run":<bool>,"reason":"<why>","details":{"from":"<asset>","to":"<asset>","amount":"<n>","drift":{}}}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
`action` is `noop` when within band. Put the human explanation in `reason`.
|
|
60
|
-
|
|
61
|
-
## Don'ts
|
|
62
|
-
|
|
63
|
-
- Don't invent prices, quotes, or balances — call the tool.
|
|
64
|
-
- Don't rebalance on noise — honor the drift threshold.
|
|
65
|
-
- Don't place more than one swap per run.
|
|
66
|
-
- Don't breach the reserve / stop-loss, ever.
|
|
67
|
-
- Don't execute anything when `dry_run` is true.
|
|
13
|
+
Holdings: BTC from `rln_get_balances`, RGB assets (with balances, raw units ÷
|
|
14
|
+
10^precision) from `rln_list_assets`. Prices from `get_price`. Targets, budget,
|
|
15
|
+
reserve and `dry_run` come from the task parameters or the user.
|
|
16
|
+
|
|
17
|
+
## Do
|
|
18
|
+
- Value each holding in one currency, compute weight and drift = weight −
|
|
19
|
+
target. Inside the threshold → no trade.
|
|
20
|
+
- Rebalance: one swap per run, the smallest that brings the worst drift back
|
|
21
|
+
inside the band, from the over-weight asset into the most under-weight one.
|
|
22
|
+
- DCA: buy the fixed slice every run; never catch up missed runs; skip when
|
|
23
|
+
BTC minus the slice would fall below the reserve.
|
|
24
|
+
- Quote with `kaleidoswap_get_quote` (display units). Execute only when
|
|
25
|
+
`dry_run` is false and within limits, via the atomic chain in the
|
|
26
|
+
`kaleido-trading` skill.
|
|
27
|
+
- Scheduled runs: `action` is `rebalance`, `buy`, `skip` or `noop`; put the
|
|
28
|
+
explanation in `reason`.
|
|
29
|
+
|
|
30
|
+
## Examples
|
|
31
|
+
- "Show my allocation" → `rln_get_balances {}` then `rln_list_assets {}` then `get_price {"asset":"BTC"}`
|
|
32
|
+
- "DCA 0.0002 BTC into USDT" → `kaleidoswap_get_quote {"from_asset_id":"BTC","to_asset_id":"USDT","from_amount":0.0002}`
|
|
33
|
+
- "Sell 50 USDT back to BTC" → `kaleidoswap_get_quote {"from_asset_id":"USDT","to_asset_id":"BTC","from_amount":50}`
|