starkfi 0.4.2 → 0.4.3
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 +59 -35
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<a href="https://starkfi.app">
|
|
3
|
-
<img src="landing/
|
|
3
|
+
<img src="landing/readme-banner.png" alt="StarkFi — The AI-native DeFi toolkit for Starknet" width="100%" />
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
<h1 align="center">StarkFi</h1>
|
|
8
|
-
|
|
9
7
|
<p align="center">
|
|
10
|
-
|
|
11
|
-
A production-grade CLI and MCP server that gives both developers and AI agents full access to swaps, multi-swap, atomic batch transactions, staking, lending, portfolio management, and gasless transactions — all powered by the <a href="https://github.com/keep-starknet-strange/starkzap">Starkzap SDK</a>.
|
|
8
|
+
A production-grade CLI, MCP server, and Telegram bot that gives both developers and AI agents full access to swaps, multi-swap, atomic batch transactions, staking, lending, portfolio management, and gasless transactions — all powered by the <a href="https://github.com/keep-starknet-strange/starkzap">Starkzap SDK</a>.
|
|
12
9
|
</p>
|
|
13
10
|
|
|
14
11
|
<p align="center">
|
|
@@ -31,42 +28,43 @@ Most DeFi tools are built for humans clicking buttons. StarkFi is built for **ag
|
|
|
31
28
|
- 💸 **Gas Abstraction Built-In** — Pay gas in STRK, ETH, USDC, USDT, or DAI via AVNU Paymaster, or let the developer sponsor gas entirely (gasfree mode)
|
|
32
29
|
- 📊 **Full Portfolio** — Unified view of balances, staking positions, and lending positions with USD values
|
|
33
30
|
- 🧪 **Simulate Everything** — Dry-run any transaction to estimate fees before broadcasting
|
|
31
|
+
- 💬 **Telegram Bot** — Chat-based DeFi via natural language, BYOAI model (OpenAI, Claude, Gemini)
|
|
34
32
|
|
|
35
33
|
---
|
|
36
34
|
|
|
37
35
|
## Architecture
|
|
38
36
|
|
|
39
37
|
```
|
|
40
|
-
|
|
41
|
-
│
|
|
42
|
-
│
|
|
43
|
-
│ ┌──────────┐
|
|
44
|
-
│ │ CLI │
|
|
45
|
-
│ │ (30+ │
|
|
46
|
-
│ │ commands)│
|
|
47
|
-
│ └────┬─────┘
|
|
48
|
-
│ │
|
|
49
|
-
│
|
|
50
|
-
│
|
|
51
|
-
│
|
|
52
|
-
│ │
|
|
53
|
-
│ │ ┌──────────┐ ┌──────────┐ ┌────────┐ ┌──────────┐
|
|
54
|
-
│ │ │ Fibrous │ │ Staking │ │ Vesu │ │ Batch │
|
|
55
|
-
│ │ │ Swap │ │ Lifecycle│ │ V2 │ │ Multicall│
|
|
56
|
-
│ │ └────┬─────┘ └────┬─────┘ └───┬────┘ └────┬─────┘
|
|
57
|
-
│ │
|
|
58
|
-
│ │ │
|
|
59
|
-
│ │ ┌───────────────┴───────────────────────────┐
|
|
60
|
-
│ │ │ Starkzap SDK (starkzap v1.0.0) │
|
|
61
|
-
│ │ │ Wallet · TxBuilder · Tokens · Paymaster │
|
|
62
|
-
│ │ └───────────────┬───────────────────────────┘
|
|
63
|
-
│
|
|
64
|
-
│ ▼
|
|
65
|
-
│ ┌──────────────────────────────────────┐ ┌──────────────────────┐
|
|
66
|
-
│ │ Auth Server (Hono + Privy TEE) │ │ AVNU Paymaster │
|
|
67
|
-
│ │ Email OTP · Wallet · Sign · Gas │ │ Gas Abstraction │
|
|
68
|
-
│ └──────────────────────────────────────┘ └──────────────────────┘
|
|
69
|
-
|
|
38
|
+
┌─────────────────────────────────────────────────────────────────────────────────────┐
|
|
39
|
+
│ StarkFi │
|
|
40
|
+
│ │
|
|
41
|
+
│ ┌──────────┐ ┌───────────────┐ ┌───────────────┐ ┌──────────────────────────┐ │
|
|
42
|
+
│ │ CLI │ │ MCP Server │ │ Agent Skills │ │ Telegram Bot │ │
|
|
43
|
+
│ │ (30+ │ │ (27 tools) │ │ (10 workflows) │ │ (BYOAI · Chat DeFi) │ │
|
|
44
|
+
│ │ commands)│ │ stdio transport│ │ npx starkfi │ │ OpenAI / Claude / │ │
|
|
45
|
+
│ └────┬─────┘ └──────┬────────┘ └──────┬─────────┘ │ Gemini │ │
|
|
46
|
+
│ │ │ │ └────────────┬─────────────┘ │
|
|
47
|
+
│ └───────────────┼──────────────────┼─────────────────────────┘ │
|
|
48
|
+
│ ▼ ▼ │
|
|
49
|
+
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
|
|
50
|
+
│ │ Service Layer │ │
|
|
51
|
+
│ │ ┌──────────┐ ┌──────────┐ ┌────────┐ ┌──────────┐ ┌──────────────┐ │ │
|
|
52
|
+
│ │ │ Fibrous │ │ Staking │ │ Vesu │ │ Batch │ │ Portfolio │ │ │
|
|
53
|
+
│ │ │ Swap │ │ Lifecycle│ │ V2 │ │ Multicall│ │ Dashboard │ │ │
|
|
54
|
+
│ │ └────┬─────┘ └────┬─────┘ └───┬────┘ └────┬─────┘ └──────┬───────┘ │ │
|
|
55
|
+
│ │ └─────────────┴────────────┴────────────┴───────────────┘ │ │
|
|
56
|
+
│ │ │ │ │
|
|
57
|
+
│ │ ┌───────────────┴───────────────────────────┐ │ │
|
|
58
|
+
│ │ │ Starkzap SDK (starkzap v1.0.0) │ │ │
|
|
59
|
+
│ │ │ Wallet · TxBuilder · Tokens · Paymaster │ │ │
|
|
60
|
+
│ │ └───────────────┬───────────────────────────┘ │ │
|
|
61
|
+
│ └───────────────────────┼───────────────────────────────────────────────────────┘ │
|
|
62
|
+
│ ▼ │
|
|
63
|
+
│ ┌──────────────────────────────────────┐ ┌──────────────────────┐ │
|
|
64
|
+
│ │ Auth Server (Hono + Privy TEE) │ │ AVNU Paymaster │ │
|
|
65
|
+
│ │ Email OTP · Wallet · Sign · Gas │ │ Gas Abstraction │ │
|
|
66
|
+
│ └──────────────────────────────────────┘ └──────────────────────┘ │
|
|
67
|
+
└─────────────────────────────────────────────────────────────────────────────────────┘
|
|
70
68
|
│
|
|
71
69
|
▼
|
|
72
70
|
┌──────────────────┐
|
|
@@ -371,6 +369,32 @@ See [`server/README.md`](server/README.md) for setup instructions.
|
|
|
371
369
|
|
|
372
370
|
---
|
|
373
371
|
|
|
372
|
+
## Telegram Bot
|
|
373
|
+
|
|
374
|
+
StarkFi has a dedicated **[Telegram bot](https://github.com/ahmetenesdur/starkfi-telegram-bot)** that brings DeFi to chat. Users interact with natural language — the bot translates commands into StarkFi operations.
|
|
375
|
+
|
|
376
|
+
**BYOAI Model** — each user provides their own API key (OpenAI, Claude, or Gemini). No shared keys, no centralized billing.
|
|
377
|
+
|
|
378
|
+
| Feature | Description |
|
|
379
|
+
| --- | --- |
|
|
380
|
+
| **Swap** | DEX-aggregated trading via Fibrous |
|
|
381
|
+
| **Stake** | Multi-token staking (STRK, WBTC, tBTC, SolvBTC, LBTC) |
|
|
382
|
+
| **Lend** | Supply, borrow, repay, withdraw, close on Vesu V2 |
|
|
383
|
+
| **Portfolio** | Balances with USD valuations and position health |
|
|
384
|
+
| **Batch** | Combine swap + stake + supply + send in one transaction |
|
|
385
|
+
| **Gas Modes** | Gasless (pay in ERC-20) and gasfree (developer-sponsored) |
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
git clone https://github.com/ahmetenesdur/starkfi-telegram-bot.git
|
|
389
|
+
cd starkfi-telegram-bot && pnpm install
|
|
390
|
+
cp .env.example .env # Configure TELEGRAM_BOT_TOKEN, BOT_ENCRYPTION_SECRET
|
|
391
|
+
pnpm dev
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
See the [starkfi-telegram-bot](https://github.com/ahmetenesdur/starkfi-telegram-bot) repo for full setup and deployment (Docker support included).
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
374
398
|
## Tech Stack
|
|
375
399
|
|
|
376
400
|
| Layer | Technology |
|
package/dist/index.js
CHANGED
|
@@ -106,7 +106,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
106
106
|
`:`[${o[c]}\r
|
|
107
107
|
]`;continue}n+=o[c],o[c]==="\\"?a=true:i&&o[c]==="]"?i=false:!i&&o[c]==="["&&(i=true);}try{new RegExp(n);}catch{return console.warn(`Could not convert regex pattern at ${t.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`),e.source}return n}function jb(e,t){if(t.target==="openAi"&&console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead."),t.target==="openApi3"&&e.keyType?._def.typeName===P.ZodEnum)return {type:"object",required:e.keyType._def.values,properties:e.keyType._def.values.reduce((o,n)=>({...o,[n]:ue(e.valueType._def,{...t,currentPath:[...t.currentPath,"properties",n]})??mt(t)}),{}),additionalProperties:t.rejectedAdditionalProperties};let r={type:"object",additionalProperties:ue(e.valueType._def,{...t,currentPath:[...t.currentPath,"additionalProperties"]})??t.allowedAdditionalProperties};if(t.target==="openApi3")return r;if(e.keyType?._def.typeName===P.ZodString&&e.keyType._def.checks?.length){let{type:o,...n}=Mb(e.keyType._def,t);return {...r,propertyNames:n}}else {if(e.keyType?._def.typeName===P.ZodEnum)return {...r,propertyNames:{enum:e.keyType._def.values}};if(e.keyType?._def.typeName===P.ZodBranded&&e.keyType._def.type._def.typeName===P.ZodString&&e.keyType._def.type._def.checks?.length){let{type:o,...n}=Bb(e.keyType._def,t);return {...r,propertyNames:n}}}return r}function T$(e,t){if(t.mapStrategy==="record")return jb(e,t);let r=ue(e.keyType._def,{...t,currentPath:[...t.currentPath,"items","items","0"]})||mt(t),o=ue(e.valueType._def,{...t,currentPath:[...t.currentPath,"items","items","1"]})||mt(t);return {type:"array",maxItems:125,items:{type:"array",items:[r,o],minItems:2,maxItems:2}}}function E$(e){let t=e.values,o=Object.keys(e.values).filter(a=>typeof t[t[a]]!="number").map(a=>t[a]),n=Array.from(new Set(o.map(a=>typeof a)));return {type:n.length===1?n[0]==="string"?"string":"number":["string","number"],enum:o}}function $$(e){return e.target==="openAi"?void 0:{not:mt({...e,currentPath:[...e.currentPath,"not"]})}}function A$(e){return e.target==="openApi3"?{enum:["null"],nullable:true}:{type:"null"}}var Bf={ZodString:"string",ZodNumber:"number",ZodBigInt:"integer",ZodBoolean:"boolean",ZodNull:"null"};function C$(e,t){if(t.target==="openApi3")return I$(e,t);let r=e.options instanceof Map?Array.from(e.options.values()):e.options;if(r.every(o=>o._def.typeName in Bf&&(!o._def.checks||!o._def.checks.length))){let o=r.reduce((n,a)=>{let i=Bf[a._def.typeName];return i&&!n.includes(i)?[...n,i]:n},[]);return {type:o.length>1?o:o[0]}}else if(r.every(o=>o._def.typeName==="ZodLiteral"&&!o.description)){let o=r.reduce((n,a)=>{let i=typeof a._def.value;switch(i){case "string":case "number":case "boolean":return [...n,i];case "bigint":return [...n,"integer"];case "object":if(a._def.value===null)return [...n,"null"];default:return n}},[]);if(o.length===r.length){let n=o.filter((a,i,s)=>s.indexOf(a)===i);return {type:n.length>1?n:n[0],enum:r.reduce((a,i)=>a.includes(i._def.value)?a:[...a,i._def.value],[])}}}else if(r.every(o=>o._def.typeName==="ZodEnum"))return {type:"string",enum:r.reduce((o,n)=>[...o,...n._def.values.filter(a=>!o.includes(a))],[])};return I$(e,t)}var I$=(e,t)=>{let r=(e.options instanceof Map?Array.from(e.options.values()):e.options).map((o,n)=>ue(o._def,{...t,currentPath:[...t.currentPath,"anyOf",`${n}`]})).filter(o=>!!o&&(!t.strictUnions||typeof o=="object"&&Object.keys(o).length>0));return r.length?{anyOf:r}:void 0};function O$(e,t){if(["ZodString","ZodNumber","ZodBigInt","ZodBoolean","ZodNull"].includes(e.innerType._def.typeName)&&(!e.innerType._def.checks||!e.innerType._def.checks.length))return t.target==="openApi3"?{type:Bf[e.innerType._def.typeName],nullable:true}:{type:[Bf[e.innerType._def.typeName],"null"]};if(t.target==="openApi3"){let o=ue(e.innerType._def,{...t,currentPath:[...t.currentPath]});return o&&"$ref"in o?{allOf:[o],nullable:true}:o&&{...o,nullable:true}}let r=ue(e.innerType._def,{...t,currentPath:[...t.currentPath,"anyOf","0"]});return r&&{anyOf:[r,{type:"null"}]}}function P$(e,t){let r={type:"number"};if(!e.checks)return r;for(let o of e.checks)switch(o.kind){case "int":r.type="integer",rS(r,"type",o.message,t);break;case "min":t.target==="jsonSchema7"?o.inclusive?Oe(r,"minimum",o.value,o.message,t):Oe(r,"exclusiveMinimum",o.value,o.message,t):(o.inclusive||(r.exclusiveMinimum=true),Oe(r,"minimum",o.value,o.message,t));break;case "max":t.target==="jsonSchema7"?o.inclusive?Oe(r,"maximum",o.value,o.message,t):Oe(r,"exclusiveMaximum",o.value,o.message,t):(o.inclusive||(r.exclusiveMaximum=true),Oe(r,"maximum",o.value,o.message,t));break;case "multipleOf":Oe(r,"multipleOf",o.value,o.message,t);break}return r}function R$(e,t){let r=t.target==="openAi",o={type:"object",properties:{}},n=[],a=e.shape();for(let s in a){let c=a[s];if(c===void 0||c._def===void 0)continue;let l=RZ(c);l&&r&&(c._def.typeName==="ZodOptional"&&(c=c._def.innerType),c.isNullable()||(c=c.nullable()),l=false);let d=ue(c._def,{...t,currentPath:[...t.currentPath,"properties",s],propertyPath:[...t.currentPath,"properties",s]});d!==void 0&&(o.properties[s]=d,l||n.push(s));}n.length&&(o.required=n);let i=PZ(e,t);return i!==void 0&&(o.additionalProperties=i),o}function PZ(e,t){if(e.catchall._def.typeName!=="ZodNever")return ue(e.catchall._def,{...t,currentPath:[...t.currentPath,"additionalProperties"]});switch(e.unknownKeys){case "passthrough":return t.allowedAdditionalProperties;case "strict":return t.rejectedAdditionalProperties;case "strip":return t.removeAdditionalStrategy==="strict"?t.allowedAdditionalProperties:t.rejectedAdditionalProperties}}function RZ(e){try{return e.isOptional()}catch{return true}}var N$=(e,t)=>{if(t.currentPath.toString()===t.propertyPath?.toString())return ue(e.innerType._def,t);let r=ue(e.innerType._def,{...t,currentPath:[...t.currentPath,"anyOf","1"]});return r?{anyOf:[{not:mt(t)},r]}:mt(t)};var D$=(e,t)=>{if(t.pipeStrategy==="input")return ue(e.in._def,t);if(t.pipeStrategy==="output")return ue(e.out._def,t);let r=ue(e.in._def,{...t,currentPath:[...t.currentPath,"allOf","0"]}),o=ue(e.out._def,{...t,currentPath:[...t.currentPath,"allOf",r?"1":"0"]});return {allOf:[r,o].filter(n=>n!==void 0)}};function U$(e,t){return ue(e.type._def,t)}function L$(e,t){let o={type:"array",uniqueItems:true,items:ue(e.valueType._def,{...t,currentPath:[...t.currentPath,"items"]})};return e.minSize&&Oe(o,"minItems",e.minSize.value,e.minSize.message,t),e.maxSize&&Oe(o,"maxItems",e.maxSize.value,e.maxSize.message,t),o}function z$(e,t){return e.rest?{type:"array",minItems:e.items.length,items:e.items.map((r,o)=>ue(r._def,{...t,currentPath:[...t.currentPath,"items",`${o}`]})).reduce((r,o)=>o===void 0?r:[...r,o],[]),additionalItems:ue(e.rest._def,{...t,currentPath:[...t.currentPath,"additionalItems"]})}:{type:"array",minItems:e.items.length,maxItems:e.items.length,items:e.items.map((r,o)=>ue(r._def,{...t,currentPath:[...t.currentPath,"items",`${o}`]})).reduce((r,o)=>o===void 0?r:[...r,o],[])}}function B$(e){return {not:mt(e)}}function M$(e){return mt(e)}var j$=(e,t)=>ue(e.innerType._def,t);var F$=(e,t,r)=>{switch(t){case P.ZodString:return Mb(e,r);case P.ZodNumber:return P$(e,r);case P.ZodObject:return R$(e,r);case P.ZodBigInt:return g$(e,r);case P.ZodBoolean:return b$();case P.ZodDate:return nS(e,r);case P.ZodUndefined:return B$(r);case P.ZodNull:return A$(r);case P.ZodArray:return h$(e,r);case P.ZodUnion:case P.ZodDiscriminatedUnion:return C$(e,r);case P.ZodIntersection:return w$(e,r);case P.ZodTuple:return z$(e,r);case P.ZodRecord:return jb(e,r);case P.ZodLiteral:return S$(e,r);case P.ZodEnum:return x$(e);case P.ZodNativeEnum:return E$(e);case P.ZodNullable:return O$(e,r);case P.ZodOptional:return N$(e,r);case P.ZodMap:return T$(e,r);case P.ZodSet:return L$(e,r);case P.ZodLazy:return ()=>e.getter()._def;case P.ZodPromise:return U$(e,r);case P.ZodNaN:case P.ZodNever:return $$(r);case P.ZodEffects:return v$(e,r);case P.ZodAny:return mt(r);case P.ZodUnknown:return M$(r);case P.ZodDefault:return _$(e,r);case P.ZodBranded:return Bb(e,r);case P.ZodReadonly:return j$(e,r);case P.ZodCatch:return y$(e,r);case P.ZodPipeline:return D$(e,r);case P.ZodFunction:case P.ZodVoid:case P.ZodSymbol:return;default:return (o=>{})()}};function ue(e,t,r=false){let o=t.seen.get(e);if(t.override){let s=t.override?.(e,t,o,r);if(s!==f$)return s}if(o&&!r){let s=NZ(o,t);if(s!==void 0)return s}let n={def:e,path:t.currentPath,jsonSchema:void 0};t.seen.set(e,n);let a=F$(e,e.typeName,t),i=typeof a=="function"?ue(a(),t):a;if(i&&DZ(e,t,i),t.postProcess){let s=t.postProcess(i,e,t);return n.jsonSchema=i,s}return n.jsonSchema=i,i}var NZ=(e,t)=>{switch(t.$refStrategy){case "root":return {$ref:e.path.join("/")};case "relative":return {$ref:zb(t.currentPath,e.path)};case "none":case "seen":return e.path.length<t.currentPath.length&&e.path.every((r,o)=>t.currentPath[o]===r)?(console.warn(`Recursive reference detected at ${t.currentPath.join("/")}! Defaulting to any`),mt(t)):t.$refStrategy==="seen"?mt(t):void 0}},DZ=(e,t,r)=>(e.description&&(r.description=e.description,t.markdownDescription&&(r.markdownDescription=e.description)),r);var iS=(e,t)=>{let r=p$(t),o=typeof t=="object"&&t.definitions?Object.entries(t.definitions).reduce((c,[l,d])=>({...c,[l]:ue(d._def,{...r,currentPath:[...r.basePath,r.definitionPath,l]},true)??mt(r)}),{}):void 0,n=typeof t=="string"?t:t?.nameStrategy==="title"?void 0:t?.name,a=ue(e._def,n===void 0?r:{...r,currentPath:[...r.basePath,r.definitionPath,n]},false)??mt(r),i=typeof t=="object"&&t.name!==void 0&&t.nameStrategy==="title"?t.name:void 0;i!==void 0&&(a.title=i),r.flags.hasReferencedOpenAiAnyType&&(o||(o={}),o[r.openAiAnyTypeName]||(o[r.openAiAnyTypeName]={type:["string","number","integer","boolean","array","null"],items:{$ref:r.$refStrategy==="relative"?"1":[...r.basePath,r.definitionPath,r.openAiAnyTypeName].join("/")}}));let s=n===void 0?o?{...a,[r.definitionPath]:o}:a:{$ref:[...r.$refStrategy==="relative"?[]:r.basePath,r.definitionPath,n].join("/"),[r.definitionPath]:{...o,[n]:a}};return r.target==="jsonSchema7"?s.$schema="http://json-schema.org/draft-07/schema#":(r.target==="jsonSchema2019-09"||r.target==="openAi")&&(s.$schema="https://json-schema.org/draft/2019-09/schema#"),r.target==="openAi"&&("anyOf"in s||"oneOf"in s||"allOf"in s||"type"in s&&Array.isArray(s.type))&&console.warn("Warning: OpenAI may not support schemas with unions as roots! Try wrapping it in an object property."),s};function UZ(e){return !e||e==="jsonSchema7"||e==="draft-7"?"draft-7":e==="jsonSchema2019-09"||e==="draft-2020-12"?"draft-2020-12":"draft-7"}function sS(e,t){return xn(e)?gs(e,{target:UZ(t?.target),io:t?.pipeStrategy??"input"}):iS(e,{strictUnions:t?.strictUnions??true,pipeStrategy:t?.pipeStrategy??"input"})}function cS(e){let r=Fa(e)?.method;if(!r)throw new Error("Schema is missing a method literal");let o=M0(r);if(typeof o!="string")throw new Error("Schema method literal must be a string");return o}function lS(e,t){let r=ja(e,t);if(!r.success)throw r.error;return r.data}var LZ=6e4,Fb=class{constructor(t){this._options=t,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this._taskProgressTokens=new Map,this._requestResolvers=new Map,this.setNotificationHandler(xb,r=>{this._oncancel(r);}),this.setNotificationHandler(Sb,r=>{this._onprogress(r);}),this.setRequestHandler(wb,r=>({})),this._taskStore=t?.taskStore,this._taskMessageQueue=t?.taskMessageQueue,this._taskStore&&(this.setRequestHandler(kb,async(r,o)=>{let n=await this._taskStore.getTask(r.params.taskId,o.sessionId);if(!n)throw new re(oe.InvalidParams,"Failed to retrieve task: Task not found");return {...n}}),this.setRequestHandler(Eb,async(r,o)=>{let n=async()=>{let a=r.params.taskId;if(this._taskMessageQueue){let s;for(;s=await this._taskMessageQueue.dequeue(a,o.sessionId);){if(s.type==="response"||s.type==="error"){let c=s.message,l=c.id,d=this._requestResolvers.get(l);if(d)if(this._requestResolvers.delete(l),s.type==="response")d(c);else {let u=c,f=new re(u.error.code,u.error.message,u.error.data);d(f);}else {let u=s.type==="response"?"Response":"Error";this._onerror(new Error(`${u} handler missing for request ${l}`));}continue}await this._transport?.send(s.message,{relatedRequestId:o.requestId});}}let i=await this._taskStore.getTask(a,o.sessionId);if(!i)throw new re(oe.InvalidParams,`Task not found: ${a}`);if(!Za(i.status))return await this._waitForTaskUpdate(a,o.signal),await n();if(Za(i.status)){let s=await this._taskStore.getTaskResult(a,o.sessionId);return this._clearTaskQueue(a),{...s,_meta:{...s._meta,[Ha]:{taskId:a}}}}return await n()};return await n()}),this.setRequestHandler($b,async(r,o)=>{try{let{tasks:n,nextCursor:a}=await this._taskStore.listTasks(r.params?.cursor,o.sessionId);return {tasks:n,nextCursor:a,_meta:{}}}catch(n){throw new re(oe.InvalidParams,`Failed to list tasks: ${n instanceof Error?n.message:String(n)}`)}}),this.setRequestHandler(Ib,async(r,o)=>{try{let n=await this._taskStore.getTask(r.params.taskId,o.sessionId);if(!n)throw new re(oe.InvalidParams,`Task not found: ${r.params.taskId}`);if(Za(n.status))throw new re(oe.InvalidParams,`Cannot cancel task in terminal status: ${n.status}`);await this._taskStore.updateTaskStatus(r.params.taskId,"cancelled","Client cancelled task execution.",o.sessionId),this._clearTaskQueue(r.params.taskId);let a=await this._taskStore.getTask(r.params.taskId,o.sessionId);if(!a)throw new re(oe.InvalidParams,`Task not found after cancellation: ${r.params.taskId}`);return {_meta:{},...a}}catch(n){throw n instanceof re?n:new re(oe.InvalidRequest,`Failed to cancel task: ${n instanceof Error?n.message:String(n)}`)}}));}async _oncancel(t){if(!t.params.requestId)return;this._requestHandlerAbortControllers.get(t.params.requestId)?.abort(t.params.reason);}_setupTimeout(t,r,o,n,a=false){this._timeoutInfo.set(t,{timeoutId:setTimeout(n,r),startTime:Date.now(),timeout:r,maxTotalTimeout:o,resetTimeoutOnProgress:a,onTimeout:n});}_resetTimeout(t){let r=this._timeoutInfo.get(t);if(!r)return false;let o=Date.now()-r.startTime;if(r.maxTotalTimeout&&o>=r.maxTotalTimeout)throw this._timeoutInfo.delete(t),re.fromError(oe.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:r.maxTotalTimeout,totalElapsed:o});return clearTimeout(r.timeoutId),r.timeoutId=setTimeout(r.onTimeout,r.timeout),true}_cleanupTimeout(t){let r=this._timeoutInfo.get(t);r&&(clearTimeout(r.timeoutId),this._timeoutInfo.delete(t));}async connect(t){if(this._transport)throw new Error("Already connected to a transport. Call close() before connecting to a new transport, or use a separate Protocol instance per connection.");this._transport=t;let r=this.transport?.onclose;this._transport.onclose=()=>{r?.(),this._onclose();};let o=this.transport?.onerror;this._transport.onerror=a=>{o?.(a),this._onerror(a);};let n=this._transport?.onmessage;this._transport.onmessage=(a,i)=>{n?.(a,i),Cf(a)||e$(a)?this._onresponse(a):F2(a)?this._onrequest(a,i):Q9(a)?this._onnotification(a):this._onerror(new Error(`Unknown message type: ${JSON.stringify(a)}`));},await this._transport.start();}_onclose(){let t=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._taskProgressTokens.clear(),this._pendingDebouncedNotifications.clear();for(let o of this._requestHandlerAbortControllers.values())o.abort();this._requestHandlerAbortControllers.clear();let r=re.fromError(oe.ConnectionClosed,"Connection closed");this._transport=void 0,this.onclose?.();for(let o of t.values())o(r);}_onerror(t){this.onerror?.(t);}_onnotification(t){let r=this._notificationHandlers.get(t.method)??this.fallbackNotificationHandler;r!==void 0&&Promise.resolve().then(()=>r(t)).catch(o=>this._onerror(new Error(`Uncaught error in notification handler: ${o}`)));}_onrequest(t,r){let o=this._requestHandlers.get(t.method)??this.fallbackRequestHandler,n=this._transport,a=t.params?._meta?.[Ha]?.taskId;if(o===void 0){let d={jsonrpc:"2.0",id:t.id,error:{code:oe.MethodNotFound,message:"Method not found"}};a&&this._taskMessageQueue?this._enqueueTaskMessage(a,{type:"error",message:d,timestamp:Date.now()},n?.sessionId).catch(u=>this._onerror(new Error(`Failed to enqueue error response: ${u}`))):n?.send(d).catch(u=>this._onerror(new Error(`Failed to send an error response: ${u}`)));return}let i=new AbortController;this._requestHandlerAbortControllers.set(t.id,i);let s=Y9(t.params)?t.params.task:void 0,c=this._taskStore?this.requestTaskStore(t,n?.sessionId):void 0,l={signal:i.signal,sessionId:n?.sessionId,_meta:t.params?._meta,sendNotification:async d=>{if(i.signal.aborted)return;let u={relatedRequestId:t.id};a&&(u.relatedTask={taskId:a}),await this.notification(d,u);},sendRequest:async(d,u,f)=>{if(i.signal.aborted)throw new re(oe.ConnectionClosed,"Request was cancelled");let m={...f,relatedRequestId:t.id};a&&!m.relatedTask&&(m.relatedTask={taskId:a});let p=m.relatedTask?.taskId??a;return p&&c&&await c.updateTaskStatus(p,"input_required"),await this.request(d,u,m)},authInfo:r?.authInfo,requestId:t.id,requestInfo:r?.requestInfo,taskId:a,taskStore:c,taskRequestedTtl:s?.ttl,closeSSEStream:r?.closeSSEStream,closeStandaloneSSEStream:r?.closeStandaloneSSEStream};Promise.resolve().then(()=>{s&&this.assertTaskHandlerCapability(t.method);}).then(()=>o(t,l)).then(async d=>{if(i.signal.aborted)return;let u={result:d,jsonrpc:"2.0",id:t.id};a&&this._taskMessageQueue?await this._enqueueTaskMessage(a,{type:"response",message:u,timestamp:Date.now()},n?.sessionId):await n?.send(u);},async d=>{if(i.signal.aborted)return;let u={jsonrpc:"2.0",id:t.id,error:{code:Number.isSafeInteger(d.code)?d.code:oe.InternalError,message:d.message??"Internal error",...d.data!==void 0&&{data:d.data}}};a&&this._taskMessageQueue?await this._enqueueTaskMessage(a,{type:"error",message:u,timestamp:Date.now()},n?.sessionId):await n?.send(u);}).catch(d=>this._onerror(new Error(`Failed to send response: ${d}`))).finally(()=>{this._requestHandlerAbortControllers.delete(t.id);});}_onprogress(t){let{progressToken:r,...o}=t.params,n=Number(r),a=this._progressHandlers.get(n);if(!a){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(t)}`));return}let i=this._responseHandlers.get(n),s=this._timeoutInfo.get(n);if(s&&i&&s.resetTimeoutOnProgress)try{this._resetTimeout(n);}catch(c){this._responseHandlers.delete(n),this._progressHandlers.delete(n),this._cleanupTimeout(n),i(c);return}a(o);}_onresponse(t){let r=Number(t.id),o=this._requestResolvers.get(r);if(o){if(this._requestResolvers.delete(r),Cf(t))o(t);else {let i=new re(t.error.code,t.error.message,t.error.data);o(i);}return}let n=this._responseHandlers.get(r);if(n===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(t)}`));return}this._responseHandlers.delete(r),this._cleanupTimeout(r);let a=false;if(Cf(t)&&t.result&&typeof t.result=="object"){let i=t.result;if(i.task&&typeof i.task=="object"){let s=i.task;typeof s.taskId=="string"&&(a=true,this._taskProgressTokens.set(s.taskId,r));}}if(a||this._progressHandlers.delete(r),Cf(t))n(t);else {let i=re.fromError(t.error.code,t.error.message,t.error.data);n(i);}}get transport(){return this._transport}async close(){await this._transport?.close();}async*requestStream(t,r,o){let{task:n}=o??{};if(!n){try{yield {type:"result",result:await this.request(t,r,o)};}catch(i){yield {type:"error",error:i instanceof re?i:new re(oe.InternalError,String(i))};}return}let a;try{let i=await this.request(t,Pl,o);if(i.task)a=i.task.taskId,yield {type:"taskCreated",task:i.task};else throw new re(oe.InternalError,"Task creation did not return a task");for(;;){let s=await this.getTask({taskId:a},o);if(yield {type:"taskStatus",task:s},Za(s.status)){s.status==="completed"?yield {type:"result",result:await this.getTaskResult({taskId:a},r,o)}:s.status==="failed"?yield {type:"error",error:new re(oe.InternalError,`Task ${a} failed`)}:s.status==="cancelled"&&(yield {type:"error",error:new re(oe.InternalError,`Task ${a} was cancelled`)});return}if(s.status==="input_required"){yield {type:"result",result:await this.getTaskResult({taskId:a},r,o)};return}let c=s.pollInterval??this._options?.defaultTaskPollInterval??1e3;await new Promise(l=>setTimeout(l,c)),o?.signal?.throwIfAborted();}}catch(i){yield {type:"error",error:i instanceof re?i:new re(oe.InternalError,String(i))};}}request(t,r,o){let{relatedRequestId:n,resumptionToken:a,onresumptiontoken:i,task:s,relatedTask:c}=o??{};return new Promise((l,d)=>{let u=v=>{d(v);};if(!this._transport){u(new Error("Not connected"));return}if(this._options?.enforceStrictCapabilities===true)try{this.assertCapabilityForMethod(t.method),s&&this.assertTaskCapability(t.method);}catch(v){u(v);return}o?.signal?.throwIfAborted();let f=this._requestMessageId++,m={...t,jsonrpc:"2.0",id:f};o?.onprogress&&(this._progressHandlers.set(f,o.onprogress),m.params={...t.params,_meta:{...t.params?._meta||{},progressToken:f}}),s&&(m.params={...m.params,task:s}),c&&(m.params={...m.params,_meta:{...m.params?._meta||{},[Ha]:c}});let p=v=>{this._responseHandlers.delete(f),this._progressHandlers.delete(f),this._cleanupTimeout(f),this._transport?.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:f,reason:String(v)}},{relatedRequestId:n,resumptionToken:a,onresumptiontoken:i}).catch(y=>this._onerror(new Error(`Failed to send cancellation: ${y}`)));let _=v instanceof re?v:new re(oe.RequestTimeout,String(v));d(_);};this._responseHandlers.set(f,v=>{if(!o?.signal?.aborted){if(v instanceof Error)return d(v);try{let _=ja(r,v.result);_.success?l(_.data):d(_.error);}catch(_){d(_);}}}),o?.signal?.addEventListener("abort",()=>{p(o?.signal?.reason);});let h=o?.timeout??LZ,g=()=>p(re.fromError(oe.RequestTimeout,"Request timed out",{timeout:h}));this._setupTimeout(f,h,o?.maxTotalTimeout,g,o?.resetTimeoutOnProgress??false);let b=c?.taskId;if(b){let v=_=>{let y=this._responseHandlers.get(f);y?y(_):this._onerror(new Error(`Response handler missing for side-channeled request ${f}`));};this._requestResolvers.set(f,v),this._enqueueTaskMessage(b,{type:"request",message:m,timestamp:Date.now()}).catch(_=>{this._cleanupTimeout(f),d(_);});}else this._transport.send(m,{relatedRequestId:n,resumptionToken:a,onresumptiontoken:i}).catch(v=>{this._cleanupTimeout(f),d(v);});})}async getTask(t,r){return this.request({method:"tasks/get",params:t},Tb,r)}async getTaskResult(t,r,o){return this.request({method:"tasks/result",params:t},r,o)}async listTasks(t,r){return this.request({method:"tasks/list",params:t},Ab,r)}async cancelTask(t,r){return this.request({method:"tasks/cancel",params:t},n$,r)}async notification(t,r){if(!this._transport)throw new Error("Not connected");this.assertNotificationCapability(t.method);let o=r?.relatedTask?.taskId;if(o){let s={...t,jsonrpc:"2.0",params:{...t.params,_meta:{...t.params?._meta||{},[Ha]:r.relatedTask}}};await this._enqueueTaskMessage(o,{type:"notification",message:s,timestamp:Date.now()});return}if((this._options?.debouncedNotificationMethods??[]).includes(t.method)&&!t.params&&!r?.relatedRequestId&&!r?.relatedTask){if(this._pendingDebouncedNotifications.has(t.method))return;this._pendingDebouncedNotifications.add(t.method),Promise.resolve().then(()=>{if(this._pendingDebouncedNotifications.delete(t.method),!this._transport)return;let s={...t,jsonrpc:"2.0"};r?.relatedTask&&(s={...s,params:{...s.params,_meta:{...s.params?._meta||{},[Ha]:r.relatedTask}}}),this._transport?.send(s,r).catch(c=>this._onerror(c));});return}let i={...t,jsonrpc:"2.0"};r?.relatedTask&&(i={...i,params:{...i.params,_meta:{...i.params?._meta||{},[Ha]:r.relatedTask}}}),await this._transport.send(i,r);}setRequestHandler(t,r){let o=cS(t);this.assertRequestHandlerCapability(o),this._requestHandlers.set(o,(n,a)=>{let i=lS(t,n);return Promise.resolve(r(i,a))});}removeRequestHandler(t){this._requestHandlers.delete(t);}assertCanSetRequestHandler(t){if(this._requestHandlers.has(t))throw new Error(`A request handler for ${t} already exists, which would be overridden`)}setNotificationHandler(t,r){let o=cS(t);this._notificationHandlers.set(o,n=>{let a=lS(t,n);return Promise.resolve(r(a))});}removeNotificationHandler(t){this._notificationHandlers.delete(t);}_cleanupTaskProgressHandler(t){let r=this._taskProgressTokens.get(t);r!==void 0&&(this._progressHandlers.delete(r),this._taskProgressTokens.delete(t));}async _enqueueTaskMessage(t,r,o){if(!this._taskStore||!this._taskMessageQueue)throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");let n=this._options?.maxTaskQueueSize;await this._taskMessageQueue.enqueue(t,r,o,n);}async _clearTaskQueue(t,r){if(this._taskMessageQueue){let o=await this._taskMessageQueue.dequeueAll(t,r);for(let n of o)if(n.type==="request"&&F2(n.message)){let a=n.message.id,i=this._requestResolvers.get(a);i?(i(new re(oe.InternalError,"Task cancelled or completed")),this._requestResolvers.delete(a)):this._onerror(new Error(`Resolver missing for request ${a} during task ${t} cleanup`));}}}async _waitForTaskUpdate(t,r){let o=this._options?.defaultTaskPollInterval??1e3;try{let n=await this._taskStore?.getTask(t);n?.pollInterval&&(o=n.pollInterval);}catch{}return new Promise((n,a)=>{if(r.aborted){a(new re(oe.InvalidRequest,"Request cancelled"));return}let i=setTimeout(n,o);r.addEventListener("abort",()=>{clearTimeout(i),a(new re(oe.InvalidRequest,"Request cancelled"));},{once:true});})}requestTaskStore(t,r){let o=this._taskStore;if(!o)throw new Error("No task store configured");return {createTask:async n=>{if(!t)throw new Error("No request provided");return await o.createTask(n,t.id,{method:t.method,params:t.params},r)},getTask:async n=>{let a=await o.getTask(n,r);if(!a)throw new re(oe.InvalidParams,"Failed to retrieve task: Task not found");return a},storeTaskResult:async(n,a,i)=>{await o.storeTaskResult(n,a,i,r);let s=await o.getTask(n,r);if(s){let c=Df.parse({method:"notifications/tasks/status",params:s});await this.notification(c),Za(s.status)&&this._cleanupTaskProgressHandler(n);}},getTaskResult:n=>o.getTaskResult(n,r),updateTaskStatus:async(n,a,i)=>{let s=await o.getTask(n,r);if(!s)throw new re(oe.InvalidParams,`Task "${n}" not found - it may have been cleaned up`);if(Za(s.status))throw new re(oe.InvalidParams,`Cannot update task "${n}" from terminal status "${s.status}" to "${a}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);await o.updateTaskStatus(n,a,i,r);let c=await o.getTask(n,r);if(c){let l=Df.parse({method:"notifications/tasks/status",params:c});await this.notification(l),Za(c.status)&&this._cleanupTaskProgressHandler(n);}},listTasks:n=>o.listTasks(n,r)}}};function V$(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function H$(e,t){let r={...e};for(let o in t){let n=o,a=t[n];if(a===void 0)continue;let i=r[n];V$(i)&&V$(a)?r[n]={...i,...a}:r[n]=a;}return r}var CI=W1(Wk()),OI=W1(II());function AJ(){let e=new CI.default({strict:false,validateFormats:true,validateSchema:false,allErrors:true});return (0, OI.default)(e),e}var ky=class{constructor(t){this._ajv=t??AJ();}getValidator(t){let r="$id"in t&&typeof t.$id=="string"?this._ajv.getSchema(t.$id)??this._ajv.compile(t):this._ajv.compile(t);return o=>r(o)?{valid:true,data:o,errorMessage:void 0}:{valid:false,data:void 0,errorMessage:this._ajv.errorsText(r.errors)}}};var Ty=class{constructor(t){this._server=t;}requestStream(t,r,o){return this._server.requestStream(t,r,o)}createMessageStream(t,r){let o=this._server.getClientCapabilities();if((t.tools||t.toolChoice)&&!o?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let n=t.messages[t.messages.length-1],a=Array.isArray(n.content)?n.content:[n.content],i=a.some(d=>d.type==="tool_result"),s=t.messages.length>1?t.messages[t.messages.length-2]:void 0,c=s?Array.isArray(s.content)?s.content:[s.content]:[],l=c.some(d=>d.type==="tool_use");if(i){if(a.some(d=>d.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!l)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(l){let d=new Set(c.filter(f=>f.type==="tool_use").map(f=>f.id)),u=new Set(a.filter(f=>f.type==="tool_result").map(f=>f.toolUseId));if(d.size!==u.size||![...d].every(f=>u.has(f)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return this.requestStream({method:"sampling/createMessage",params:t},zf,r)}elicitInputStream(t,r){let o=this._server.getClientCapabilities(),n=t.mode??"form";switch(n){case "url":{if(!o?.elicitation?.url)throw new Error("Client does not support url elicitation.");break}case "form":{if(!o?.elicitation?.form)throw new Error("Client does not support form elicitation.");break}}let a=n==="form"&&t.mode===void 0?{...t,mode:"form"}:t;return this.requestStream({method:"elicitation/create",params:a},Dl,r)}async getTask(t,r){return this._server.getTask({taskId:t},r)}async getTaskResult(t,r,o){return this._server.getTaskResult({taskId:t},r,o)}async listTasks(t,r){return this._server.listTasks(t?{cursor:t}:void 0,r)}async cancelTask(t,r){return this._server.cancelTask({taskId:t},r)}};function PI(e,t,r){if(!e)throw new Error(`${r} does not support task creation (required for ${t})`);switch(t){case "tools/call":if(!e.tools?.call)throw new Error(`${r} does not support task creation for tools/call (required for ${t})`);break;}}function RI(e,t,r){if(!e)throw new Error(`${r} does not support task creation (required for ${t})`);switch(t){case "sampling/createMessage":if(!e.sampling?.createMessage)throw new Error(`${r} does not support task creation for sampling/createMessage (required for ${t})`);break;case "elicitation/create":if(!e.elicitation?.create)throw new Error(`${r} does not support task creation for elicitation/create (required for ${t})`);break;}}var Ey=class extends Fb{constructor(t,r){super(r),this._serverInfo=t,this._loggingLevels=new Map,this.LOG_LEVEL_SEVERITY=new Map(Lf.options.map((o,n)=>[o,n])),this.isMessageIgnored=(o,n)=>{let a=this._loggingLevels.get(n);return a?this.LOG_LEVEL_SEVERITY.get(o)<this.LOG_LEVEL_SEVERITY.get(a):false},this._capabilities=r?.capabilities??{},this._instructions=r?.instructions,this._jsonSchemaValidator=r?.jsonSchemaValidator??new ky,this.setRequestHandler(Z2,o=>this._oninitialize(o)),this.setNotificationHandler(q2,()=>this.oninitialized?.()),this._capabilities.logging&&this.setRequestHandler(Q2,async(o,n)=>{let a=n.sessionId||n.requestInfo?.headers["mcp-session-id"]||void 0,{level:i}=o.params,s=Lf.safeParse(i);return s.success&&this._loggingLevels.set(a,s.data),{}});}get experimental(){return this._experimental||(this._experimental={tasks:new Ty(this)}),this._experimental}registerCapabilities(t){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=H$(this._capabilities,t);}setRequestHandler(t,r){let n=Fa(t)?.method;if(!n)throw new Error("Schema is missing a method literal");let a;if(xn(n)){let s=n;a=s._zod?.def?.value??s.value;}else {let s=n;a=s._def?.value??s.value;}if(typeof a!="string")throw new Error("Schema method literal must be a string");if(a==="tools/call"){let s=async(c,l)=>{let d=ja(Nl,c);if(!d.success){let p=d.error instanceof Error?d.error.message:String(d.error);throw new re(oe.InvalidParams,`Invalid tools/call request: ${p}`)}let{params:u}=d.data,f=await Promise.resolve(r(c,l));if(u.task){let p=ja(Pl,f);if(!p.success){let h=p.error instanceof Error?p.error.message:String(p.error);throw new re(oe.InvalidParams,`Invalid task creation result: ${h}`)}return p.data}let m=ja(Ub,f);if(!m.success){let p=m.error instanceof Error?m.error.message:String(m.error);throw new re(oe.InvalidParams,`Invalid tools/call result: ${p}`)}return m.data};return super.setRequestHandler(t,s)}return super.setRequestHandler(t,r)}assertCapabilityForMethod(t){switch(t){case "sampling/createMessage":if(!this._clientCapabilities?.sampling)throw new Error(`Client does not support sampling (required for ${t})`);break;case "elicitation/create":if(!this._clientCapabilities?.elicitation)throw new Error(`Client does not support elicitation (required for ${t})`);break;case "roots/list":if(!this._clientCapabilities?.roots)throw new Error(`Client does not support listing roots (required for ${t})`);break;}}assertNotificationCapability(t){switch(t){case "notifications/message":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case "notifications/resources/updated":case "notifications/resources/list_changed":if(!this._capabilities.resources)throw new Error(`Server does not support notifying about resources (required for ${t})`);break;case "notifications/tools/list_changed":if(!this._capabilities.tools)throw new Error(`Server does not support notifying of tool list changes (required for ${t})`);break;case "notifications/prompts/list_changed":if(!this._capabilities.prompts)throw new Error(`Server does not support notifying of prompt list changes (required for ${t})`);break;case "notifications/elicitation/complete":if(!this._clientCapabilities?.elicitation?.url)throw new Error(`Client does not support URL elicitation (required for ${t})`);break;}}assertRequestHandlerCapability(t){if(this._capabilities)switch(t){case "completion/complete":if(!this._capabilities.completions)throw new Error(`Server does not support completions (required for ${t})`);break;case "logging/setLevel":if(!this._capabilities.logging)throw new Error(`Server does not support logging (required for ${t})`);break;case "prompts/get":case "prompts/list":if(!this._capabilities.prompts)throw new Error(`Server does not support prompts (required for ${t})`);break;case "resources/list":case "resources/templates/list":case "resources/read":if(!this._capabilities.resources)throw new Error(`Server does not support resources (required for ${t})`);break;case "tools/call":case "tools/list":if(!this._capabilities.tools)throw new Error(`Server does not support tools (required for ${t})`);break;case "tasks/get":case "tasks/list":case "tasks/result":case "tasks/cancel":if(!this._capabilities.tasks)throw new Error(`Server does not support tasks capability (required for ${t})`);break;}}assertTaskCapability(t){RI(this._clientCapabilities?.tasks?.requests,t,"Client");}assertTaskHandlerCapability(t){this._capabilities&&PI(this._capabilities.tasks?.requests,t,"Server");}async _oninitialize(t){let r=t.params.protocolVersion;return this._clientCapabilities=t.params.capabilities,this._clientVersion=t.params.clientInfo,{protocolVersion:K9.includes(r)?r:M2,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},vb)}async createMessage(t,r){if((t.tools||t.toolChoice)&&!this._clientCapabilities?.sampling?.tools)throw new Error("Client does not support sampling tools capability.");if(t.messages.length>0){let o=t.messages[t.messages.length-1],n=Array.isArray(o.content)?o.content:[o.content],a=n.some(l=>l.type==="tool_result"),i=t.messages.length>1?t.messages[t.messages.length-2]:void 0,s=i?Array.isArray(i.content)?i.content:[i.content]:[],c=s.some(l=>l.type==="tool_use");if(a){if(n.some(l=>l.type!=="tool_result"))throw new Error("The last message must contain only tool_result content if any is present");if(!c)throw new Error("tool_result blocks are not matching any tool_use from the previous message")}if(c){let l=new Set(s.filter(u=>u.type==="tool_use").map(u=>u.id)),d=new Set(n.filter(u=>u.type==="tool_result").map(u=>u.toolUseId));if(l.size!==d.size||![...l].every(u=>d.has(u)))throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return t.tools?this.request({method:"sampling/createMessage",params:t},eS,r):this.request({method:"sampling/createMessage",params:t},zf,r)}async elicitInput(t,r){switch(t.mode??"form"){case "url":{if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support url elicitation.");let n=t;return this.request({method:"elicitation/create",params:n},Dl,r)}case "form":{if(!this._clientCapabilities?.elicitation?.form)throw new Error("Client does not support form elicitation.");let n=t.mode==="form"?t:{...t,mode:"form"},a=await this.request({method:"elicitation/create",params:n},Dl,r);if(a.action==="accept"&&a.content&&n.requestedSchema)try{let s=this._jsonSchemaValidator.getValidator(n.requestedSchema)(a.content);if(!s.valid)throw new re(oe.InvalidParams,`Elicitation response content does not match requested schema: ${s.errorMessage}`)}catch(i){throw i instanceof re?i:new re(oe.InternalError,`Error validating elicitation response: ${i instanceof Error?i.message:String(i)}`)}return a}}}createElicitationCompletionNotifier(t,r){if(!this._clientCapabilities?.elicitation?.url)throw new Error("Client does not support URL elicitation (required for notifications/elicitation/complete)");return ()=>this.notification({method:"notifications/elicitation/complete",params:{elicitationId:t}},r)}async listRoots(t,r){return this.request({method:"roots/list",params:t},tS,r)}async sendLoggingMessage(t,r){if(this._capabilities.logging&&!this.isMessageIgnored(t.level,r))return this.notification({method:"notifications/message",params:t})}async sendResourceUpdated(t){return this.notification({method:"notifications/resources/updated",params:t})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}};var DI=Symbol.for("mcp.completable");function r6(e){return !!e&&typeof e=="object"&&DI in e}function UI(e){return e[DI]?.complete}var NI;(function(e){e.Completable="McpCompletable";})(NI||(NI={}));var IJ=/^[A-Za-z0-9._-]{1,128}$/;function CJ(e){let t=[];if(e.length===0)return {isValid:false,warnings:["Tool name cannot be empty"]};if(e.length>128)return {isValid:false,warnings:[`Tool name exceeds maximum length of 128 characters (current: ${e.length})`]};if(e.includes(" ")&&t.push("Tool name contains spaces, which may cause parsing issues"),e.includes(",")&&t.push("Tool name contains commas, which may cause parsing issues"),(e.startsWith("-")||e.endsWith("-"))&&t.push("Tool name starts or ends with a dash, which may cause parsing issues in some contexts"),(e.startsWith(".")||e.endsWith("."))&&t.push("Tool name starts or ends with a dot, which may cause parsing issues in some contexts"),!IJ.test(e)){let r=e.split("").filter(o=>!/[A-Za-z0-9._-]/.test(o)).filter((o,n,a)=>a.indexOf(o)===n);return t.push(`Tool name contains invalid characters: ${r.map(o=>`"${o}"`).join(", ")}`,"Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)"),{isValid:false,warnings:t}}return {isValid:true,warnings:t}}function OJ(e,t){if(t.length>0){console.warn(`Tool name validation warning for "${e}":`);for(let r of t)console.warn(` - ${r}`);console.warn("Tool registration will proceed, but this may cause compatibility issues."),console.warn("Consider updating the tool name to conform to the MCP tool naming standard."),console.warn("See SEP: Specify Format for Tool Names (https://github.com/modelcontextprotocol/modelcontextprotocol/issues/986) for more details.");}}function n6(e){let t=CJ(e);return OJ(e,t.warnings),t.isValid}var $y=class{constructor(t){this._mcpServer=t;}registerToolTask(t,r,o){let n={taskSupport:"required",...r.execution};if(n.taskSupport==="forbidden")throw new Error(`Cannot register task-based tool '${t}' with taskSupport 'forbidden'. Use registerTool() instead.`);return this._mcpServer._createRegisteredTool(t,r.title,r.description,r.inputSchema,r.outputSchema,r.annotations,n,r._meta,o)}};var Ay=class{constructor(t,r){this._registeredResources={},this._registeredResourceTemplates={},this._registeredTools={},this._registeredPrompts={},this._toolHandlersInitialized=false,this._completionHandlerInitialized=false,this._resourceHandlersInitialized=false,this._promptHandlersInitialized=false,this.server=new Ey(t,r);}get experimental(){return this._experimental||(this._experimental={tasks:new $y(this)}),this._experimental}async connect(t){return await this.server.connect(t)}async close(){await this.server.close();}setToolRequestHandlers(){this._toolHandlersInitialized||(this.server.assertCanSetRequestHandler(ei(Db)),this.server.assertCanSetRequestHandler(ei(Nl)),this.server.registerCapabilities({tools:{listChanged:true}}),this.server.setRequestHandler(Db,()=>({tools:Object.entries(this._registeredTools).filter(([,t])=>t.enabled).map(([t,r])=>{let o={name:t,title:r.title,description:r.description,inputSchema:(()=>{let n=xl(r.inputSchema);return n?sS(n,{strictUnions:true,pipeStrategy:"input"}):PJ})(),annotations:r.annotations,execution:r.execution,_meta:r._meta};if(r.outputSchema){let n=xl(r.outputSchema);n&&(o.outputSchema=sS(n,{strictUnions:true,pipeStrategy:"output"}));}return o})})),this.server.setRequestHandler(Nl,async(t,r)=>{try{let o=this._registeredTools[t.params.name];if(!o)throw new re(oe.InvalidParams,`Tool ${t.params.name} not found`);if(!o.enabled)throw new re(oe.InvalidParams,`Tool ${t.params.name} disabled`);let n=!!t.params.task,a=o.execution?.taskSupport,i="createTask"in o.handler;if((a==="required"||a==="optional")&&!i)throw new re(oe.InternalError,`Tool ${t.params.name} has taskSupport '${a}' but was not registered with registerToolTask`);if(a==="required"&&!n)throw new re(oe.MethodNotFound,`Tool ${t.params.name} requires task augmentation (taskSupport: 'required')`);if(a==="optional"&&!n&&i)return await this.handleAutomaticTaskPolling(o,t,r);let s=await this.validateToolInput(o,t.params.arguments,t.params.name),c=await this.executeToolHandler(o,s,r);return n||await this.validateToolOutput(o,c,t.params.name),c}catch(o){if(o instanceof re&&o.code===oe.UrlElicitationRequired)throw o;return this.createToolError(o instanceof Error?o.message:String(o))}}),this._toolHandlersInitialized=true);}createToolError(t){return {content:[{type:"text",text:t}],isError:true}}async validateToolInput(t,r,o){if(!t.inputSchema)return;let a=xl(t.inputSchema)??t.inputSchema,i=await z0(a,r);if(!i.success){let s="error"in i?i.error:"Unknown error",c=B0(s);throw new re(oe.InvalidParams,`Input validation error: Invalid arguments for tool ${o}: ${c}`)}return i.data}async validateToolOutput(t,r,o){if(!t.outputSchema||!("content"in r)||r.isError)return;if(!r.structuredContent)throw new re(oe.InvalidParams,`Output validation error: Tool ${o} has an output schema but no structured content was provided`);let n=xl(t.outputSchema),a=await z0(n,r.structuredContent);if(!a.success){let i="error"in a?a.error:"Unknown error",s=B0(i);throw new re(oe.InvalidParams,`Output validation error: Invalid structured content for tool ${o}: ${s}`)}}async executeToolHandler(t,r,o){let n=t.handler;if("createTask"in n){if(!o.taskStore)throw new Error("No task store provided.");let i={...o,taskStore:o.taskStore};if(t.inputSchema){let s=n;return await Promise.resolve(s.createTask(r,i))}else {let s=n;return await Promise.resolve(s.createTask(i))}}if(t.inputSchema){let i=n;return await Promise.resolve(i(r,o))}else {let i=n;return await Promise.resolve(i(o))}}async handleAutomaticTaskPolling(t,r,o){if(!o.taskStore)throw new Error("No task store provided for task-capable tool.");let n=await this.validateToolInput(t,r.params.arguments,r.params.name),a=t.handler,i={...o,taskStore:o.taskStore},s=n?await Promise.resolve(a.createTask(n,i)):await Promise.resolve(a.createTask(i)),c=s.task.taskId,l=s.task,d=l.pollInterval??5e3;for(;l.status!=="completed"&&l.status!=="failed"&&l.status!=="cancelled";){await new Promise(f=>setTimeout(f,d));let u=await o.taskStore.getTask(c);if(!u)throw new re(oe.InternalError,`Task ${c} not found during polling`);l=u;}return await o.taskStore.getTaskResult(c)}setCompletionRequestHandler(){this._completionHandlerInitialized||(this.server.assertCanSetRequestHandler(ei(Lb)),this.server.registerCapabilities({completions:{}}),this.server.setRequestHandler(Lb,async t=>{switch(t.params.ref.type){case "ref/prompt":return l$(t),this.handlePromptCompletion(t,t.params.ref);case "ref/resource":return d$(t),this.handleResourceCompletion(t,t.params.ref);default:throw new re(oe.InvalidParams,`Invalid completion reference: ${t.params.ref}`)}}),this._completionHandlerInitialized=true);}async handlePromptCompletion(t,r){let o=this._registeredPrompts[r.name];if(!o)throw new re(oe.InvalidParams,`Prompt ${r.name} not found`);if(!o.enabled)throw new re(oe.InvalidParams,`Prompt ${r.name} disabled`);if(!o.argsSchema)return hm;let a=Fa(o.argsSchema)?.[t.params.argument.name];if(!r6(a))return hm;let i=UI(a);if(!i)return hm;let s=await i(t.params.argument.value,t.params.context);return zI(s)}async handleResourceCompletion(t,r){let o=Object.values(this._registeredResourceTemplates).find(i=>i.resourceTemplate.uriTemplate.toString()===r.uri);if(!o){if(this._registeredResources[r.uri])return hm;throw new re(oe.InvalidParams,`Resource template ${t.params.ref.uri} not found`)}let n=o.resourceTemplate.completeCallback(t.params.argument.name);if(!n)return hm;let a=await n(t.params.argument.value,t.params.context);return zI(a)}setResourceRequestHandlers(){this._resourceHandlersInitialized||(this.server.assertCanSetRequestHandler(ei(Cb)),this.server.assertCanSetRequestHandler(ei(Ob)),this.server.assertCanSetRequestHandler(ei(Pb)),this.server.registerCapabilities({resources:{listChanged:true}}),this.server.setRequestHandler(Cb,async(t,r)=>{let o=Object.entries(this._registeredResources).filter(([a,i])=>i.enabled).map(([a,i])=>({uri:a,name:i.name,...i.metadata})),n=[];for(let a of Object.values(this._registeredResourceTemplates)){if(!a.resourceTemplate.listCallback)continue;let i=await a.resourceTemplate.listCallback(r);for(let s of i.resources)n.push({...a.metadata,...s});}return {resources:[...o,...n]}}),this.server.setRequestHandler(Ob,async()=>({resourceTemplates:Object.entries(this._registeredResourceTemplates).map(([r,o])=>({name:r,uriTemplate:o.resourceTemplate.uriTemplate.toString(),...o.metadata}))})),this.server.setRequestHandler(Pb,async(t,r)=>{let o=new URL(t.params.uri),n=this._registeredResources[o.toString()];if(n){if(!n.enabled)throw new re(oe.InvalidParams,`Resource ${o} disabled`);return n.readCallback(o,r)}for(let a of Object.values(this._registeredResourceTemplates)){let i=a.resourceTemplate.uriTemplate.match(o.toString());if(i)return a.readCallback(o,i,r)}throw new re(oe.InvalidParams,`Resource ${o} not found`)}),this._resourceHandlersInitialized=true);}setPromptRequestHandlers(){this._promptHandlersInitialized||(this.server.assertCanSetRequestHandler(ei(Rb)),this.server.assertCanSetRequestHandler(ei(Nb)),this.server.registerCapabilities({prompts:{listChanged:true}}),this.server.setRequestHandler(Rb,()=>({prompts:Object.entries(this._registeredPrompts).filter(([,t])=>t.enabled).map(([t,r])=>({name:t,title:r.title,description:r.description,arguments:r.argsSchema?NJ(r.argsSchema):void 0}))})),this.server.setRequestHandler(Nb,async(t,r)=>{let o=this._registeredPrompts[t.params.name];if(!o)throw new re(oe.InvalidParams,`Prompt ${t.params.name} not found`);if(!o.enabled)throw new re(oe.InvalidParams,`Prompt ${t.params.name} disabled`);if(o.argsSchema){let n=xl(o.argsSchema),a=await z0(n,t.params.arguments);if(!a.success){let c="error"in a?a.error:"Unknown error",l=B0(c);throw new re(oe.InvalidParams,`Invalid arguments for prompt ${t.params.name}: ${l}`)}let i=a.data,s=o.callback;return await Promise.resolve(s(i,r))}else {let n=o.callback;return await Promise.resolve(n(r))}}),this._promptHandlersInitialized=true);}resource(t,r,...o){let n;typeof o[0]=="object"&&(n=o.shift());let a=o[0];if(typeof r=="string"){if(this._registeredResources[r])throw new Error(`Resource ${r} is already registered`);let i=this._createRegisteredResource(t,void 0,r,n,a);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),i}else {if(this._registeredResourceTemplates[t])throw new Error(`Resource template ${t} is already registered`);let i=this._createRegisteredResourceTemplate(t,void 0,r,n,a);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),i}}registerResource(t,r,o,n){if(typeof r=="string"){if(this._registeredResources[r])throw new Error(`Resource ${r} is already registered`);let a=this._createRegisteredResource(t,o.title,r,o,n);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),a}else {if(this._registeredResourceTemplates[t])throw new Error(`Resource template ${t} is already registered`);let a=this._createRegisteredResourceTemplate(t,o.title,r,o,n);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),a}}_createRegisteredResource(t,r,o,n,a){let i={name:t,title:r,metadata:n,readCallback:a,enabled:true,disable:()=>i.update({enabled:false}),enable:()=>i.update({enabled:true}),remove:()=>i.update({uri:null}),update:s=>{typeof s.uri<"u"&&s.uri!==o&&(delete this._registeredResources[o],s.uri&&(this._registeredResources[s.uri]=i)),typeof s.name<"u"&&(i.name=s.name),typeof s.title<"u"&&(i.title=s.title),typeof s.metadata<"u"&&(i.metadata=s.metadata),typeof s.callback<"u"&&(i.readCallback=s.callback),typeof s.enabled<"u"&&(i.enabled=s.enabled),this.sendResourceListChanged();}};return this._registeredResources[o]=i,i}_createRegisteredResourceTemplate(t,r,o,n,a){let i={resourceTemplate:o,title:r,metadata:n,readCallback:a,enabled:true,disable:()=>i.update({enabled:false}),enable:()=>i.update({enabled:true}),remove:()=>i.update({name:null}),update:l=>{typeof l.name<"u"&&l.name!==t&&(delete this._registeredResourceTemplates[t],l.name&&(this._registeredResourceTemplates[l.name]=i)),typeof l.title<"u"&&(i.title=l.title),typeof l.template<"u"&&(i.resourceTemplate=l.template),typeof l.metadata<"u"&&(i.metadata=l.metadata),typeof l.callback<"u"&&(i.readCallback=l.callback),typeof l.enabled<"u"&&(i.enabled=l.enabled),this.sendResourceListChanged();}};this._registeredResourceTemplates[t]=i;let s=o.uriTemplate.variableNames;return Array.isArray(s)&&s.some(l=>!!o.completeCallback(l))&&this.setCompletionRequestHandler(),i}_createRegisteredPrompt(t,r,o,n,a){let i={title:r,description:o,argsSchema:n===void 0?void 0:bs(n),callback:a,enabled:true,disable:()=>i.update({enabled:false}),enable:()=>i.update({enabled:true}),remove:()=>i.update({name:null}),update:s=>{typeof s.name<"u"&&s.name!==t&&(delete this._registeredPrompts[t],s.name&&(this._registeredPrompts[s.name]=i)),typeof s.title<"u"&&(i.title=s.title),typeof s.description<"u"&&(i.description=s.description),typeof s.argsSchema<"u"&&(i.argsSchema=bs(s.argsSchema)),typeof s.callback<"u"&&(i.callback=s.callback),typeof s.enabled<"u"&&(i.enabled=s.enabled),this.sendPromptListChanged();}};return this._registeredPrompts[t]=i,n&&Object.values(n).some(c=>{let l=c instanceof Cl?c._def?.innerType:c;return r6(l)})&&this.setCompletionRequestHandler(),i}_createRegisteredTool(t,r,o,n,a,i,s,c,l){n6(t);let d={title:r,description:o,inputSchema:LI(n),outputSchema:LI(a),annotations:i,execution:s,_meta:c,handler:l,enabled:true,disable:()=>d.update({enabled:false}),enable:()=>d.update({enabled:true}),remove:()=>d.update({name:null}),update:u=>{typeof u.name<"u"&&u.name!==t&&(typeof u.name=="string"&&n6(u.name),delete this._registeredTools[t],u.name&&(this._registeredTools[u.name]=d)),typeof u.title<"u"&&(d.title=u.title),typeof u.description<"u"&&(d.description=u.description),typeof u.paramsSchema<"u"&&(d.inputSchema=bs(u.paramsSchema)),typeof u.outputSchema<"u"&&(d.outputSchema=bs(u.outputSchema)),typeof u.callback<"u"&&(d.handler=u.callback),typeof u.annotations<"u"&&(d.annotations=u.annotations),typeof u._meta<"u"&&(d._meta=u._meta),typeof u.enabled<"u"&&(d.enabled=u.enabled),this.sendToolListChanged();}};return this._registeredTools[t]=d,this.setToolRequestHandlers(),this.sendToolListChanged(),d}tool(t,...r){if(this._registeredTools[t])throw new Error(`Tool ${t} is already registered`);let o,n,a,i;if(typeof r[0]=="string"&&(o=r.shift()),r.length>1){let c=r[0];o6(c)?(n=r.shift(),r.length>1&&typeof r[0]=="object"&&r[0]!==null&&!o6(r[0])&&(i=r.shift())):typeof c=="object"&&c!==null&&(i=r.shift());}let s=r[0];return this._createRegisteredTool(t,void 0,o,n,a,i,{taskSupport:"forbidden"},void 0,s)}registerTool(t,r,o){if(this._registeredTools[t])throw new Error(`Tool ${t} is already registered`);let{title:n,description:a,inputSchema:i,outputSchema:s,annotations:c,_meta:l}=r;return this._createRegisteredTool(t,n,a,i,s,c,{taskSupport:"forbidden"},l,o)}prompt(t,...r){if(this._registeredPrompts[t])throw new Error(`Prompt ${t} is already registered`);let o;typeof r[0]=="string"&&(o=r.shift());let n;r.length>1&&(n=r.shift());let a=r[0],i=this._createRegisteredPrompt(t,void 0,o,n,a);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),i}registerPrompt(t,r,o){if(this._registeredPrompts[t])throw new Error(`Prompt ${t} is already registered`);let{title:n,description:a,argsSchema:i}=r,s=this._createRegisteredPrompt(t,n,a,i,o);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),s}isConnected(){return this.server.transport!==void 0}async sendLoggingMessage(t,r){return this.server.sendLoggingMessage(t,r)}sendResourceListChanged(){this.isConnected()&&this.server.sendResourceListChanged();}sendToolListChanged(){this.isConnected()&&this.server.sendToolListChanged();}sendPromptListChanged(){this.isConnected()&&this.server.sendPromptListChanged();}};var PJ={type:"object",properties:{}};function BI(e){return e!==null&&typeof e=="object"&&"parse"in e&&typeof e.parse=="function"&&"safeParse"in e&&typeof e.safeParse=="function"}function RJ(e){return "_def"in e||"_zod"in e||BI(e)}function o6(e){return typeof e!="object"||e===null||RJ(e)?false:Object.keys(e).length===0?true:Object.values(e).some(BI)}function LI(e){if(e)return o6(e)?bs(e):e}function NJ(e){let t=Fa(e);return t?Object.entries(t).map(([r,o])=>{let n=N5(o),a=D5(o);return {name:r,description:n,required:!a}}):[]}function ei(e){let r=Fa(e)?.method;if(!r)throw new Error("Schema is missing a method literal");let o=M0(r);if(typeof o=="string")return o;throw new Error("Schema method literal must be a string")}function zI(e){return {completion:{values:e.slice(0,100),total:e.length,hasMore:e.length>100}}}var hm={completion:{values:[],hasMore:false}};var Iy=class{append(t){this._buffer=this._buffer?Buffer.concat([this._buffer,t]):t;}readMessage(){if(!this._buffer)return null;let t=this._buffer.indexOf(`
|
|
108
108
|
`);if(t===-1)return null;let r=this._buffer.toString("utf8",0,t).replace(/\r$/,"");return this._buffer=this._buffer.subarray(t+1),DJ(r)}clear(){this._buffer=void 0;}};function DJ(e){return t$.parse(JSON.parse(e))}function MI(e){return JSON.stringify(e)+`
|
|
109
|
-
`}var Cy=class{constructor(t=Mc.stdin,r=Mc.stdout){this._stdin=t,this._stdout=r,this._readBuffer=new Iy,this._started=false,this._ondata=o=>{this._readBuffer.append(o),this.processReadBuffer();},this._onerror=o=>{this.onerror?.(o);};}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=true,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror);}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t);}catch(t){this.onerror?.(t);}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.();}send(t){return new Promise(r=>{let o=MI(t);this._stdout.write(o)?r():this._stdout.once("drain",r);})}};var ti=FI.homedir(),i6=FI.tmpdir(),{env:Ql}=Mc,UJ=e=>{let t=bt.join(ti,"Library");return {data:bt.join(t,"Application Support",e),config:bt.join(t,"Preferences",e),cache:bt.join(t,"Caches",e),log:bt.join(t,"Logs",e),temp:bt.join(i6,e)}},LJ=e=>{let t=Ql.APPDATA||bt.join(ti,"AppData","Roaming"),r=Ql.LOCALAPPDATA||bt.join(ti,"AppData","Local");return {data:bt.join(r,e,"Data"),config:bt.join(t,e,"Config"),cache:bt.join(r,e,"Cache"),log:bt.join(r,e,"Log"),temp:bt.join(i6,e)}},zJ=e=>{let t=bt.basename(ti);return {data:bt.join(Ql.XDG_DATA_HOME||bt.join(ti,".local","share"),e),config:bt.join(Ql.XDG_CONFIG_HOME||bt.join(ti,".config"),e),cache:bt.join(Ql.XDG_CACHE_HOME||bt.join(ti,".cache"),e),log:bt.join(Ql.XDG_STATE_HOME||bt.join(ti,".local","state"),e),temp:bt.join(i6,t,e)}};function s6(e,{suffix:t="nodejs"}={}){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);return t&&(e+=`-${t}`),Mc.platform==="darwin"?UJ(e):Mc.platform==="win32"?LJ(e):zJ(e)}var VI=s6("starkfi"),Oy="https://2c29jsb475.eu-central-1.awsapprunner.com",c6=VI.data,Py=VI.config;function HI(e,t){return `${t==="mainnet"?"https://voyager.online":"https://sepolia.voyager.online"}/tx/${e}`}Tr();var gm=join(c6,"session.json");function Is(){if(!existsSync(gm))return null;try{let e=readFileSync(gm,"utf-8");return JSON.parse(e)}catch{return null}}function ZI(e){let t=c6;existsSync(t)||mkdirSync(t,{recursive:true}),writeFileSync(gm,JSON.stringify(e,null,2),"utf-8");}function d6(){existsSync(gm)&&unlinkSync(gm);}function HJ(e){try{let t=e.split(".");if(t.length!==3||!t[1])return !1;let r=JSON.parse(Buffer.from(t[1],"base64url").toString());return r.exp?Date.now()>=(r.exp-300)*1e3:!1}catch{return false}}function Ee(){let e=Is();if(!e)throw new Q("AUTH_REQUIRED","Not authenticated. Run 'starkfi auth login <email>' first.");if(HJ(e.token))throw d6(),new Q("SESSION_EXPIRED","Session expired. Please re-authenticate with 'starkfi auth login <email>'");return e}var ed="https://api.fibrous.finance/starknet";var Er="0x00f6f4CF62E3C010E0aC2451cC7807b5eEc19a40b0FaaCd00CCA3914280FDf5a";async function Ry(){try{let e=await fetch(`${ed}/healthCheck`);if(!e.ok)return {ok:!1,message:`Fibrous API returned ${e.status}`};let t=await e.json();return {ok:t.staus===200,message:t.message}}catch(e){return {ok:false,message:`Failed to reach Fibrous API: ${e instanceof Error?e.message:String(e)}`}}}function To(e){return {content:[{type:"text",text:e}]}}function se(e){return To(JSON.stringify(e,null,2))}function ri(e,t){return se({success:e.success,mode:"SIMULATION (no TX sent)",...t,estimatedFee:e.estimatedFee,estimatedFeeUsd:e.estimatedFeeUsd,callCount:e.callCount,...e.revertReason?{revertReason:e.revertReason}:{}})}async function qI(){let e=Is(),t=await Ry();return e?se({authenticated:true,type:e.type,network:e.network,address:e.address,fibrous:t}):se({authenticated:false,fibrous:t,message:"Not authenticated. Use 'starkfi auth login'."})}Rr();var Ec=join(Py,"config.json"),Mt=class e{static instance;config;lastMtime=0;constructor(){this.config=this.load(),this.updateMtime();}static getInstance(){return e.instance||(e.instance=new e),e.instance}get(t){return this.refreshIfChanged(),this.config[t]}set(t,r){this.config[t]=r,this.save();}delete(t){delete this.config[t],this.save();}clear(){this.config={},this.save();}getAll(){return this.refreshIfChanged(),{...this.config}}refreshIfChanged(){try{if(!existsSync(Ec))return;let t=statSync(Ec).mtimeMs;t>this.lastMtime&&(this.config=this.load(),this.lastMtime=t);}catch{}}updateMtime(){try{existsSync(Ec)&&(this.lastMtime=statSync(Ec).mtimeMs);}catch{}}load(){if(!existsSync(Ec))return {};try{let t=readFileSync(Ec,"utf-8");return JSON.parse(t)}catch{return {}}}save(){existsSync(Py)||mkdirSync(Py,{recursive:true}),writeFileSync(Ec,JSON.stringify(this.config,null,2),"utf-8"),this.updateMtime();}};var WL="https://starknet.paymaster.avnu.fi",GL="https://sepolia.paymaster.avnu.fi",YL="STRK",k1={ETH:"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",STRK:"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",USDC:"0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",USDT:"0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",DAI:"0x05574eb6b8789a91466f902c380d978e472db68170ff82a5b650b95a58ddf4ad"},Zi=Object.keys(k1);function qi(e,t){if(e)return {feeMode:"sponsored",gasTokenAddress:void 0,needsPaymaster:true};let o=k1[(t??YL).toUpperCase()];return o?{feeMode:"sponsored",gasTokenAddress:o,needsPaymaster:true}:{feeMode:"sponsored",gasTokenAddress:k1.STRK,needsPaymaster:true}}function cie(e,t){let r=e.getAccount(),o=r,n=o.executePaymasterTransaction;if(typeof n!="function"){console.warn("[StarkFi] Cannot patch gasless mode \u2014 executePaymasterTransaction not found on account. Gas will use default sponsored mode. Consider updating StarkZap SDK.");return}let a=n.bind(r);o.executePaymasterTransaction=async function(i,s,...c){let l={...s,feeMode:{mode:"default",gasToken:t}};return a(i,l,...c)};}function $c(e="mainnet",t,r=false,o,n){let a={network:e};if(t&&(a.rpcUrl=t),r){let i=e==="sepolia"?GL:WL;a.paymaster={nodeUrl:o??i,...n?{headers:n}:{}};}return new Yd(a)}async function HT(e,t){let r=Mt.getInstance(),o=r.get("gasfreeMode")===true,n=r.get("gasToken"),{feeMode:a,gasTokenAddress:i}=qi(o,n),s=new Tc({walletId:t.walletId,publicKey:t.publicKey,serverUrl:t.serverUrl,headers:{Authorization:`Bearer ${t.token}`}}),c=await e.connectWallet({account:{signer:s,accountClass:Kd},feeMode:a});return !o&&i&&cie(c,i),c}async function Be(e){let t=Mt.getInstance(),r=t.get("rpcUrl"),o=t.get("gasfreeMode")===true,n=t.get("gasToken"),{gasTokenAddress:a,needsPaymaster:i}=qi(o,n),s=e.type==="privy"&&e.serverUrl?e.serverUrl.replace("/sign/hash","/paymaster"):void 0,c=s&&e.token?{Authorization:`Bearer ${e.token}`}:void 0,l=$c(e.network,r,i,s,c),d=await HT(l,e);return {sdk:l,wallet:d,gasTokenAddress:a}}gr();async function T1(e,t,r){let o=[],n=0,a=async()=>{for(;n<e.length;){let s=n++,c=e[s];if(!c)continue;let l=await r(c);l!==void 0&&o.push(l);}},i=Array.from({length:Math.min(t,e.length)},()=>a());return await Promise.all(i),o}var lie=10;async function Jd(e){let t=qT();return T1(t,lie,async r=>{try{let o=await e.balanceOf(r);if(o.isPositive())return {symbol:r.symbol,name:r.name,balance:o.toUnit()}}catch{}})}gr();Rr();Rr();gr();Tr();Tr();async function Ki(e,t){let{maxRetries:r=2,baseDelayMs:o=500,retryOnCodes:n}=t??{},a;for(let i=0;i<=r;i++)try{return await e()}catch(s){if(a=s,s instanceof Q&&n?.length&&!n.includes(s.code))throw s;if(i<r){let c=o*2**i;await new Promise(l=>setTimeout(l,c));}}throw a}async function Qd(e,t,r){let o=new URLSearchParams({amount:r,tokenInAddress:e.address,tokenOutAddress:t.address}),n=await Ki(()=>fetch(`${ed}/route?${o.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(!n.ok)throw new Q("NO_ROUTE_FOUND",`Fibrous route API error: ${n.status}`);let a=await n.json();if(!a.success)throw new Q("NO_ROUTE_FOUND",a.errorMessage||"No route found for this swap");return a}async function Ac(e,t,r,o=1,n){let a=new URLSearchParams({amount:r,tokenInAddress:e.address,tokenOutAddress:t.address,slippage:o.toString()});n&&a.append("destination",n);let i=await Ki(()=>fetch(`${ed}/calldata?${a.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(!i.ok){let c=await i.text().catch(()=>"");throw new Q("SWAP_FAILED",`Fibrous calldata API error: ${i.status} ${c}`)}let s=await i.json();if(!s.route?.success)throw new Q("NO_ROUTE_FOUND","Failed to generate calldata: no valid route");return s}var E1=3;async function $1(e){if(e.length>E1)throw new Q("BATCH_LIMIT_EXCEEDED",`Multi-swap supports up to ${E1} pairs, got ${e.length}`);if(e.every(r=>r.tokenOut.address.toLowerCase()===e[0].tokenOut.address.toLowerCase()))try{let r=new URLSearchParams({amounts:e.map(n=>n.amount).join(","),tokenInAddresses:e.map(n=>n.tokenIn.address).join(","),tokenOutAddresses:e[0].tokenOut.address}),o=await Ki(()=>fetch(`${ed}/routeBatch?${r.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(o.ok){let n=await o.json();if(Array.isArray(n)&&n.length===e.length){for(let a=0;a<n.length;a++)if(!n[a].success){let i=e[a];throw new Q("NO_ROUTE_FOUND",`No route found for pair ${a+1}: ${i.tokenIn.symbol} \u2192 ${i.tokenOut.symbol}`)}return n}}}catch(r){if(r instanceof Q)throw r}return Promise.all(e.map(r=>Qd(r.tokenIn,r.tokenOut,r.amount)))}async function A1(e,t=1,r){if(e.length>E1)throw new Q("BATCH_LIMIT_EXCEEDED",`Multi-swap supports up to ${E1} pairs, got ${e.length}`);return Promise.all(e.map(o=>Ac(o.tokenIn,o.tokenOut,o.amount,t,r)))}var Xd=new Map,die=6e4,uie=50;async function Fo(e){let t=e.symbol.toUpperCase();if(t==="USDC"||t==="USDT")return 1;let r=e.address.toLowerCase(),o=Xd.get(r);if(o&&Date.now()-o.timestamp<die)return o.promise;if(Xd.size>=uie){let a=Xd.keys().next().value;a&&Xd.delete(a);}let n=fie(e);return Xd.set(r,{promise:n,timestamp:Date.now()}),n.catch(()=>Xd.delete(r)),n}async function fie(e){try{let t=await Promise.resolve().then(()=>(gr(),JL)).then(n=>n.resolveToken("USDC")),r=(10n**BigInt(e.decimals)).toString(),o=await Qd(e,t,r);if(o.success&&o.inputToken?.price)return parseFloat(o.inputToken.price)}catch{}return 0}Tr();var QL="STRK";async function jt(e){let r=(await e.calls()).length;if(r===0)throw new Q("SIMULATION_FAILED","No calls to simulate \u2014 builder is empty.");let o=await e.preflight();if(!o.ok)return {success:false,estimatedFee:"N/A",estimatedFeeUsd:"N/A",callCount:r,revertReason:o.reason};try{let n=await e.estimateFee(),a=BigInt(n.overall_fee),i=le(QL),c=ae.fromRaw(a,i).toUnit(),l="unknown";try{let d=await Fo(i);d>0&&(l=`$${(parseFloat(c)*d).toFixed(4)}`);}catch{}return {success:!0,estimatedFee:`${c} ${QL}`,estimatedFeeUsd:l,callCount:r}}catch(n){return {success:true,estimatedFee:"estimation failed",estimatedFeeUsd:"unknown",callCount:r,revertReason:n instanceof Error?`Fee estimation failed: ${n.message}`:"Fee estimation failed"}}}async function Rt(e){let t=Ee(),{sdk:r,wallet:o}=await Be(t);return await o.ensureReady({deploy:"if_needed"}),e({session:t,sdk:r,wallet:o})}async function Un(e){let t=Ee(),{sdk:r,wallet:o}=await Be(t);return e({session:t,sdk:r,wallet:o})}async function ez(e){return Un(async({session:t,wallet:r})=>{if(e.token){let n=le(e.token),a=await r.balanceOf(n);return se({symbol:n.symbol,name:n.name,balance:a.toUnit()})}let o=await Jd(r);return se({network:t.network,address:t.address,balances:o})})}async function tz(){return Un(async({session:e,wallet:t})=>{let r=await t.isDeployed();if(!r){let o=Mt.getInstance(),n=o.get("gasfreeMode")===true,a=o.get("gasToken"),{feeMode:i}=qi(n,a);await t.ensureReady({deploy:"if_needed",feeMode:i});}return se({alreadyDeployed:r,success:true,address:e.address,network:e.network,message:r?"Account is already deployed. No action needed.":"Account deployed successfully. You can now send, swap, and stake."})})}async function rz(e){return Rt(async({wallet:t})=>{let r=le(e.token),o=ae.parse(e.amount,r),n=await t.balanceOf(r);if(n.lt(o))return se({success:false,error:`Insufficient balance. You have: ${n.toFormatted()}, attempting to send: ${o.toFormatted()}`});let a=t.tx().transfer(r,[{to:J(e.recipient),amount:o}]);if(e.simulate){let s=await jt(a);return ri(s,{amount:`${e.amount} ${e.token.toUpperCase()}`,to:e.recipient})}let i=await a.send();return await i.wait(),se({success:true,txHash:i.hash,explorerUrl:i.explorerUrl,amount:`${e.amount} ${e.token.toUpperCase()}`,to:e.recipient})})}async function nz(e){let t=Ee(),o=Mt.getInstance().get("rpcUrl"),i=await $c(t.network,o).getProvider().getTransactionReceipt(e.hash),s="actual_fee"in i?i.actual_fee:void 0,c=s?lh(s):void 0,l="block_number"in i?i.block_number:void 0;return se({hash:e.hash,status:i.statusReceipt,actualFee:c,blockNumber:l})}gr();Rr();async function oz(e){let t=le(e.from_token),r=le(e.to_token),n=ae.parse(e.amount,t).toBase().toString(),a=await Qd(t,r,n),s=ae.fromRaw(BigInt(a.outputAmount),r).toUnit();return se({success:true,amountIn:`${e.amount} ${t.symbol}`,expectedAmountOut:`~${s} ${r.symbol}`,estimatedGasUsd:a.estimatedGasUsedInUsd?`$${a.estimatedGasUsedInUsd.toFixed(4)}`:"Unknown",routeId:a.routeId,message:"Quote generated successfully. Use swap_tokens to execute."})}async function az(e){return Rt(async({session:t,wallet:r})=>{let o=le(e.from_token),n=le(e.to_token),a=ae.parse(e.amount,o),i=a.toBase().toString(),s=await Ac(o,n,i,e.slippage??1,t.address),c=r.tx().approve(o,J(Er),a).add({contractAddress:Er,entrypoint:"swap",calldata:s.calldata}),d=ae.fromRaw(BigInt(s.route.outputAmount),n).toUnit();if(e.simulate){let f=await jt(c);return ri(f,{amountIn:`${e.amount} ${o.symbol}`,expectedAmountOut:`~${d} ${n.symbol}`})}let u=await c.send();return await u.wait(),se({success:true,txHash:u.hash,explorerUrl:u.explorerUrl,amountIn:`${e.amount} ${o.symbol}`,amountOut:`~${d} ${n.symbol}`,slippage:`${e.slippage??1}%`})})}Rr();gr();Tr();function tu(e,t){let r=t.toUpperCase(),o=e.find(n=>n.tokenSymbol.toUpperCase()===r);if(!o){let n=e.map(a=>a.tokenSymbol).join(", ");throw new Q("POOL_NOT_FOUND",`No ${t} pool found for this validator. Available: ${n}`)}return o}async function va(e,t,r){let o=await e.getStakerPools(J(t));return Promise.all(o.map(async n=>{let a=r?await r.getPoolCommission(n.poolContract):void 0;return {poolContract:n.poolContract.toString(),tokenSymbol:n.token.symbol,amount:n.amount.toFormatted(true),commission:a}}))}async function I1(e,t,r,o="STRK"){let n=le(o),a=ae.parse(r,n),i=await e.stake(J(t),a);return {hash:i.hash,explorerUrl:i.explorerUrl}}async function C1(e,t){let r=await e.getPoolPosition(J(t));if(!r||r.rewards.isZero())throw new Q("STAKING_FAILED","No rewards to claim for this pool.");let o=await e.claimPoolRewards(J(t));return {hash:o.hash,explorerUrl:o.explorerUrl}}async function O1(e,t){let r=await e.getPoolPosition(J(t));if(!r||r.rewards.isZero())throw new Q("STAKING_FAILED","No rewards to compound for this pool.");let o=r.rewards.toFormatted(true),n=await e.tx().claimPoolRewards(J(t)).stake(J(t),r.rewards).send();return await n.wait(),{hash:n.hash,explorerUrl:n.explorerUrl,compounded:o}}async function P1(e,t,r,o="STRK"){let n=le(o),a=ae.parse(r,n),i=await e.exitPoolIntent(J(t),a);return {hash:i.hash,explorerUrl:i.explorerUrl}}async function R1(e,t){let r=await e.getPoolPosition(J(t));if(!r)throw new Q("STAKING_FAILED","Not a member of this pool.");if(r.unpooling.isZero())throw new Q("EXIT_NOT_READY","No exit intent declared. Call 'unstake intent' first.");if(r.unpoolTime&&new Date<r.unpoolTime)throw new Q("EXIT_NOT_READY",`Cooldown period is still active. Please wait until ${r.unpoolTime.toLocaleString()}`);let o=await e.exitPool(J(t));return {hash:o.hash,explorerUrl:o.explorerUrl}}async function sz(e,t){let r=await e.getPoolPosition(J(t));return r?{staked:r.staked.toFormatted(true),rewards:r.rewards.toFormatted(true),total:r.total.toFormatted(true),unpooling:r.unpooling.toFormatted(true),unpoolTime:r.unpoolTime??void 0,commissionPercent:r.commissionPercent}:null}async function ru(e,t,r,o,n){let{getValidators:a,findValidator:i}=await Promise.resolve().then(()=>(Hp(),iz)),s=a(r);if(n){let m=i(n,r);if(m)s=[m];else throw new Q("VALIDATOR_NOT_FOUND",`Validator '${n}' not found`)}let l=(await Promise.all(s.map(async m=>{try{return (await e.getStakerPools(m.stakerAddress)).map(h=>({validator:m.name,pool:h}))}catch{return []}}))).flat(),f=(await Promise.all(l.map(async({validator:m,pool:p})=>{let h;try{h=await t.getPoolPosition(p.poolContract);}catch{return null}return h?{validator:m,pool:p.poolContract.toString(),tokenSymbol:p.token.symbol,staked:h.staked,rewards:h.rewards,total:h.total,unpooling:h.unpooling,unpoolTime:h.unpoolTime??null,commissionPercent:h.commissionPercent}:null}))).filter(m=>m!==null).map(m=>({validator:m.validator,pool:m.pool,token:m.tokenSymbol,staked:m.staked.toFormatted(true),rewards:m.rewards.toFormatted(true),total:m.total.toFormatted(true),unpooling:m.unpooling.toFormatted(true),cooldownEndsAt:m.unpoolTime?m.unpoolTime.toISOString():null,commission:`${m.commissionPercent}%`}));return {network:r,address:o,positions:f}}Hp();async function lz(e){return Rt(async({wallet:t})=>{let r=(e.token??"STRK").toUpperCase(),o=await I1(t,e.pool,e.amount,r);return se({success:true,txHash:o.hash,explorerUrl:o.explorerUrl,amount:`${e.amount} ${r}`,pool:e.pool})})}async function dz(e){return Rt(async({wallet:t})=>{if(e.action==="intent"){if(!e.amount)return To("Amount is required for exit intent.");let o=(e.token??"STRK").toUpperCase(),n=await P1(t,e.pool,e.amount,o);return se({success:true,action:"exit_intent",txHash:n.hash,explorerUrl:n.explorerUrl,message:"Exit intent declared. Wait for cooldown period, then call with action='exit'."})}let r=await R1(t,e.pool);return se({success:true,action:"exit_complete",txHash:r.hash,explorerUrl:r.explorerUrl,message:"Tokens withdrawn from pool."})})}async function uz(e){return Un(async({wallet:t})=>{let r=await sz(t,e.pool);return r?se({isMember:true,pool:e.pool,staked:r.staked,rewards:r.rewards,total:r.total,unpooling:r.unpooling,cooldownEndsAt:r.unpoolTime?r.unpoolTime.toISOString():null,commissionPercent:r.commissionPercent}):se({isMember:false,pool:e.pool,message:"Not a member of this pool."})})}async function fz(e){return Un(async({session:t,sdk:r,wallet:o})=>{let n=Vo(e.validator,t.network),a=n?n.stakerAddress.toString():e.validator,i=await va(r,a,o);return se({validator:n?n.name:e.validator,stakerAddress:a,pools:i})})}async function mz(){let e=Ee(),t=eu(e.network);return se({network:e.network,count:t.length,validators:t.map(r=>({name:r.name,stakerAddress:r.stakerAddress.toString()}))})}async function pz(e){return Rt(async({wallet:t})=>{let r=await C1(t,e.pool);return se({success:true,txHash:r.hash,explorerUrl:r.explorerUrl})})}async function hz(e){return Rt(async({wallet:t})=>{let r=await O1(t,e.pool);return se({success:true,txHash:r.hash,explorerUrl:r.explorerUrl,compounded:r.compounded})})}async function gz({validator:e}={}){return Un(async({session:t,sdk:r,wallet:o})=>{let n=await ru(r,o,t.network,t.address,e);return se(n)})}async function bz(e){let t=Mt.getInstance();switch(e.action){case "set-rpc":return e.value?(t.set("rpcUrl",e.value),se({success:true,rpcUrl:e.value})):To("RPC URL value is required.");case "get-rpc":{let r=t.get("rpcUrl");return se({rpcUrl:r||"default (Cartridge RPC)"})}case "set-network":return !e.value||!["mainnet","sepolia"].includes(e.value)?To("Network must be 'mainnet' or 'sepolia'."):(t.set("network",e.value),se({success:true,network:e.value}));case "set-gasfree":{if(!e.value||!["on","off"].includes(e.value))return To("Gasfree mode must be 'on' or 'off'.");let r=e.value==="on";return t.set("gasfreeMode",r),r&&t.delete("gasToken"),se({success:true,gasfreeMode:r,note:r?"Developer sponsors gas via Paymaster (requires API key + credits)":"Gasfree disabled \u2014 using gasless mode (default: STRK)"})}case "set-gas-token":{if(!e.value)return To("Token symbol or 'reset' is required.");if(["off","reset","default"].includes(e.value.toLowerCase()))return t.delete("gasToken"),se({success:true,gasToken:"STRK",note:"Gas token reset to default: STRK"});let r=e.value.toUpperCase();return Zi.includes(r)?(t.delete("gasfreeMode"),t.set("gasToken",r),se({success:true,gasToken:r,note:`Gas paid in ${r} via Paymaster`})):To(`Unsupported token '${e.value}'. Supported: ${Zi.join(", ")}`)}case "list":{let r=t.getAll(),o=r.gasfreeMode===true,n=r.gasToken,a="gasless (pays STRK via Paymaster)";return o?a="gasfree (developer-sponsored via Paymaster)":n&&(a=`gasless (pays ${n} via Paymaster)`),se({...r,feeMode:a})}case "reset":return t.clear(),se({success:true,note:"All settings reset to defaults."});default:return To(`Unknown action: ${e.action}`)}}Rr();gr();Tr();var yz="https://api.vesu.xyz",_z="0x03760f903a37948f97302736f89ce30290e45f441559325026842b7a6fb388c0",N1=[{name:"Prime",address:"0x0451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5"},{name:"Re7 USDC Core",address:"0x03976cac265a12609934089004df458ea29c776d77da423c96dc761d09d24124"},{name:"Re7 USDC Prime",address:"0x02eef0c13b10b487ea5916b54c0a7f98ec43fb3048f60fdeedaf5b08f6f88aaf"},{name:"Re7 USDC Frontier",address:"0x05c03e7e0ccfe79c634782388eb1e6ed4e8e2a013ab0fcc055140805e46261bd"},{name:"Re7 xBTC",address:"0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf"},{name:"Re7 USDC Stable Core",address:"0x073702fce24aba36da1eac539bd4bae62d4d6a76747b7cdd3e016da754d7a135"}],Ic=1;Tr();async function D1(e,t){let{timeoutMs:r=15e3,...o}=t??{},n=new AbortController,a=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...o,signal:n.signal})}finally{clearTimeout(a);}}var mie=300*1e3,pie=15e3,KT=new Map;function hie(e){let t=KT.get(e);return t?Date.now()-t.fetchedAt>mie?(KT.delete(e),null):t.data:null}function WT(e){return Number(BigInt(e.value))/10**e.decimals}function vz(e){return `${(e*100).toFixed(2)}%`}function gie(e){return {address:e.address,name:e.name,symbol:e.symbol,decimals:e.decimals,canBeBorrowed:e.stats.canBeBorrowed,vTokenAddress:e.vToken.address,supplyApy:vz(WT(e.stats.supplyApy)),borrowApr:vz(WT(e.stats.borrowApr))}}function bie(e,t){return {collateralAddress:e.collateralAssetAddress,collateralSymbol:t.get(e.collateralAssetAddress)??"UNKNOWN",debtAddress:e.debtAssetAddress,debtSymbol:t.get(e.debtAssetAddress)??"UNKNOWN",maxLTV:WT(e.maxLTV)}}async function GT(e){let t=hie(e);if(t)return t;try{let r=`${yz}/pools/${e}`,o=await Ki(()=>D1(r,{timeoutMs:pie}),{retryOnCodes:["NETWORK_ERROR"]});if(!o.ok)throw new Q("NETWORK_ERROR",`Vesu API returned ${o.status} for pool ${e}`);let a=(await o.json()).data,i=new Map;for(let c of a.assets)i.set(c.address,c.symbol);let s={address:a.id,name:a.name,protocolVersion:a.protocolVersion,isDeprecated:a.isDeprecated,assets:a.assets.map(gie),pairs:a.pairs.map(c=>bie(c,i))};return KT.set(e,{data:s,fetchedAt:Date.now()}),s}catch(r){throw r instanceof Q?r:r instanceof DOMException&&r.name==="AbortError"?new Q("NETWORK_ERROR",`Vesu API request timed out for pool ${e}`):new Q("NETWORK_ERROR",`Failed to fetch pool data from Vesu API: ${r instanceof Error?r.message:String(r)}`)}}async function xz(){let e=await Promise.allSettled(N1.map(r=>GT(r.address))),t=[];for(let r of e)r.status==="fulfilled"&&t.push(r.value);return t}function Cc(e){let t=e&(1n<<128n)-1n,r=e>>128n;return [`0x${t.toString(16)}`,`0x${r.toString(16)}`]}function nu(e,t){let r=t<0n,o=r?-t:t;return [`0x${e.toString(16)}`,...Cc(o),r?"0x1":"0x0"]}function yie(){return nu(Ic,0n)}async function U1(e,t,r,o){let n=le(r),a=ae.parse(o,n),i=e.address.toString(),s=await ou(e,t,n),c=await e.tx().approve(n,J(s),a).add({contractAddress:J(s),entrypoint:"deposit",calldata:[...Cc(a.toBase()),i]}).send();return await c.wait(),{hash:c.hash,explorerUrl:c.explorerUrl}}async function L1(e,t,r,o){let n=le(r),a=ae.parse(o,n),i=await ou(e,t,n),s=e.address.toString(),c=await e.tx().add({contractAddress:J(i),entrypoint:"withdraw",calldata:[...Cc(a.toBase()),s,s]}).send();return await c.wait(),{hash:c.hash,explorerUrl:c.explorerUrl}}async function z1(e,t,r,o,n,a,i=false){let s=le(r),c=le(n),l=ae.parse(o,s),d=ae.parse(a,c),u=e.address.toString(),f=await Fo(s);if(f>0){let b=parseFloat(o)*f;if(b<10)throw new Q("LENDING_FAILED",`dusty-collateral-balance: Collateral amount is too small. Minimum equivalent of ~$10 is required by Vesu. Current value: ~$${b.toFixed(2)}`)}let m=await Fo(c);if(m>0){let b=parseFloat(a)*m;if(b<10)throw new Q("LENDING_FAILED",`dusty-debt-balance: Borrow amount is too small. Minimum equivalent of ~$10 is required by Vesu. Current value: ~$${b.toFixed(2)}`)}let p=[s.address.toString(),c.address.toString(),u,...nu(Ic,l.toBase()),...nu(Ic,d.toBase())],h=e.tx();if(i){let b=await ou(e,t,s);h=h.add({contractAddress:J(b),entrypoint:"withdraw",calldata:[...Cc(l.toBase()),u,u]});}let g=await h.approve(s,J(t),l).add({contractAddress:J(t),entrypoint:"modify_position",calldata:p}).send();return await g.wait(),{hash:g.hash,explorerUrl:g.explorerUrl}}async function B1(e,t,r,o,n){let a=le(r),i=le(o),s=ae.parse(n,i),c=e.address.toString(),l=[a.address.toString(),i.address.toString(),c,...yie(),...nu(Ic,-s.toBase())],d=await e.tx().approve(i,J(t),s).add({contractAddress:J(t),entrypoint:"modify_position",calldata:l}).send();return await d.wait(),{hash:d.hash,explorerUrl:d.explorerUrl}}async function M1(e,t,r,o){let n=await Zp(e,t,r,o);if(!n)throw new Q("LENDING_FAILED","No active position found to close.");let a=le(r),i=le(o),s=ae.parse(n.collateralAmount,a),c=ae.parse(n.debtAmount,i),l=e.address.toString(),d=[a.address.toString(),i.address.toString(),l,...nu(Ic,-s.toBase()),...nu(Ic,-c.toBase())],u=await e.tx().approve(i,J(t),c).add({contractAddress:J(t),entrypoint:"modify_position",calldata:d}).send();return await u.wait(),{hash:u.hash,explorerUrl:u.explorerUrl}}async function Zp(e,t,r,o){let n=le(r),a=le(o),i=e.address.toString();try{let s=await e.callContract({contractAddress:t,entrypoint:"position",calldata:[n.address.toString(),a.address.toString(),i]});if(s.length<8)return null;let c=BigInt(s[4])+(BigInt(s[5])<<128n),l=BigInt(s[6])+(BigInt(s[7])<<128n);if(c===0n&&l===0n)return null;let d=ae.fromRaw(c,n).toFormatted(!0),u=ae.fromRaw(l,a).toFormatted(!0),f,m="UNKNOWN";try{let h=(await GT(t)).pairs.find(g=>g.collateralAddress===n.address.toString()&&g.debtAddress===a.address.toString());if(h){let g=await Fo(n),b=await Fo(a);if(g>0&&b>0){let v=parseFloat(d)*g,_=parseFloat(u)*b,y=v*h.maxLTV;_>0?(f=y/_,f>1.5?m="SAFE":f>1.1?m="WARNING":m="DANGER"):(f=9999,m="SAFE");}}}catch{}return {collateralAsset:r.toUpperCase(),debtAsset:o.toUpperCase(),collateralAmount:d,debtAmount:u,healthFactor:f,riskLevel:m}}catch{return null}}async function ou(e,t,r){let o=await e.callContract({contractAddress:_z,entrypoint:"v_token_for_asset",calldata:[t,r.address.toString()]});if(!o||o.length===0||o[0]==="0x0")throw new Q("LENDING_FAILED",`No vToken found for ${r.symbol} in pool ${t}. This asset may not be supported by this pool.`);return o[0]}async function xa(e,t,r){let o=le(r),n=e.address.toString();try{let a=await ou(e,t,o),i=await e.callContract({contractAddress:a,entrypoint:"balance_of",calldata:[n]});if(!i||i.length===0)return null;let s=BigInt(i[0])+(BigInt(i[1]||"0x0")<<128n);if(s===0n)return "0";let c=await e.callContract({contractAddress:a,entrypoint:"convert_to_assets",calldata:[...Cc(s)]});if(!c||c.length===0)return null;let l=BigInt(c[0])+(BigInt(c[1]||"0x0")<<128n);return ae.fromRaw(l,o).toFormatted(!0)}catch{return null}}var _ie=F.string().regex(/^0x[0-9a-fA-F]{1,64}$/,"Invalid Starknet address");function Ln(e){return _ie.parse(e)}async function Oc(e){return e!=="mainnet"?[]:xz()}function vie(e,t){if(t!=="mainnet")return null;let r=e.toLowerCase();return N1.find(o=>o.address.toLowerCase()===r||o.name.toLowerCase().startsWith(r))??null}function br(e,t){let r=vie(e,t);return r?{address:r.address,name:r.name}:{address:Ln(e),name:null}}Tr();async function Sz(e){return Un(async({session:t})=>{let r=await Oc(t.network);if(e.name){let o=e.name.toLowerCase();r=r.filter(n=>n.name.toLowerCase().includes(o));}return se({success:true,pools:r.map(o=>({name:o.name,poolContract:o.address,protocolVersion:o.protocolVersion,isDeprecated:o.isDeprecated,assets:o.assets.map(n=>n.symbol),pairs:o.pairs.map(n=>`${n.collateralSymbol}/${n.debtSymbol}`)}))})})}async function kz(e){return Un(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await xa(r,o.address,e.collateral_token),a=null;return e.borrow_token&&(a=await Zp(r,o.address,e.collateral_token,e.borrow_token)),!a&&(!n||n==="0.0")?se({success:true,position:null,suppliedYield:null,message:"No active position or supply found for this pool and token."}):se({success:true,suppliedYield:n&&n!=="0.0"?`${n} ${e.collateral_token.toUpperCase()}`:null,position:a})})}async function Tz(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await U1(r,o.address,e.token,e.amount);return se({success:true,action:"supply",amount:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function Ez(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await L1(r,o.address,e.token,e.amount);return se({success:true,action:"withdraw",amount:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function $z(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=false;if(e.use_supplied){let i=await xa(r,o.address,e.collateral_token);if(!i||parseFloat(i)<parseFloat(e.collateral_amount))throw new Q("INSUFFICIENT_BALANCE",`Insufficient supplied balance. You have ${i||"0"} ${e.collateral_token} supplied, but want to use ${e.collateral_amount} as collateral.`);n=true;}let a=await z1(r,o.address,e.collateral_token,e.collateral_amount,e.borrow_token,e.borrow_amount,n);return se({success:true,action:"borrow",collateral:`${e.collateral_amount} ${e.collateral_token.toUpperCase()}`,borrowed:`${e.borrow_amount} ${e.borrow_token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:a.hash,explorerUrl:a.explorerUrl})})}async function Az(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await B1(r,o.address,e.collateral_token,e.token,e.amount);return se({success:true,action:"repay",repaid:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function Iz(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await M1(r,o.address,e.collateral_token,e.debt_token);return se({success:true,action:"close_position",pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}gr();async function j1(e,t,r){let[o,n,a]=await Promise.allSettled([wie(t),Sie(e,t,r),Tie(t)]),i=o.status==="fulfilled"?o.value:[],s=n.status==="fulfilled"?n.value:[],c=a.status==="fulfilled"?a.value:[],l=i.reduce((u,f)=>u+f.usdValue,0),d=s.reduce((u,f)=>u+f.usdValue,0);return {address:r.address,network:r.network,balances:i,staking:s,lending:c,totalUsdValue:l+d}}var xie=5;async function wie(e){let t=await Jd(e);return (await T1(t,xie,async o=>{let n=0;try{let a=le(o.symbol),i=await Fo(a);n=parseFloat(o.balance)*i;}catch{}return {symbol:o.symbol,name:o.name,amount:o.balance,usdValue:n}})).sort((o,n)=>n.usdValue-o.usdValue)}async function Sie(e,t,r){let o=await ru(e,t,r.network,r.address);if(o.positions.length===0)return [];let n=[...new Set(o.positions.map(s=>s.token))],a=await Promise.allSettled(n.map(async s=>{try{let c=le(s);return {symbol:s,price:await Fo(c)}}catch{return {symbol:s,price:0}}})),i=new Map;for(let s of a)s.status==="fulfilled"&&i.set(s.value.symbol,s.value.price);return o.positions.map(s=>({validator:s.validator,pool:s.pool,token:s.token,staked:s.staked,rewards:s.rewards,unpooling:s.unpooling,cooldownEndsAt:s.cooldownEndsAt,usdValue:kie(s.total)*(i.get(s.token)??0)}))}function kie(e){let t=e.match(/([\d.]+)/);return t?parseFloat(t[1]):0}async function Tie(e){let r=(await Oc("mainnet")).flatMap(n=>n.assets.map(async a=>{let i=await xa(e,n.address,a.symbol);return i&&i!=="0"?{pool:n.name,asset:a.symbol,supplied:i}:null}));return (await Promise.allSettled(r)).filter(n=>n.status==="fulfilled"&&n.value!==null).map(n=>n.value)}async function Cz(){return Un(async({session:e,sdk:t,wallet:r})=>{let o=await j1(t,r,e);return se(o)})}Rr();gr();async function Oz(e){return Promise.all(e.map(async t=>{let r=le(t.from_token),o=le(t.to_token),n=ae.parse(t.amount,r);return {tokenIn:r,tokenOut:o,amount:n.toBase().toString()}}))}async function Pz(e){let t=await Oz(e.swaps),r=await $1(t);return se({success:true,quotes:r.map((o,n)=>({amountIn:`${e.swaps[n].amount} ${t[n].tokenIn.symbol}`,expectedAmountOut:`~${ae.fromRaw(BigInt(o.outputAmount),t[n].tokenOut).toUnit()} ${t[n].tokenOut.symbol}`,estimatedGasUsd:o.estimatedGasUsedInUsd??null})),message:"Quotes generated. Use multi_swap to execute."})}async function Rz(e){return Rt(async({session:t,wallet:r})=>{let o=await Oz(e.swaps),n=await A1(o,e.slippage??1,t.address),a=r.tx();for(let c=0;c<o.length;c++){let l=o[c],d=n[c],u=ae.parse(e.swaps[c].amount,l.tokenIn);a.approve(l.tokenIn,J(Er),u).add({contractAddress:Er,entrypoint:"swap",calldata:d.calldata});}let i=c=>({amountIn:`${e.swaps[c].amount} ${o[c].tokenIn.symbol}`,expectedAmountOut:`~${ae.fromRaw(BigInt(n[c].route.outputAmount),o[c].tokenOut).toUnit()} ${o[c].tokenOut.symbol}`});if(e.simulate){let c=await jt(a);return ri(c,{swaps:o.map((l,d)=>i(d))})}let s=await a.send();return await s.wait(),se({success:true,txHash:s.hash,explorerUrl:s.explorerUrl,swaps:o.map((c,l)=>i(l)),slippage:`${e.slippage??1}%`})})}Rr();gr();Hp();Tr();async function F1(e,t,r){if(r.length<2)throw new Q("INVALID_AMOUNT","Batch requires at least 2 operations. Use individual commands for single operations.");let o=e.tx(),n=[];for(let a of r){switch(a.type){case "swap":await Eie(o,a.params,t);break;case "stake":await $ie(o,a.params,e,t);break;case "supply":await Aie(o,a.params,e,t);break;case "send":await Iie(o,a.params);break;default:throw new Q("INVALID_CONFIG",`Unknown batch operation type: ${String(a.type)}`)}n.push(Cie(a));}return {builder:o,summary:n}}async function Eie(e,t,r){let o=le(t.from_token),n=le(t.to_token),a=ae.parse(t.amount,o),i=a.toBase().toString(),s=await Ac(o,n,i,t.slippage??1,r.address);e.approve(o,J(Er),a).add({contractAddress:Er,entrypoint:"swap",calldata:s.calldata});}async function $ie(e,t,r,o){let n=(t.token??"STRK").toUpperCase(),a=le(n),i=ae.parse(t.amount,a),s=t.pool;if(!s&&t.validator){let{sdk:c}=await Be(o),l=Vo(t.validator,o.network);if(!l)throw new Q("VALIDATOR_NOT_FOUND",`Validator '${t.validator}' not found`);let d=await va(c,l.stakerAddress.toString());s=tu(d,n).poolContract;}if(!s)throw new Q("INVALID_CONFIG","Stake operation requires pool or validator");e.stake(J(Ln(s)),i);}async function Aie(e,t,r,o){let n=le(t.token),a=ae.parse(t.amount,n),i=r.address.toString(),s=br(t.pool,o.network),c=await ou(r,s.address,n);e.approve(n,J(c),a).add({contractAddress:J(c),entrypoint:"deposit",calldata:[...Cc(a.toBase()),i]});}async function Iie(e,t){let r=le(t.token),o=ae.parse(t.amount,r),n=Ln(t.to);e.transfer(r,{to:J(n),amount:o});}function Cie(e){let t=e.params;switch(e.type){case "swap":{let r=t;return `swap ${r.amount} ${r.from_token.toUpperCase()} \u2192 ${r.to_token.toUpperCase()}`}case "stake":{let r=t;return `stake ${r.amount} ${(r.token??"STRK").toUpperCase()}`}case "supply":{let r=t;return `supply ${r.amount} ${r.token.toUpperCase()}`}case "send":{let r=t;return `send ${r.amount} ${r.token.toUpperCase()} \u2192 ${r.to.slice(0,10)}\u2026`}default:return `${e.type}: ${JSON.stringify(t)}`}}async function Nz(e){return Rt(async({session:t,wallet:r})=>{let o=e.operations.map(s=>({type:s.type,params:s.params})),{builder:n,summary:a}=await F1(r,t,o);if(e.simulate){let s=await jt(n);return ri(s,{operations:a})}let i=await n.send();return await i.wait(),se({success:true,txHash:i.hash,explorerUrl:i.explorerUrl,operations:a})})}Tr();function Fe(e){return async(...t)=>{try{return await e(...t)}catch(r){let o=r instanceof Q,n=r instanceof Error?r.message:String(r);return se({success:false,error:ch(n),code:o?r.code:"UNKNOWN_ERROR",...o&&r.details?{details:r.details}:{}})}}}function Dz(e){return e.tool("get_auth_status","Check authentication status and Fibrous API health on Starknet. Use this to verify the user's active wallet.",{},{readOnlyHint:true,destructiveHint:false},Fe(qI)),e.tool("config_action","View and modify starkfi global configuration such as active network, RPC URL, and Gas Payment mechanisms.",{action:F.enum(["list","set-rpc","get-rpc","set-network","set-gasfree","set-gas-token","reset"]).describe("list: view all. reset: clear all settings to defaults. set-gasfree: dev pays gas using paymaster credits. set-gas-token: user pays gas in ERC20 token instead of STRK."),value:F.string().optional().describe("set-gasfree: 'on'/'off'. set-gas-token: symbol 'USDC'/'ETH' or 'off'. set-rpc: URL string. set-network: 'mainnet'/'sepolia'.")},{readOnlyHint:false,destructiveHint:false},Fe(bz)),2}function Uz(e){return e.tool("get_tx_status","Check Starknet transaction status by hash. Use this to verify if a recently submitted transaction has been accepted on L2 or L1.",{hash:F.string().describe("Transaction hash (0x...)")},{readOnlyHint:true,destructiveHint:false},Fe(nz)),e.tool("get_balance","Get native token and ERC-20 token balances on Starknet for the authorized user.",{token:F.string().optional().describe("Specific token symbol (e.g. 'STRK', 'ETH', 'USDC'). Omit to fetch all balances.")},{readOnlyHint:true,destructiveHint:false},Fe(ez)),e.tool("deploy_account","Deploy the Starknet smart contract account on-chain. Required once before sending transactions. Safe to call multiple times (idempotent) \u2014 returns status if already deployed.",{},{readOnlyHint:false,destructiveHint:true,idempotentHint:true},Fe(tz)),e.tool("send_tokens","Transfer tokens to a recipient on Starknet. Set simulate=true to estimate fees without executing.",{amount:F.string().describe("Amount to send (e.g. '0.1', '100')"),token:F.string().describe("Token symbol (e.g. 'STRK', 'ETH', 'USDC')"),recipient:F.string().describe("Recipient Starknet address (0x...)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without sending a transaction")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(rz)),e.tool("get_portfolio","Get complete DeFi portfolio overview: all token balances (with USD values), staking positions, and lending positions in one call.",{},{readOnlyHint:true,destructiveHint:false},Fe(Cz)),5}function Lz(e){e.tool("get_swap_quote","Get an expected output and route from Fibrous *without* executing the swap. ALWAYS use this BEFORE calling swap_tokens so the user can review the expected output amount and slippage.",{amount:F.string().describe("Amount to swap in (e.g. '0.1', '100')"),from_token:F.string().describe("Source token symbol to sell (e.g. 'ETH', 'USDC')"),to_token:F.string().describe("Destination token symbol to buy (e.g. 'STRK', 'DAI')")},{readOnlyHint:true,destructiveHint:false},Fe(oz)),e.tool("swap_tokens","Execute a token swap on Starknet using Fibrous aggregation. Finds optimal route and executes. Set simulate=true to estimate fees without executing. ONLY call this after showing the user a quote via get_swap_quote.",{amount:F.string().describe("Amount to swap in (e.g. '0.1', '100')"),from_token:F.string().describe("Source token symbol to sell (e.g. 'ETH', 'STRK')"),to_token:F.string().describe("Destination token symbol to buy (e.g. 'USDC', 'DAI')"),slippage:F.number().optional().describe("Slippage tolerance % (default: 1)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without sending a transaction")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(az));let t=F.object({amount:F.string().describe("Amount to swap in (e.g. '100', '0.5')"),from_token:F.string().describe("Source token symbol (e.g. 'USDC', 'ETH')"),to_token:F.string().describe("Destination token symbol (e.g. 'ETH', 'STRK')")});return e.tool("get_multi_swap_quote","Get quotes for multiple token swaps at once (2-3 pairs). Uses Fibrous batch routing for optimal rates.",{swaps:F.array(t).min(2).max(3).describe("Array of swap pairs (2-3 items)")},{readOnlyHint:true,destructiveHint:false},Fe(Pz)),e.tool("multi_swap","Execute multiple token swaps in a single transaction (2-3 pairs). Uses Fibrous batch routing. Call get_multi_swap_quote first to preview.",{swaps:F.array(t).min(2).max(3).describe("Array of swap pairs (2-3 items)"),slippage:F.number().optional().describe("Slippage tolerance % (default: 1)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without executing")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Rz)),e.tool("batch_execute","Execute multiple DeFi operations in a single Starknet transaction (multicall). Supports: swap, stake, supply, send. Requires at least 2 operations.",{operations:F.array(F.object({type:F.enum(["swap","stake","supply","send"]).describe("Operation type"),params:F.record(F.string(),F.string()).describe("Operation params. swap: {amount, from_token, to_token}. stake: {amount, token?, pool? or validator?}. supply: {amount, token, pool}. send: {amount, token, to}.")})).min(2).describe("Array of operations to batch (min 2)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without executing")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Nz)),5}function zz(e){return e.tool("list_validators","List all known Starknet staking validators. Use this FIRST to see available validators and their names before trying to find pools.",{},{readOnlyHint:true,destructiveHint:false},Fe(mz)),e.tool("list_pools","List delegation pools for a specific validator. Look up a validator name via list_validators first.",{validator:F.string().describe("Validator name (e.g. 'Karnot', 'Kakarot') or staker address. Supports partial matches.")},{readOnlyHint:true,destructiveHint:false},Fe(fz)),e.tool("get_staking_info","Get staking position info (staked balance, unclaimed rewards, total balance, commission, unpooling cooldown) for a specific pool contract.",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:true,destructiveHint:false},Fe(uz)),e.tool("get_stake_status","Scan ALL known validators and pools to return a consolidated staking dashboard with total staked, total rewards, total value, and per-pool breakdown. Use this to give the user a full picture of their staking portfolio.",{validator:F.string().optional().describe("Optional validator name or staker address to strictly filter results.")},{readOnlyHint:true,destructiveHint:false},Fe(gz)),e.tool("stake_tokens","Stake tokens in a delegation pool on Starknet. Smart stake: auto-detects whether the user needs to enter the pool or just add to an existing delegation. Supports STRK, WBTC, tBTC, SolvBTC, LBTC.",{amount:F.string().describe("Amount to stake (e.g. '100', '0.01')"),pool:F.string().describe("Staking pool contract address (0x...)"),token:F.string().optional().describe("Token symbol to stake (default: STRK). Supported: STRK, WBTC, tBTC, SolvBTC, LBTC")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(lz)),e.tool("unstake_tokens","Unstake tokens from a pool. Unstaking is a TWO-STEP process: 1. call with action='intent', 2. wait for cooldown, 3. call with action='exit' to complete withdrawal.",{action:F.enum(["intent","exit"]).describe("'intent' strictly starts the unstaking process, 'exit' completes withdrawal after cooldown."),pool:F.string().describe("Staking pool contract address (0x...)"),amount:F.string().optional().describe("Amount to unstake (ONLY required when action='intent')"),token:F.string().optional().describe("Token symbol (default: STRK). Must match the pool's token.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(dz)),e.tool("claim_rewards","Extract earned rewards from a staking pool to the user's wallet.",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(pz)),e.tool("compound_rewards","Atomically claim staking rewards and re-stake them recursively into the same pool in a single transaction (compound interest).",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(hz)),8}function Bz(e){return e.tool("list_lending_pools","List available Vesu V2 lending pools on Starknet with their supported collateral/debt pairs. Use this FIRST to discover available pools before supplying, borrowing, or checking positions.",{name:F.string().optional().describe("Filter pools by name (partial match). Omit to list all.")},{readOnlyHint:true,destructiveHint:false},Fe(Sz)),e.tool("get_lending_position","Get the user's lending position (supplied collateral and outstanding debt) in a specific Vesu pool.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_token:F.string().describe("Collateral token symbol (e.g. 'ETH', 'STRK')"),borrow_token:F.string().optional().describe("Borrow token symbol (e.g. 'USDC', 'USDT')")},{readOnlyHint:true,destructiveHint:false},Fe(kz)),e.tool("supply_assets","Supply (lend) tokens into a Vesu V2 pool to earn interest. The tokens are deposited into the pool's ERC-4626 vToken vault.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to supply (e.g. '100', '0.5')"),token:F.string().describe("Token symbol to supply (e.g. 'STRK', 'ETH', 'USDC')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Tz)),e.tool("withdraw_assets","Withdraw previously supplied tokens from a Vesu V2 lending pool.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to withdraw (e.g. '100', '0.5')"),token:F.string().describe("Token symbol to withdraw (e.g. 'STRK', 'ETH', 'USDC')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Ez)),e.tool("borrow_assets","Borrow tokens from a Vesu V2 pool by supplying collateral. Atomically deposits collateral and borrows the debt asset in a single transaction.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_amount:F.string().describe("Collateral amount to deposit (e.g. '1000')"),collateral_token:F.string().describe("Collateral token symbol (e.g. 'STRK', 'ETH')"),borrow_amount:F.string().describe("Amount to borrow (e.g. '100')"),borrow_token:F.string().describe("Token to borrow (e.g. 'USDC', 'USDT')"),use_supplied:F.boolean().optional().describe("Set to true to use previously supplied yield tokens as collateral via Multicall instead of transferring fresh tokens from wallet.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe($z)),e.tool("repay_debt","Repay borrowed tokens on an existing Vesu V2 lending position. Approves and repays the specified amount of debt.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to repay (e.g. '50', '100')"),token:F.string().describe("Token to repay (e.g. 'USDC', 'USDT')"),collateral_token:F.string().describe("Collateral token of the position (e.g. 'ETH', 'STRK'). Needed to identify the position.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Az)),e.tool("close_position","Atomically close an active Vesu V2 lending position. Repays all outstanding debt and withdraws all collateral in a single transaction.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_token:F.string().describe("Collateral token symbol of the position (e.g. 'STRK', 'ETH')"),debt_token:F.string().describe("Borrowed token symbol of the position (e.g. 'USDC', 'USDT')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Iz)),7}function Mz(e){let t=[{name:"Auth & Config",count:Dz(e)},{name:"Wallet",count:Uz(e)},{name:"Trade",count:Lz(e)},{name:"Staking",count:zz(e)},{name:"Lending",count:Bz(e)}];return {total:t.reduce((r,o)=>r+o.count,0),categories:t}}var YT={name:"starkfi",version:"0.4.2"},Oie=`StarkFi is a Starknet DeFi toolkit. You can:
|
|
109
|
+
`}var Cy=class{constructor(t=Mc.stdin,r=Mc.stdout){this._stdin=t,this._stdout=r,this._readBuffer=new Iy,this._started=false,this._ondata=o=>{this._readBuffer.append(o),this.processReadBuffer();},this._onerror=o=>{this.onerror?.(o);};}async start(){if(this._started)throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=true,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror);}processReadBuffer(){for(;;)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t);}catch(t){this.onerror?.(t);}}async close(){this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0&&this._stdin.pause(),this._readBuffer.clear(),this.onclose?.();}send(t){return new Promise(r=>{let o=MI(t);this._stdout.write(o)?r():this._stdout.once("drain",r);})}};var ti=FI.homedir(),i6=FI.tmpdir(),{env:Ql}=Mc,UJ=e=>{let t=bt.join(ti,"Library");return {data:bt.join(t,"Application Support",e),config:bt.join(t,"Preferences",e),cache:bt.join(t,"Caches",e),log:bt.join(t,"Logs",e),temp:bt.join(i6,e)}},LJ=e=>{let t=Ql.APPDATA||bt.join(ti,"AppData","Roaming"),r=Ql.LOCALAPPDATA||bt.join(ti,"AppData","Local");return {data:bt.join(r,e,"Data"),config:bt.join(t,e,"Config"),cache:bt.join(r,e,"Cache"),log:bt.join(r,e,"Log"),temp:bt.join(i6,e)}},zJ=e=>{let t=bt.basename(ti);return {data:bt.join(Ql.XDG_DATA_HOME||bt.join(ti,".local","share"),e),config:bt.join(Ql.XDG_CONFIG_HOME||bt.join(ti,".config"),e),cache:bt.join(Ql.XDG_CACHE_HOME||bt.join(ti,".cache"),e),log:bt.join(Ql.XDG_STATE_HOME||bt.join(ti,".local","state"),e),temp:bt.join(i6,t,e)}};function s6(e,{suffix:t="nodejs"}={}){if(typeof e!="string")throw new TypeError(`Expected a string, got ${typeof e}`);return t&&(e+=`-${t}`),Mc.platform==="darwin"?UJ(e):Mc.platform==="win32"?LJ(e):zJ(e)}var VI=s6("starkfi"),Oy="https://2c29jsb475.eu-central-1.awsapprunner.com",c6=VI.data,Py=VI.config;function HI(e,t){return `${t==="mainnet"?"https://voyager.online":"https://sepolia.voyager.online"}/tx/${e}`}Tr();var gm=join(c6,"session.json");function Is(){if(!existsSync(gm))return null;try{let e=readFileSync(gm,"utf-8");return JSON.parse(e)}catch{return null}}function ZI(e){let t=c6;existsSync(t)||mkdirSync(t,{recursive:true}),writeFileSync(gm,JSON.stringify(e,null,2),"utf-8");}function d6(){existsSync(gm)&&unlinkSync(gm);}function HJ(e){try{let t=e.split(".");if(t.length!==3||!t[1])return !1;let r=JSON.parse(Buffer.from(t[1],"base64url").toString());return r.exp?Date.now()>=(r.exp-300)*1e3:!1}catch{return false}}function Ee(){let e=Is();if(!e)throw new Q("AUTH_REQUIRED","Not authenticated. Run 'starkfi auth login <email>' first.");if(HJ(e.token))throw d6(),new Q("SESSION_EXPIRED","Session expired. Please re-authenticate with 'starkfi auth login <email>'");return e}var ed="https://api.fibrous.finance/starknet";var Er="0x00f6f4CF62E3C010E0aC2451cC7807b5eEc19a40b0FaaCd00CCA3914280FDf5a";async function Ry(){try{let e=await fetch(`${ed}/healthCheck`);if(!e.ok)return {ok:!1,message:`Fibrous API returned ${e.status}`};let t=await e.json();return {ok:t.staus===200,message:t.message}}catch(e){return {ok:false,message:`Failed to reach Fibrous API: ${e instanceof Error?e.message:String(e)}`}}}function To(e){return {content:[{type:"text",text:e}]}}function se(e){return To(JSON.stringify(e,null,2))}function ri(e,t){return se({success:e.success,mode:"SIMULATION (no TX sent)",...t,estimatedFee:e.estimatedFee,estimatedFeeUsd:e.estimatedFeeUsd,callCount:e.callCount,...e.revertReason?{revertReason:e.revertReason}:{}})}async function qI(){let e=Is(),t=await Ry();return e?se({authenticated:true,type:e.type,network:e.network,address:e.address,fibrous:t}):se({authenticated:false,fibrous:t,message:"Not authenticated. Use 'starkfi auth login'."})}Rr();var Ec=join(Py,"config.json"),Mt=class e{static instance;config;lastMtime=0;constructor(){this.config=this.load(),this.updateMtime();}static getInstance(){return e.instance||(e.instance=new e),e.instance}get(t){return this.refreshIfChanged(),this.config[t]}set(t,r){this.config[t]=r,this.save();}delete(t){delete this.config[t],this.save();}clear(){this.config={},this.save();}getAll(){return this.refreshIfChanged(),{...this.config}}refreshIfChanged(){try{if(!existsSync(Ec))return;let t=statSync(Ec).mtimeMs;t>this.lastMtime&&(this.config=this.load(),this.lastMtime=t);}catch{}}updateMtime(){try{existsSync(Ec)&&(this.lastMtime=statSync(Ec).mtimeMs);}catch{}}load(){if(!existsSync(Ec))return {};try{let t=readFileSync(Ec,"utf-8");return JSON.parse(t)}catch{return {}}}save(){existsSync(Py)||mkdirSync(Py,{recursive:true}),writeFileSync(Ec,JSON.stringify(this.config,null,2),"utf-8"),this.updateMtime();}};var WL="https://starknet.paymaster.avnu.fi",GL="https://sepolia.paymaster.avnu.fi",YL="STRK",k1={ETH:"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",STRK:"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",USDC:"0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",USDT:"0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",DAI:"0x05574eb6b8789a91466f902c380d978e472db68170ff82a5b650b95a58ddf4ad"},Zi=Object.keys(k1);function qi(e,t){if(e)return {feeMode:"sponsored",gasTokenAddress:void 0,needsPaymaster:true};let o=k1[(t??YL).toUpperCase()];return o?{feeMode:"sponsored",gasTokenAddress:o,needsPaymaster:true}:{feeMode:"sponsored",gasTokenAddress:k1.STRK,needsPaymaster:true}}function cie(e,t){let r=e.getAccount(),o=r,n=o.executePaymasterTransaction;if(typeof n!="function"){console.warn("[StarkFi] Cannot patch gasless mode \u2014 executePaymasterTransaction not found on account. Gas will use default sponsored mode. Consider updating StarkZap SDK.");return}let a=n.bind(r);o.executePaymasterTransaction=async function(i,s,...c){let l={...s,feeMode:{mode:"default",gasToken:t}};return a(i,l,...c)};}function $c(e="mainnet",t,r=false,o,n){let a={network:e};if(t&&(a.rpcUrl=t),r){let i=e==="sepolia"?GL:WL;a.paymaster={nodeUrl:o??i,...n?{headers:n}:{}};}return new Yd(a)}async function HT(e,t){let r=Mt.getInstance(),o=r.get("gasfreeMode")===true,n=r.get("gasToken"),{feeMode:a,gasTokenAddress:i}=qi(o,n),s=new Tc({walletId:t.walletId,publicKey:t.publicKey,serverUrl:t.serverUrl,headers:{Authorization:`Bearer ${t.token}`}}),c=await e.connectWallet({account:{signer:s,accountClass:Kd},feeMode:a});return !o&&i&&cie(c,i),c}async function Be(e){let t=Mt.getInstance(),r=t.get("rpcUrl"),o=t.get("gasfreeMode")===true,n=t.get("gasToken"),{gasTokenAddress:a,needsPaymaster:i}=qi(o,n),s=e.type==="privy"&&e.serverUrl?e.serverUrl.replace("/sign/hash","/paymaster"):void 0,c=s&&e.token?{Authorization:`Bearer ${e.token}`}:void 0,l=$c(e.network,r,i,s,c),d=await HT(l,e);return {sdk:l,wallet:d,gasTokenAddress:a}}gr();async function T1(e,t,r){let o=[],n=0,a=async()=>{for(;n<e.length;){let s=n++,c=e[s];if(!c)continue;let l=await r(c);l!==void 0&&o.push(l);}},i=Array.from({length:Math.min(t,e.length)},()=>a());return await Promise.all(i),o}var lie=10;async function Jd(e){let t=qT();return T1(t,lie,async r=>{try{let o=await e.balanceOf(r);if(o.isPositive())return {symbol:r.symbol,name:r.name,balance:o.toUnit()}}catch{}})}gr();Rr();Rr();gr();Tr();Tr();async function Ki(e,t){let{maxRetries:r=2,baseDelayMs:o=500,retryOnCodes:n}=t??{},a;for(let i=0;i<=r;i++)try{return await e()}catch(s){if(a=s,s instanceof Q&&n?.length&&!n.includes(s.code))throw s;if(i<r){let c=o*2**i;await new Promise(l=>setTimeout(l,c));}}throw a}async function Qd(e,t,r){let o=new URLSearchParams({amount:r,tokenInAddress:e.address,tokenOutAddress:t.address}),n=await Ki(()=>fetch(`${ed}/route?${o.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(!n.ok)throw new Q("NO_ROUTE_FOUND",`Fibrous route API error: ${n.status}`);let a=await n.json();if(!a.success)throw new Q("NO_ROUTE_FOUND",a.errorMessage||"No route found for this swap");return a}async function Ac(e,t,r,o=1,n){let a=new URLSearchParams({amount:r,tokenInAddress:e.address,tokenOutAddress:t.address,slippage:o.toString()});n&&a.append("destination",n);let i=await Ki(()=>fetch(`${ed}/calldata?${a.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(!i.ok){let c=await i.text().catch(()=>"");throw new Q("SWAP_FAILED",`Fibrous calldata API error: ${i.status} ${c}`)}let s=await i.json();if(!s.route?.success)throw new Q("NO_ROUTE_FOUND","Failed to generate calldata: no valid route");return s}var E1=3;async function $1(e){if(e.length>E1)throw new Q("BATCH_LIMIT_EXCEEDED",`Multi-swap supports up to ${E1} pairs, got ${e.length}`);if(e.every(r=>r.tokenOut.address.toLowerCase()===e[0].tokenOut.address.toLowerCase()))try{let r=new URLSearchParams({amounts:e.map(n=>n.amount).join(","),tokenInAddresses:e.map(n=>n.tokenIn.address).join(","),tokenOutAddresses:e[0].tokenOut.address}),o=await Ki(()=>fetch(`${ed}/routeBatch?${r.toString()}`),{retryOnCodes:["NETWORK_ERROR"]});if(o.ok){let n=await o.json();if(Array.isArray(n)&&n.length===e.length){for(let a=0;a<n.length;a++)if(!n[a].success){let i=e[a];throw new Q("NO_ROUTE_FOUND",`No route found for pair ${a+1}: ${i.tokenIn.symbol} \u2192 ${i.tokenOut.symbol}`)}return n}}}catch(r){if(r instanceof Q)throw r}return Promise.all(e.map(r=>Qd(r.tokenIn,r.tokenOut,r.amount)))}async function A1(e,t=1,r){if(e.length>E1)throw new Q("BATCH_LIMIT_EXCEEDED",`Multi-swap supports up to ${E1} pairs, got ${e.length}`);return Promise.all(e.map(o=>Ac(o.tokenIn,o.tokenOut,o.amount,t,r)))}var Xd=new Map,die=6e4,uie=50;async function Fo(e){let t=e.symbol.toUpperCase();if(t==="USDC"||t==="USDT")return 1;let r=e.address.toLowerCase(),o=Xd.get(r);if(o&&Date.now()-o.timestamp<die)return o.promise;if(Xd.size>=uie){let a=Xd.keys().next().value;a&&Xd.delete(a);}let n=fie(e);return Xd.set(r,{promise:n,timestamp:Date.now()}),n.catch(()=>Xd.delete(r)),n}async function fie(e){try{let t=await Promise.resolve().then(()=>(gr(),JL)).then(n=>n.resolveToken("USDC")),r=(10n**BigInt(e.decimals)).toString(),o=await Qd(e,t,r);if(o.success&&o.inputToken?.price)return parseFloat(o.inputToken.price)}catch{}return 0}Tr();var QL="STRK";async function jt(e){let r=(await e.calls()).length;if(r===0)throw new Q("SIMULATION_FAILED","No calls to simulate \u2014 builder is empty.");let o=await e.preflight();if(!o.ok)return {success:false,estimatedFee:"N/A",estimatedFeeUsd:"N/A",callCount:r,revertReason:o.reason};try{let n=await e.estimateFee(),a=BigInt(n.overall_fee),i=le(QL),c=ae.fromRaw(a,i).toUnit(),l="unknown";try{let d=await Fo(i);d>0&&(l=`$${(parseFloat(c)*d).toFixed(4)}`);}catch{}return {success:!0,estimatedFee:`${c} ${QL}`,estimatedFeeUsd:l,callCount:r}}catch(n){return {success:true,estimatedFee:"estimation failed",estimatedFeeUsd:"unknown",callCount:r,revertReason:n instanceof Error?`Fee estimation failed: ${n.message}`:"Fee estimation failed"}}}async function Rt(e){let t=Ee(),{sdk:r,wallet:o}=await Be(t);return await o.ensureReady({deploy:"if_needed"}),e({session:t,sdk:r,wallet:o})}async function Un(e){let t=Ee(),{sdk:r,wallet:o}=await Be(t);return e({session:t,sdk:r,wallet:o})}async function ez(e){return Un(async({session:t,wallet:r})=>{if(e.token){let n=le(e.token),a=await r.balanceOf(n);return se({symbol:n.symbol,name:n.name,balance:a.toUnit()})}let o=await Jd(r);return se({network:t.network,address:t.address,balances:o})})}async function tz(){return Un(async({session:e,wallet:t})=>{let r=await t.isDeployed();if(!r){let o=Mt.getInstance(),n=o.get("gasfreeMode")===true,a=o.get("gasToken"),{feeMode:i}=qi(n,a);await t.ensureReady({deploy:"if_needed",feeMode:i});}return se({alreadyDeployed:r,success:true,address:e.address,network:e.network,message:r?"Account is already deployed. No action needed.":"Account deployed successfully. You can now send, swap, and stake."})})}async function rz(e){return Rt(async({wallet:t})=>{let r=le(e.token),o=ae.parse(e.amount,r),n=await t.balanceOf(r);if(n.lt(o))return se({success:false,error:`Insufficient balance. You have: ${n.toFormatted()}, attempting to send: ${o.toFormatted()}`});let a=t.tx().transfer(r,[{to:J(e.recipient),amount:o}]);if(e.simulate){let s=await jt(a);return ri(s,{amount:`${e.amount} ${e.token.toUpperCase()}`,to:e.recipient})}let i=await a.send();return await i.wait(),se({success:true,txHash:i.hash,explorerUrl:i.explorerUrl,amount:`${e.amount} ${e.token.toUpperCase()}`,to:e.recipient})})}async function nz(e){let t=Ee(),o=Mt.getInstance().get("rpcUrl"),i=await $c(t.network,o).getProvider().getTransactionReceipt(e.hash),s="actual_fee"in i?i.actual_fee:void 0,c=s?lh(s):void 0,l="block_number"in i?i.block_number:void 0;return se({hash:e.hash,status:i.statusReceipt,actualFee:c,blockNumber:l})}gr();Rr();async function oz(e){let t=le(e.from_token),r=le(e.to_token),n=ae.parse(e.amount,t).toBase().toString(),a=await Qd(t,r,n),s=ae.fromRaw(BigInt(a.outputAmount),r).toUnit();return se({success:true,amountIn:`${e.amount} ${t.symbol}`,expectedAmountOut:`~${s} ${r.symbol}`,estimatedGasUsd:a.estimatedGasUsedInUsd?`$${a.estimatedGasUsedInUsd.toFixed(4)}`:"Unknown",routeId:a.routeId,message:"Quote generated successfully. Use swap_tokens to execute."})}async function az(e){return Rt(async({session:t,wallet:r})=>{let o=le(e.from_token),n=le(e.to_token),a=ae.parse(e.amount,o),i=a.toBase().toString(),s=await Ac(o,n,i,e.slippage??1,t.address),c=r.tx().approve(o,J(Er),a).add({contractAddress:Er,entrypoint:"swap",calldata:s.calldata}),d=ae.fromRaw(BigInt(s.route.outputAmount),n).toUnit();if(e.simulate){let f=await jt(c);return ri(f,{amountIn:`${e.amount} ${o.symbol}`,expectedAmountOut:`~${d} ${n.symbol}`})}let u=await c.send();return await u.wait(),se({success:true,txHash:u.hash,explorerUrl:u.explorerUrl,amountIn:`${e.amount} ${o.symbol}`,amountOut:`~${d} ${n.symbol}`,slippage:`${e.slippage??1}%`})})}Rr();gr();Tr();function tu(e,t){let r=t.toUpperCase(),o=e.find(n=>n.tokenSymbol.toUpperCase()===r);if(!o){let n=e.map(a=>a.tokenSymbol).join(", ");throw new Q("POOL_NOT_FOUND",`No ${t} pool found for this validator. Available: ${n}`)}return o}async function va(e,t,r){let o=await e.getStakerPools(J(t));return Promise.all(o.map(async n=>{let a=r?await r.getPoolCommission(n.poolContract):void 0;return {poolContract:n.poolContract.toString(),tokenSymbol:n.token.symbol,amount:n.amount.toFormatted(true),commission:a}}))}async function I1(e,t,r,o="STRK"){let n=le(o),a=ae.parse(r,n),i=await e.stake(J(t),a);return {hash:i.hash,explorerUrl:i.explorerUrl}}async function C1(e,t){let r=await e.getPoolPosition(J(t));if(!r||r.rewards.isZero())throw new Q("STAKING_FAILED","No rewards to claim for this pool.");let o=await e.claimPoolRewards(J(t));return {hash:o.hash,explorerUrl:o.explorerUrl}}async function O1(e,t){let r=await e.getPoolPosition(J(t));if(!r||r.rewards.isZero())throw new Q("STAKING_FAILED","No rewards to compound for this pool.");let o=r.rewards.toFormatted(true),n=await e.tx().claimPoolRewards(J(t)).stake(J(t),r.rewards).send();return await n.wait(),{hash:n.hash,explorerUrl:n.explorerUrl,compounded:o}}async function P1(e,t,r,o="STRK"){let n=le(o),a=ae.parse(r,n),i=await e.exitPoolIntent(J(t),a);return {hash:i.hash,explorerUrl:i.explorerUrl}}async function R1(e,t){let r=await e.getPoolPosition(J(t));if(!r)throw new Q("STAKING_FAILED","Not a member of this pool.");if(r.unpooling.isZero())throw new Q("EXIT_NOT_READY","No exit intent declared. Call 'unstake intent' first.");if(r.unpoolTime&&new Date<r.unpoolTime)throw new Q("EXIT_NOT_READY",`Cooldown period is still active. Please wait until ${r.unpoolTime.toLocaleString()}`);let o=await e.exitPool(J(t));return {hash:o.hash,explorerUrl:o.explorerUrl}}async function sz(e,t){let r=await e.getPoolPosition(J(t));return r?{staked:r.staked.toFormatted(true),rewards:r.rewards.toFormatted(true),total:r.total.toFormatted(true),unpooling:r.unpooling.toFormatted(true),unpoolTime:r.unpoolTime??void 0,commissionPercent:r.commissionPercent}:null}async function ru(e,t,r,o,n){let{getValidators:a,findValidator:i}=await Promise.resolve().then(()=>(Hp(),iz)),s=a(r);if(n){let m=i(n,r);if(m)s=[m];else throw new Q("VALIDATOR_NOT_FOUND",`Validator '${n}' not found`)}let l=(await Promise.all(s.map(async m=>{try{return (await e.getStakerPools(m.stakerAddress)).map(h=>({validator:m.name,pool:h}))}catch{return []}}))).flat(),f=(await Promise.all(l.map(async({validator:m,pool:p})=>{let h;try{h=await t.getPoolPosition(p.poolContract);}catch{return null}return h?{validator:m,pool:p.poolContract.toString(),tokenSymbol:p.token.symbol,staked:h.staked,rewards:h.rewards,total:h.total,unpooling:h.unpooling,unpoolTime:h.unpoolTime??null,commissionPercent:h.commissionPercent}:null}))).filter(m=>m!==null).map(m=>({validator:m.validator,pool:m.pool,token:m.tokenSymbol,staked:m.staked.toFormatted(true),rewards:m.rewards.toFormatted(true),total:m.total.toFormatted(true),unpooling:m.unpooling.toFormatted(true),cooldownEndsAt:m.unpoolTime?m.unpoolTime.toISOString():null,commission:`${m.commissionPercent}%`}));return {network:r,address:o,positions:f}}Hp();async function lz(e){return Rt(async({wallet:t})=>{let r=(e.token??"STRK").toUpperCase(),o=await I1(t,e.pool,e.amount,r);return se({success:true,txHash:o.hash,explorerUrl:o.explorerUrl,amount:`${e.amount} ${r}`,pool:e.pool})})}async function dz(e){return Rt(async({wallet:t})=>{if(e.action==="intent"){if(!e.amount)return To("Amount is required for exit intent.");let o=(e.token??"STRK").toUpperCase(),n=await P1(t,e.pool,e.amount,o);return se({success:true,action:"exit_intent",txHash:n.hash,explorerUrl:n.explorerUrl,message:"Exit intent declared. Wait for cooldown period, then call with action='exit'."})}let r=await R1(t,e.pool);return se({success:true,action:"exit_complete",txHash:r.hash,explorerUrl:r.explorerUrl,message:"Tokens withdrawn from pool."})})}async function uz(e){return Un(async({wallet:t})=>{let r=await sz(t,e.pool);return r?se({isMember:true,pool:e.pool,staked:r.staked,rewards:r.rewards,total:r.total,unpooling:r.unpooling,cooldownEndsAt:r.unpoolTime?r.unpoolTime.toISOString():null,commissionPercent:r.commissionPercent}):se({isMember:false,pool:e.pool,message:"Not a member of this pool."})})}async function fz(e){return Un(async({session:t,sdk:r,wallet:o})=>{let n=Vo(e.validator,t.network),a=n?n.stakerAddress.toString():e.validator,i=await va(r,a,o);return se({validator:n?n.name:e.validator,stakerAddress:a,pools:i})})}async function mz(){let e=Ee(),t=eu(e.network);return se({network:e.network,count:t.length,validators:t.map(r=>({name:r.name,stakerAddress:r.stakerAddress.toString()}))})}async function pz(e){return Rt(async({wallet:t})=>{let r=await C1(t,e.pool);return se({success:true,txHash:r.hash,explorerUrl:r.explorerUrl})})}async function hz(e){return Rt(async({wallet:t})=>{let r=await O1(t,e.pool);return se({success:true,txHash:r.hash,explorerUrl:r.explorerUrl,compounded:r.compounded})})}async function gz({validator:e}={}){return Un(async({session:t,sdk:r,wallet:o})=>{let n=await ru(r,o,t.network,t.address,e);return se(n)})}async function bz(e){let t=Mt.getInstance();switch(e.action){case "set-rpc":return e.value?(t.set("rpcUrl",e.value),se({success:true,rpcUrl:e.value})):To("RPC URL value is required.");case "get-rpc":{let r=t.get("rpcUrl");return se({rpcUrl:r||"default (Cartridge RPC)"})}case "set-network":return !e.value||!["mainnet","sepolia"].includes(e.value)?To("Network must be 'mainnet' or 'sepolia'."):(t.set("network",e.value),se({success:true,network:e.value}));case "set-gasfree":{if(!e.value||!["on","off"].includes(e.value))return To("Gasfree mode must be 'on' or 'off'.");let r=e.value==="on";return t.set("gasfreeMode",r),r&&t.delete("gasToken"),se({success:true,gasfreeMode:r,note:r?"Developer sponsors gas via Paymaster (requires API key + credits)":"Gasfree disabled \u2014 using gasless mode (default: STRK)"})}case "set-gas-token":{if(!e.value)return To("Token symbol or 'reset' is required.");if(["off","reset","default"].includes(e.value.toLowerCase()))return t.delete("gasToken"),se({success:true,gasToken:"STRK",note:"Gas token reset to default: STRK"});let r=e.value.toUpperCase();return Zi.includes(r)?(t.delete("gasfreeMode"),t.set("gasToken",r),se({success:true,gasToken:r,note:`Gas paid in ${r} via Paymaster`})):To(`Unsupported token '${e.value}'. Supported: ${Zi.join(", ")}`)}case "list":{let r=t.getAll(),o=r.gasfreeMode===true,n=r.gasToken,a="gasless (pays STRK via Paymaster)";return o?a="gasfree (developer-sponsored via Paymaster)":n&&(a=`gasless (pays ${n} via Paymaster)`),se({...r,feeMode:a})}case "reset":return t.clear(),se({success:true,note:"All settings reset to defaults."});default:return To(`Unknown action: ${e.action}`)}}Rr();gr();Tr();var yz="https://api.vesu.xyz",_z="0x03760f903a37948f97302736f89ce30290e45f441559325026842b7a6fb388c0",N1=[{name:"Prime",address:"0x0451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5"},{name:"Re7 USDC Core",address:"0x03976cac265a12609934089004df458ea29c776d77da423c96dc761d09d24124"},{name:"Re7 USDC Prime",address:"0x02eef0c13b10b487ea5916b54c0a7f98ec43fb3048f60fdeedaf5b08f6f88aaf"},{name:"Re7 USDC Frontier",address:"0x05c03e7e0ccfe79c634782388eb1e6ed4e8e2a013ab0fcc055140805e46261bd"},{name:"Re7 xBTC",address:"0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf"},{name:"Re7 USDC Stable Core",address:"0x073702fce24aba36da1eac539bd4bae62d4d6a76747b7cdd3e016da754d7a135"}],Ic=1;Tr();async function D1(e,t){let{timeoutMs:r=15e3,...o}=t??{},n=new AbortController,a=setTimeout(()=>n.abort(),r);try{return await fetch(e,{...o,signal:n.signal})}finally{clearTimeout(a);}}var mie=300*1e3,pie=15e3,KT=new Map;function hie(e){let t=KT.get(e);return t?Date.now()-t.fetchedAt>mie?(KT.delete(e),null):t.data:null}function WT(e){return Number(BigInt(e.value))/10**e.decimals}function vz(e){return `${(e*100).toFixed(2)}%`}function gie(e){return {address:e.address,name:e.name,symbol:e.symbol,decimals:e.decimals,canBeBorrowed:e.stats.canBeBorrowed,vTokenAddress:e.vToken.address,supplyApy:vz(WT(e.stats.supplyApy)),borrowApr:vz(WT(e.stats.borrowApr))}}function bie(e,t){return {collateralAddress:e.collateralAssetAddress,collateralSymbol:t.get(e.collateralAssetAddress)??"UNKNOWN",debtAddress:e.debtAssetAddress,debtSymbol:t.get(e.debtAssetAddress)??"UNKNOWN",maxLTV:WT(e.maxLTV)}}async function GT(e){let t=hie(e);if(t)return t;try{let r=`${yz}/pools/${e}`,o=await Ki(()=>D1(r,{timeoutMs:pie}),{retryOnCodes:["NETWORK_ERROR"]});if(!o.ok)throw new Q("NETWORK_ERROR",`Vesu API returned ${o.status} for pool ${e}`);let a=(await o.json()).data,i=new Map;for(let c of a.assets)i.set(c.address,c.symbol);let s={address:a.id,name:a.name,protocolVersion:a.protocolVersion,isDeprecated:a.isDeprecated,assets:a.assets.map(gie),pairs:a.pairs.map(c=>bie(c,i))};return KT.set(e,{data:s,fetchedAt:Date.now()}),s}catch(r){throw r instanceof Q?r:r instanceof DOMException&&r.name==="AbortError"?new Q("NETWORK_ERROR",`Vesu API request timed out for pool ${e}`):new Q("NETWORK_ERROR",`Failed to fetch pool data from Vesu API: ${r instanceof Error?r.message:String(r)}`)}}async function xz(){let e=await Promise.allSettled(N1.map(r=>GT(r.address))),t=[];for(let r of e)r.status==="fulfilled"&&t.push(r.value);return t}function Cc(e){let t=e&(1n<<128n)-1n,r=e>>128n;return [`0x${t.toString(16)}`,`0x${r.toString(16)}`]}function nu(e,t){let r=t<0n,o=r?-t:t;return [`0x${e.toString(16)}`,...Cc(o),r?"0x1":"0x0"]}function yie(){return nu(Ic,0n)}async function U1(e,t,r,o){let n=le(r),a=ae.parse(o,n),i=e.address.toString(),s=await ou(e,t,n),c=await e.tx().approve(n,J(s),a).add({contractAddress:J(s),entrypoint:"deposit",calldata:[...Cc(a.toBase()),i]}).send();return await c.wait(),{hash:c.hash,explorerUrl:c.explorerUrl}}async function L1(e,t,r,o){let n=le(r),a=ae.parse(o,n),i=await ou(e,t,n),s=e.address.toString(),c=await e.tx().add({contractAddress:J(i),entrypoint:"withdraw",calldata:[...Cc(a.toBase()),s,s]}).send();return await c.wait(),{hash:c.hash,explorerUrl:c.explorerUrl}}async function z1(e,t,r,o,n,a,i=false){let s=le(r),c=le(n),l=ae.parse(o,s),d=ae.parse(a,c),u=e.address.toString(),f=await Fo(s);if(f>0){let b=parseFloat(o)*f;if(b<10)throw new Q("LENDING_FAILED",`dusty-collateral-balance: Collateral amount is too small. Minimum equivalent of ~$10 is required by Vesu. Current value: ~$${b.toFixed(2)}`)}let m=await Fo(c);if(m>0){let b=parseFloat(a)*m;if(b<10)throw new Q("LENDING_FAILED",`dusty-debt-balance: Borrow amount is too small. Minimum equivalent of ~$10 is required by Vesu. Current value: ~$${b.toFixed(2)}`)}let p=[s.address.toString(),c.address.toString(),u,...nu(Ic,l.toBase()),...nu(Ic,d.toBase())],h=e.tx();if(i){let b=await ou(e,t,s);h=h.add({contractAddress:J(b),entrypoint:"withdraw",calldata:[...Cc(l.toBase()),u,u]});}let g=await h.approve(s,J(t),l).add({contractAddress:J(t),entrypoint:"modify_position",calldata:p}).send();return await g.wait(),{hash:g.hash,explorerUrl:g.explorerUrl}}async function B1(e,t,r,o,n){let a=le(r),i=le(o),s=ae.parse(n,i),c=e.address.toString(),l=[a.address.toString(),i.address.toString(),c,...yie(),...nu(Ic,-s.toBase())],d=await e.tx().approve(i,J(t),s).add({contractAddress:J(t),entrypoint:"modify_position",calldata:l}).send();return await d.wait(),{hash:d.hash,explorerUrl:d.explorerUrl}}async function M1(e,t,r,o){let n=await Zp(e,t,r,o);if(!n)throw new Q("LENDING_FAILED","No active position found to close.");let a=le(r),i=le(o),s=ae.parse(n.collateralAmount,a),c=ae.parse(n.debtAmount,i),l=e.address.toString(),d=[a.address.toString(),i.address.toString(),l,...nu(Ic,-s.toBase()),...nu(Ic,-c.toBase())],u=await e.tx().approve(i,J(t),c).add({contractAddress:J(t),entrypoint:"modify_position",calldata:d}).send();return await u.wait(),{hash:u.hash,explorerUrl:u.explorerUrl}}async function Zp(e,t,r,o){let n=le(r),a=le(o),i=e.address.toString();try{let s=await e.callContract({contractAddress:t,entrypoint:"position",calldata:[n.address.toString(),a.address.toString(),i]});if(s.length<8)return null;let c=BigInt(s[4])+(BigInt(s[5])<<128n),l=BigInt(s[6])+(BigInt(s[7])<<128n);if(c===0n&&l===0n)return null;let d=ae.fromRaw(c,n).toFormatted(!0),u=ae.fromRaw(l,a).toFormatted(!0),f,m="UNKNOWN";try{let h=(await GT(t)).pairs.find(g=>g.collateralAddress===n.address.toString()&&g.debtAddress===a.address.toString());if(h){let g=await Fo(n),b=await Fo(a);if(g>0&&b>0){let v=parseFloat(d)*g,_=parseFloat(u)*b,y=v*h.maxLTV;_>0?(f=y/_,f>1.5?m="SAFE":f>1.1?m="WARNING":m="DANGER"):(f=9999,m="SAFE");}}}catch{}return {collateralAsset:r.toUpperCase(),debtAsset:o.toUpperCase(),collateralAmount:d,debtAmount:u,healthFactor:f,riskLevel:m}}catch{return null}}async function ou(e,t,r){let o=await e.callContract({contractAddress:_z,entrypoint:"v_token_for_asset",calldata:[t,r.address.toString()]});if(!o||o.length===0||o[0]==="0x0")throw new Q("LENDING_FAILED",`No vToken found for ${r.symbol} in pool ${t}. This asset may not be supported by this pool.`);return o[0]}async function xa(e,t,r){let o=le(r),n=e.address.toString();try{let a=await ou(e,t,o),i=await e.callContract({contractAddress:a,entrypoint:"balance_of",calldata:[n]});if(!i||i.length===0)return null;let s=BigInt(i[0])+(BigInt(i[1]||"0x0")<<128n);if(s===0n)return "0";let c=await e.callContract({contractAddress:a,entrypoint:"convert_to_assets",calldata:[...Cc(s)]});if(!c||c.length===0)return null;let l=BigInt(c[0])+(BigInt(c[1]||"0x0")<<128n);return ae.fromRaw(l,o).toFormatted(!0)}catch{return null}}var _ie=F.string().regex(/^0x[0-9a-fA-F]{1,64}$/,"Invalid Starknet address");function Ln(e){return _ie.parse(e)}async function Oc(e){return e!=="mainnet"?[]:xz()}function vie(e,t){if(t!=="mainnet")return null;let r=e.toLowerCase();return N1.find(o=>o.address.toLowerCase()===r||o.name.toLowerCase().startsWith(r))??null}function br(e,t){let r=vie(e,t);return r?{address:r.address,name:r.name}:{address:Ln(e),name:null}}Tr();async function Sz(e){return Un(async({session:t})=>{let r=await Oc(t.network);if(e.name){let o=e.name.toLowerCase();r=r.filter(n=>n.name.toLowerCase().includes(o));}return se({success:true,pools:r.map(o=>({name:o.name,poolContract:o.address,protocolVersion:o.protocolVersion,isDeprecated:o.isDeprecated,assets:o.assets.map(n=>n.symbol),pairs:o.pairs.map(n=>`${n.collateralSymbol}/${n.debtSymbol}`)}))})})}async function kz(e){return Un(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await xa(r,o.address,e.collateral_token),a=null;return e.borrow_token&&(a=await Zp(r,o.address,e.collateral_token,e.borrow_token)),!a&&(!n||n==="0.0")?se({success:true,position:null,suppliedYield:null,message:"No active position or supply found for this pool and token."}):se({success:true,suppliedYield:n&&n!=="0.0"?`${n} ${e.collateral_token.toUpperCase()}`:null,position:a})})}async function Tz(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await U1(r,o.address,e.token,e.amount);return se({success:true,action:"supply",amount:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function Ez(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await L1(r,o.address,e.token,e.amount);return se({success:true,action:"withdraw",amount:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function $z(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=false;if(e.use_supplied){let i=await xa(r,o.address,e.collateral_token);if(!i||parseFloat(i)<parseFloat(e.collateral_amount))throw new Q("INSUFFICIENT_BALANCE",`Insufficient supplied balance. You have ${i||"0"} ${e.collateral_token} supplied, but want to use ${e.collateral_amount} as collateral.`);n=true;}let a=await z1(r,o.address,e.collateral_token,e.collateral_amount,e.borrow_token,e.borrow_amount,n);return se({success:true,action:"borrow",collateral:`${e.collateral_amount} ${e.collateral_token.toUpperCase()}`,borrowed:`${e.borrow_amount} ${e.borrow_token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:a.hash,explorerUrl:a.explorerUrl})})}async function Az(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await B1(r,o.address,e.collateral_token,e.token,e.amount);return se({success:true,action:"repay",repaid:`${e.amount} ${e.token.toUpperCase()}`,pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}async function Iz(e){return Rt(async({session:t,wallet:r})=>{let o=br(e.pool,t.network),n=await M1(r,o.address,e.collateral_token,e.debt_token);return se({success:true,action:"close_position",pool:o.address,poolName:o.name,txHash:n.hash,explorerUrl:n.explorerUrl})})}gr();async function j1(e,t,r){let[o,n,a]=await Promise.allSettled([wie(t),Sie(e,t,r),Tie(t)]),i=o.status==="fulfilled"?o.value:[],s=n.status==="fulfilled"?n.value:[],c=a.status==="fulfilled"?a.value:[],l=i.reduce((u,f)=>u+f.usdValue,0),d=s.reduce((u,f)=>u+f.usdValue,0);return {address:r.address,network:r.network,balances:i,staking:s,lending:c,totalUsdValue:l+d}}var xie=5;async function wie(e){let t=await Jd(e);return (await T1(t,xie,async o=>{let n=0;try{let a=le(o.symbol),i=await Fo(a);n=parseFloat(o.balance)*i;}catch{}return {symbol:o.symbol,name:o.name,amount:o.balance,usdValue:n}})).sort((o,n)=>n.usdValue-o.usdValue)}async function Sie(e,t,r){let o=await ru(e,t,r.network,r.address);if(o.positions.length===0)return [];let n=[...new Set(o.positions.map(s=>s.token))],a=await Promise.allSettled(n.map(async s=>{try{let c=le(s);return {symbol:s,price:await Fo(c)}}catch{return {symbol:s,price:0}}})),i=new Map;for(let s of a)s.status==="fulfilled"&&i.set(s.value.symbol,s.value.price);return o.positions.map(s=>({validator:s.validator,pool:s.pool,token:s.token,staked:s.staked,rewards:s.rewards,unpooling:s.unpooling,cooldownEndsAt:s.cooldownEndsAt,usdValue:kie(s.total)*(i.get(s.token)??0)}))}function kie(e){let t=e.match(/([\d.]+)/);return t?parseFloat(t[1]):0}async function Tie(e){let r=(await Oc("mainnet")).flatMap(n=>n.assets.map(async a=>{let i=await xa(e,n.address,a.symbol);return i&&i!=="0"?{pool:n.name,asset:a.symbol,supplied:i}:null}));return (await Promise.allSettled(r)).filter(n=>n.status==="fulfilled"&&n.value!==null).map(n=>n.value)}async function Cz(){return Un(async({session:e,sdk:t,wallet:r})=>{let o=await j1(t,r,e);return se(o)})}Rr();gr();async function Oz(e){return Promise.all(e.map(async t=>{let r=le(t.from_token),o=le(t.to_token),n=ae.parse(t.amount,r);return {tokenIn:r,tokenOut:o,amount:n.toBase().toString()}}))}async function Pz(e){let t=await Oz(e.swaps),r=await $1(t);return se({success:true,quotes:r.map((o,n)=>({amountIn:`${e.swaps[n].amount} ${t[n].tokenIn.symbol}`,expectedAmountOut:`~${ae.fromRaw(BigInt(o.outputAmount),t[n].tokenOut).toUnit()} ${t[n].tokenOut.symbol}`,estimatedGasUsd:o.estimatedGasUsedInUsd??null})),message:"Quotes generated. Use multi_swap to execute."})}async function Rz(e){return Rt(async({session:t,wallet:r})=>{let o=await Oz(e.swaps),n=await A1(o,e.slippage??1,t.address),a=r.tx();for(let c=0;c<o.length;c++){let l=o[c],d=n[c],u=ae.parse(e.swaps[c].amount,l.tokenIn);a.approve(l.tokenIn,J(Er),u).add({contractAddress:Er,entrypoint:"swap",calldata:d.calldata});}let i=c=>({amountIn:`${e.swaps[c].amount} ${o[c].tokenIn.symbol}`,expectedAmountOut:`~${ae.fromRaw(BigInt(n[c].route.outputAmount),o[c].tokenOut).toUnit()} ${o[c].tokenOut.symbol}`});if(e.simulate){let c=await jt(a);return ri(c,{swaps:o.map((l,d)=>i(d))})}let s=await a.send();return await s.wait(),se({success:true,txHash:s.hash,explorerUrl:s.explorerUrl,swaps:o.map((c,l)=>i(l)),slippage:`${e.slippage??1}%`})})}Rr();gr();Hp();Tr();async function F1(e,t,r){if(r.length<2)throw new Q("INVALID_AMOUNT","Batch requires at least 2 operations. Use individual commands for single operations.");let o=e.tx(),n=[];for(let a of r){switch(a.type){case "swap":await Eie(o,a.params,t);break;case "stake":await $ie(o,a.params,e,t);break;case "supply":await Aie(o,a.params,e,t);break;case "send":await Iie(o,a.params);break;default:throw new Q("INVALID_CONFIG",`Unknown batch operation type: ${String(a.type)}`)}n.push(Cie(a));}return {builder:o,summary:n}}async function Eie(e,t,r){let o=le(t.from_token),n=le(t.to_token),a=ae.parse(t.amount,o),i=a.toBase().toString(),s=await Ac(o,n,i,t.slippage??1,r.address);e.approve(o,J(Er),a).add({contractAddress:Er,entrypoint:"swap",calldata:s.calldata});}async function $ie(e,t,r,o){let n=(t.token??"STRK").toUpperCase(),a=le(n),i=ae.parse(t.amount,a),s=t.pool;if(!s&&t.validator){let{sdk:c}=await Be(o),l=Vo(t.validator,o.network);if(!l)throw new Q("VALIDATOR_NOT_FOUND",`Validator '${t.validator}' not found`);let d=await va(c,l.stakerAddress.toString());s=tu(d,n).poolContract;}if(!s)throw new Q("INVALID_CONFIG","Stake operation requires pool or validator");e.stake(J(Ln(s)),i);}async function Aie(e,t,r,o){let n=le(t.token),a=ae.parse(t.amount,n),i=r.address.toString(),s=br(t.pool,o.network),c=await ou(r,s.address,n);e.approve(n,J(c),a).add({contractAddress:J(c),entrypoint:"deposit",calldata:[...Cc(a.toBase()),i]});}async function Iie(e,t){let r=le(t.token),o=ae.parse(t.amount,r),n=Ln(t.to);e.transfer(r,{to:J(n),amount:o});}function Cie(e){let t=e.params;switch(e.type){case "swap":{let r=t;return `swap ${r.amount} ${r.from_token.toUpperCase()} \u2192 ${r.to_token.toUpperCase()}`}case "stake":{let r=t;return `stake ${r.amount} ${(r.token??"STRK").toUpperCase()}`}case "supply":{let r=t;return `supply ${r.amount} ${r.token.toUpperCase()}`}case "send":{let r=t;return `send ${r.amount} ${r.token.toUpperCase()} \u2192 ${r.to.slice(0,10)}\u2026`}default:return `${e.type}: ${JSON.stringify(t)}`}}async function Nz(e){return Rt(async({session:t,wallet:r})=>{let o=e.operations.map(s=>({type:s.type,params:s.params})),{builder:n,summary:a}=await F1(r,t,o);if(e.simulate){let s=await jt(n);return ri(s,{operations:a})}let i=await n.send();return await i.wait(),se({success:true,txHash:i.hash,explorerUrl:i.explorerUrl,operations:a})})}Tr();function Fe(e){return async(...t)=>{try{return await e(...t)}catch(r){let o=r instanceof Q,n=r instanceof Error?r.message:String(r);return se({success:false,error:ch(n),code:o?r.code:"UNKNOWN_ERROR",...o&&r.details?{details:r.details}:{}})}}}function Dz(e){return e.tool("get_auth_status","Check authentication status and Fibrous API health on Starknet. Use this to verify the user's active wallet.",{},{readOnlyHint:true,destructiveHint:false},Fe(qI)),e.tool("config_action","View and modify starkfi global configuration such as active network, RPC URL, and Gas Payment mechanisms.",{action:F.enum(["list","set-rpc","get-rpc","set-network","set-gasfree","set-gas-token","reset"]).describe("list: view all. reset: clear all settings to defaults. set-gasfree: dev pays gas using paymaster credits. set-gas-token: user pays gas in ERC20 token instead of STRK."),value:F.string().optional().describe("set-gasfree: 'on'/'off'. set-gas-token: symbol 'USDC'/'ETH' or 'off'. set-rpc: URL string. set-network: 'mainnet'/'sepolia'.")},{readOnlyHint:false,destructiveHint:false},Fe(bz)),2}function Uz(e){return e.tool("get_tx_status","Check Starknet transaction status by hash. Use this to verify if a recently submitted transaction has been accepted on L2 or L1.",{hash:F.string().describe("Transaction hash (0x...)")},{readOnlyHint:true,destructiveHint:false},Fe(nz)),e.tool("get_balance","Get native token and ERC-20 token balances on Starknet for the authorized user.",{token:F.string().optional().describe("Specific token symbol (e.g. 'STRK', 'ETH', 'USDC'). Omit to fetch all balances.")},{readOnlyHint:true,destructiveHint:false},Fe(ez)),e.tool("deploy_account","Deploy the Starknet smart contract account on-chain. Required once before sending transactions. Safe to call multiple times (idempotent) \u2014 returns status if already deployed.",{},{readOnlyHint:false,destructiveHint:true,idempotentHint:true},Fe(tz)),e.tool("send_tokens","Transfer tokens to a recipient on Starknet. Set simulate=true to estimate fees without executing.",{amount:F.string().describe("Amount to send (e.g. '0.1', '100')"),token:F.string().describe("Token symbol (e.g. 'STRK', 'ETH', 'USDC')"),recipient:F.string().describe("Recipient Starknet address (0x...)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without sending a transaction")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(rz)),e.tool("get_portfolio","Get complete DeFi portfolio overview: all token balances (with USD values), staking positions, and lending positions in one call.",{},{readOnlyHint:true,destructiveHint:false},Fe(Cz)),5}function Lz(e){e.tool("get_swap_quote","Get an expected output and route from Fibrous *without* executing the swap. ALWAYS use this BEFORE calling swap_tokens so the user can review the expected output amount and slippage.",{amount:F.string().describe("Amount to swap in (e.g. '0.1', '100')"),from_token:F.string().describe("Source token symbol to sell (e.g. 'ETH', 'USDC')"),to_token:F.string().describe("Destination token symbol to buy (e.g. 'STRK', 'DAI')")},{readOnlyHint:true,destructiveHint:false},Fe(oz)),e.tool("swap_tokens","Execute a token swap on Starknet using Fibrous aggregation. Finds optimal route and executes. Set simulate=true to estimate fees without executing. ONLY call this after showing the user a quote via get_swap_quote.",{amount:F.string().describe("Amount to swap in (e.g. '0.1', '100')"),from_token:F.string().describe("Source token symbol to sell (e.g. 'ETH', 'STRK')"),to_token:F.string().describe("Destination token symbol to buy (e.g. 'USDC', 'DAI')"),slippage:F.number().optional().describe("Slippage tolerance % (default: 1)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without sending a transaction")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(az));let t=F.object({amount:F.string().describe("Amount to swap in (e.g. '100', '0.5')"),from_token:F.string().describe("Source token symbol (e.g. 'USDC', 'ETH')"),to_token:F.string().describe("Destination token symbol (e.g. 'ETH', 'STRK')")});return e.tool("get_multi_swap_quote","Get quotes for multiple token swaps at once (2-3 pairs). Uses Fibrous batch routing for optimal rates.",{swaps:F.array(t).min(2).max(3).describe("Array of swap pairs (2-3 items)")},{readOnlyHint:true,destructiveHint:false},Fe(Pz)),e.tool("multi_swap","Execute multiple token swaps in a single transaction (2-3 pairs). Uses Fibrous batch routing. Call get_multi_swap_quote first to preview.",{swaps:F.array(t).min(2).max(3).describe("Array of swap pairs (2-3 items)"),slippage:F.number().optional().describe("Slippage tolerance % (default: 1)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without executing")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Rz)),e.tool("batch_execute","Execute multiple DeFi operations in a single Starknet transaction (multicall). Supports: swap, stake, supply, send. Requires at least 2 operations.",{operations:F.array(F.object({type:F.enum(["swap","stake","supply","send"]).describe("Operation type"),params:F.record(F.string(),F.string()).describe("Operation params. swap: {amount, from_token, to_token}. stake: {amount, token?, pool? or validator?}. supply: {amount, token, pool}. send: {amount, token, to}.")})).min(2).describe("Array of operations to batch (min 2)"),simulate:F.boolean().optional().describe("Set true to simulate only \u2014 estimates fees without executing")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Nz)),5}function zz(e){return e.tool("list_validators","List all known Starknet staking validators. Use this FIRST to see available validators and their names before trying to find pools.",{},{readOnlyHint:true,destructiveHint:false},Fe(mz)),e.tool("list_pools","List delegation pools for a specific validator. Look up a validator name via list_validators first.",{validator:F.string().describe("Validator name (e.g. 'Karnot', 'Kakarot') or staker address. Supports partial matches.")},{readOnlyHint:true,destructiveHint:false},Fe(fz)),e.tool("get_staking_info","Get staking position info (staked balance, unclaimed rewards, total balance, commission, unpooling cooldown) for a specific pool contract.",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:true,destructiveHint:false},Fe(uz)),e.tool("get_stake_status","Scan ALL known validators and pools to return a consolidated staking dashboard with total staked, total rewards, total value, and per-pool breakdown. Use this to give the user a full picture of their staking portfolio.",{validator:F.string().optional().describe("Optional validator name or staker address to strictly filter results.")},{readOnlyHint:true,destructiveHint:false},Fe(gz)),e.tool("stake_tokens","Stake tokens in a delegation pool on Starknet. Smart stake: auto-detects whether the user needs to enter the pool or just add to an existing delegation. Supports STRK, WBTC, tBTC, SolvBTC, LBTC.",{amount:F.string().describe("Amount to stake (e.g. '100', '0.01')"),pool:F.string().describe("Staking pool contract address (0x...)"),token:F.string().optional().describe("Token symbol to stake (default: STRK). Supported: STRK, WBTC, tBTC, SolvBTC, LBTC")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(lz)),e.tool("unstake_tokens","Unstake tokens from a pool. Unstaking is a TWO-STEP process: 1. call with action='intent', 2. wait for cooldown, 3. call with action='exit' to complete withdrawal.",{action:F.enum(["intent","exit"]).describe("'intent' strictly starts the unstaking process, 'exit' completes withdrawal after cooldown."),pool:F.string().describe("Staking pool contract address (0x...)"),amount:F.string().optional().describe("Amount to unstake (ONLY required when action='intent')"),token:F.string().optional().describe("Token symbol (default: STRK). Must match the pool's token.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(dz)),e.tool("claim_rewards","Extract earned rewards from a staking pool to the user's wallet.",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(pz)),e.tool("compound_rewards","Atomically claim staking rewards and re-stake them recursively into the same pool in a single transaction (compound interest).",{pool:F.string().describe("Staking pool contract address (0x...)")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(hz)),8}function Bz(e){return e.tool("list_lending_pools","List available Vesu V2 lending pools on Starknet with their supported collateral/debt pairs. Use this FIRST to discover available pools before supplying, borrowing, or checking positions.",{name:F.string().optional().describe("Filter pools by name (partial match). Omit to list all.")},{readOnlyHint:true,destructiveHint:false},Fe(Sz)),e.tool("get_lending_position","Get the user's lending position (supplied collateral and outstanding debt) in a specific Vesu pool.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_token:F.string().describe("Collateral token symbol (e.g. 'ETH', 'STRK')"),borrow_token:F.string().optional().describe("Borrow token symbol (e.g. 'USDC', 'USDT')")},{readOnlyHint:true,destructiveHint:false},Fe(kz)),e.tool("supply_assets","Supply (lend) tokens into a Vesu V2 pool to earn interest. The tokens are deposited into the pool's ERC-4626 vToken vault.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to supply (e.g. '100', '0.5')"),token:F.string().describe("Token symbol to supply (e.g. 'STRK', 'ETH', 'USDC')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Tz)),e.tool("withdraw_assets","Withdraw previously supplied tokens from a Vesu V2 lending pool.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to withdraw (e.g. '100', '0.5')"),token:F.string().describe("Token symbol to withdraw (e.g. 'STRK', 'ETH', 'USDC')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Ez)),e.tool("borrow_assets","Borrow tokens from a Vesu V2 pool by supplying collateral. Atomically deposits collateral and borrows the debt asset in a single transaction.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_amount:F.string().describe("Collateral amount to deposit (e.g. '1000')"),collateral_token:F.string().describe("Collateral token symbol (e.g. 'STRK', 'ETH')"),borrow_amount:F.string().describe("Amount to borrow (e.g. '100')"),borrow_token:F.string().describe("Token to borrow (e.g. 'USDC', 'USDT')"),use_supplied:F.boolean().optional().describe("Set to true to use previously supplied yield tokens as collateral via Multicall instead of transferring fresh tokens from wallet.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe($z)),e.tool("repay_debt","Repay borrowed tokens on an existing Vesu V2 lending position. Approves and repays the specified amount of debt.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),amount:F.string().describe("Amount to repay (e.g. '50', '100')"),token:F.string().describe("Token to repay (e.g. 'USDC', 'USDT')"),collateral_token:F.string().describe("Collateral token of the position (e.g. 'ETH', 'STRK'). Needed to identify the position.")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Az)),e.tool("close_position","Atomically close an active Vesu V2 lending position. Repays all outstanding debt and withdraws all collateral in a single transaction.",{pool:F.string().describe("Pool name (e.g. 'Prime', 'Re7') or contract address (0x...)"),collateral_token:F.string().describe("Collateral token symbol of the position (e.g. 'STRK', 'ETH')"),debt_token:F.string().describe("Borrowed token symbol of the position (e.g. 'USDC', 'USDT')")},{readOnlyHint:false,destructiveHint:true,idempotentHint:false},Fe(Iz)),7}function Mz(e){let t=[{name:"Auth & Config",count:Dz(e)},{name:"Wallet",count:Uz(e)},{name:"Trade",count:Lz(e)},{name:"Staking",count:zz(e)},{name:"Lending",count:Bz(e)}];return {total:t.reduce((r,o)=>r+o.count,0),categories:t}}var YT={name:"starkfi",version:"0.4.3"},Oie=`StarkFi is a Starknet DeFi toolkit. You can:
|
|
110
110
|
- Check auth status and configure settings (network, RPC, gas payment mode)
|
|
111
111
|
- Query balances, deploy accounts, send tokens, and view full portfolio
|
|
112
112
|
- Get swap quotes and execute token swaps via Fibrous aggregation
|
|
@@ -244,7 +244,7 @@ Example:
|
|
|
244
244
|
$ starkfi config list`).action(()=>{let o=t.getAll();if(Object.keys(o).length===0){console.log(` No custom settings. Using defaults.
|
|
245
245
|
`);return}let n=o.gasfreeMode===true,a=o.gasToken,i="gasless (pays STRK via Paymaster)";n?i="gasfree (developer-sponsored via Paymaster)":a&&(i=`gasless (pays ${a} via Paymaster)`),console.log(Je({...o,feeMode:i}));}),r.command("reset").description("Reset all configuration to defaults").addHelpText("after",`
|
|
246
246
|
Example:
|
|
247
|
-
$ starkfi config reset`).action(()=>{t.clear(),console.log($t("All settings reset to defaults."));});}var vB="0.4.
|
|
247
|
+
$ starkfi config reset`).action(()=>{t.clear(),console.log($t("All settings reset to defaults."));});}var vB="0.4.3";process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));var Die=["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557","\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551","\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551","\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551","\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551","\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D"],Uie=Die.map((e,t)=>B.bold.hex(B3[t]??jc)(e)).join(`
|
|
248
248
|
`),Lie=B.dim("v")+B.hex(Sa).bold(vB)+B.dim(" \xB7 ")+B.white("Starknet DeFi CLI + MCP Server"),zie=`
|
|
249
249
|
${Uie}
|
|
250
250
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "starkfi",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "AI-native Starknet DeFi CLI + MCP Server + Agent Skills — Swaps, multi-swap, batch (multicall), staking, lending, simulation, portfolio, gas abstraction",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|