From 5c3951cb742bdffdf189cefed27b6f311131948c Mon Sep 17 00:00:00 2001 From: sidrisov Date: Thu, 22 Jan 2026 19:51:53 +0400 Subject: [PATCH 1/8] add capability skills to bankr-agent and bankr-agent-dev plugins bankr-agent skills (direct use focus): - bankr-token-trading, bankr-transfers, bankr-polymarket - bankr-leverage-trading, bankr-nft-operations, bankr-portfolio - bankr-market-research, bankr-automation, bankr-token-deployment - bankr-job-workflow, bankr-error-handling (workflow support) bankr-agent-dev skills (developer focus): - Same 9 capability skills adapted for building bots - Includes prompt templates, response handling, TypeScript types - Bot class implementations and error handling patterns - bankr-client-patterns, bankr-project-templates (dev core) Updated scaffold command to reference new capability skills --- bankr-agent-dev/commands/scaffold.md | 385 ++---------- .../skills/bankr-automation/SKILL.md | 503 +++++++++++++++ .../skills/bankr-client-patterns/SKILL.md | 508 +++++++++++++++ .../skills/bankr-leverage-trading/SKILL.md | 434 +++++++++++++ .../skills/bankr-market-research/SKILL.md | 580 ++++++++++++++++++ .../skills/bankr-nft-operations/SKILL.md | 410 +++++++++++++ .../skills/bankr-polymarket/SKILL.md | 368 +++++++++++ .../skills/bankr-portfolio/SKILL.md | 505 +++++++++++++++ .../skills/bankr-project-templates/SKILL.md | 322 ++++++++++ .../skills/bankr-token-deployment/SKILL.md | 547 +++++++++++++++++ .../skills/bankr-token-trading/SKILL.md | 220 +++++++ .../skills/bankr-transfers/SKILL.md | 323 ++++++++++ bankr-agent/agents/bankr-agent.md | 130 ++-- bankr-agent/commands/bankr-agent.md | 17 +- bankr-agent/skills/bankr-automation/SKILL.md | 265 ++++++++ .../skills/bankr-error-handling/SKILL.md | 223 +++++++ .../skills/bankr-job-workflow/SKILL.md | 183 ++++++ .../skills/bankr-leverage-trading/SKILL.md | 233 +++++++ .../skills/bankr-market-research/SKILL.md | 268 ++++++++ .../skills/bankr-nft-operations/SKILL.md | 176 ++++++ bankr-agent/skills/bankr-polymarket/SKILL.md | 201 ++++++ bankr-agent/skills/bankr-portfolio/SKILL.md | 208 +++++++ .../skills/bankr-token-deployment/SKILL.md | 271 ++++++++ .../skills/bankr-token-trading/SKILL.md | 180 ++++++ bankr-agent/skills/bankr-transfers/SKILL.md | 146 +++++ 25 files changed, 7177 insertions(+), 429 deletions(-) create mode 100644 bankr-agent-dev/skills/bankr-automation/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-client-patterns/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-market-research/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-nft-operations/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-polymarket/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-portfolio/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-project-templates/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-token-deployment/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-token-trading/SKILL.md create mode 100644 bankr-agent-dev/skills/bankr-transfers/SKILL.md create mode 100644 bankr-agent/skills/bankr-automation/SKILL.md create mode 100644 bankr-agent/skills/bankr-error-handling/SKILL.md create mode 100644 bankr-agent/skills/bankr-job-workflow/SKILL.md create mode 100644 bankr-agent/skills/bankr-leverage-trading/SKILL.md create mode 100644 bankr-agent/skills/bankr-market-research/SKILL.md create mode 100644 bankr-agent/skills/bankr-nft-operations/SKILL.md create mode 100644 bankr-agent/skills/bankr-polymarket/SKILL.md create mode 100644 bankr-agent/skills/bankr-portfolio/SKILL.md create mode 100644 bankr-agent/skills/bankr-token-deployment/SKILL.md create mode 100644 bankr-agent/skills/bankr-token-trading/SKILL.md create mode 100644 bankr-agent/skills/bankr-transfers/SKILL.md diff --git a/bankr-agent-dev/commands/scaffold.md b/bankr-agent-dev/commands/scaffold.md index 2ddaeab..307e95c 100644 --- a/bankr-agent-dev/commands/scaffold.md +++ b/bankr-agent-dev/commands/scaffold.md @@ -10,359 +10,52 @@ Create a complete TypeScript/Node.js project scaffold for building on the Bankr ## Process -1. **Determine project type** - If `$ARGUMENTS` specifies a type, use it. Otherwise, ask the user: +1. **Determine project type** - If `$ARGUMENTS` specifies a type, use it. Otherwise, ask the user. -Available project types: -- **bot** - Automated trading bot, price monitor, alert system, or scheduled task -- **web-service** - HTTP API that wraps or extends Bankr functionality -- **dashboard** - Web UI for portfolio tracking, market analysis, or monitoring -- **cli** - Command-line tool for Bankr operations + Load the `bankr-project-templates` skill for available types: + - **bot** - Automated trading bot, price monitor, alert system, scheduled task + - **web-service** - HTTP API that wraps or extends Bankr functionality + - **dashboard** - Web UI for portfolio tracking, market analysis, monitoring + - **cli** - Command-line tool for Bankr operations 2. **Ask for project details**: - Project name (kebab-case, e.g., `my-trading-bot`) - Brief description of what it will do - Any specific Bankr operations it will use (trading, prices, polymarket, defi) -3. **Create project structure** using the appropriate template below. - -4. **Explain next steps** - How to set up API key, install dependencies, and run. - ---- - -## Project Templates - -### Bot Template - -For automated bots, monitors, and scheduled tasks: - -``` -{project-name}/ -├── package.json -├── tsconfig.json -├── .env.example -├── .gitignore -├── README.md -├── src/ -│ ├── index.ts # Main entry point with scheduler -│ ├── bankr-client.ts # Bankr API client -│ ├── types.ts # TypeScript interfaces -│ └── config.ts # Configuration loading -└── scripts/ - └── run.sh # Convenience script -``` - -**Key features:** -- Polling loop with configurable interval -- Status update streaming -- Error handling and retries -- Environment-based configuration - -### Web Service Template - -For HTTP APIs that extend Bankr: - -``` -{project-name}/ -├── package.json -├── tsconfig.json -├── .env.example -├── .gitignore -├── README.md -├── src/ -│ ├── index.ts # Server entry point -│ ├── server.ts # Express/Fastify server setup -│ ├── routes/ -│ │ ├── health.ts # Health check endpoint -│ │ └── bankr.ts # Bankr proxy/extension routes -│ ├── bankr-client.ts # Bankr API client -│ ├── types.ts # TypeScript interfaces -│ └── config.ts # Configuration loading -└── scripts/ - └── run.sh -``` - -**Key features:** -- REST API endpoints -- Request validation -- Async job handling -- Webhook support for job completion - -### Dashboard Template - -For web UIs with frontend and backend: - -``` -{project-name}/ -├── package.json -├── tsconfig.json -├── .env.example -├── .gitignore -├── README.md -├── server/ -│ ├── index.ts # Backend server -│ ├── bankr-client.ts # Bankr API client -│ ├── routes/ -│ │ └── api.ts # API routes for frontend -│ └── types.ts -├── public/ -│ ├── index.html # Main HTML page -│ ├── styles.css # Basic styles -│ └── app.js # Frontend JavaScript -└── scripts/ - └── run.sh -``` - -**Key features:** -- Simple HTML/CSS/JS frontend (no build step required) -- Backend API for Bankr operations -- Real-time status updates via polling -- Portfolio/market data display - -### CLI Template - -For command-line tools: - -``` -{project-name}/ -├── package.json -├── tsconfig.json -├── .env.example -├── .gitignore -├── README.md -├── src/ -│ ├── index.ts # CLI entry with commander.js -│ ├── commands/ -│ │ ├── trade.ts # Trading commands -│ │ ├── price.ts # Price query commands -│ │ └── status.ts # Job status commands -│ ├── bankr-client.ts # Bankr API client -│ └── types.ts -└── scripts/ - └── run.sh -``` - -**Key features:** -- Commander.js CLI framework -- Subcommands for different operations -- Interactive prompts where needed -- Progress indicators during polling - ---- - -## Common Files - -### package.json - -```json -{ - "name": "{project-name}", - "version": "0.1.1", - "description": "{description}", - "type": "module", - "main": "dist/index.js", - "scripts": { - "build": "tsc", - "start": "node dist/index.js", - "dev": "tsx src/index.ts" - }, - "dependencies": { - "dotenv": "^16.3.1" - }, - "devDependencies": { - "@types/node": "^20.10.0", - "tsx": "^4.7.0", - "typescript": "^5.3.0" - } -} -``` - -Add framework-specific dependencies based on project type: -- **web-service**: Add `express` or `fastify` -- **cli**: Add `commander` -- **dashboard**: Add `express` for backend - -### tsconfig.json - -```json -{ - "compilerOptions": { - "target": "ES2022", - "module": "NodeNext", - "moduleResolution": "NodeNext", - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "declaration": true - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] -} -``` - -### .env.example - -``` -BANKR_API_KEY=bk_your_api_key_here -BANKR_API_URL=https://api.bankr.bot -``` - -### .gitignore - -``` -node_modules/ -dist/ -.env -*.log -``` - -### bankr-client.ts (Core Module) - -This is the essential Bankr API client that all project types share: - -```typescript -import "dotenv/config"; - -const API_URL = process.env.BANKR_API_URL || "https://api.bankr.bot"; -const API_KEY = process.env.BANKR_API_KEY; - -// Types -export interface JobStatusResponse { - success: boolean; - jobId: string; - status: "pending" | "processing" | "completed" | "failed" | "cancelled"; - prompt: string; - response?: string; - transactions?: Transaction[]; - richData?: RichData[]; - statusUpdates?: StatusUpdate[]; - error?: string; - createdAt: string; - completedAt?: string; - processingTime?: number; -} - -export interface Transaction { - type: string; - metadata?: { - humanReadableMessage?: string; - inputTokenTicker?: string; - outputTokenTicker?: string; - inputTokenAmount?: string; - outputTokenAmount?: string; - transaction?: { - chainId: number; - to: string; - data: string; - gas?: string; - value?: string; - }; - }; -} - -export interface StatusUpdate { - message: string; - timestamp: string; -} - -export interface RichData { - type: string; - base64?: string; - url?: string; -} - -// API Functions -export async function submitPrompt(prompt: string): Promise<{ jobId: string }> { - if (!API_KEY) throw new Error("BANKR_API_KEY not set"); - - const response = await fetch(`${API_URL}/agent/prompt`, { - method: "POST", - headers: { - "x-api-key": API_KEY, - "Content-Type": "application/json", - }, - body: JSON.stringify({ prompt }), - }); - - if (!response.ok) { - throw new Error(`API error: ${response.status} - ${await response.text()}`); - } - - const data = await response.json(); - if (!data.success) throw new Error(data.error || "Failed to submit prompt"); - return { jobId: data.jobId }; -} - -export async function getJobStatus(jobId: string): Promise { - if (!API_KEY) throw new Error("BANKR_API_KEY not set"); - - const response = await fetch(`${API_URL}/agent/job/${jobId}`, { - headers: { "x-api-key": API_KEY }, - }); - - if (!response.ok) { - throw new Error(`API error: ${response.status} - ${await response.text()}`); - } - - return response.json(); -} - -export async function waitForCompletion( - jobId: string, - onProgress?: (msg: string) => void -): Promise { - let lastUpdateCount = 0; - - for (let i = 0; i < 120; i++) { - const status = await getJobStatus(jobId); - - // Report new status updates - if (onProgress && status.statusUpdates) { - for (let j = lastUpdateCount; j < status.statusUpdates.length; j++) { - onProgress(status.statusUpdates[j].message); - } - lastUpdateCount = status.statusUpdates.length; - } - - if (["completed", "failed", "cancelled"].includes(status.status)) { - return status; - } - - await new Promise((r) => setTimeout(r, 2000)); - } - - throw new Error("Job timed out"); -} - -export async function execute( - prompt: string, - onProgress?: (msg: string) => void -): Promise { - const { jobId } = await submitPrompt(prompt); - onProgress?.(`Job submitted: ${jobId}`); - return waitForCompletion(jobId, onProgress); -} -``` - ---- +3. **Create project structure**: + - Load `bankr-project-templates` skill for the directory structure + - Load `bankr-client-patterns` skill for common files and client code + - Create all directories using `mkdir -p` + - Write each file using the Write tool + - Customize based on user's description + +4. **Explain next steps**: + - How to get a Bankr API key (https://bankr.bot/api) + - How to run the project (`npm install && npm run dev`) + - What to customize first based on their use case + +## Skills to Load + +**Core Skills (always load):** +- `bankr-project-templates` - Directory structures for each project type +- `bankr-client-patterns` - bankr-client.ts and common files (package.json, tsconfig.json, .env.example, .gitignore) +- `bankr-api-basics` - API documentation for reference + +**Capability Skills (load based on project purpose):** +- `bankr-token-trading` - For trading bots: prompt templates, swap response handling +- `bankr-transfers` - For payment bots: recipient resolution, transfer patterns +- `bankr-polymarket` - For prediction market bots: betting API, position tracking +- `bankr-leverage-trading` - For leverage bots: Avantis patterns, position management +- `bankr-nft-operations` - For NFT bots: OpenSea browsing, purchase automation +- `bankr-portfolio` - For dashboards: balance aggregation, portfolio tracking +- `bankr-market-research` - For price bots: monitoring patterns, alert systems +- `bankr-automation` - For order bots: limit orders, DCA, TWAP implementation +- `bankr-token-deployment` - For token launchers: Clanker integration, fee claiming ## Implementation Notes -When scaffolding: - -1. **Create all directories first** using mkdir -p -2. **Write each file** using the Write tool -3. **Customize based on user's description** - adjust the example code to match their use case -4. **Include helpful comments** in the generated code -5. **Generate a README.md** with: - - Project description - - Setup instructions (npm install, configure .env) - - Usage examples - - Bankr API reference link - -After scaffolding, explain: -- How to get a Bankr API key (https://bankr.bot/api) -- How to run the project (`npm install && npm run dev`) -- What to customize first based on their use case +- Create all directories first using `mkdir -p` +- Write each file using the Write tool +- Include helpful comments in generated code +- Generate a README.md with setup instructions and usage examples diff --git a/bankr-agent-dev/skills/bankr-automation/SKILL.md b/bankr-agent-dev/skills/bankr-automation/SKILL.md new file mode 100644 index 0000000..d25a1b4 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-automation/SKILL.md @@ -0,0 +1,503 @@ +--- +name: Bankr Automation (Developer Guide) +description: This skill should be used when building a limit order system, implementing DCA strategies programmatically, creating TWAP execution, or building a grid trading bot. Covers TypeScript prompt templates like `automationPrompts.dca()`, automation ID parsing, DcaStrategyBuilder and GridTradingBot classes, and retry patterns. Triggered by "limit order bot code", "DCA automation TypeScript", "TWAP implementation", "grid trading bot". +version: 1.0.0 +--- + +# Automation - Developer Guide + +Build bots and applications that create and manage automated orders via the Bankr API. + +## Overview + +Automation through Bankr supports: +- Limit orders (buy/sell at target price) +- Stop loss orders (sell on price drop) +- DCA (Dollar Cost Averaging) +- TWAP (Time-Weighted Average Price) +- Scheduled commands +- Solana trigger orders (Jupiter) + +**Supported Chains:** Base, Polygon, Ethereum (EVM), Solana (Jupiter triggers) + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for automation operations +const automationPrompts = { + // Limit orders + limitBuy: (token: string, price: string, amount?: string) => + amount + ? `Set a limit order to buy ${amount} of ${token} at ${price}` + : `Set a limit order to buy ${token} at ${price}`, + + limitSell: (token: string, price: string, amount?: string) => + amount + ? `Limit sell ${amount} ${token} when it hits ${price}` + : `Limit sell ${token} when it hits ${price}`, + + // Stop loss + stopLoss: (token: string, price: string) => + `Set stop loss for my ${token} at ${price}`, + + stopLossPercent: (token: string, percent: number) => + `Stop loss: sell ${token} if it drops ${percent}%`, + + // DCA + dca: (amount: string, token: string, frequency: string) => + `DCA ${amount} into ${token} ${frequency}`, + + dcaWithDuration: (amount: string, token: string, frequency: string, duration: string) => + `DCA ${amount} into ${token} ${frequency} for ${duration}`, + + // TWAP + twap: (amount: string, token: string, duration: string) => + `TWAP buy ${amount} of ${token} over ${duration}`, + + twapSell: (amount: string, token: string, duration: string) => + `TWAP sell ${amount} ${token} over ${duration}`, + + // Scheduled commands + schedule: (command: string, schedule: string) => + `${schedule}, ${command}`, + + // Management + viewAutomations: () => "Show my automations", + viewLimitOrders: () => "What limit orders do I have?", + viewDcaOrders: () => "Show my DCA orders", + cancelAutomation: (id: string) => `Cancel automation ${id}`, + cancelAll: () => "Cancel all my automations", + + // History + automationHistory: () => "Show automation history", + executedOrders: () => "What orders executed today?", +}; + +// Frequency helpers +const FREQUENCIES = { + hourly: "every hour", + daily: "every day", + weekly: "every week", + monthly: "every month", + custom: (cron: string) => cron, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface Automation { + id: string; + type: "limit" | "stop_loss" | "dca" | "twap" | "scheduled"; + token: string; + status: "active" | "triggered" | "cancelled" | "expired"; + params: Record; + createdAt: Date; + nextExecution?: Date; +} + +function parseAutomationCreated(response: string): { id: string; type: string } | null { + const idMatch = response.match(/Order ID:\s*(\w+)/i) || response.match(/ID:\s*(\w+)/i); + if (!idMatch) return null; + + const lower = response.toLowerCase(); + let type = "scheduled"; + if (lower.includes("limit")) type = "limit"; + else if (lower.includes("dca")) type = "dca"; + else if (lower.includes("stop")) type = "stop_loss"; + else if (lower.includes("twap")) type = "twap"; + + return { id: idMatch[1], type }; +} + +function parseAutomations(response: string): Automation[] { + const automations: Automation[] = []; + const sections = response.split(/\n\n?\d+\./); + + for (const section of sections) { + const idMatch = section.match(/\((\w+)\)/); + const statusMatch = section.match(/Status:\s*(\w+)/i); + if (!idMatch) continue; + + const lower = section.toLowerCase(); + let type: Automation["type"] = "scheduled"; + if (lower.includes("limit")) type = "limit"; + else if (lower.includes("dca")) type = "dca"; + else if (lower.includes("stop")) type = "stop_loss"; + else if (lower.includes("twap")) type = "twap"; + + automations.push({ + id: idMatch[1], + type, + token: "", + status: (statusMatch?.[1].toLowerCase() as Automation["status"]) || "active", + params: {}, + createdAt: new Date(), + }); + } + + return automations; +} + +async function handleAutomationResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Automation operation successful"); + console.log(result.response); + + const created = parseAutomationCreated(result.response || ""); + if (created) { + console.log(`Created ${created.type} automation: ${created.id}`); + } + } else if (result.status === "failed") { + console.error("Automation operation failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Automation-specific types +interface LimitOrderConfig { + token: string; + side: "buy" | "sell"; + price: number; + amount?: number; + amountUsd?: number; + expiresIn?: string; // e.g., "24h", "7d" +} + +interface StopLossConfig { + token: string; + triggerPrice?: number; + triggerPercent?: number; + sellAmount?: number; // Percentage of holdings +} + +interface DcaConfig { + token: string; + amountUsd: number; + frequency: "hourly" | "daily" | "weekly" | "monthly"; + duration?: string; // e.g., "1 month", "indefinite" + startDate?: Date; +} + +interface TwapConfig { + token: string; + side: "buy" | "sell"; + totalAmount: number; + duration: string; // e.g., "24 hours", "4 hours" + intervals?: number; +} + +interface AutomationResult { + success: boolean; + automationId?: string; + type: string; + message: string; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Limit Order Bot | Entry/exit at prices | `Set limit order to buy ETH at $3,000` | +| Risk Manager | Auto stop losses | `Set stop loss for my ETH at $2,800` | +| DCA Bot | Regular accumulation | `DCA $100 into ETH every week` | +| Large Order Bot | Execute with TWAP | `TWAP buy $5000 of ETH over 24 hours` | +| Portfolio Bot | Scheduled rebalancing | Schedule rebalance commands | + +## Code Example: Automation Manager + +```typescript +import { execute } from "./bankr-client"; + +interface ManagedAutomation { + id: string; + type: string; + config: LimitOrderConfig | StopLossConfig | DcaConfig | TwapConfig; + createdAt: Date; + status: "active" | "triggered" | "cancelled"; +} + +class AutomationManager { + private automations: Map = new Map(); + + private async createAutomation( + type: string, + prompt: string, + config: LimitOrderConfig | StopLossConfig | DcaConfig | TwapConfig + ): Promise { + const result = await execute(prompt, (msg) => console.log(" >", msg)); + if (result.status !== "completed") { + return { success: false, type, message: result.error || `Failed to create ${type}` }; + } + + const created = parseAutomationCreated(result.response || ""); + if (!created) { + return { success: false, type, message: `Failed to parse ${type} response` }; + } + + this.automations.set(created.id, { id: created.id, type, config, createdAt: new Date(), status: "active" }); + return { success: true, automationId: created.id, type, message: result.response || `${type} created` }; + } + + async createLimitOrder(config: LimitOrderConfig): Promise { + const prompt = config.side === "buy" + ? automationPrompts.limitBuy(config.token, `$${config.price}`, config.amountUsd ? `$${config.amountUsd}` : undefined) + : automationPrompts.limitSell(config.token, `$${config.price}`, config.amount ? `${config.amount}` : undefined); + return this.createAutomation("limit", prompt, config); + } + + async createStopLoss(config: StopLossConfig): Promise { + const prompt = config.triggerPrice + ? automationPrompts.stopLoss(config.token, `$${config.triggerPrice}`) + : automationPrompts.stopLossPercent(config.token, config.triggerPercent || 10); + return this.createAutomation("stop_loss", prompt, config); + } + + async createDca(config: DcaConfig): Promise { + const prompt = config.duration + ? automationPrompts.dcaWithDuration(`$${config.amountUsd}`, config.token, FREQUENCIES[config.frequency], config.duration) + : automationPrompts.dca(`$${config.amountUsd}`, config.token, FREQUENCIES[config.frequency]); + return this.createAutomation("dca", prompt, config); + } + + async createTwap(config: TwapConfig): Promise { + const prompt = config.side === "buy" + ? automationPrompts.twap(`$${config.totalAmount}`, config.token, config.duration) + : automationPrompts.twapSell(`${config.totalAmount}`, config.token, config.duration); + return this.createAutomation("twap", prompt, config); + } + + async refreshAutomations(): Promise { + const result = await execute(automationPrompts.viewAutomations()); + return result.status === "completed" && result.response ? parseAutomations(result.response) : []; + } + + async cancelAutomation(id: string): Promise { + const result = await execute(automationPrompts.cancelAutomation(id)); + if (result.status === "completed") { + const automation = this.automations.get(id); + if (automation) automation.status = "cancelled"; + return true; + } + return false; + } + + getAutomation(id: string): ManagedAutomation | undefined { + return this.automations.get(id); + } + + // Get all local automations + getAllAutomations(): ManagedAutomation[] { + return Array.from(this.automations.values()); + } +} + +// Usage +const manager = new AutomationManager(); + +// Create limit order +const limitResult = await manager.createLimitOrder({ + token: "ETH", + side: "buy", + price: 3000, + amountUsd: 500, +}); +console.log("Limit order:", limitResult); + +// Create stop loss +const stopResult = await manager.createStopLoss({ + token: "ETH", + triggerPercent: 10, +}); +console.log("Stop loss:", stopResult); + +// Create DCA +const dcaResult = await manager.createDca({ + token: "ETH", + amountUsd: 100, + frequency: "weekly", + duration: "3 months", +}); +console.log("DCA:", dcaResult); + +// Create TWAP +const twapResult = await manager.createTwap({ + token: "ETH", + side: "buy", + totalAmount: 5000, + duration: "24 hours", +}); +console.log("TWAP:", twapResult); + +// Check all automations +const automations = await manager.refreshAutomations(); +console.log("Active automations:", automations); +``` + +## DCA Strategy Builder + +```typescript +interface DcaStrategy { + name: string; + tokens: { token: string; allocation: number }[]; // allocation as percentage + totalAmountUsd: number; + frequency: "daily" | "weekly" | "monthly"; +} + +class DcaStrategyBuilder { + async executeStrategy( + strategy: DcaStrategy, + manager: AutomationManager + ): Promise { + const results: AutomationResult[] = []; + + for (const { token, allocation } of strategy.tokens) { + const amountUsd = (strategy.totalAmountUsd * allocation) / 100; + + const result = await manager.createDca({ + token, + amountUsd, + frequency: strategy.frequency, + }); + + results.push(result); + } + + return results; + } +} + +// Example: Create a diversified DCA strategy +const strategy: DcaStrategy = { + name: "Balanced Crypto DCA", + tokens: [ + { token: "BTC", allocation: 50 }, + { token: "ETH", allocation: 30 }, + { token: "SOL", allocation: 20 }, + ], + totalAmountUsd: 500, + frequency: "weekly", +}; + +const builder = new DcaStrategyBuilder(); +const results = await builder.executeStrategy(strategy, manager); +console.log("DCA strategy created:", results); +``` + +## Grid Trading Bot + +```typescript +interface GridConfig { + token: string; + lowerPrice: number; + upperPrice: number; + gridLines: number; + amountPerGrid: number; +} + +class GridTradingBot { + async setupGrid( + config: GridConfig, + manager: AutomationManager + ): Promise { + const results: AutomationResult[] = []; + const priceStep = (config.upperPrice - config.lowerPrice) / config.gridLines; + + // Create buy orders below current price + for (let i = 0; i < config.gridLines / 2; i++) { + const buyPrice = config.lowerPrice + priceStep * i; + + const result = await manager.createLimitOrder({ + token: config.token, + side: "buy", + price: buyPrice, + amountUsd: config.amountPerGrid, + }); + + results.push(result); + } + + // Create sell orders above current price + for (let i = config.gridLines / 2; i < config.gridLines; i++) { + const sellPrice = config.lowerPrice + priceStep * i; + + const result = await manager.createLimitOrder({ + token: config.token, + side: "sell", + price: sellPrice, + amountUsd: config.amountPerGrid, + }); + + results.push(result); + } + + return results; + } +} + +// Example: Set up grid trading +const gridBot = new GridTradingBot(); +const gridResults = await gridBot.setupGrid( + { + token: "ETH", + lowerPrice: 2800, + upperPrice: 3200, + gridLines: 10, + amountPerGrid: 50, + }, + manager +); +``` + +## Error Handling + +Common errors and how to handle them: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Order not triggering | Price never reached | Check threshold | +| Insufficient balance | Funds depleted | Check before creating | +| Order cancelled | Expired or conflict | Re-create if needed | +| Rate limit | Too many orders | Space out creation | + +```typescript +async function createWithRetry( + createFn: () => Promise, + maxRetries: number = 3 +): Promise { + for (let attempt = 1; attempt <= maxRetries; attempt++) { + const result = await createFn(); + + if (result.success) { + return result; + } + + // Check for retryable errors + if (result.message.includes("rate limit") || result.message.includes("timeout")) { + console.log(`Attempt ${attempt} failed, retrying...`); + await new Promise((r) => setTimeout(r, 5000 * attempt)); + continue; + } + + // Non-retryable error + return result; + } + + return { success: false, type: "unknown", message: "Max retries exceeded" }; +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-token-trading` - Immediate trades +- `bankr-market-research` - Price data for setting triggers diff --git a/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md b/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md new file mode 100644 index 0000000..b1e40ae --- /dev/null +++ b/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md @@ -0,0 +1,508 @@ +--- +name: Bankr Client Patterns +description: This skill should be used when the user asks to "implement Bankr client", "write bankr-client.ts", "create API client for Bankr", "common files for Bankr project", "package.json for Bankr", "tsconfig for Bankr", "Bankr TypeScript patterns", "Bankr response types", or needs the reusable client code and common project files for Bankr API integrations. +version: 1.0.0 +--- + +# Bankr Client Patterns + +Reusable client code and common files for Bankr API projects. + +## bankr-client.ts + +The core API client module for all Bankr projects: + +```typescript +import "dotenv/config"; + +const API_URL = process.env.BANKR_API_URL || "https://api.bankr.bot"; +const API_KEY = process.env.BANKR_API_KEY; + +// ============================================ +// Types +// ============================================ + +export type JobStatus = "pending" | "processing" | "completed" | "failed" | "cancelled"; + +export interface JobStatusResponse { + success: boolean; + jobId: string; + status: JobStatus; + prompt: string; + response?: string; + transactions?: Transaction[]; + richData?: RichData[]; + statusUpdates?: StatusUpdate[]; + error?: string; + createdAt: string; + startedAt?: string; + completedAt?: string; + cancelledAt?: string; + processingTime?: number; + cancellable?: boolean; +} + +export interface StatusUpdate { + message: string; + timestamp: string; +} + +// Transaction types +export type Transaction = + | SwapTransaction + | ApprovalTransaction + | TransferErc20Transaction + | TransferEthTransaction + | ConvertEthToWethTransaction + | ConvertWethToEthTransaction + | TransferNftTransaction + | MintManifoldNftTransaction + | MintSeaDropNftTransaction + | BuyNftTransaction + | AvantisTradeTransaction + | SwapCrossChainTransaction + | ManageBankrStakingTransaction; + +interface BaseTransactionMetadata { + __ORIGINAL_TX_DATA__: { + chain: string; + humanReadableMessage: string; + inputTokenAddress: string; + inputTokenAmount: string; + inputTokenTicker: string; + outputTokenAddress: string; + outputTokenTicker: string; + receiver: string; + }; + transaction: { + chainId: number; + to: string; + data: string; + gas: string; + gasPrice: string; + value: string; + }; +} + +export interface SwapTransaction { + type: "swap"; + metadata: BaseTransactionMetadata & { + approvalRequired?: boolean; + approvalTx?: { to: string; data: string }; + permit2?: object; + }; +} + +export interface ApprovalTransaction { + type: "approval"; + metadata: BaseTransactionMetadata; +} + +export interface TransferErc20Transaction { + type: "transfer_erc20"; + metadata: BaseTransactionMetadata; +} + +export interface TransferEthTransaction { + type: "transfer_eth"; + metadata: BaseTransactionMetadata; +} + +export interface ConvertEthToWethTransaction { + type: "convert_eth_to_weth"; + metadata: BaseTransactionMetadata; +} + +export interface ConvertWethToEthTransaction { + type: "convert_weth_to_eth"; + metadata: BaseTransactionMetadata; +} + +export interface TransferNftTransaction { + type: "transfer_nft"; + metadata: BaseTransactionMetadata; +} + +export interface MintManifoldNftTransaction { + type: "mint_manifold_nft"; + metadata: BaseTransactionMetadata; +} + +export interface MintSeaDropNftTransaction { + type: "mint_seadrop_nft"; + metadata: BaseTransactionMetadata; +} + +export interface BuyNftTransaction { + type: "buy_nft"; + metadata: BaseTransactionMetadata; +} + +export interface AvantisTradeTransaction { + type: "avantisTrade"; + metadata: { + chainId: number; + description: string; + to: string; + data: string; + value?: string; + }; +} + +export interface SwapCrossChainTransaction { + type: "swapCrossChain"; + metadata: { + chainId: number; + description: string; + to: string; + data: string; + value: string; + }; +} + +export interface ManageBankrStakingTransaction { + type: "manage_bankr_staking"; + metadata: { + chainId: number; + description: string; + to: string; + data: string; + value?: string; + }; +} + +// Rich data types +export type RichData = SocialCard | Chart; + +export interface SocialCard { + type: "social-card"; + variant: "analysis"; + text: string; +} + +export interface Chart { + type: "chart"; + url: string; +} + +// ============================================ +// API Functions +// ============================================ + +export async function submitPrompt(prompt: string): Promise<{ jobId: string }> { + if (!API_KEY) { + throw new Error("BANKR_API_KEY not set. Get one at https://bankr.bot/api"); + } + + const response = await fetch(`${API_URL}/agent/prompt`, { + method: "POST", + headers: { + "x-api-key": API_KEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ prompt }), + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`API error ${response.status}: ${text}`); + } + + const data = await response.json(); + if (!data.success) { + throw new Error(data.error || "Failed to submit prompt"); + } + + return { jobId: data.jobId }; +} + +export async function getJobStatus(jobId: string): Promise { + if (!API_KEY) { + throw new Error("BANKR_API_KEY not set"); + } + + const response = await fetch(`${API_URL}/agent/job/${jobId}`, { + headers: { "x-api-key": API_KEY }, + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`API error ${response.status}: ${text}`); + } + + return response.json(); +} + +export async function cancelJob(jobId: string): Promise { + if (!API_KEY) { + throw new Error("BANKR_API_KEY not set"); + } + + const response = await fetch(`${API_URL}/agent/job/${jobId}/cancel`, { + method: "POST", + headers: { + "x-api-key": API_KEY, + "Content-Type": "application/json", + }, + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`API error ${response.status}: ${text}`); + } + + return response.json(); +} + +export async function waitForCompletion( + jobId: string, + onProgress?: (message: string) => void, + options?: { pollInterval?: number; maxAttempts?: number } +): Promise { + const pollInterval = options?.pollInterval || 2000; + const maxAttempts = options?.maxAttempts || 150; // 5 minutes max + let lastUpdateCount = 0; + + for (let attempt = 0; attempt < maxAttempts; attempt++) { + const status = await getJobStatus(jobId); + + // Report new status updates + if (onProgress && status.statusUpdates) { + for (let i = lastUpdateCount; i < status.statusUpdates.length; i++) { + onProgress(status.statusUpdates[i].message); + } + lastUpdateCount = status.statusUpdates.length; + } + + // Check for terminal states + if (["completed", "failed", "cancelled"].includes(status.status)) { + return status; + } + + await new Promise((resolve) => setTimeout(resolve, pollInterval)); + } + + throw new Error("Job timed out after maximum attempts"); +} + +/** + * Execute a Bankr prompt and wait for completion + * Convenience function that combines submit + poll + */ +export async function execute( + prompt: string, + onProgress?: (message: string) => void +): Promise { + const { jobId } = await submitPrompt(prompt); + onProgress?.(`Job submitted: ${jobId}`); + return waitForCompletion(jobId, onProgress); +} +``` + +--- + +## Common Files + +### package.json + +Base package.json for all Bankr projects: + +```json +{ + "name": "{project-name}", + "version": "0.1.0", + "description": "{description}", + "type": "module", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "start": "node dist/index.js", + "dev": "tsx src/index.ts" + }, + "dependencies": { + "dotenv": "^16.3.1" + }, + "devDependencies": { + "@types/node": "^20.10.0", + "tsx": "^4.7.0", + "typescript": "^5.3.0" + } +} +``` + +#### Framework-Specific Dependencies + +Add based on project template: + +**Web Service (Express):** +```json +"dependencies": { + "express": "^4.18.0" +}, +"devDependencies": { + "@types/express": "^4.17.21" +} +``` + +**Web Service (Fastify):** +```json +"dependencies": { + "fastify": "^4.25.0" +} +``` + +**CLI:** +```json +"dependencies": { + "commander": "^12.0.0" +} +``` + +--- + +### tsconfig.json + +TypeScript configuration: + +```json +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} +``` + +--- + +### .env.example + +Environment variables template: + +```bash +# Bankr API Configuration +BANKR_API_KEY=bk_your_api_key_here +BANKR_API_URL=https://api.bankr.bot + +# Optional: Wallet address for context +BANKR_WALLET_ADDRESS=0x... +``` + +--- + +### .gitignore + +Standard ignore patterns: + +``` +# Dependencies +node_modules/ + +# Build output +dist/ + +# Environment +.env +.env.local +.env.*.local + +# Logs +*.log +npm-debug.log* + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Testing +coverage/ +``` + +--- + +## Usage Patterns + +### Basic Usage + +```typescript +import { execute } from "./bankr-client"; + +const result = await execute("What is the price of ETH?", (msg) => { + console.log("Progress:", msg); +}); + +console.log(result.response); +``` + +### With Error Handling + +```typescript +import { execute } from "./bankr-client"; + +try { + const result = await execute("Buy $50 of ETH on Base"); + + if (result.status === "completed") { + console.log("Success:", result.response); + + // Handle transactions + if (result.transactions) { + for (const tx of result.transactions) { + console.log(`${tx.type}:`, tx.metadata.__ORIGINAL_TX_DATA__?.humanReadableMessage); + } + } + } else if (result.status === "failed") { + console.error("Failed:", result.error); + } +} catch (error) { + console.error("Error:", error.message); +} +``` + +### Manual Control + +```typescript +import { submitPrompt, waitForCompletion, cancelJob } from "./bankr-client"; + +// Submit +const { jobId } = await submitPrompt("Analyze ETH market"); + +// Set up timeout +const timeout = setTimeout(() => { + cancelJob(jobId); +}, 120000); + +// Wait with custom options +const result = await waitForCompletion(jobId, console.log, { + pollInterval: 2000, + maxAttempts: 60, +}); + +clearTimeout(timeout); +``` + +--- + +## API Reference + +Consult the `bankr-api-basics` skill for: +- Complete endpoint documentation +- Authentication details +- Response field descriptions +- Error codes and handling diff --git a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md new file mode 100644 index 0000000..be0d01d --- /dev/null +++ b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md @@ -0,0 +1,434 @@ +--- +name: Bankr Leverage Trading (Developer Guide) +description: This skill should be used when building a leverage trading bot, implementing perpetual position management, creating risk management systems with stop-loss automation, or building an Avantis integration. Covers TypeScript prompt templates like `leveragePrompts.openLongWithRisk()`, liquidation price calculations, position PnL parsing, and LeverageTradingBot class with risk parameters. Triggered by "leverage bot code", "perpetual trading TypeScript", "Avantis integration", "stop loss automation". +version: 1.0.0 +--- + +# Leverage Trading - Developer Guide + +Build bots and applications that trade perpetuals via Avantis and the Bankr API. + +## Overview + +Leverage trading through Bankr (via Avantis) supports: +- Long and short positions +- Leverage from 1x to 100x+ +- Crypto, forex, and commodities markets +- Stop loss and take profit orders + +**Chain:** Base + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for leverage trading operations +const leveragePrompts = { + // Open positions + openLong: (asset: string, leverage: number, collateral: string) => + `Open a ${leverage}x long on ${asset} with ${collateral}`, + + openShort: (asset: string, leverage: number, collateral: string) => + `Open a ${leverage}x short on ${asset} with ${collateral}`, + + // With risk management + openLongWithSL: (asset: string, leverage: number, collateral: string, stopLoss: string) => + `Open a ${leverage}x long on ${asset} with ${collateral}, stop loss at ${stopLoss}`, + + openLongWithTP: (asset: string, leverage: number, collateral: string, takeProfit: string) => + `Open a ${leverage}x long on ${asset} with ${collateral}, take profit at ${takeProfit}`, + + openLongWithRisk: ( + asset: string, + leverage: number, + collateral: string, + stopLoss: string, + takeProfit: string + ) => + `Open a ${leverage}x long on ${asset} with ${collateral}, stop loss at ${stopLoss}, take profit at ${takeProfit}`, + + // View/close positions + viewPositions: () => "Show my Avantis positions", + closePosition: (asset: string, direction: "long" | "short") => + `Close my ${asset} ${direction} position`, + closeAllPositions: () => "Close all my Avantis positions", + + // Check PnL + checkPnl: () => "Check my PnL on Avantis", +}; + +// Asset categories +const SUPPORTED_ASSETS = { + crypto: ["BTC", "ETH", "SOL", "ARB", "AVAX", "BNB", "DOGE", "LINK", "OP", "MATIC"], + forex: ["EUR/USD", "GBP/USD", "USD/JPY", "AUD/USD", "USD/CAD"], + commodities: ["Gold", "Silver", "Oil", "Natural Gas"], +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface PositionInfo { + asset: string; + direction: "long" | "short"; + leverage: number; + collateral: number; + entryPrice: number; + liquidationPrice: number; + pnl: number; + pnlPercentage: number; +} + +// Parse position opened response +function parsePositionOpened(response: string): Partial | null { + // Example: "Opened 5x long on ETH with $100 collateral. Entry: $3,245.67. Liquidation: $2,596.54" + const match = response.match( + /Opened\s+(\d+)x\s+(long|short)\s+on\s+(\w+).+Entry:\s+\$([0-9,.]+).+Liquidation:\s+\$([0-9,.]+)/i + ); + + if (match) { + return { + leverage: parseInt(match[1]), + direction: match[2].toLowerCase() as "long" | "short", + asset: match[3], + entryPrice: parseFloat(match[4].replace(",", "")), + liquidationPrice: parseFloat(match[5].replace(",", "")), + }; + } + return null; +} + +// Parse positions list +function parsePositions(response: string): PositionInfo[] { + const positions: PositionInfo[] = []; + // Example: "- ETH Long 5x: +$23.45 (7.2%)" + const lines = response.split("\n").filter((l) => l.startsWith("-")); + + for (const line of lines) { + const match = line.match(/-\s+(\w+)\s+(Long|Short)\s+(\d+)x:\s+([+-]?\$[0-9.]+)\s+\(([+-]?[0-9.]+)%\)/i); + if (match) { + positions.push({ + asset: match[1], + direction: match[2].toLowerCase() as "long" | "short", + leverage: parseInt(match[3]), + collateral: 0, // Not in response + entryPrice: 0, + liquidationPrice: 0, + pnl: parseFloat(match[4].replace("$", "").replace("+", "")), + pnlPercentage: parseFloat(match[5].replace("+", "")), + }); + } + } + return positions; +} + +async function handleLeverageResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Leverage operation successful"); + console.log(result.response); + + // Handle transactions + if (result.transactions) { + for (const tx of result.transactions) { + if (tx.metadata.description) { + console.log(`Trade: ${tx.metadata.description}`); + } + } + } + } else if (result.status === "failed") { + console.error("Leverage operation failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Leverage trading specific types +interface LeveragePosition { + asset: string; + direction: "long" | "short"; + leverage: number; + collateral: number; // USD + stopLoss?: number; // Price or percentage + takeProfit?: number; // Price or percentage +} + +interface PositionResult { + success: boolean; + asset: string; + direction: "long" | "short"; + leverage: number; + entryPrice: number; + liquidationPrice: number; + collateral: number; +} + +// Risk parameters +interface RiskParams { + maxLeverage: number; + maxPositionSize: number; // USD + defaultStopLoss: number; // Percentage + defaultTakeProfit: number; // Percentage +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Trend Follower | Long/short based on trend | `Open a 5x long on ETH with $100` | +| Mean Reversion | Fade extreme moves | `Short BTC with 3x leverage` | +| Scalper | Quick in/out trades | Open/close with tight SL/TP | +| Risk Manager | Monitor liquidation risk | `Show my Avantis positions` | +| Auto-Closer | Close at PnL targets | `Close my ETH long position` | + +## Code Example: Leverage Trading Bot + +```typescript +import { execute } from "./bankr-client"; + +interface TradingSignal { + asset: string; + direction: "long" | "short"; + confidence: number; // 0-1 +} + +class LeverageTradingBot { + private riskParams: RiskParams = { + maxLeverage: 10, + maxPositionSize: 500, + defaultStopLoss: 5, + defaultTakeProfit: 15, + }; + + calculatePositionSize(confidence: number): number { + return Math.min(this.riskParams.maxPositionSize * confidence, this.riskParams.maxPositionSize); + } + + calculateLeverage(confidence: number): number { + return Math.max(1, Math.min(Math.ceil(confidence * this.riskParams.maxLeverage), this.riskParams.maxLeverage)); + } + + async openPosition(signal: TradingSignal): Promise { + const collateral = this.calculatePositionSize(signal.confidence); + const leverage = this.calculateLeverage(signal.confidence); + + const prompt = leveragePrompts.openLongWithRisk( + signal.asset, + leverage, + `$${collateral}`, + `-${this.riskParams.defaultStopLoss}%`, + `+${this.riskParams.defaultTakeProfit}%` + ); + + const result = await execute(prompt, (msg) => console.log(" >", msg)); + if (result.status !== "completed") return null; + + const parsed = parsePositionOpened(result.response || ""); + if (!parsed) return null; + + return { + success: true, + asset: signal.asset, + direction: signal.direction, + leverage: parsed.leverage || leverage, + entryPrice: parsed.entryPrice || 0, + liquidationPrice: parsed.liquidationPrice || 0, + collateral, + }; + } + + async getPositions(): Promise { + const result = await execute(leveragePrompts.viewPositions()); + return result.status === "completed" && result.response ? parsePositions(result.response) : []; + } + + async closePosition(asset: string, direction: "long" | "short"): Promise { + return (await execute(leveragePrompts.closePosition(asset, direction))).status === "completed"; + } + + async closeAllPositions(): Promise { + return (await execute(leveragePrompts.closeAllPositions())).status === "completed"; + } + + async monitorPositions(): Promise { + const positions = await this.getPositions(); + + for (const position of positions) { + const shouldClose = + position.pnlPercentage <= -this.riskParams.defaultStopLoss || + position.pnlPercentage >= this.riskParams.defaultTakeProfit; + + if (shouldClose) { + await this.closePosition(position.asset, position.direction); + } + } + } +} + +// Usage +const bot = new LeverageTradingBot(); + +// Open a position based on a signal +const signal: TradingSignal = { + asset: "ETH", + direction: "long", + confidence: 0.7, +}; + +const position = await bot.openPosition(signal); +console.log("Opened position:", position); + +// Monitor positions periodically +setInterval(() => bot.monitorPositions(), 30000); + +// Get current positions +const positions = await bot.getPositions(); +console.log("Current positions:", positions); +``` + +## Risk Management + +```typescript +// Risk calculation utilities +function calculateLiquidationPrice( + entryPrice: number, + leverage: number, + direction: "long" | "short", + maintenanceMargin: number = 0.005 // 0.5% +): number { + if (direction === "long") { + // Liquidated when price drops enough to wipe collateral + return entryPrice * (1 - 1 / leverage + maintenanceMargin); + } else { + // Liquidated when price rises enough + return entryPrice * (1 + 1 / leverage - maintenanceMargin); + } +} + +function calculatePositionSize( + collateral: number, + leverage: number +): number { + return collateral * leverage; +} + +function calculatePnL( + entryPrice: number, + currentPrice: number, + positionSize: number, + direction: "long" | "short" +): number { + const priceDiff = currentPrice - entryPrice; + const pnl = direction === "long" ? priceDiff : -priceDiff; + return (pnl / entryPrice) * positionSize; +} + +function checkRisk( + collateral: number, + leverage: number, + accountBalance: number, + existingExposure: number +): { allowed: boolean; reason?: string } { + const positionSize = collateral * leverage; + const totalExposure = existingExposure + positionSize; + + if (totalExposure > accountBalance * 3) { + return { allowed: false, reason: "Exceeds maximum total exposure" }; + } + if (collateral > accountBalance * 0.2) { + return { allowed: false, reason: "Position too large for account size" }; + } + if (collateral > 100 && leverage > 10) { + return { allowed: false, reason: "Reduce leverage for larger positions" }; + } + + return { allowed: true }; +} +``` + +## Error Handling + +Common errors and how to handle them: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Insufficient collateral | Not enough funds | Reduce position size | +| Asset not supported | Invalid market | Check supported list | +| Liquidation | Price moved against | Position closed, log loss | +| High funding rate | Expensive to hold | Consider closing | + +```typescript +async function safeOpenPosition( + position: LeveragePosition, + accountBalance: number +): Promise { + // Risk check first + const riskCheck = checkRisk( + position.collateral, + position.leverage, + accountBalance, + 0 // Calculate existing exposure + ); + + if (!riskCheck.allowed) { + console.error("Risk check failed:", riskCheck.reason); + return null; + } + + // Validate asset + const allAssets = [ + ...SUPPORTED_ASSETS.crypto, + ...SUPPORTED_ASSETS.forex, + ...SUPPORTED_ASSETS.commodities, + ]; + + if (!allAssets.some((a) => position.asset.toUpperCase().includes(a.toUpperCase()))) { + console.error("Asset not supported:", position.asset); + return null; + } + + // Open position + const bot = new LeverageTradingBot(); + return await bot.openPosition({ + asset: position.asset, + direction: position.direction, + confidence: 1, // Use full specified size + }); +} +``` + +## Leverage Guidelines + +| Risk Level | Leverage | Use Case | +|------------|----------|----------| +| Conservative | 1-3x | Long-term trend following | +| Moderate | 3-10x | Swing trading | +| Aggressive | 10-25x | Short-term scalping | +| High Risk | 25x+ | Experienced traders only | + +```typescript +function getLeverageGuidance( + timeframe: "scalp" | "swing" | "position", + confidence: number +): number { + const baseLeverage = { + scalp: 15, + swing: 5, + position: 2, + }; + + return Math.ceil(baseLeverage[timeframe] * confidence); +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-market-research` - Price data for trading decisions +- `bankr-portfolio` - Check balances before trading diff --git a/bankr-agent-dev/skills/bankr-market-research/SKILL.md b/bankr-agent-dev/skills/bankr-market-research/SKILL.md new file mode 100644 index 0000000..d7eb1c1 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-market-research/SKILL.md @@ -0,0 +1,580 @@ +--- +name: Bankr Market Research (Developer Guide) +description: This skill should be used when building a price alert system, implementing technical analysis automation, creating sentiment tracking, or building a trending token discovery bot. Covers TypeScript prompt templates like `marketPrompts.technicalAnalysis()`, price/TA/sentiment parsing, trading signal generation, and MarketMonitor class with alert callbacks. Triggered by "price alert bot code", "market research TypeScript", "sentiment tracking automation", "technical analysis implementation". +version: 1.0.0 +--- + +# Market Research - Developer Guide + +Build bots and applications that perform market research via the Bankr API. + +## Overview + +Market research through Bankr supports: +- Token price queries +- Market data (cap, volume, supply) +- Technical analysis indicators +- Social sentiment analysis +- Price charts +- Trending token discovery + +**Supported Chains:** All chains - data aggregated from multiple sources + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for market research operations +const marketPrompts = { + // Price queries + price: (token: string) => `What's the price of ${token}?`, + priceWithDetails: (token: string) => `Show me ${token} market data`, + + // Market data + marketCap: (token: string) => `What's the market cap of ${token}?`, + volume: (token: string) => `What's the 24h volume for ${token}?`, + holders: (token: string) => `How many holders does ${token} have?`, + + // Technical analysis + technicalAnalysis: (token: string) => `Do technical analysis on ${token}`, + rsi: (token: string) => `What's the RSI for ${token}?`, + priceAction: (token: string) => `Analyze ${token} price action`, + + // Sentiment + sentiment: (token: string) => `What's the sentiment on ${token}?`, + socialMentions: (token: string) => `Check social mentions for ${token}`, + + // Charts + chart: (token: string, period?: string) => + period ? `Show ${token} price chart for ${period}` : `Show ${token} price chart`, + + // Discovery + trending: () => "What tokens are trending today?", + topGainers: () => "Show top gainers today", + topLosers: () => "Show top losers today", + trendingOnChain: (chain: string) => `What's trending on ${chain}?`, + + // Comparison + compare: (token1: string, token2: string) => `Compare ${token1} vs ${token2}`, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse, RichData, Chart } from "./bankr-client"; + +interface PriceData { + token: string; + priceUsd: number; + change24h: number; + change7d?: number; + marketCap?: number; + volume24h?: number; + ath?: number; + atl?: number; +} + +interface TechnicalIndicators { + rsi: number; + rsiSignal: "oversold" | "neutral" | "overbought"; + macd: "bullish" | "bearish" | "neutral"; + ma50: number; + ma200: number; + trend: "bullish" | "bearish" | "neutral"; +} + +interface SentimentData { + overall: "bullish" | "bearish" | "neutral"; + bullishPercent: number; + socialMentions: number; + mentionChange: number; + keyTopics: string[]; +} + +// Parse price response +function parsePriceData(response: string, token: string): PriceData | null { + // Example: "Ethereum (ETH): $3,245.67\n24h: +2.3%\n7d: -1.5%\nMarket Cap: $390.2B" + const priceMatch = response.match(/\$([0-9,.]+)/); + const change24hMatch = response.match(/24h:\s*([+-]?[0-9.]+)%/); + const change7dMatch = response.match(/7d:\s*([+-]?[0-9.]+)%/); + const marketCapMatch = response.match(/Market Cap:\s*\$([0-9,.]+)([BMK])?/); + + if (!priceMatch) return null; + + let marketCap: number | undefined; + if (marketCapMatch) { + marketCap = parseFloat(marketCapMatch[1].replace(",", "")); + const suffix = marketCapMatch[2]; + if (suffix === "B") marketCap *= 1e9; + else if (suffix === "M") marketCap *= 1e6; + else if (suffix === "K") marketCap *= 1e3; + } + + return { + token, + priceUsd: parseFloat(priceMatch[1].replace(",", "")), + change24h: change24hMatch ? parseFloat(change24hMatch[1]) : 0, + change7d: change7dMatch ? parseFloat(change7dMatch[1]) : undefined, + marketCap, + }; +} + +// Parse technical analysis +function parseTechnicalAnalysis(response: string): TechnicalIndicators | null { + const rsiMatch = response.match(/RSI:\s*(\d+)\s*\((\w+)\)/i); + const macdMatch = response.match(/MACD:\s*(\w+)/i); + const ma50Match = response.match(/50\s*MA:\s*\$([0-9,.]+)/i); + const ma200Match = response.match(/200\s*MA:\s*\$([0-9,.]+)/i); + + if (!rsiMatch) return null; + + const rsi = parseInt(rsiMatch[1]); + + function getRsiSignal(value: number): "oversold" | "neutral" | "overbought" { + if (value < 30) return "oversold"; + if (value > 70) return "overbought"; + return "neutral"; + } + + function getMacdSignal(match: RegExpMatchArray | null): "bullish" | "bearish" | "neutral" { + const signal = match?.[1]?.toLowerCase() || ""; + if (signal.includes("bullish")) return "bullish"; + if (signal.includes("bearish")) return "bearish"; + return "neutral"; + } + + return { + rsi, + rsiSignal: getRsiSignal(rsi), + macd: getMacdSignal(macdMatch), + ma50: ma50Match ? parseFloat(ma50Match[1].replace(",", "")) : 0, + ma200: ma200Match ? parseFloat(ma200Match[1].replace(",", "")) : 0, + trend: "neutral", + }; +} + +// Parse sentiment +function parseSentiment(response: string): SentimentData | null { + // Example: "Sentiment: 67% Bullish\nSocial mentions: 12.5K (up 15%)" + const sentimentMatch = response.match(/(\d+)%\s*(Bullish|Bearish|Neutral)/i); + const mentionsMatch = response.match(/mentions:\s*([0-9.]+)K?\s*\((\w+)\s*(\d+)%\)/i); + + if (!sentimentMatch) return null; + + const bullishPercent = parseInt(sentimentMatch[1]); + let overall: "bullish" | "bearish" | "neutral" = "neutral"; + if (bullishPercent > 60) overall = "bullish"; + else if (bullishPercent < 40) overall = "bearish"; + + return { + overall, + bullishPercent, + socialMentions: mentionsMatch ? parseFloat(mentionsMatch[1]) * 1000 : 0, + mentionChange: mentionsMatch ? parseInt(mentionsMatch[3]) : 0, + keyTopics: [], // Extract from response if available + }; +} + +// Extract chart URL from rich data +function extractChartUrl(richData?: RichData[]): string | null { + if (!richData) return null; + const chart = richData.find((d) => d.type === "chart") as Chart | undefined; + return chart?.url || null; +} + +async function handleMarketResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Market research successful"); + console.log(result.response); + + // Check for charts + const chartUrl = extractChartUrl(result.richData); + if (chartUrl) { + console.log("Chart available:", chartUrl); + } + } else if (result.status === "failed") { + console.error("Market research failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Market research specific types +interface PriceAlert { + token: string; + type: "above" | "below" | "change"; + threshold: number; + enabled: boolean; +} + +interface TokenWatchlist { + token: string; + addedAt: Date; + alertPrice?: number; + notes?: string; +} + +interface MarketSnapshot { + timestamp: Date; + prices: Map; + totalMarketCap?: number; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Price Bot | Track token prices | `What's the price of ETH?` | +| Alert System | Notify on price changes | Poll + compare | +| TA Bot | Technical analysis | `Do technical analysis on BTC` | +| Sentiment Tracker | Monitor social mood | `What's the sentiment on SOL?` | +| Discovery Bot | Find trending tokens | `What tokens are trending?` | + +## Code Example: Market Monitor Bot + +```typescript +import { execute } from "./bankr-client"; + +interface PriceAlert { + token: string; + type: "above" | "below"; + threshold: number; + callback: (price: number, token: string) => void; +} + +class MarketMonitor { + private priceCache: Map = new Map(); + private alerts: PriceAlert[] = []; + private watchlist: string[] = []; + + async getPrice(token: string): Promise { + const result = await execute(marketPrompts.price(token)); + if (result.status !== "completed" || !result.response) return null; + + const data = parsePriceData(result.response, token); + if (data) this.priceCache.set(token, data); + return data; + } + + async getMarketData(token: string): Promise { + const result = await execute(marketPrompts.priceWithDetails(token)); + return result.status === "completed" && result.response ? parsePriceData(result.response, token) : null; + } + + async getTechnicalAnalysis(token: string): Promise { + const result = await execute(marketPrompts.technicalAnalysis(token)); + return result.status === "completed" && result.response ? parseTechnicalAnalysis(result.response) : null; + } + + async getSentiment(token: string): Promise { + const result = await execute(marketPrompts.sentiment(token)); + return result.status === "completed" && result.response ? parseSentiment(result.response) : null; + } + + async getChart(token: string, period = "7d"): Promise { + const result = await execute(marketPrompts.chart(token, period)); + return result.status === "completed" ? extractChartUrl(result.richData) : null; + } + + async getTrending(): Promise { + const result = await execute(marketPrompts.trending()); + if (result.status !== "completed" || !result.response) return []; + + return result.response + .split("\n") + .map((line) => line.match(/\d+\.\s*(\w+)/)?.[1]) + .filter((token): token is string => Boolean(token)); + } + + addAlert(alert: PriceAlert): void { + this.alerts.push(alert); + } + + addToWatchlist(token: string): void { + if (!this.watchlist.includes(token)) this.watchlist.push(token); + } + + async checkAlerts(): Promise { + for (const alert of this.alerts) { + const price = await this.getPrice(alert.token); + if (!price) continue; + + const triggered = + (alert.type === "above" && price.priceUsd >= alert.threshold) || + (alert.type === "below" && price.priceUsd <= alert.threshold); + + if (triggered) { + alert.callback(price.priceUsd, alert.token); + this.alerts = this.alerts.filter((a) => a !== alert); + } + } + } + + async updateWatchlist(): Promise> { + const updates = new Map(); + + for (const token of this.watchlist) { + const data = await this.getPrice(token); + if (data) updates.set(token, data); + await new Promise((r) => setTimeout(r, 1000)); + } + + return updates; + } + + getCachedPrice(token: string): PriceData | undefined { + return this.priceCache.get(token); + } +} + +// Usage +const monitor = new MarketMonitor(); + +// Get current price +const ethPrice = await monitor.getPrice("ETH"); +console.log("ETH price:", ethPrice); + +// Get technical analysis +const btcTa = await monitor.getTechnicalAnalysis("BTC"); +console.log("BTC TA:", btcTa); + +// Get sentiment +const solSentiment = await monitor.getSentiment("SOL"); +console.log("SOL sentiment:", solSentiment); + +// Set up alerts +monitor.addAlert({ + token: "ETH", + type: "below", + threshold: 3000, + callback: (price, token) => { + console.log(`ALERT: ${token} dropped to $${price}!`); + }, +}); + +// Check alerts periodically +setInterval(() => monitor.checkAlerts(), 60000); + +// Get trending +const trending = await monitor.getTrending(); +console.log("Trending tokens:", trending); +``` + +## Price Alert System + +```typescript +interface AlertConfig { + token: string; + conditions: AlertCondition[]; + notifyMethod: "console" | "webhook" | "callback"; + webhookUrl?: string; +} + +type AlertCondition = + | { type: "priceAbove"; value: number } + | { type: "priceBelow"; value: number } + | { type: "changeAbove"; value: number; period: "1h" | "24h" } + | { type: "changeBelow"; value: number; period: "1h" | "24h" }; + +class AlertSystem { + private configs: AlertConfig[] = []; + private priceHistory: Map = new Map(); + + addConfig(config: AlertConfig): void { + this.configs.push(config); + } + + async checkCondition( + condition: AlertCondition, + currentPrice: PriceData + ): Promise { + switch (condition.type) { + case "priceAbove": + return currentPrice.priceUsd >= condition.value; + case "priceBelow": + return currentPrice.priceUsd <= condition.value; + case "changeAbove": + return ( + (condition.period === "24h" ? currentPrice.change24h : 0) >= + condition.value + ); + case "changeBelow": + return ( + (condition.period === "24h" ? currentPrice.change24h : 0) <= + condition.value + ); + default: + return false; + } + } + + async notify(config: AlertConfig, price: PriceData): Promise { + const message = `Alert: ${config.token} at $${price.priceUsd} (${price.change24h}% 24h)`; + + switch (config.notifyMethod) { + case "console": + console.log(message); + break; + case "webhook": + if (config.webhookUrl) { + await fetch(config.webhookUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ token: config.token, price, message }), + }); + } + break; + } + } +} +``` + +## Trading Signal Generation + +```typescript +interface TradingSignal { + token: string; + action: "buy" | "sell" | "hold"; + confidence: number; + reasons: string[]; + timestamp: Date; +} + +async function generateSignal( + monitor: MarketMonitor, + token: string +): Promise { + const [price, ta, sentiment] = await Promise.all([ + monitor.getPrice(token), + monitor.getTechnicalAnalysis(token), + monitor.getSentiment(token), + ]); + + const reasons: string[] = []; + let score = 0; + + // Technical indicators + if (ta) { + if (ta.rsiSignal === "oversold") { + score += 2; + reasons.push("RSI oversold (potential buy)"); + } else if (ta.rsiSignal === "overbought") { + score -= 2; + reasons.push("RSI overbought (potential sell)"); + } + + if (ta.macd === "bullish") { + score += 1; + reasons.push("MACD bullish"); + } else if (ta.macd === "bearish") { + score -= 1; + reasons.push("MACD bearish"); + } + } + + // Sentiment + if (sentiment) { + if (sentiment.overall === "bullish") { + score += 1; + reasons.push(`Sentiment bullish (${sentiment.bullishPercent}%)`); + } else if (sentiment.overall === "bearish") { + score -= 1; + reasons.push(`Sentiment bearish`); + } + } + + // Price momentum + if (price && price.change24h) { + if (price.change24h > 5) { + score += 1; + reasons.push(`Strong momentum (+${price.change24h}%)`); + } else if (price.change24h < -5) { + score -= 1; + reasons.push(`Negative momentum (${price.change24h}%)`); + } + } + + // Determine action + let action: "buy" | "sell" | "hold" = "hold"; + if (score >= 2) action = "buy"; + else if (score <= -2) action = "sell"; + + return { + token, + action, + confidence: Math.min(Math.abs(score) / 4, 1), + reasons, + timestamp: new Date(), + }; +} +``` + +## Error Handling + +Common errors and how to handle them in bots: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Token not found | Invalid symbol | Check symbol, try alternatives | +| Price unavailable | Delisted or new token | Skip or use external source | +| Chart generation failed | Server issue | Retry or skip chart | +| Sentiment data empty | Insufficient social data | Return neutral sentiment | +| Rate limited | Too many requests | Implement backoff, cache results | + +```typescript +async function safeGetPrice( + monitor: MarketMonitor, + token: string +): Promise { + try { + const price = await monitor.getPrice(token); + + if (!price) { + console.warn(`No price data for ${token}`); + return null; + } + + return price; + } catch (err) { + const error = err as Error; + + if (error.message.includes("not found")) { + console.error(`Token ${token} not found, check symbol`); + } else if (error.message.includes("rate limit")) { + console.error("Rate limited, implementing backoff"); + await new Promise((r) => setTimeout(r, 5000)); + } + + return null; + } +} + +async function safeGetMarketData( + monitor: MarketMonitor, + token: string +): Promise<{ price?: PriceData; ta?: TechnicalIndicators; sentiment?: SentimentData }> { + const [price, ta, sentiment] = await Promise.allSettled([ + monitor.getPrice(token), + monitor.getTechnicalAnalysis(token), + monitor.getSentiment(token), + ]); + + return { + price: price.status === "fulfilled" ? price.value || undefined : undefined, + ta: ta.status === "fulfilled" ? ta.value || undefined : undefined, + sentiment: sentiment.status === "fulfilled" ? sentiment.value || undefined : undefined, + }; +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-token-trading` - Execute trades based on research +- `bankr-automation` - Set up automated responses to signals diff --git a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md new file mode 100644 index 0000000..111852c --- /dev/null +++ b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md @@ -0,0 +1,410 @@ +--- +name: Bankr NFT Operations (Developer Guide) +description: This skill should be used when building an NFT sniping bot, implementing floor price monitoring, creating a collection sweeper, or automating NFT purchases via OpenSea. Covers TypeScript prompt templates like `nftPrompts.buyFloor()`, floor tracking with trend detection, and NftBot class with watchlist management. Triggered by "NFT bot code", "floor sweeper TypeScript", "OpenSea automation", "NFT sniping implementation". +version: 1.0.0 +--- + +# NFT Operations - Developer Guide + +Build bots and applications that interact with NFTs via the Bankr API. + +## Overview + +NFT operations through Bankr (via OpenSea) support: +- Browsing NFT collections +- Finding best listings and floor prices +- Purchasing NFTs +- Viewing NFT holdings + +**Supported Chains:** Base, Ethereum, Polygon, and other EVM chains + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for NFT operations +const nftPrompts = { + // Browse collections + searchCollection: (collection: string) => `Find NFTs from the ${collection} collection`, + trendingCollections: () => "Show me trending NFT collections", + searchByChain: (chain: string) => `Search for NFT collections on ${chain}`, + + // Check listings + floorPrice: (collection: string) => `What's the floor price for ${collection}?`, + cheapestNfts: (collection: string, count: number = 5) => + `Show the ${count} cheapest NFTs in ${collection}`, + listingsUnder: (collection: string, price: string) => + `Find NFT listings under ${price} in ${collection}`, + + // Buy NFTs + buyFloor: (collection: string) => `Buy the floor NFT from ${collection}`, + buyCheapest: (collection: string) => `Buy the cheapest NFT from ${collection}`, + buyByUrl: (url: string) => `Buy this NFT: ${url}`, + buyWithBudget: (collection: string, maxPrice: string) => + `Buy a ${collection} NFT under ${maxPrice}`, + + // View holdings + viewHoldings: () => "Show my NFTs", + viewHoldingsOnChain: (chain: string) => `Show my NFTs on ${chain}`, + viewCollection: (collection: string) => `Show my NFTs from ${collection}`, +}; + +// Popular collections mapping +const COLLECTION_ALIASES: Record = { + "bored apes": "boredapeyachtclub", + "bayc": "boredapeyachtclub", + "pudgy penguins": "pudgypenguins", + "cryptopunks": "cryptopunks", + "azuki": "azuki", + "doodles": "doodles-official", + "milady": "milady", +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface NftListing { + tokenId: string; + collection: string; + price: number; + currency: string; + url?: string; +} + +interface NftHolding { + tokenId: string; + collection: string; + estimatedValue: number; + chain: string; +} + +// Parse listings from response +function parseListings(response: string): NftListing[] { + const listings: NftListing[] = []; + // Example: "1. #4521 - 8.5 ETH" + const lines = response.split("\n").filter((l) => l.match(/^\d+\./)); + + for (const line of lines) { + const match = line.match(/^(\d+)\.\s+#?(\d+)\s+-\s+([0-9.]+)\s+(\w+)/); + if (match) { + listings.push({ + tokenId: match[2], + collection: "", // From context + price: parseFloat(match[3]), + currency: match[4], + }); + } + } + return listings; +} + +// Parse floor price from response +function parseFloorPrice(response: string): { price: number; currency: string } | null { + // Example: "Pudgy Penguins floor price: 8.5 ETH" + const match = response.match(/floor\s*price:\s*([0-9.]+)\s*(\w+)/i); + if (match) { + return { + price: parseFloat(match[1]), + currency: match[2], + }; + } + return null; +} + +// Parse holdings from response +function parseHoldings(response: string): NftHolding[] { + const holdings: NftHolding[] = []; + // Example: "- Pudgy Penguin #4521 (8.5 ETH value)" + const lines = response.split("\n").filter((l) => l.startsWith("-")); + + for (const line of lines) { + const match = line.match(/-\s+(.+?)\s+#(\d+)\s+\(([0-9.]+)\s+(\w+)\s+value\)/); + if (match) { + holdings.push({ + collection: match[1], + tokenId: match[2], + estimatedValue: parseFloat(match[3]), + chain: "ethereum", // Default, may vary + }); + } + } + return holdings; +} + +async function handleNftResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("NFT operation successful"); + console.log(result.response); + + // Handle transactions + if (result.transactions) { + for (const tx of result.transactions) { + const data = tx.metadata.__ORIGINAL_TX_DATA__; + if (data) { + console.log(`${data.humanReadableMessage}`); + console.log(`Price: ${data.inputTokenAmount} ${data.inputTokenTicker}`); + } + } + } + } else if (result.status === "failed") { + console.error("NFT operation failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// NFT-specific types for your bot +interface NftPurchaseConfig { + collection: string; + maxPrice: number; // ETH + autoApprove: boolean; +} + +interface FloorTracker { + collection: string; + targetFloor: number; + currentFloor?: number; + lastChecked?: Date; +} + +interface PurchaseResult { + success: boolean; + tokenId: string; + collection: string; + price: number; + currency: string; + txHash?: string; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Floor Sweeper | Buy floor when cheap | `Buy the floor NFT from Pudgy Penguins` | +| Sniper | Watch for underpriced | `Find listings under 5 ETH in Azuki` | +| Portfolio Tracker | Monitor holdings | `Show my NFTs` | +| Deal Finder | Find bargains | `Show cheapest NFTs in BAYC` | + +## Code Example: NFT Monitoring Bot + +```typescript +import { execute } from "./bankr-client"; + +interface CollectionWatch { + collection: string; + targetFloor: number; // Buy if floor drops below this + maxBudget: number; // Max to spend + enabled: boolean; +} + +class NftBot { + private watchlist: CollectionWatch[] = []; + + async getFloorPrice(collection: string): Promise { + const result = await execute(nftPrompts.floorPrice(collection)); + if (result.status !== "completed" || !result.response) return null; + return parseFloorPrice(result.response)?.price || null; + } + + async getCheapestListings(collection: string, count = 5): Promise { + const result = await execute(nftPrompts.cheapestNfts(collection, count)); + return result.status === "completed" && result.response ? parseListings(result.response) : []; + } + + async buyFloor(collection: string): Promise { + const result = await execute(nftPrompts.buyFloor(collection), (msg) => console.log(" >", msg)); + if (result.status !== "completed") return null; + + const txData = result.transactions?.[0]?.metadata.__ORIGINAL_TX_DATA__; + if (!txData) return null; + + return { + success: true, + tokenId: "", + collection, + price: parseFloat(txData.inputTokenAmount), + currency: txData.inputTokenTicker, + }; + } + + async buyByUrl(url: string): Promise { + const result = await execute(nftPrompts.buyByUrl(url), (msg) => console.log(" >", msg)); + if (result.status !== "completed") return null; + return { success: true, tokenId: "", collection: "", price: 0, currency: "ETH" }; + } + + async getHoldings(): Promise { + const result = await execute(nftPrompts.viewHoldings()); + return result.status === "completed" && result.response ? parseHoldings(result.response) : []; + } + + addToWatchlist(watch: CollectionWatch): void { + this.watchlist.push(watch); + } + + async checkWatchlist(): Promise { + for (const watch of this.watchlist) { + if (!watch.enabled) continue; + + const floor = await this.getFloorPrice(watch.collection); + if (floor === null || floor > watch.targetFloor || floor > watch.maxBudget) continue; + + const purchase = await this.buyFloor(watch.collection); + if (purchase?.success) { + watch.enabled = false; + } + } + } +} + +// Usage +const bot = new NftBot(); + +// Check floor prices +const floor = await bot.getFloorPrice("Pudgy Penguins"); +console.log("Pudgy Penguins floor:", floor); + +// Get cheapest listings +const listings = await bot.getCheapestListings("Azuki", 5); +console.log("Cheapest Azuki:", listings); + +// Add to watchlist +bot.addToWatchlist({ + collection: "Pudgy Penguins", + targetFloor: 7.5, + maxBudget: 8, + enabled: true, +}); + +// Check watchlist periodically +setInterval(() => bot.checkWatchlist(), 60000); + +// Get holdings +const holdings = await bot.getHoldings(); +console.log("My NFTs:", holdings); +``` + +## Floor Tracking + +```typescript +interface FloorHistory { + timestamp: Date; + floor: number; +} + +class FloorTracker { + private history: Map = new Map(); + + async trackFloor(collection: string, bot: NftBot): Promise { + const floor = await bot.getFloorPrice(collection); + if (floor === null) return; + + const history = this.history.get(collection) || []; + history.push({ + timestamp: new Date(), + floor, + }); + + // Keep last 100 data points + if (history.length > 100) { + history.shift(); + } + + this.history.set(collection, history); + } + + getFloorTrend(collection: string): "up" | "down" | "stable" | null { + const history = this.history.get(collection); + if (!history || history.length < 2) return null; + + const recent = history.slice(-5); + const oldAvg = recent.slice(0, 2).reduce((a, b) => a + b.floor, 0) / 2; + const newAvg = recent.slice(-2).reduce((a, b) => a + b.floor, 0) / 2; + + const change = (newAvg - oldAvg) / oldAvg; + if (change > 0.05) return "up"; + if (change < -0.05) return "down"; + return "stable"; + } + + getLowestFloor(collection: string): number | null { + const history = this.history.get(collection); + if (!history || history.length === 0) return null; + return Math.min(...history.map((h) => h.floor)); + } +} +``` + +## Error Handling + +Common errors and how to handle them: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Collection not found | Invalid name | Try aliases | +| NFT already sold | Race condition | Try next listing | +| Insufficient funds | Not enough ETH | Check balance first | +| High gas | Network congestion | Wait or use L2 | + +```typescript +async function safePurchase( + collection: string, + maxPrice: number, + bot: NftBot +): Promise { + // Check floor first + const floor = await bot.getFloorPrice(collection); + if (floor === null) { + console.error("Could not get floor price"); + return null; + } + + if (floor > maxPrice) { + console.error(`Floor (${floor}) exceeds max price (${maxPrice})`); + return null; + } + + // Attempt purchase + const result = await bot.buyFloor(collection); + + if (!result?.success) { + // Try next cheapest if floor sold + const listings = await bot.getCheapestListings(collection, 3); + const affordable = listings.filter((l) => l.price <= maxPrice); + + if (affordable.length > 0) { + // Could implement buying by token ID here + console.log("Alternative listings found:", affordable); + } + } + + return result; +} +``` + +## Chain Selection for NFTs + +```typescript +const NFT_CHAINS = { + ethereum: { majorCollections: true, highGas: true }, + base: { majorCollections: false, highGas: false }, + polygon: { majorCollections: false, highGas: false }, +}; + +function recommendChain(budget: number): string { + return budget > 1 ? "Ethereum" : "Base"; +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-portfolio` - Check ETH balance before purchases diff --git a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md new file mode 100644 index 0000000..9e1c03c --- /dev/null +++ b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md @@ -0,0 +1,368 @@ +--- +name: Bankr Polymarket (Developer Guide) +description: This skill should be used when building a prediction market bot, implementing odds monitoring, creating an auto-betting system, or tracking Polymarket positions programmatically. Covers TypeScript prompt templates like `polymarketPrompts.betYes()`, odds parsing, expected value calculations, and PolymarketBot class with alert systems. Triggered by "Polymarket bot code", "betting prompt template", "odds tracking TypeScript", "prediction market automation". +version: 1.0.0 +--- + +# Polymarket - Developer Guide + +Build bots and applications that interact with Polymarket via the Bankr API. + +## Overview + +Polymarket operations through Bankr support: +- Searching and discovering markets +- Checking odds and probabilities +- Placing bets (buying shares) +- Viewing and redeeming positions + +**Chain:** Polygon (uses USDC.e for betting) + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for Polymarket operations +const polymarketPrompts = { + // Search markets + search: (query: string) => `Search Polymarket for ${query}`, + trending: () => "What prediction markets are trending on Polymarket?", + + // Check odds + checkOdds: (event: string) => `What are the odds ${event}?`, + marketDetails: (market: string) => `Show me details for the ${market} market on Polymarket`, + + // Place bets + bet: (amount: string, outcome: string, market: string) => + `Bet ${amount} on ${outcome} for ${market}`, + betYes: (amount: string, market: string) => `Bet ${amount} on Yes for ${market}`, + betNo: (amount: string, market: string) => `Bet ${amount} on No for ${market}`, + + // Manage positions + viewPositions: () => "Show my Polymarket positions", + redeemPositions: () => "Redeem my Polymarket positions", + checkPosition: (market: string) => `Check my position on ${market}`, +}; + +// Bet amount helpers +const formatBetAmount = { + dollars: (amount: number) => `$${amount}`, + shares: (amount: number) => `${amount} shares`, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface MarketInfo { + title: string; + yesPrice: number; + noPrice: number; + volume24h?: number; + liquidity?: number; +} + +interface Position { + market: string; + outcome: string; + shares: number; + avgPrice: number; + currentValue: number; + pnl: number; +} + +// Parse market search results +function parseMarketResults(response: string): MarketInfo[] { + // Response format varies, parse accordingly + const markets: MarketInfo[] = []; + // Parse the response text to extract market info + // Example: "1. Presidential Election 2024 - 65% Yes" + const lines = response.split("\n").filter((l) => l.match(/^\d+\./)); + + for (const line of lines) { + const match = line.match(/^(\d+)\.\s+(.+?)\s+-\s+(\d+)%\s+(Yes|No)?/); + if (match) { + const yesPrice = parseInt(match[3]) / 100; + markets.push({ + title: match[2], + yesPrice, + noPrice: 1 - yesPrice, + }); + } + } + return markets; +} + +// Parse position results +function parsePositions(response: string): Position[] { + const positions: Position[] = []; + // Parse response text for position data + // Example: "- Presidential Election: 20 Yes shares ($13 value)" + const lines = response.split("\n").filter((l) => l.startsWith("-")); + + for (const line of lines) { + const match = line.match(/-\s+(.+?):\s+(\d+)\s+(Yes|No)\s+shares\s+\(\$([0-9.]+)\s+value\)/); + if (match) { + positions.push({ + market: match[1], + outcome: match[3], + shares: parseInt(match[2]), + avgPrice: 0, // Not always in response + currentValue: parseFloat(match[4]), + pnl: 0, // Calculate if needed + }); + } + } + return positions; +} + +async function handlePolymarketResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Polymarket operation successful"); + console.log(result.response); + + // Handle bet confirmations + if (result.transactions?.length) { + for (const tx of result.transactions) { + console.log(`Transaction: ${tx.type}`); + } + } + } else if (result.status === "failed") { + console.error("Polymarket operation failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Polymarket-specific types for your bot +interface PolymarketBet { + market: string; + outcome: "yes" | "no"; + amount: number; // USD + expectedShares?: number; +} + +interface BetResult { + success: boolean; + shares: number; + avgPrice: number; + totalCost: number; + market: string; + outcome: string; +} + +interface MarketOdds { + market: string; + yesPrice: number; // 0-1 + noPrice: number; // 0-1 + yesProbability: number; // Percentage + noProbability: number; + timestamp: Date; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Odds Tracker | Monitor odds changes | `What are the odds Trump wins?` | +| Auto-Bettor | Bet when odds hit target | `Bet $10 on Yes for election` | +| Arbitrage | Find mispriced markets | Search + compare odds | +| Portfolio Tracker | Monitor all positions | `Show my Polymarket positions` | +| Auto-Redeemer | Claim winning positions | `Redeem my Polymarket positions` | + +## Code Example: Prediction Market Bot + +```typescript +import { execute } from "./bankr-client"; + +interface OddsAlert { + market: string; + outcome: "yes" | "no"; + targetOdds: number; // Price at which to bet + betAmount: number; +} + +class PolymarketBot { + private alerts: OddsAlert[] = []; + + async searchMarkets(query: string): Promise { + const result = await execute(polymarketPrompts.search(query)); + return result.status === "completed" && result.response ? parseMarketResults(result.response) : []; + } + + async getOdds(event: string): Promise { + const result = await execute(polymarketPrompts.checkOdds(event)); + if (result.status !== "completed" || !result.response) return null; + + const match = result.response.match(/(\d+)%\s+Yes/); + if (!match) return null; + + const yesPct = parseInt(match[1]); + return { + market: event, + yesPrice: yesPct / 100, + noPrice: 1 - yesPct / 100, + yesProbability: yesPct, + noProbability: 100 - yesPct, + timestamp: new Date(), + }; + } + + async placeBet(bet: PolymarketBet): Promise { + const prompt = bet.outcome === "yes" + ? polymarketPrompts.betYes(`$${bet.amount}`, bet.market) + : polymarketPrompts.betNo(`$${bet.amount}`, bet.market); + + const result = await execute(prompt, (msg) => console.log(" >", msg)); + if (result.status !== "completed") return null; + + const sharesMatch = result.response?.match(/(\d+\.?\d*)\s+shares/); + const priceMatch = result.response?.match(/\$([0-9.]+)\s+each/); + + return { + success: true, + shares: sharesMatch ? parseFloat(sharesMatch[1]) : 0, + avgPrice: priceMatch ? parseFloat(priceMatch[1]) : 0, + totalCost: bet.amount, + market: bet.market, + outcome: bet.outcome, + }; + } + + async getPositions(): Promise { + const result = await execute(polymarketPrompts.viewPositions()); + return result.status === "completed" && result.response ? parsePositions(result.response) : []; + } + + async redeemPositions(): Promise { + return (await execute(polymarketPrompts.redeemPositions())).status === "completed"; + } + + addAlert(alert: OddsAlert): void { + this.alerts.push(alert); + } + + async checkAlerts(): Promise { + for (const alert of this.alerts) { + const odds = await this.getOdds(alert.market); + if (!odds) continue; + + const currentPrice = alert.outcome === "yes" ? odds.yesPrice : odds.noPrice; + if (currentPrice <= alert.targetOdds) { + await this.placeBet({ market: alert.market, outcome: alert.outcome, amount: alert.betAmount }); + this.alerts = this.alerts.filter((a) => a !== alert); + } + } + } +} + +// Usage +const bot = new PolymarketBot(); + +// Search for markets +const markets = await bot.searchMarkets("election"); +console.log("Found markets:", markets); + +// Check odds +const odds = await bot.getOdds("Trump wins the election"); +console.log("Current odds:", odds); + +// Place a bet +const betResult = await bot.placeBet({ + market: "Presidential Election 2024", + outcome: "yes", + amount: 10, +}); +console.log("Bet result:", betResult); + +// Set up alerts +bot.addAlert({ + market: "Super Bowl", + outcome: "yes", + targetOdds: 0.45, // Bet when Yes shares are at 45 cents + betAmount: 20, +}); + +// Check alerts periodically +setInterval(() => bot.checkAlerts(), 60000); +``` + +## Error Handling + +Common errors and how to handle them in bots: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Market not found | Invalid search | Try different terms | +| Insufficient USDC | Not enough funds | Check balance first | +| Market closed | Already resolved | Skip and remove | +| Low liquidity | Thin order book | Use smaller amounts | + +```typescript +async function safeBet(bot: PolymarketBot, bet: PolymarketBet): Promise { + const odds = await bot.getOdds(bet.market); + if (!odds) return null; + + const price = bet.outcome === "yes" ? odds.yesPrice : odds.noPrice; + if (price < 0.01 || price > 0.99) return null; // Market likely closed + + return bot.placeBet(bet); +} +``` + +## Calculating Expected Value + +```typescript +interface BetAnalysis { + expectedValue: number; + breakEvenProbability: number; + potentialProfit: number; + potentialLoss: number; +} + +function analyzeBet( + amount: number, + price: number, + yourProbability: number +): BetAnalysis { + // Shares you get for your bet + const shares = amount / price; + + // If you win, each share pays $1 + const potentialProfit = shares - amount; + const potentialLoss = amount; + + // Expected value + const expectedValue = yourProbability * potentialProfit - (1 - yourProbability) * potentialLoss; + + // Break-even probability (when EV = 0) + const breakEvenProbability = price; + + return { + expectedValue, + breakEvenProbability, + potentialProfit, + potentialLoss, + }; +} + +// Example: Should you bet $100 on Yes at 60 cents if you think probability is 70%? +const analysis = analyzeBet(100, 0.6, 0.7); +console.log(analysis); +// expectedValue: ~16.67 (positive = good bet) +// breakEvenProbability: 0.6 (60%) +// potentialProfit: ~66.67 +// potentialLoss: 100 +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-portfolio` - Check USDC balance for betting diff --git a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md new file mode 100644 index 0000000..312d2c2 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md @@ -0,0 +1,505 @@ +--- +name: Bankr Portfolio (Developer Guide) +description: This skill should be used when building a portfolio dashboard, implementing balance monitoring across chains, creating allocation tracking, or building a rebalancing bot. Covers TypeScript prompt templates like `portfolioPrompts.chainBalance()`, portfolio parsing utilities, change detection algorithms, and PortfolioTracker class with analytics. Triggered by "portfolio tracker code", "balance monitoring TypeScript", "multi-chain dashboard", "rebalancing automation". +version: 1.0.0 +--- + +# Portfolio - Developer Guide + +Build bots and applications that query portfolio data via the Bankr API. + +## Overview + +Portfolio operations through Bankr support: +- Total portfolio value across all chains +- Chain-specific balances +- Token-specific holdings +- Real-time USD valuations + +**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for portfolio operations +const portfolioPrompts = { + // Full portfolio + totalPortfolio: () => "Show my portfolio", + totalBalance: () => "What's my total balance?", + allHoldings: () => "List all my crypto holdings", + portfolioValue: () => "How much is my wallet worth?", + + // Chain-specific + chainBalance: (chain: string) => `Show my ${chain} balance`, + chainHoldings: (chain: string) => `What tokens do I have on ${chain}?`, + + // Token-specific + tokenBalance: (token: string) => `How much ${token} do I have?`, + tokenAcrossChains: (token: string) => `Show my ${token} on all chains`, + + // Comparisons + largestHolding: () => "What's my largest holding?", + tokenLocation: (token: string) => `Where do I have the most ${token}?`, +}; + +// Chain constants +const CHAINS = ["Base", "Polygon", "Ethereum", "Unichain", "Solana"] as const; +type Chain = (typeof CHAINS)[number]; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface TokenBalance { + token: string; + amount: number; + valueUsd: number; + chain: string; +} + +interface ChainBalance { + chain: string; + totalValueUsd: number; + tokens: TokenBalance[]; +} + +interface Portfolio { + totalValueUsd: number; + chains: ChainBalance[]; + lastUpdated: Date; +} + +// Parse full portfolio response +function parsePortfolio(response: string): Portfolio { + const portfolio: Portfolio = { + totalValueUsd: 0, + chains: [], + lastUpdated: new Date(), + }; + + // Example format: + // "Your portfolio ($12,345.67 total): + // + // Base: + // - ETH: 2.5 ($8,125.00) + // - USDC: 1,500.00 ($1,500.00)" + + // Extract total + const totalMatch = response.match(/\(\$([0-9,.]+)\s+total\)/); + if (totalMatch) { + portfolio.totalValueUsd = parseFloat(totalMatch[1].replace(",", "")); + } + + // Parse by chain + const chainSections = response.split(/\n\n(?=[A-Za-z]+:)/); + + for (const section of chainSections) { + const chainMatch = section.match(/^([A-Za-z]+):/); + if (!chainMatch) continue; + + const chainBalance: ChainBalance = { + chain: chainMatch[1], + totalValueUsd: 0, + tokens: [], + }; + + // Parse token lines + const tokenLines = section.split("\n").filter((l) => l.startsWith("-")); + for (const line of tokenLines) { + const match = line.match(/-\s+(\w+):\s+([0-9,.]+)\s+\(\$([0-9,.]+)\)/); + if (match) { + const valueUsd = parseFloat(match[3].replace(",", "")); + chainBalance.tokens.push({ + token: match[1], + amount: parseFloat(match[2].replace(",", "")), + valueUsd, + chain: chainBalance.chain, + }); + chainBalance.totalValueUsd += valueUsd; + } + } + + if (chainBalance.tokens.length > 0) { + portfolio.chains.push(chainBalance); + } + } + + return portfolio; +} + +// Parse single token balance +function parseTokenBalance(response: string, token: string): TokenBalance[] { + const balances: TokenBalance[] = []; + + // Example: "Your ETH balance: + // - Base: 2.5 ETH ($8,125.00) + // - Ethereum: 0.5 ETH ($1,625.00)" + + const lines = response.split("\n").filter((l) => l.startsWith("-")); + for (const line of lines) { + const match = line.match(/-\s+(\w+):\s+([0-9,.]+)\s+\w+\s+\(\$([0-9,.]+)\)/); + if (match) { + balances.push({ + token, + chain: match[1], + amount: parseFloat(match[2].replace(",", "")), + valueUsd: parseFloat(match[3].replace(",", "")), + }); + } + } + + return balances; +} + +async function handlePortfolioResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Portfolio query successful"); + console.log(result.response); + } else if (result.status === "failed") { + console.error("Portfolio query failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Portfolio-specific types for your bot +interface PortfolioSnapshot { + timestamp: Date; + totalValueUsd: number; + holdings: TokenBalance[]; +} + +interface BalanceChange { + token: string; + chain: string; + previousAmount: number; + currentAmount: number; + change: number; + changePercent: number; +} + +interface PortfolioAlert { + type: "balance_drop" | "balance_rise" | "token_received" | "token_sent"; + token: string; + chain: string; + amount: number; + threshold: number; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Dashboard | Display portfolio | `Show my portfolio` | +| Balance Check | Pre-trade validation | `How much ETH do I have?` | +| Chain Monitor | Track specific chain | `Show my Base balance` | +| Token Tracker | Follow specific token | `Show my USDC on all chains` | +| Alert System | Monitor for changes | Compare snapshots | + +## Code Example: Portfolio Tracker + +```typescript +import { execute } from "./bankr-client"; + +class PortfolioTracker { + private snapshots: PortfolioSnapshot[] = []; + + async getPortfolio(): Promise { + const result = await execute(portfolioPrompts.totalPortfolio()); + return result.status === "completed" && result.response ? parsePortfolio(result.response) : null; + } + + async getChainBalance(chain: string): Promise { + const result = await execute(portfolioPrompts.chainBalance(chain)); + if (result.status !== "completed" || !result.response) return null; + const portfolio = parsePortfolio(result.response); + return portfolio.chains.find((c) => c.chain.toLowerCase() === chain.toLowerCase()) || null; + } + + async getTokenBalance(token: string): Promise { + const result = await execute(portfolioPrompts.tokenBalance(token)); + return result.status === "completed" && result.response ? parseTokenBalance(result.response, token) : []; + } + + async takeSnapshot(): Promise { + const portfolio = await this.getPortfolio(); + if (!portfolio) return null; + + const snapshot: PortfolioSnapshot = { + timestamp: new Date(), + totalValueUsd: portfolio.totalValueUsd, + holdings: portfolio.chains.flatMap((c) => c.tokens), + }; + + this.snapshots.push(snapshot); + if (this.snapshots.length > 100) this.snapshots.shift(); + + return snapshot; + } + + detectChanges(): BalanceChange[] { + if (this.snapshots.length < 2) return []; + + const previous = this.snapshots[this.snapshots.length - 2]; + const current = this.snapshots[this.snapshots.length - 1]; + const changes: BalanceChange[] = []; + + for (const holding of current.holdings) { + const prev = previous.holdings.find((h) => h.token === holding.token && h.chain === holding.chain); + const previousAmount = prev?.amount || 0; + const change = holding.amount - previousAmount; + + if (Math.abs(change) > 0.0001) { + changes.push({ + token: holding.token, + chain: holding.chain, + previousAmount, + currentAmount: holding.amount, + change, + changePercent: previousAmount > 0 ? (change / previousAmount) * 100 : 100, + }); + } + } + + for (const holding of previous.holdings) { + const stillExists = current.holdings.find((h) => h.token === holding.token && h.chain === holding.chain); + if (!stillExists && holding.amount > 0.0001) { + changes.push({ + token: holding.token, + chain: holding.chain, + previousAmount: holding.amount, + currentAmount: 0, + change: -holding.amount, + changePercent: -100, + }); + } + } + + return changes; + } + + async hasEnoughBalance(token: string, amount: number, chain?: string): Promise<{ enough: boolean; available: number; chain?: string }> { + const balances = await this.getTokenBalance(token); + + if (chain) { + const chainBalance = balances.find((b) => b.chain.toLowerCase() === chain.toLowerCase()); + const available = chainBalance?.amount || 0; + return { enough: available >= amount, available, chain }; + } + + const best = [...balances].sort((a, b) => b.amount - a.amount)[0]; + return best + ? { enough: best.amount >= amount, available: best.amount, chain: best.chain } + : { enough: false, available: 0 }; + } + + getValueHistory(): { timestamp: Date; value: number }[] { + return this.snapshots.map((s) => ({ timestamp: s.timestamp, value: s.totalValueUsd })); + } +} + +// Usage +const tracker = new PortfolioTracker(); + +// Get full portfolio +const portfolio = await tracker.getPortfolio(); +console.log("Total value:", portfolio?.totalValueUsd); +console.log("Chains:", portfolio?.chains.map((c) => c.chain)); + +// Check specific token +const ethBalances = await tracker.getTokenBalance("ETH"); +console.log("ETH holdings:", ethBalances); + +// Take periodic snapshots +setInterval(async () => { + await tracker.takeSnapshot(); + const changes = tracker.detectChanges(); + if (changes.length > 0) { + console.log("Balance changes detected:", changes); + } +}, 60000); + +// Check before trading +const canTrade = await tracker.hasEnoughBalance("ETH", 0.1, "Base"); +console.log("Can trade 0.1 ETH on Base:", canTrade); +``` + +## Portfolio Analytics + +```typescript +// Portfolio analysis utilities +function calculateAllocation(portfolio: Portfolio): Map { + const allocation = new Map(); + + for (const chain of portfolio.chains) { + for (const token of chain.tokens) { + const current = allocation.get(token.token) || 0; + allocation.set(token.token, current + token.valueUsd); + } + } + + // Convert to percentages + for (const [token, value] of allocation) { + allocation.set(token, (value / portfolio.totalValueUsd) * 100); + } + + return allocation; +} + +function getTopHoldings(portfolio: Portfolio, count: number = 5): TokenBalance[] { + const allTokens = portfolio.chains.flatMap((c) => c.tokens); + return allTokens.sort((a, b) => b.valueUsd - a.valueUsd).slice(0, count); +} + +function calculateChainExposure(portfolio: Portfolio): Map { + const exposure = new Map(); + + for (const chain of portfolio.chains) { + exposure.set(chain.chain, (chain.totalValueUsd / portfolio.totalValueUsd) * 100); + } + + return exposure; +} + +// Rebalancing suggestions +interface RebalanceSuggestion { + action: "buy" | "sell"; + token: string; + amount: number; + reason: string; +} + +function suggestRebalance( + portfolio: Portfolio, + targetAllocation: Map +): RebalanceSuggestion[] { + const suggestions: RebalanceSuggestion[] = []; + const currentAllocation = calculateAllocation(portfolio); + + for (const [token, targetPct] of targetAllocation) { + const currentPct = currentAllocation.get(token) || 0; + const diff = targetPct - currentPct; + + if (Math.abs(diff) > 2) { + // Only suggest if >2% off + const amount = (Math.abs(diff) / 100) * portfolio.totalValueUsd; + suggestions.push({ + action: diff > 0 ? "buy" : "sell", + token, + amount, + reason: `Currently ${currentPct.toFixed(1)}%, target ${targetPct}%`, + }); + } + } + + return suggestions; +} +``` + +## Dashboard Data Structure + +```typescript +// Data structure for building dashboards +interface DashboardData { + summary: { + totalValueUsd: number; + totalValueChange24h: number; + totalValueChangePercent24h: number; + }; + holdings: { + token: string; + totalAmount: number; + totalValueUsd: number; + priceUsd: number; + change24h: number; + chains: { chain: string; amount: number }[]; + }[]; + chainBreakdown: { + chain: string; + valueUsd: number; + percentage: number; + tokenCount: number; + }[]; + recentActivity: BalanceChange[]; +} + +async function buildDashboardData(tracker: PortfolioTracker): Promise { + const portfolio = await tracker.getPortfolio(); + if (!portfolio) throw new Error("Failed to fetch portfolio"); + + const history = tracker.getValueHistory(); + const value24hAgo = history.length > 24 ? history[history.length - 25]?.value : history[0]?.value; + const valueChange = portfolio.totalValueUsd - (value24hAgo || portfolio.totalValueUsd); + + return { + summary: { + totalValueUsd: portfolio.totalValueUsd, + totalValueChange24h: valueChange, + totalValueChangePercent24h: value24hAgo ? (valueChange / value24hAgo) * 100 : 0, + }, + holdings: [], // Aggregate tokens across chains + chainBreakdown: portfolio.chains.map((c) => ({ + chain: c.chain, + valueUsd: c.totalValueUsd, + percentage: (c.totalValueUsd / portfolio.totalValueUsd) * 100, + tokenCount: c.tokens.length, + })), + recentActivity: tracker.detectChanges(), + }; +} +``` + +## Error Handling + +Common errors and how to handle them in bots: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Empty response | No holdings found | Return empty portfolio | +| Chain unavailable | RPC issues | Skip chain, retry later | +| Token not recognized | Unknown token in wallet | Log warning, include raw data | +| Price data unavailable | Market data gap | Use last known price or mark as stale | +| Timeout | Large portfolio | Increase timeout, paginate if possible | + +```typescript +async function safeGetPortfolio(tracker: PortfolioTracker): Promise { + try { + const portfolio = await tracker.getPortfolio(); + + if (!portfolio || portfolio.chains.length === 0) { + console.warn("Empty portfolio returned"); + return { + totalValueUsd: 0, + chains: [], + lastUpdated: new Date(), + }; + } + + return portfolio; + } catch (err) { + const error = err as Error; + + if (error.message.includes("timeout")) { + console.error("Portfolio query timed out, retrying with longer timeout"); + // Implement retry logic + } + + console.error("Portfolio error:", error.message); + return null; + } +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-token-trading` - Trade based on portfolio data +- `bankr-market-research` - Price data for valuations diff --git a/bankr-agent-dev/skills/bankr-project-templates/SKILL.md b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md new file mode 100644 index 0000000..3a58e20 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md @@ -0,0 +1,322 @@ +--- +name: Bankr Project Templates +description: This skill should be used when the user asks to "scaffold a Bankr project", "create new Bankr bot", "build a Bankr web service", "create Bankr dashboard", "build Bankr CLI tool", "project structure for Bankr", "Bankr project types", or needs guidance on directory structures and templates for different types of Bankr API integrations. +version: 1.0.0 +--- + +# Bankr Project Templates + +Directory structures and templates for Bankr API projects. + +## Available Templates + +| Template | Use Case | Key Features | +|----------|----------|--------------| +| **bot** | Automated tasks | Polling loop, scheduler, status streaming | +| **web-service** | HTTP APIs | REST endpoints, webhooks, async handling | +| **dashboard** | Web UIs | Frontend + backend, real-time updates | +| **cli** | Command-line tools | Subcommands, interactive prompts | + +## Bot Template + +For automated trading bots, price monitors, alert systems, and scheduled tasks. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # Main entry point with scheduler +│ ├── bankr-client.ts # Bankr API client (from bankr-client-patterns skill) +│ ├── types.ts # TypeScript interfaces +│ └── config.ts # Configuration loading +└── scripts/ + └── run.sh # Convenience script +``` + +### Key Features + +- **Polling loop**: Configurable interval for recurring checks +- **Status streaming**: Real-time job status updates +- **Error handling**: Automatic retries with backoff +- **Environment config**: `.env` based configuration +- **Graceful shutdown**: Handles SIGINT/SIGTERM + +### Use Cases + +- Price monitoring and alerts +- Automated trading strategies +- Portfolio rebalancing +- Scheduled market analysis +- DCA automation + +### Entry Point Pattern (index.ts) + +```typescript +import { execute } from "./bankr-client"; + +const INTERVAL = 60000; // 1 minute + +async function runBot() { + console.log("Starting Bankr bot..."); + + while (true) { + try { + const result = await execute( + "Check ETH price", + (msg) => console.log("Status:", msg) + ); + + if (result.status === "completed") { + console.log("Result:", result.response); + // Add your logic here + } + } catch (error) { + console.error("Error:", error); + } + + await new Promise(r => setTimeout(r, INTERVAL)); + } +} + +runBot(); +``` + +--- + +## Web Service Template + +For HTTP APIs that wrap or extend Bankr functionality. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # Server entry point +│ ├── server.ts # Express/Fastify server setup +│ ├── routes/ +│ │ ├── health.ts # Health check endpoint +│ │ └── bankr.ts # Bankr proxy/extension routes +│ ├── bankr-client.ts # Bankr API client +│ ├── types.ts # TypeScript interfaces +│ └── config.ts # Configuration loading +└── scripts/ + └── run.sh +``` + +### Key Features + +- **REST API endpoints**: Clean API design +- **Request validation**: Input sanitization +- **Async job handling**: Non-blocking operations +- **Webhook support**: Callbacks on job completion +- **Rate limiting**: Prevent abuse +- **CORS**: Cross-origin support + +### Use Cases + +- API gateway for Bankr +- Custom trading APIs +- Webhook integrations +- Backend for mobile apps +- Microservice architecture + +### Additional Dependencies + +```json +{ + "dependencies": { + "express": "^4.18.0" + } +} +``` + +Or for Fastify: + +```json +{ + "dependencies": { + "fastify": "^4.25.0" + } +} +``` + +--- + +## Dashboard Template + +For web UIs with portfolio tracking, market analysis, or monitoring. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── server/ +│ ├── index.ts # Backend server +│ ├── bankr-client.ts # Bankr API client +│ ├── routes/ +│ │ └── api.ts # API routes for frontend +│ └── types.ts +├── public/ +│ ├── index.html # Main HTML page +│ ├── styles.css # Basic styles +│ └── app.js # Frontend JavaScript +└── scripts/ + └── run.sh +``` + +### Key Features + +- **Simple frontend**: HTML/CSS/JS (no build step required) +- **Backend API**: Express server for Bankr operations +- **Real-time updates**: Polling for status changes +- **Portfolio display**: Token balances and values +- **Market data**: Price charts and analysis + +### Use Cases + +- Portfolio tracking dashboard +- Trading interface +- Market monitoring +- Position management +- Analytics dashboard + +### Frontend Pattern (app.js) + +```javascript +async function checkPrice() { + const response = await fetch('/api/price/ETH'); + const data = await response.json(); + document.getElementById('eth-price').textContent = data.price; +} + +setInterval(checkPrice, 30000); +checkPrice(); +``` + +--- + +## CLI Template + +For command-line tools with subcommands and interactive features. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # CLI entry with commander.js +│ ├── commands/ +│ │ ├── trade.ts # Trading commands +│ │ ├── price.ts # Price query commands +│ │ └── status.ts # Job status commands +│ ├── bankr-client.ts # Bankr API client +│ └── types.ts +└── scripts/ + └── run.sh +``` + +### Key Features + +- **Commander.js**: CLI framework with subcommands +- **Interactive prompts**: User input when needed +- **Progress indicators**: Status during polling +- **Colored output**: Better UX +- **Help system**: Auto-generated from commands + +### Use Cases + +- Personal trading tool +- Scripting and automation +- DevOps integration +- Quick price checks +- Batch operations + +### Additional Dependencies + +```json +{ + "dependencies": { + "commander": "^12.0.0" + } +} +``` + +### CLI Pattern (index.ts) + +```typescript +import { program } from "commander"; +import { price } from "./commands/price"; +import { trade } from "./commands/trade"; + +program + .name("bankr-cli") + .description("CLI for Bankr operations") + .version("1.0.0"); + +program + .command("price ") + .description("Get token price") + .action(price); + +program + .command("trade ") + .description("Execute a trade") + .option("-c, --chain ", "Target chain", "base") + .action(trade); + +program.parse(); +``` + +--- + +## Choosing a Template + +| Need | Recommended Template | +|------|---------------------| +| Automated recurring tasks | **bot** | +| HTTP API for integrations | **web-service** | +| Visual interface | **dashboard** | +| Terminal-based tool | **cli** | +| Price alerts | **bot** | +| Trading API | **web-service** | +| Portfolio viewer | **dashboard** | +| Quick trades | **cli** | + +## Common Files + +All templates share common files. Load the `bankr-client-patterns` skill for: +- `bankr-client.ts` - Complete API client +- `package.json` - Base dependencies +- `tsconfig.json` - TypeScript config +- `.env.example` - Environment template +- `.gitignore` - Standard ignores + +## Next Steps After Scaffolding + +1. **Install dependencies**: `npm install` +2. **Configure API key**: Copy `.env.example` to `.env` and add `BANKR_API_KEY` +3. **Customize**: Modify the template for your use case +4. **Run**: `npm run dev` for development +5. **Build**: `npm run build` for production diff --git a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md new file mode 100644 index 0000000..f0b23da --- /dev/null +++ b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md @@ -0,0 +1,547 @@ +--- +name: Bankr Token Deployment (Developer Guide) +description: This skill should be used when building a token deployment system, implementing Clanker integration, creating fee auto-claiming, or automating token metadata updates. Covers TypeScript prompt templates like `tokenPrompts.deployWithSocials()`, deployment result parsing, batch deployment with rate limiting, and FeeAutoClaimer class. Triggered by "token deployment bot code", "Clanker integration TypeScript", "fee claiming automation", "batch token deployment". +version: 1.0.0 +--- + +# Token Deployment - Developer Guide + +Build bots and applications that deploy and manage tokens via Clanker and the Bankr API. + +## Overview + +Token deployment through Bankr (via Clanker) supports: +- Deploy new ERC20 tokens +- Update token metadata +- Update token images +- Claim trading fees +- Manage reward recipients + +**Supported Chains:** Base (primary), Unichain (secondary) + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for token deployment operations +const tokenPrompts = { + // Deploy token + deploy: (name: string, symbol: string) => + `Deploy a token called ${name} with symbol ${symbol}`, + + deployWithDescription: (name: string, symbol: string, description: string) => + `Deploy a token called ${name} (${symbol}) with description: ${description}`, + + deployWithSocials: ( + name: string, + symbol: string, + options: { website?: string; twitter?: string; telegram?: string } + ) => { + let prompt = `Deploy token ${name} (${symbol})`; + if (options.website) prompt += ` with website ${options.website}`; + if (options.twitter) prompt += ` and Twitter @${options.twitter}`; + if (options.telegram) prompt += ` and Telegram @${options.telegram}`; + return prompt; + }, + + // Fee management + checkFees: () => "Check my Clanker fees", + claimFees: (token?: string) => + token ? `Claim fees for my token ${token}` : "Claim all my Clanker fees", + claimLegacyFees: () => "Claim legacy Clanker fees", + + // Metadata updates + updateDescription: (token: string, description: string) => + `Update description for ${token}: ${description}`, + updateSocials: (token: string, socials: { twitter?: string; website?: string }) => { + let prompt = `Update ${token}`; + if (socials.twitter) prompt += ` Twitter to @${socials.twitter}`; + if (socials.website) prompt += ` website to ${socials.website}`; + return prompt; + }, + updateImage: (token: string, imageUrl: string) => + `Update logo for ${token} to ${imageUrl}`, + + // Reward recipient + updateRewardRecipient: (token: string, address: string) => + `Update reward recipient for ${token} to ${address}`, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +interface DeployedToken { + name: string; + symbol: string; + contractAddress: string; + chain: string; + deployedAt: Date; +} + +interface TokenFees { + token: string; + symbol: string; + unclaimedAmount: number; + currency: string; +} + +// Parse deployment response +function parseDeploymentResult(response: string): DeployedToken | null { + // Example: "Token deployed successfully!\n\nName: MyToken\nSymbol: MTK\nChain: Base\nContract: 0x1234...abcd" + const nameMatch = response.match(/Name:\s*(.+)/); + const symbolMatch = response.match(/Symbol:\s*(\w+)/); + const chainMatch = response.match(/Chain:\s*(\w+)/); + const contractMatch = response.match(/Contract:\s*(0x[a-fA-F0-9]+)/); + + if (!contractMatch) return null; + + return { + name: nameMatch?.[1] || "", + symbol: symbolMatch?.[1] || "", + contractAddress: contractMatch[1], + chain: chainMatch?.[1] || "Base", + deployedAt: new Date(), + }; +} + +// Parse fees response +function parseFees(response: string): TokenFees[] { + const fees: TokenFees[] = []; + // Example: "Your unclaimed Clanker fees:\n\nMyToken (MTK): 0.5 ETH\nOtherToken (OTK): 0.1 ETH" + const lines = response.split("\n").filter((l) => l.includes(":") && l.includes("ETH")); + + for (const line of lines) { + const match = line.match(/(.+?)\s*\((\w+)\):\s*([0-9.]+)\s*(\w+)/); + if (match) { + fees.push({ + token: match[1].trim(), + symbol: match[2], + unclaimedAmount: parseFloat(match[3]), + currency: match[4], + }); + } + } + + return fees; +} + +// Parse claim response +function parseClaimResult(response: string): { amount: number; currency: string } | null { + // Example: "Fees claimed successfully!\n\nToken: MyToken (MTK)\nAmount: 0.5 ETH" + const amountMatch = response.match(/Amount:\s*([0-9.]+)\s*(\w+)/); + if (amountMatch) { + return { + amount: parseFloat(amountMatch[1]), + currency: amountMatch[2], + }; + } + return null; +} + +async function handleDeploymentResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Token operation successful"); + console.log(result.response); + + const deployed = parseDeploymentResult(result.response || ""); + if (deployed) { + console.log(`Token deployed: ${deployed.symbol} at ${deployed.contractAddress}`); + } + } else if (result.status === "failed") { + console.error("Token operation failed:", result.error); + } +} +``` + +## TypeScript Types + +```typescript +// Token deployment specific types +interface TokenConfig { + name: string; + symbol: string; + description?: string; + imageUrl?: string; + website?: string; + twitter?: string; + telegram?: string; + discord?: string; +} + +interface DeploymentResult { + success: boolean; + token?: DeployedToken; + error?: string; +} + +interface FeeClaimResult { + success: boolean; + amount: number; + currency: string; + txHash?: string; +} + +// Rate limits +const RATE_LIMITS = { + standard: 1, // tokens per day + bankrClub: 10, // tokens per day +}; +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Token Launcher | Deploy new tokens | `Deploy token MyToken (MTK)` | +| Fee Claimer | Auto-claim fees | `Claim all my Clanker fees` | +| Metadata Manager | Update token info | `Update description for MTK` | +| Batch Deployer | Launch multiple tokens | Multiple deploy calls | + +## Code Example: Token Manager + +```typescript +import { execute } from "./bankr-client"; + +class TokenManager { + private deployedTokens: DeployedToken[] = []; + + async deployToken(config: TokenConfig): Promise { + let prompt: string; + if (config.website || config.twitter || config.telegram) { + prompt = tokenPrompts.deployWithSocials(config.name, config.symbol, { + website: config.website, + twitter: config.twitter, + telegram: config.telegram, + }); + } else if (config.description) { + prompt = tokenPrompts.deployWithDescription(config.name, config.symbol, config.description); + } else { + prompt = tokenPrompts.deploy(config.name, config.symbol); + } + + const result = await execute(prompt, (msg) => console.log(" >", msg)); + if (result.status !== "completed") { + return { success: false, error: result.error || "Failed to deploy token" }; + } + + const token = parseDeploymentResult(result.response || ""); + if (!token) return { success: false, error: "Failed to parse deployment response" }; + + this.deployedTokens.push(token); + return { success: true, token }; + } + + async checkFees(): Promise { + const result = await execute(tokenPrompts.checkFees()); + return result.status === "completed" && result.response ? parseFees(result.response) : []; + } + + async claimFees(token?: string): Promise { + const result = await execute(tokenPrompts.claimFees(token)); + if (result.status !== "completed") return { success: false, amount: 0, currency: "ETH" }; + + const claimed = parseClaimResult(result.response || ""); + return claimed + ? { success: true, amount: claimed.amount, currency: claimed.currency } + : { success: false, amount: 0, currency: "ETH" }; + } + + async claimAllFees(): Promise { + const fees = await this.checkFees(); + const results: FeeClaimResult[] = []; + + for (const fee of fees) { + if (fee.unclaimedAmount > 0) { + results.push(await this.claimFees(fee.symbol)); + await new Promise((r) => setTimeout(r, 3000)); + } + } + + return results; + } + + async updateMetadata(symbol: string, updates: { description?: string; twitter?: string; website?: string }): Promise { + if (updates.description) { + const result = await execute(tokenPrompts.updateDescription(symbol, updates.description)); + if (result.status !== "completed") return false; + } + + if (updates.twitter || updates.website) { + const result = await execute(tokenPrompts.updateSocials(symbol, { twitter: updates.twitter, website: updates.website })); + if (result.status !== "completed") return false; + } + + return true; + } + + async updateImage(symbol: string, imageUrl: string): Promise { + return (await execute(tokenPrompts.updateImage(symbol, imageUrl))).status === "completed"; + } + + getDeployedTokens(): DeployedToken[] { + return this.deployedTokens; + } +} + +// Usage +const manager = new TokenManager(); + +// Deploy a token +const deployResult = await manager.deployToken({ + name: "MyAwesomeToken", + symbol: "MAT", + description: "A community token for awesome people", + website: "https://mytoken.xyz", + twitter: "mytoken", +}); + +console.log("Deployment result:", deployResult); + +// Check fees +const fees = await manager.checkFees(); +console.log("Unclaimed fees:", fees); + +// Claim all fees +const claimResults = await manager.claimAllFees(); +console.log("Claimed fees:", claimResults); + +// Update metadata +await manager.updateMetadata("MAT", { + description: "Updated description for the token", + twitter: "newhandle", +}); +``` + +## Batch Token Deployment + +```typescript +interface BatchDeployConfig { + tokens: TokenConfig[]; + delayBetween: number; // milliseconds + maxPerDay: number; +} + +class BatchDeployer { + private deployed: DeployedToken[] = []; + private deployedToday = 0; + + async deployBatch( + configs: TokenConfig[], + manager: TokenManager, + options: { delayMs: number; maxPerDay: number } + ): Promise { + const results: DeploymentResult[] = []; + + for (const config of configs) { + if (this.deployedToday >= options.maxPerDay) break; + + const result = await manager.deployToken(config); + results.push(result); + + if (result.success && result.token) { + this.deployed.push(result.token); + this.deployedToday++; + } + + await new Promise((r) => setTimeout(r, options.delayMs)); + } + + return results; + } + + resetDailyCount(): void { + this.deployedToday = 0; + } +} + +// Example: Batch deploy tokens +const deployer = new BatchDeployer(); +const tokens: TokenConfig[] = [ + { name: "Token One", symbol: "ONE" }, + { name: "Token Two", symbol: "TWO" }, + { name: "Token Three", symbol: "THREE" }, +]; + +const batchResults = await deployer.deployBatch(tokens, manager, { + delayMs: 10000, // 10 seconds between deploys + maxPerDay: RATE_LIMITS.standard, +}); +``` + +## Fee Auto-Claimer + +```typescript +interface FeeClaimerConfig { + checkInterval: number; // milliseconds + minClaimAmount: number; // minimum ETH to trigger claim + autoClaimLegacy: boolean; +} + +class FeeAutoClaimer { + private isRunning = false; + private intervalId?: NodeJS.Timeout; + + constructor(private manager: TokenManager, private config: FeeClaimerConfig) {} + + start(): void { + if (this.isRunning) return; + this.isRunning = true; + + this.intervalId = setInterval(() => this.checkAndClaim(), this.config.checkInterval); + this.checkAndClaim(); + } + + stop(): void { + if (this.intervalId) { + clearInterval(this.intervalId); + this.intervalId = undefined; + } + this.isRunning = false; + } + + private async checkAndClaim(): Promise { + const fees = await this.manager.checkFees(); + const totalUnclaimed = fees.reduce((sum, f) => sum + f.unclaimedAmount, 0); + + if (totalUnclaimed >= this.config.minClaimAmount) { + const results = await this.manager.claimAllFees(); + const totalClaimed = results.filter((r) => r.success).reduce((sum, r) => sum + r.amount, 0); + console.log(`Claimed ${totalClaimed} ETH`); + } + + if (this.config.autoClaimLegacy) { + await execute(tokenPrompts.claimLegacyFees()); + } + } +} + +// Usage +const claimer = new FeeAutoClaimer(manager, { + checkInterval: 3600000, // Check every hour + minClaimAmount: 0.01, // Claim when > 0.01 ETH accumulated + autoClaimLegacy: true, +}); + +claimer.start(); +``` + +## Token Naming Validation + +```typescript +interface NamingValidation { + valid: boolean; + errors: string[]; + suggestions?: string[]; +} + +function validateTokenConfig(config: TokenConfig): NamingValidation { + const errors: string[] = []; + const suggestions: string[] = []; + + // Check symbol + if (config.symbol.length < 2) { + errors.push("Symbol too short (min 2 characters)"); + } + if (config.symbol.length > 5) { + errors.push("Symbol too long (max 5 characters)"); + } + if (!/^[A-Z0-9]+$/.test(config.symbol.toUpperCase())) { + errors.push("Symbol should be alphanumeric"); + } + + // Check name + if (config.name.length < 2) { + errors.push("Name too short"); + } + if (config.name.length > 32) { + errors.push("Name too long (max 32 characters)"); + } + + // Check for common issues + const commonSymbols = ["ETH", "BTC", "USDC", "USDT", "SOL", "BNKR"]; + if (commonSymbols.includes(config.symbol.toUpperCase())) { + errors.push("Symbol conflicts with major token"); + suggestions.push(`Consider: ${config.symbol}2, x${config.symbol}`); + } + + return { + valid: errors.length === 0, + errors, + suggestions: suggestions.length > 0 ? suggestions : undefined, + }; +} + +// Example usage +const validation = validateTokenConfig({ + name: "My Token", + symbol: "MTK", +}); + +if (!validation.valid) { + console.log("Validation errors:", validation.errors); + if (validation.suggestions) { + console.log("Suggestions:", validation.suggestions); + } +} else { + console.log("Config is valid, ready to deploy"); +} +``` + +## Error Handling + +Common errors and how to handle them: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Rate limit reached | Daily limit exceeded | Wait 24 hours or upgrade | +| Name taken | Duplicate name | Choose different name | +| Symbol exists | Duplicate symbol | Choose different symbol | +| Image upload failed | Invalid format/size | Validate before upload | + +```typescript +async function safeDeployToken( + config: TokenConfig, + manager: TokenManager +): Promise { + // Validate first + const validation = validateTokenConfig(config); + if (!validation.valid) { + return { + success: false, + error: `Validation failed: ${validation.errors.join(", ")}`, + }; + } + + // Attempt deployment + const result = await manager.deployToken(config); + + if (!result.success) { + // Handle specific errors + if (result.error?.includes("rate limit")) { + return { + success: false, + error: "Daily deployment limit reached. Try again in 24 hours.", + }; + } + if (result.error?.includes("name taken") || result.error?.includes("symbol exists")) { + return { + success: false, + error: "Name or symbol already exists. Please choose a different one.", + }; + } + } + + return result; +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-token-trading` - Trade deployed tokens +- `bankr-market-research` - Track token performance diff --git a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md new file mode 100644 index 0000000..a19d6d8 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md @@ -0,0 +1,220 @@ +--- +name: Bankr Token Trading (Developer Guide) +description: This skill should be used when building a trading bot, implementing token swaps programmatically, creating a DCA bot, building an arbitrage system, or automating cross-chain bridges. Covers TypeScript prompt templates like `tradingPrompts.buy()`, swap response parsing, and complete TradingBot class implementation. Triggered by "trading bot code", "swap prompt template", "TypeScript trading types", "programmatic token swaps". +version: 1.0.0 +--- + +# Token Trading - Developer Guide + +Build bots and applications that trade tokens via the Bankr API. + +## Overview + +Token trading through Bankr supports: +- Same-chain swaps (buy/sell tokens) +- Cross-chain bridges and swaps +- ETH/WETH conversions +- Multiple amount formats (USD, percentage, exact) + +**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for trading operations +const tradingPrompts = { + // Same-chain swaps + buy: (amount: string, token: string, chain?: string) => + chain ? `Buy ${amount} of ${token} on ${chain}` : `Buy ${amount} of ${token}`, + + sell: (amount: string, token: string, chain?: string) => + chain ? `Sell ${amount} of ${token} on ${chain}` : `Sell ${amount} of ${token}`, + + swap: (fromAmount: string, fromToken: string, toToken: string, chain?: string) => + chain + ? `Swap ${fromAmount} ${fromToken} for ${toToken} on ${chain}` + : `Swap ${fromAmount} ${fromToken} for ${toToken}`, + + // Cross-chain + bridge: (amount: string, token: string, fromChain: string, toChain: string) => + `Bridge ${amount} ${token} from ${fromChain} to ${toChain}`, + + crossChainSwap: (fromToken: string, fromChain: string, toToken: string, toChain: string) => + `Swap ${fromToken} on ${fromChain} for ${toToken} on ${toChain}`, + + // ETH/WETH conversion + wrapEth: (amount: string) => `Convert ${amount} ETH to WETH`, + unwrapWeth: (amount: string) => `Convert ${amount} WETH to ETH`, +}; + +// Amount format helpers +const formatAmount = { + usd: (dollars: number) => `$${dollars}`, + percentage: (pct: number) => `${pct}%`, + exact: (amount: number, token: string) => `${amount} ${token}`, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +async function handleTradeResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Trade successful:", result.response); + + // Process executed transactions + if (result.transactions) { + for (const tx of result.transactions) { + const data = tx.metadata.__ORIGINAL_TX_DATA__; + if (data) { + console.log(data.humanReadableMessage); + console.log(`${data.inputTokenAmount} ${data.inputTokenTicker} → ${data.outputTokenTicker}`); + } else if (tx.metadata.description) { + console.log(tx.metadata.description); + } + } + } + } else if (result.status === "failed") { + console.error("Trade failed:", result.error); + } +} +``` + +## TypeScript Types + +Reference `bankr-client-patterns` skill for complete types. Key trading types: + +```typescript +// Transaction types for trading +type TradingTransaction = + | SwapTransaction + | ApprovalTransaction + | ConvertEthToWethTransaction + | ConvertWethToEthTransaction + | SwapCrossChainTransaction; + +// Swap transaction metadata +interface SwapMetadata { + __ORIGINAL_TX_DATA__: { + chain: string; + humanReadableMessage: string; + inputTokenAddress: string; + inputTokenAmount: string; + inputTokenTicker: string; + outputTokenAddress: string; + outputTokenAmount: string; + outputTokenTicker: string; + receiver: string; + }; + approvalRequired?: boolean; + approvalTx?: { to: string; data: string }; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| DCA Bot | Regular purchases at intervals | `Buy $100 of ETH` | +| Dip Buyer | Buy when price drops | `Buy $50 of ETH on Base` | +| Arbitrage | Cross-chain price differences | `Swap ETH on Ethereum for USDC on Polygon` | +| Rebalancer | Maintain portfolio ratios | `Sell 10% of my ETH for USDC` | +| Auto-Sell | Take profits at targets | `Sell $500 worth of BNKR` | + +## Code Example: Trading Bot + +```typescript +import { execute } from "./bankr-client"; + +interface TradeConfig { + token: string; + chain: string; + buyAmount: string; +} + +class TradingBot { + constructor(private config: TradeConfig) {} + + async executeBuy(): Promise { + const prompt = tradingPrompts.buy(`$${this.config.buyAmount}`, this.config.token, this.config.chain); + const result = await execute(prompt, (msg) => console.log(" >", msg)); + await handleTradeResponse(result); + } + + async executeSell(percentage: number): Promise { + const prompt = tradingPrompts.sell(`${percentage}%`, this.config.token, this.config.chain); + const result = await execute(prompt, (msg) => console.log(" >", msg)); + await handleTradeResponse(result); + } + + async executeSwap(fromToken: string, toToken: string, amount: string): Promise { + const prompt = tradingPrompts.swap(amount, fromToken, toToken, this.config.chain); + const result = await execute(prompt, (msg) => console.log(" >", msg)); + await handleTradeResponse(result); + } +} + +// Usage +const bot = new TradingBot({ token: "ETH", chain: "Base", buyAmount: "50" }); +await bot.executeBuy(); +``` + +## Error Handling + +Common errors and how to handle them in bots: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| Insufficient balance | Not enough funds | Log and skip, or adjust amount | +| Token not found | Invalid symbol | Verify token exists, use contract address | +| High slippage | Price moved too much | Retry with smaller amount | +| Network congestion | Chain is busy | Implement retry with backoff | + +```typescript +async function executeTradeWithRetry(prompt: string, maxRetries = 3): Promise { + for (let attempt = 1; attempt <= maxRetries; attempt++) { + const result = await execute(prompt); + + if (result.status === "completed") return result; + + const error = result.error || ""; + const isRetryable = error.includes("slippage") || error.includes("congestion"); + + if (!isRetryable || attempt === maxRetries) { + console.error(`Trade failed: ${error}`); + return result; + } + + console.log(`Attempt ${attempt} failed, retrying...`); + await new Promise((r) => setTimeout(r, 5000 * attempt)); + } + return null; +} +``` + +## Chain Selection + +```typescript +const CHAINS = { + base: { native: "ETH", lowFees: true }, + polygon: { native: "MATIC", lowFees: true }, + ethereum: { native: "ETH", lowFees: false }, + solana: { native: "SOL", lowFees: true }, + unichain: { native: "ETH", lowFees: true }, +}; + +function selectChain(preferLowFees = true): string { + return preferLowFees ? "Base" : "Ethereum"; +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-automation` - Limit orders and scheduled trades +- `bankr-market-research` - Price data for trading decisions diff --git a/bankr-agent-dev/skills/bankr-transfers/SKILL.md b/bankr-agent-dev/skills/bankr-transfers/SKILL.md new file mode 100644 index 0000000..1017882 --- /dev/null +++ b/bankr-agent-dev/skills/bankr-transfers/SKILL.md @@ -0,0 +1,323 @@ +--- +name: Bankr Transfers (Developer Guide) +description: This skill should be used when building a payment bot, implementing batch transfers, creating a tip bot, automating payroll with ENS resolution, or building a distribution system. Covers TypeScript prompt templates like `transferPrompts.toEns()`, recipient validation patterns, and PaymentBot class with batch processing. Triggered by "payment bot code", "transfer prompt template", "ENS resolution TypeScript", "batch transfer implementation". +version: 1.0.0 +--- + +# Transfers - Developer Guide + +Build bots and applications that transfer tokens via the Bankr API. + +## Overview + +Token transfers through Bankr support: +- Direct wallet addresses (0x...) +- ENS name resolution (vitalik.eth) +- Social handle resolution (@username on Twitter, Farcaster, Telegram) +- Multiple chains and token types + +**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana + +> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. + +## Prompt Templates + +```typescript +// Prompt builders for transfer operations +const transferPrompts = { + // To address + toAddress: (amount: string, token: string, address: string, chain?: string) => + chain + ? `Send ${amount} ${token} to ${address} on ${chain}` + : `Send ${amount} ${token} to ${address}`, + + // To ENS name + toEns: (amount: string, token: string, ens: string, chain?: string) => + chain + ? `Send ${amount} ${token} to ${ens} on ${chain}` + : `Send ${amount} ${token} to ${ens}`, + + // To social handle + toSocial: (amount: string, token: string, handle: string, platform: string) => + `Send ${amount} ${token} to ${handle} on ${platform}`, +}; + +// Recipient format helpers +const formatRecipient = { + address: (addr: string) => addr, + ens: (name: string) => name, + social: (handle: string, platform: string) => `@${handle.replace("@", "")} on ${platform}`, +}; +``` + +## Response Handling + +```typescript +import { execute, JobStatusResponse } from "./bankr-client"; + +async function handleTransferResponse(result: JobStatusResponse) { + if (result.status === "completed") { + console.log("Transfer successful:", result.response); + + // Process executed transactions + if (result.transactions) { + for (const tx of result.transactions) { + const data = tx.metadata.__ORIGINAL_TX_DATA__; + if (data) { + console.log(`Sent ${data.inputTokenAmount} ${data.inputTokenTicker}`); + console.log(`To: ${data.receiver}`); + console.log(`Message: ${data.humanReadableMessage}`); + } + } + } + } else if (result.status === "failed") { + console.error("Transfer failed:", result.error); + } +} + +// Extract resolved address from response +function extractResolvedAddress(result: JobStatusResponse): string | null { + if (result.transactions?.[0]) { + return result.transactions[0].metadata.__ORIGINAL_TX_DATA__.receiver; + } + return null; +} +``` + +## TypeScript Types + +Reference `bankr-client-patterns` skill for complete types. Key transfer types: + +```typescript +// Transaction types for transfers +type TransferTransaction = + | TransferEthTransaction + | TransferErc20Transaction + | TransferNftTransaction; + +// Transfer transaction metadata +interface TransferMetadata { + __ORIGINAL_TX_DATA__: { + chain: string; + humanReadableMessage: string; + inputTokenAddress: string; + inputTokenAmount: string; + inputTokenTicker: string; + receiver: string; // Resolved address + }; +} +``` + +## Bot Use Cases + +| Use Case | Description | Example Prompt | +|----------|-------------|----------------| +| Payroll Bot | Scheduled payments to team | `Send $500 USDC to 0x...` | +| Tip Bot | Reward users via social | `Send $5 ETH to @user on Twitter` | +| Distribution Bot | Airdrop to multiple addresses | `Send 100 BNKR to vitalik.eth` | +| Allowance Bot | Regular transfers to wallets | `Send 10% of my ETH to 0x...` | + +## Code Example: Payment Bot + +```typescript +import { execute } from "./bankr-client"; + +interface Payment { + recipient: string; + recipientType: "address" | "ens" | "twitter" | "farcaster"; + amount: string; + token: string; + chain?: string; +} + +class PaymentBot { + async processPayment(payment: Payment): Promise { + const prompt = this.buildPrompt(payment); + const result = await execute(prompt, (msg) => console.log(" >", msg)); + + if (result.status === "completed") { + console.log("Payment sent to:", extractResolvedAddress(result)); + return true; + } + + console.error("Payment failed:", result.error); + return false; + } + + private buildPrompt(payment: Payment): string { + const { recipient, recipientType, amount, token, chain } = payment; + + switch (recipientType) { + case "address": + case "ens": + return transferPrompts.toAddress(amount, token, recipient, chain); + case "twitter": + case "farcaster": + return transferPrompts.toSocial(amount, token, formatRecipient.social(recipient, recipientType), recipientType); + default: + return transferPrompts.toAddress(amount, token, recipient, chain); + } + } + + async processBatch(payments: Payment[]): Promise<{ success: number; failed: number }> { + let success = 0; + let failed = 0; + + for (const payment of payments) { + const result = await this.processPayment(payment); + if (result) { + success++; + } else { + failed++; + } + + // Add delay between transfers to avoid rate limiting + await new Promise((r) => setTimeout(r, 3000)); + } + + return { success, failed }; + } +} + +// Usage +const bot = new PaymentBot(); + +// Single payment +await bot.processPayment({ + recipient: "vitalik.eth", + recipientType: "ens", + amount: "0.01", + token: "ETH", + chain: "Base", +}); + +// Batch payments +const payments: Payment[] = [ + { recipient: "0x1234...", recipientType: "address", amount: "100", token: "USDC" }, + { recipient: "alice.eth", recipientType: "ens", amount: "0.05", token: "ETH" }, + { recipient: "bob", recipientType: "twitter", amount: "$10", token: "ETH" }, +]; + +const results = await bot.processBatch(payments); +console.log(`Completed: ${results.success} success, ${results.failed} failed`); +``` + +## Recipient Resolution + +Bankr resolves recipients automatically. Here's how to validate before sending: + +```typescript +// Validate recipient format +function validateRecipient(recipient: string): { + type: "address" | "ens" | "social"; + valid: boolean; + normalized: string; +} { + // Ethereum address + if (/^0x[a-fA-F0-9]{40}$/.test(recipient)) { + return { type: "address", valid: true, normalized: recipient.toLowerCase() }; + } + + // ENS name + if (recipient.endsWith(".eth")) { + return { type: "ens", valid: true, normalized: recipient.toLowerCase() }; + } + + // Social handle (starts with @) + if (recipient.startsWith("@")) { + return { type: "social", valid: true, normalized: recipient }; + } + + return { type: "address", valid: false, normalized: recipient }; +} + +// Resolution may fail for these reasons: +const RESOLUTION_ERRORS = { + ENS_NOT_FOUND: "ENS name does not exist", + NO_LINKED_WALLET: "Social handle has no linked wallet", + INVALID_ADDRESS: "Address format is invalid", +}; +``` + +## Error Handling + +Common errors and how to handle them in bots: + +| Error | Cause | Bot Response | +|-------|-------|--------------| +| ENS not found | Invalid ENS name | Verify ENS exists | +| No linked wallet | Social user hasn't linked | Skip or notify user | +| Insufficient balance | Not enough funds | Check balance first | +| Invalid address | Malformed address | Validate format | + +```typescript +async function safeTransfer( + recipient: string, + amount: string, + token: string +): Promise<{ success: boolean; error?: string }> { + const validation = validateRecipient(recipient); + if (!validation.valid) { + return { success: false, error: "Invalid recipient format" }; + } + + const result = await execute(`Send ${amount} ${token} to ${recipient}`); + + if (result.status === "completed") { + return { success: true }; + } + + const error = result.error || "Unknown error"; + if (error.includes("not found") || error.includes("no linked wallet")) { + return { success: false, error: "Recipient could not be resolved" }; + } + if (error.includes("Insufficient")) { + return { success: false, error: "Insufficient balance" }; + } + + return { success: false, error }; +} +``` + +## Security Considerations + +```typescript +// Best practices for transfer bots +const TRANSFER_LIMITS = { + maxSingleTransfer: 1000, // USD + maxDailyTotal: 10000, // USD + requireConfirmation: 500, // Above this, require extra verification +}; + +function checkTransferLimits( + amountUsd: number, + dailyTotalUsd: number +): { allowed: boolean; reason?: string } { + if (amountUsd > TRANSFER_LIMITS.maxSingleTransfer) { + return { allowed: false, reason: "Exceeds single transfer limit" }; + } + if (dailyTotalUsd + amountUsd > TRANSFER_LIMITS.maxDailyTotal) { + return { allowed: false, reason: "Exceeds daily limit" }; + } + return { allowed: true }; +} + +// Always log transfers for audit +function logTransfer(payment: Payment, result: JobStatusResponse) { + console.log(JSON.stringify({ + timestamp: new Date().toISOString(), + recipient: payment.recipient, + amount: payment.amount, + token: payment.token, + status: result.status, + jobId: result.jobId, + resolvedAddress: result.transactions?.[0]?.metadata.__ORIGINAL_TX_DATA__.receiver, + })); +} +``` + +## Related Skills + +- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-api-basics` - API fundamentals +- `bankr-portfolio` - Check balances before transfers diff --git a/bankr-agent/agents/bankr-agent.md b/bankr-agent/agents/bankr-agent.md index c28fdcf..b099ca1 100644 --- a/bankr-agent/agents/bankr-agent.md +++ b/bankr-agent/agents/bankr-agent.md @@ -23,26 +23,6 @@ description: | - - Context: User wants market analysis - user: "What are the trends in the macro crypto market?" - assistant: "I'll analyze the current crypto market trends for you." - [Uses bankr-agent for market analysis] - - Market analysis, trends, and macro crypto questions should use the bankr-agent for up-to-date information. - - - - - Context: User asks about Polymarket odds - user: "What are the odds the NYC mayor is Joe?" - assistant: "Let me check the current Polymarket odds on that prediction." - [Uses bankr-agent to query Polymarket] - - Polymarket queries about odds, probabilities, or prediction market information should use the bankr-agent. - - - Context: User wants to place a bet on Polymarket user: "Bet $5 on the Eagles to win this week" @@ -53,86 +33,74 @@ description: | - - Context: User asks about DeFi or blockchain - user: "What's the TVL on Aave?" - assistant: "Let me look up the total value locked on Aave." - [Uses bankr-agent for DeFi data] - - DeFi protocol queries, blockchain statistics, and web3 data requests should go through bankr-agent. - - - model: inherit color: green --- -You are a crypto trading and prediction market assistant powered by the Bankr API. You help users with cryptocurrency operations, market analysis, and Polymarket predictions. +# Bankr Trading & Predictions Assistant + +Help users with cryptocurrency operations, market analysis, and Polymarket predictions via the Bankr API. -**Your Core Responsibilities:** +## Your Role -1. **Crypto Trading**: Execute buy, sell, and swap operations for tokens on various chains (Base, Ethereum, Solana, etc.) -2. **Price Queries**: Get current prices for any cryptocurrency -3. **Market Analysis**: Provide insights on market trends, macro analysis, and DeFi protocols -4. **Polymarket Operations**: Check odds and place bets on prediction markets -5. **Job Management**: Track job status, show real-time updates, and handle cancellations +You are a **skill router** - identify what the user needs and load the appropriate skill for detailed guidance. Don't duplicate skill content; reference and load skills instead. -**Workflow Process:** +## Available Skills -1. **Submit the Request** - - Use `bankr_agent_submit_prompt` to send the user's request to the Bankr API - - The prompt should be the user's request in natural language - - You'll receive a job ID back +### Workflow Skills -2. **Poll for Status** - - Use `bankr_agent_get_job_status` to check on the job - - Poll every 2 seconds until the job completes - - Report any status updates to the user as they come in (the statusUpdates field) - - Continue polling until status is "completed", "failed", or "cancelled" +| User Need | Load Skill | +|-----------|------------| +| Execute request, submit prompt, poll job | `bankr-job-workflow` | +| Authentication error, API key issue, setup | `bankr-error-handling` | -3. **Report Results** - - When completed, share the response with the user - - If there are transactions, explain what was executed - - If there's rich data (images/charts), mention it +### Capability Skills -4. **Handle Errors** - - If a job fails, explain the error to the user - - Suggest alternatives if applicable +| User Need | Load Skill | +|-----------|------------| +| Buy, sell, swap, trade tokens | `bankr-token-trading` | +| Send/transfer to address, ENS, @handle | `bankr-transfers` | +| Polymarket bets, odds, positions | `bankr-polymarket` | +| Leverage, long/short, Avantis | `bankr-leverage-trading` | +| Buy NFTs, view NFT holdings | `bankr-nft-operations` | +| Balances, portfolio, holdings | `bankr-portfolio` | +| Price, analysis, sentiment, charts | `bankr-market-research` | +| Limit orders, DCA, stop-loss, schedules | `bankr-automation` | +| Deploy tokens, Clanker, claim fees | `bankr-token-deployment` | -**Status Update Handling:** +## Quick Reference -The Bankr API provides real-time status updates during processing. When polling: -- Check the `statusUpdates` array for new messages -- Report each new status update to keep the user informed -- Status updates show what the agent is currently doing (e.g., "Analyzing market data...", "Preparing transaction...") +### MCP Tools -**Cancellation:** +- `bankr_agent_submit_prompt` - Send natural language request to Bankr +- `bankr_agent_get_job_status` - Poll for job status (every 2 seconds) +- `bankr_agent_cancel_job` - Cancel a running job -If the user wants to cancel a running job: -- Use `bankr_agent_cancel_job` with the job ID -- Confirm cancellation to the user +### Supported Chains -**Output Guidelines:** +Base, Polygon, Ethereum, Unichain, Solana -- Be concise but informative -- For price queries: State the price clearly with the token symbol -- For trades: Confirm what was traded, amounts, and any transaction details -- For market analysis: Summarize key insights -- For Polymarket: State odds clearly and any relevant context -- Always report any errors clearly +### Amount Formats -**Error Handling:** +- USD: `$50` +- Percentage: `50%` +- Exact: `0.1 ETH` -If you receive an authentication error (401 or "Invalid API key"), the error message will contain detailed setup instructions. Present these instructions clearly to the user - they explain how to: -1. Create an API key at https://bankr.bot/api -2. Set the BANKR_API_KEY environment variable -3. Restart Claude Code +## Workflow -Do NOT try to retry the request or use alternative methods when authentication fails. The user must fix their API key configuration first. +1. **Identify** user need from their request +2. **Load** the appropriate capability skill for context +3. **Execute** using `bankr-job-workflow` skill pattern +4. **Handle errors** with `bankr-error-handling` skill if needed -**Important Notes:** +## Capabilities Overview -- The Bankr API handles the actual execution - you just need to submit prompts and track status -- Jobs typically complete within 30 seconds to 2 minutes -- Users can ask you to cancel jobs if they change their mind -- Be transparent about what's happening during processing +**Trading**: Buy, sell, swap tokens across chains +**Transfers**: Send to addresses, ENS, or social handles +**Polymarket**: Search markets, place bets, manage positions +**Leverage**: Long/short with Avantis on Base +**NFTs**: Browse and buy on OpenSea +**Portfolio**: Check balances across all chains +**Research**: Prices, analysis, sentiment, charts +**Automation**: Limit orders, DCA, TWAP, schedules +**Token Creation**: Deploy via Clanker, claim fees diff --git a/bankr-agent/commands/bankr-agent.md b/bankr-agent/commands/bankr-agent.md index aad5f12..ae0251d 100644 --- a/bankr-agent/commands/bankr-agent.md +++ b/bankr-agent/commands/bankr-agent.md @@ -5,10 +5,23 @@ argument-hint: [query] Send the following query to the Bankr API: $ARGUMENTS -Use the bankr-agent workflow: +Follow the `bankr-job-workflow` skill for execution: 1. Submit the query using `bankr_agent_submit_prompt` 2. Poll for status using `bankr_agent_get_job_status` every 2 seconds 3. Report status updates to the user as they come in 4. When complete, share the final response -If no query is provided, ask the user what they'd like to do with Bankr (crypto trading, price checks, market analysis, or Polymarket predictions). +For context on specific operations, load the appropriate capability skill: +- Trading: `bankr-token-trading` +- Transfers: `bankr-transfers` +- Polymarket: `bankr-polymarket` +- Leverage: `bankr-leverage-trading` +- NFTs: `bankr-nft-operations` +- Portfolio: `bankr-portfolio` +- Research: `bankr-market-research` +- Automation: `bankr-automation` +- Token deployment: `bankr-token-deployment` + +If errors occur, consult the `bankr-error-handling` skill. + +If no query is provided, ask the user what they'd like to do with Bankr (crypto trading, price checks, market analysis, Polymarket predictions, etc.). diff --git a/bankr-agent/skills/bankr-automation/SKILL.md b/bankr-agent/skills/bankr-automation/SKILL.md new file mode 100644 index 0000000..1f2df90 --- /dev/null +++ b/bankr-agent/skills/bankr-automation/SKILL.md @@ -0,0 +1,265 @@ +--- +name: Bankr Automation +description: This skill should be used when the user asks about "limit order", "stop loss", "DCA", "TWAP", "schedule", "automate", "recurring order", "price trigger", "cancel automation", "my automations", or any automated trading operation. Provides guidance on limit orders, scheduled commands, and automated strategies. +version: 1.0.0 +--- + +# Bankr Automation + +Set up automated orders and scheduled trading strategies. + +## Overview + +Bankr supports various automation types: +- **Limit Orders**: Execute at target price +- **Stop Loss**: Sell when price drops +- **DCA**: Dollar Cost Averaging +- **TWAP**: Time-Weighted Average Price +- **Scheduled Commands**: Cron-based automation +- **Solana Triggers**: Jupiter trigger orders + +## Order Types + +### Limit Orders + +Execute a trade when price reaches a target: + +``` +"Set a limit order to buy ETH at $3,000" +"Buy 0.5 ETH when price drops to $2,800" +"Limit order: sell BNKR when it hits $0.02" +``` + +**Parameters**: +- Token to buy/sell +- Target price +- Amount + +### Stop Loss Orders + +Automatically sell to limit losses: + +``` +"Set stop loss for my ETH at $2,500" +"Stop loss: sell 50% of BNKR if it drops 20%" +"Protect my SOL with stop loss at $150" +``` + +**Parameters**: +- Token to sell +- Trigger price or percentage +- Amount to sell + +### DCA (Dollar Cost Averaging) + +Invest fixed amounts at regular intervals: + +``` +"DCA $100 into ETH every week" +"Set up daily $50 Bitcoin purchases" +"Start a DCA: buy $25 of BNKR every day" +``` + +**Parameters**: +- Token to buy +- Amount per purchase +- Frequency (daily, weekly, monthly) +- Duration (optional) + +### TWAP (Time-Weighted Average Price) + +Spread a large order over time: + +``` +"TWAP: buy $1000 of ETH over 24 hours" +"Execute $500 ETH purchase using TWAP" +"Spread my sell order over 4 hours" +``` + +**Parameters**: +- Token and amount +- Total duration +- Number of intervals + +### Scheduled Commands + +Run any Bankr command on a schedule: + +``` +"Every morning, check my portfolio" +"Schedule a weekly rebalance" +"At 9am daily, check ETH price" +``` + +**Parameters**: +- Command to execute +- Schedule (cron or description) + +## Prompt Examples + +### Limit Orders + +``` +"Set a limit order to buy ETH at $3,000" +"Limit buy 0.5 BTC when price hits $90,000" +"Create limit sell for BNKR at $0.02" +"Buy SOL when it drops to $180" +``` + +### Stop Loss + +``` +"Set stop loss on my ETH at $2,800" +"Stop loss: sell all BNKR if it drops 30%" +"Protect my position with 15% stop loss" +"Stop loss for SOL at $140" +``` + +### DCA + +``` +"Set up DCA: $100 into ETH weekly" +"Start daily DCA of $50 into Bitcoin" +"DCA $25 into BNKR every day for a month" +"Begin weekly $200 ETH accumulation" +``` + +### TWAP + +``` +"TWAP buy $5000 of ETH over 48 hours" +"Spread my $2000 BTC purchase over 24 hours" +"Execute TWAP sell of 1000 USDC over 4 hours" +``` + +### Scheduled + +``` +"Every day at 9am, check ETH price" +"Weekly on Monday, show my portfolio" +"Schedule daily portfolio check" +``` + +### Managing Automations + +``` +"Show my automations" +"What limit orders do I have?" +"Cancel my ETH stop loss" +"List all my scheduled orders" +``` + +## Chain Support + +### EVM Chains (Base, Polygon, Ethereum) + +All order types supported: +- Limit orders +- Stop loss +- DCA +- TWAP +- Scheduled commands + +### Solana + +Uses Jupiter Trigger API: +- Limit orders +- Stop loss +- DCA orders + +## Automation Management + +### View Automations + +``` +"Show my automations" +"List my active orders" +"What DCA orders do I have?" +"Check my limit orders" +``` + +### Cancel Automations + +``` +"Cancel my ETH limit order" +"Remove stop loss on BNKR" +"Stop my DCA into Bitcoin" +"Cancel all my automations" +``` + +### Check History + +``` +"Show automation history" +"What orders executed today?" +"Check DCA execution history" +``` + +## Response Format + +### Order Created + +```json +{ + "status": "completed", + "response": "Limit order created:\n- Buy 0.5 ETH when price reaches $3,000\n- Order ID: lmt_ABC123\n\nYou'll be notified when it executes." +} +``` + +### Automation List + +```json +{ + "response": "Your active automations:\n\n1. Limit Order (lmt_ABC123)\n Buy 0.5 ETH at $3,000\n Status: Waiting\n\n2. DCA (dca_XYZ789)\n $100 → ETH weekly\n Next: Monday 9:00 AM\n\n3. Stop Loss (sl_DEF456)\n Sell ETH if price < $2,500\n Status: Active" +} +``` + +## Best Practices + +### Limit Orders + +- Set realistic target prices +- Consider market liquidity +- Monitor for partial fills + +### Stop Loss + +- Don't set too tight (normal volatility) +- Consider trailing stop loss for profits +- Review periodically + +### DCA + +- Good for long-term accumulation +- Reduces timing risk +- Set and forget approach + +### TWAP + +- Use for large orders +- Minimizes market impact +- Better average price + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Order not triggering | Check price threshold | +| Insufficient balance | Ensure funds available | +| Order cancelled | May expire or conflict | +| Network issues | Orders resume automatically | + +## Fees + +- **Order creation**: Minimal gas +- **Execution**: Standard trading fees +- **DCA**: Per-transaction fees apply +- **Cancellation**: Small gas cost + +## Tips + +1. **Start small** - Test with small amounts first +2. **Set alerts** - Get notified on execution +3. **Review regularly** - Update orders as needed +4. **Combine strategies** - DCA + stop loss +5. **Consider fees** - Factor into order sizes diff --git a/bankr-agent/skills/bankr-error-handling/SKILL.md b/bankr-agent/skills/bankr-error-handling/SKILL.md new file mode 100644 index 0000000..c76b6ff --- /dev/null +++ b/bankr-agent/skills/bankr-error-handling/SKILL.md @@ -0,0 +1,223 @@ +--- +name: Bankr Error Handling +description: This skill should be used when encountering authentication errors, API key errors, 401 errors, "invalid API key", "BANKR_API_KEY not set", job failures, or any Bankr API errors. Provides setup instructions and troubleshooting guidance for resolving Bankr configuration issues. +version: 1.0.0 +--- + +# Bankr Error Handling + +Resolve Bankr API errors and authentication issues. + +## Authentication Errors (401) + +The most common error is an authentication failure due to missing or invalid API key. + +### Symptoms + +- HTTP 401 status code +- Error message: "Invalid API key" or "Unauthorized" +- Job submission fails immediately + +### Resolution Steps + +Present these setup instructions clearly to the user: + +**Step 1: Create an API Key** +``` +Visit https://bankr.bot/api to create a new API key +``` + +**Step 2: Set Environment Variable** +```bash +# Add to shell profile (~/.zshrc or ~/.bashrc) +export BANKR_API_KEY=bk_your_api_key_here + +# Or create .env file in project root +BANKR_API_KEY=bk_your_api_key_here +``` + +**Step 3: Restart Claude Code** +``` +Close and reopen the terminal/Claude Code session +``` + +### Important + +- **DO NOT retry** when authentication fails +- The user must fix their API key configuration first +- Do not attempt alternative methods or workarounds + +## Job Failure Errors + +When a job completes with `status: "failed"`: + +### Check the Error Field + +The `error` field contains the failure reason: + +```json +{ + "status": "failed", + "error": "Insufficient balance for transaction" +} +``` + +### Common Job Failures + +| Error | Cause | Resolution | +|-------|-------|------------| +| Insufficient balance | Not enough tokens for trade | Check balance, reduce amount | +| Token not found | Invalid token symbol/address | Verify token exists on chain | +| Slippage exceeded | Price moved too much | Retry or increase slippage | +| Transaction reverted | On-chain execution failed | Check transaction details | +| Rate limit exceeded | Too many requests | Wait and retry | +| Unsupported operation | Feature not available | Try alternative approach | + +### Suggesting Alternatives + +When a job fails, consider: +- Reducing the trade amount +- Trying a different chain +- Splitting into smaller transactions +- Checking token liquidity + +## API Request Errors + +Errors that occur before job creation: + +### HTTP Status Codes + +| Code | Meaning | Action | +|------|---------|--------| +| 400 | Bad request | Check prompt format | +| 401 | Unauthorized | Fix API key (see above) | +| 402 | Payment required | x402 payment failed | +| 404 | Not found | Invalid endpoint | +| 429 | Rate limited | Wait and retry | +| 500 | Server error | Retry after delay | + +### x402 Payment Errors (402) + +Bankr uses x402 micropayments on Base chain: + +```json +{ + "x402Version": 1, + "error": "Payment required", + "accepts": [{ + "scheme": "exact", + "network": "base", + "asset": "0x22af33fe49fd1fa80c7149773dde5890d3c76f3b" + }] +} +``` + +**Resolution**: +- Ensure wallet has BNKR tokens on Base +- Check privateKey is configured for payments +- Typical cost: ~$0.01 USD per request + +## Troubleshooting Checklist + +When errors occur, verify: + +1. **API Key Configuration** + - [ ] BANKR_API_KEY environment variable is set + - [ ] Key starts with `bk_` + - [ ] Key is not expired or revoked + - [ ] Claude Code was restarted after setting + +2. **Network/Connectivity** + - [ ] Internet connection is working + - [ ] api.bankr.bot is reachable + - [ ] No firewall blocking requests + +3. **Request Format** + - [ ] Prompt is not empty + - [ ] Prompt is under 10,000 characters + - [ ] No invalid characters + +4. **For Trading Operations** + - [ ] Wallet has sufficient balance + - [ ] Token exists on specified chain + - [ ] Recipient address is valid (for transfers) + +## Error Response Format + +All errors follow this structure: + +```json +{ + "success": false, + "error": "Error message describing the issue", + "message": "Additional context or instructions" +} +``` + +For job failures: + +```json +{ + "success": true, + "jobId": "job_ABC123", + "status": "failed", + "error": "Specific failure reason", + "prompt": "Original request" +} +``` + +## Reporting Errors to Users + +When presenting errors: + +1. **Be clear**: State what went wrong simply +2. **Be actionable**: Provide specific fix steps +3. **Don't over-explain**: Avoid technical jargon unless needed +4. **Offer alternatives**: Suggest what they can do instead + +### Example Error Responses + +**Authentication Error**: +``` +Your Bankr API key is not configured. To set it up: +1. Visit https://bankr.bot/api to create an API key +2. Set BANKR_API_KEY in your environment +3. Restart Claude Code +``` + +**Insufficient Balance**: +``` +You don't have enough ETH for this trade. Your current balance +is 0.05 ETH but the trade requires 0.1 ETH. Try a smaller amount +or add more ETH to your wallet. +``` + +**Token Not Found**: +``` +I couldn't find a token called "XYZ" on Base. Did you mean one of these? +- XYZ Protocol (XYZ) on Ethereum +- XYZ Token (XYZT) on Polygon +``` + +## Recovery Strategies + +### For Transient Errors + +Network issues, rate limits, server errors: +- Wait 5-10 seconds +- Retry the request once +- If still failing, inform user + +### For Configuration Errors + +API key, environment issues: +- Guide user through setup +- Do not retry until fixed +- Verify fix before continuing + +### For Business Logic Errors + +Insufficient balance, unsupported operations: +- Explain the limitation +- Suggest alternatives +- Help user adjust their request diff --git a/bankr-agent/skills/bankr-job-workflow/SKILL.md b/bankr-agent/skills/bankr-job-workflow/SKILL.md new file mode 100644 index 0000000..2e0604d --- /dev/null +++ b/bankr-agent/skills/bankr-job-workflow/SKILL.md @@ -0,0 +1,183 @@ +--- +name: Bankr Job Workflow +description: This skill should be used when executing Bankr requests, submitting prompts to Bankr API, polling for job status, checking job progress, using Bankr MCP tools, or understanding the submit-poll-complete workflow pattern. Provides the core asynchronous job pattern for all Bankr API operations. +version: 1.0.0 +--- + +# Bankr Job Workflow + +Execute Bankr API operations using the asynchronous job pattern via MCP tools. + +## Core Concept + +All Bankr operations follow a **submit-poll-complete** pattern: + +1. **Submit** - Send natural language prompt, receive job ID +2. **Poll** - Check status every 2 seconds until terminal state +3. **Complete** - Report results when status is completed/failed/cancelled + +## Available MCP Tools + +### `bankr_agent_submit_prompt` + +Submit a natural language prompt to start a job. + +``` +bankr_agent_submit_prompt(prompt: string) -> { jobId: string } +``` + +**Input**: Natural language request (e.g., "Buy $50 of ETH on Base") +**Output**: Job ID for tracking (e.g., "job_ABC123...") + +### `bankr_agent_get_job_status` + +Check the current status of a job. + +``` +bankr_agent_get_job_status(jobId: string) -> JobStatusResponse +``` + +**Response fields**: +- `status`: "pending" | "processing" | "completed" | "failed" | "cancelled" +- `response`: Text answer (when completed) +- `transactions`: Array of executed transactions +- `richData`: Images or charts (base64 or URL) +- `statusUpdates`: Progress messages during execution +- `error`: Error message (when failed) + +### `bankr_agent_cancel_job` + +Cancel a running job. + +``` +bankr_agent_cancel_job(jobId: string) -> JobStatusResponse +``` + +**Note**: Cancellation is idempotent - returns success even if already cancelled. + +## Workflow Steps + +### Step 1: Submit the Request + +Submit the user's request as a natural language prompt: + +``` +1. Call bankr_agent_submit_prompt with the user's request +2. Store the returned jobId for polling +3. Inform user that request was submitted +``` + +### Step 2: Poll for Status + +Poll every 2 seconds until a terminal state: + +``` +1. Call bankr_agent_get_job_status with jobId +2. Check statusUpdates array for new messages +3. Report any new status updates to the user +4. If status is terminal (completed/failed/cancelled), proceed to Step 3 +5. Otherwise, wait 2 seconds and repeat +``` + +**Status Update Handling**: +- Track the last reported update count +- Only report NEW updates to avoid repetition +- Updates show what the agent is doing (e.g., "Analyzing market data...", "Preparing transaction...") + +### Step 3: Report Results + +Handle the terminal state appropriately: + +**If completed**: +- Share the `response` text with the user +- If `transactions` exist, explain what was executed +- If `richData` exists (images/charts), mention it's available + +**If failed**: +- Report the `error` message clearly +- Suggest alternatives if applicable +- If authentication error, load `bankr-error-handling` skill + +**If cancelled**: +- Confirm cancellation to the user + +## Job Status States + +| Status | Meaning | Action | +|--------|---------|--------| +| `pending` | Job queued, not started | Keep polling | +| `processing` | Job running | Keep polling, report statusUpdates | +| `completed` | Finished successfully | Read response and transactions | +| `failed` | Error occurred | Check error field | +| `cancelled` | User cancelled | No further action | + +## Timing Guidelines + +- **Poll interval**: 2 seconds +- **Typical completion**: 30 seconds to 2 minutes +- **Maximum wait**: 4-5 minutes before suggesting cancellation +- Jobs involving complex trades or analysis take longer + +## Output Guidelines + +Present results based on query type: + +| Query Type | Output Format | +|------------|---------------| +| Price queries | State price clearly with token symbol (e.g., "ETH is $3,245.67") | +| Trades | Confirm what was traded, amounts, transaction details | +| Market analysis | Summarize key insights concisely | +| Polymarket | State odds clearly with relevant context | +| Balances | List holdings with USD values | +| Errors | Explain clearly, suggest alternatives | + +## Cancellation + +When user requests cancellation: + +``` +1. Call bankr_agent_cancel_job with the jobId +2. Confirm cancellation to user +3. Do not continue polling +``` + +**When to suggest cancellation**: +- Job running longer than expected (>3 minutes for simple queries) +- User indicates they want to stop +- User wants to modify their request + +## Example Workflow + +``` +User: "What's the price of Bitcoin?" + +1. Submit: bankr_agent_submit_prompt("What's the price of Bitcoin?") + -> jobId: "job_XYZ789" + +2. Poll: bankr_agent_get_job_status("job_XYZ789") + -> status: "processing", statusUpdates: ["Fetching price data..."] + -> Report: "Fetching price data..." + +3. Poll again (2s later): + -> status: "completed", response: "Bitcoin (BTC) is trading at $97,245.32..." + +4. Report: "Bitcoin (BTC) is currently trading at $97,245.32" +``` + +## Error Recovery + +If polling fails or connection is lost: + +1. Retry the status check after a brief delay +2. If multiple failures, inform user of connectivity issues +3. The job continues running server-side regardless +4. Can resume polling with the same jobId + +## Integration with Capability Skills + +This workflow skill handles execution. Load the appropriate capability skill first to understand: +- What operations are supported +- Required parameters and formats +- Chain-specific considerations + +Then use this workflow to execute the request. diff --git a/bankr-agent/skills/bankr-leverage-trading/SKILL.md b/bankr-agent/skills/bankr-leverage-trading/SKILL.md new file mode 100644 index 0000000..c982c51 --- /dev/null +++ b/bankr-agent/skills/bankr-leverage-trading/SKILL.md @@ -0,0 +1,233 @@ +--- +name: Bankr Leverage Trading +description: This skill should be used when the user asks about "leverage trading", "long position", "short position", "Avantis", "derivatives", "forex trading", "commodities trading", "open a position", "close position", "stop loss", "take profit", or any leveraged trading operation. Provides guidance on Avantis perpetuals trading. +version: 1.0.0 +--- + +# Bankr Leverage Trading + +Trade with leverage using Avantis perpetuals on Base. + +## Overview + +Avantis is a decentralized perpetuals exchange offering: +- Long and short positions +- Up to 100x+ leverage +- Crypto, forex, and commodities markets +- Stop loss and take profit orders + +**Chain**: Base + +## Supported Markets + +### Crypto + +``` +BTC, ETH, SOL, ARB, AVAX, BNB, DOGE, LINK, OP, MATIC, etc. +``` + +### Forex + +``` +EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CAD, etc. +``` + +### Commodities + +``` +Gold (XAU), Silver (XAG), Oil (WTI), Natural Gas, etc. +``` + +## Operations + +### Open Long Position + +Profit when price goes up: + +``` +"Open a 5x long on ETH with $100" +"Long Bitcoin with 10x leverage" +"Buy ETH with leverage" +``` + +### Open Short Position + +Profit when price goes down: + +``` +"Short ETH with 5x leverage and $50" +"Open a short position on Bitcoin" +"Go short on Gold with 3x leverage" +``` + +### View Positions + +Check open positions: + +``` +"Show my Avantis positions" +"What leveraged positions do I have?" +"Check my open trades" +``` + +### Close Positions + +Exit a position: + +``` +"Close my ETH long" +"Exit all my Avantis positions" +"Close my Bitcoin short" +``` + +## Position Parameters + +### Leverage + +- **Default**: 1x (if not specified) +- **Range**: 1x to 100x+ depending on asset +- Higher leverage = higher risk + +``` +"Long ETH with 5x leverage" → 5x +"Short BTC 10x" → 10x +"Long SOL" → 1x (default) +``` + +### Collateral + +Specify the amount to use as collateral: + +``` +"Long ETH with $100 and 5x leverage" +"Short BTC using 0.1 ETH as collateral" +``` + +### Stop Loss + +Automatically close position to limit losses: + +``` +"Long ETH 5x with stop loss at $3000" +"Short BTC with 10% stop loss" +``` + +### Take Profit + +Automatically close position to lock in gains: + +``` +"Long ETH 5x with take profit at $4000" +"Short BTC with 20% take profit" +``` + +### Combined + +``` +"Long ETH 5x with $100, stop loss at $3000, take profit at $4000" +``` + +## Prompt Examples + +### Opening Positions + +``` +"Open a 5x long on ETH with $100" +"Short Bitcoin with 10x leverage and $50 collateral" +"Long Gold with 2x leverage" +"Go long on EUR/USD with 20x" +"Open a short position on Oil" +``` + +### With Risk Management + +``` +"Long ETH 5x with stop loss at -10%" +"Short BTC 10x with take profit at 20%" +"Long SOL 3x with SL at $150 and TP at $200" +``` + +### Checking Positions + +``` +"Show my Avantis positions" +"What leverage positions do I have open?" +"Check my PnL on Avantis" +"List my open trades" +``` + +### Closing Positions + +``` +"Close my ETH long position" +"Exit all Avantis positions" +"Close my short on Bitcoin" +``` + +## Response Handling + +### Position Opened + +```json +{ + "status": "completed", + "response": "Opened 5x long on ETH with $100 collateral. Entry: $3,245.67. Liquidation: $2,596.54", + "transactions": [{ + "type": "avantisTrade", + "metadata": { + "chainId": 8453, + "description": "Open 5x long ETH-USD" + } + }] +} +``` + +### Position Summary + +```json +{ + "response": "Your Avantis positions:\n- ETH Long 5x: +$23.45 (7.2%)\n- BTC Short 3x: -$12.30 (-4.1%)" +} +``` + +## Risk Management + +### Liquidation + +- Positions are liquidated if losses exceed collateral +- Higher leverage = closer liquidation price +- Monitor positions and use stop losses + +### Leverage Guidelines + +| Risk Level | Leverage | Use Case | +|------------|----------|----------| +| Conservative | 1-3x | Long-term views | +| Moderate | 3-10x | Swing trading | +| Aggressive | 10-25x | Short-term scalps | +| High Risk | 25x+ | Experienced only | + +### Best Practices + +1. **Start with low leverage** (2-5x) +2. **Always use stop loss** to limit downside +3. **Don't over-leverage** - position sizing matters +4. **Monitor positions** - markets move fast +5. **Understand liquidation** - know your risk + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Insufficient collateral | Add more funds | +| Asset not supported | Check available markets | +| Liquidation | Position closed, collateral lost | +| High funding rate | Consider shorter hold time | + +## Fees + +- **Opening fee**: Small percentage of position size +- **Closing fee**: Small percentage of position size +- **Funding rate**: Periodic fee based on market conditions +- Gas costs on Base (very low) + diff --git a/bankr-agent/skills/bankr-market-research/SKILL.md b/bankr-agent/skills/bankr-market-research/SKILL.md new file mode 100644 index 0000000..802bdfe --- /dev/null +++ b/bankr-agent/skills/bankr-market-research/SKILL.md @@ -0,0 +1,268 @@ +--- +name: Bankr Market Research +description: This skill should be used when the user asks about "token price", "market data", "technical analysis", "sentiment", "trending tokens", "price chart", "market cap", "token research", "what's the price of", "analyze token", or any market research query. Provides guidance on token research, analysis, and market intelligence. +version: 1.0.0 +--- + +# Bankr Market Research + +Research tokens and analyze market data. + +## Overview + +Bankr provides comprehensive market intelligence: +- Token search across chains +- Price and market data +- Technical analysis +- Social sentiment +- Price charts +- Trending tokens + +## Operations + +### Price Queries + +Get current token prices: + +``` +"What's the price of ETH?" +"How much is Bitcoin worth?" +"Check the SOL price" +``` + +### Market Data + +Get comprehensive token data: + +``` +"Show me ETH market data" +"What's the market cap of BNKR?" +"Get volume for Solana" +``` + +### Technical Analysis + +Analyze price patterns: + +``` +"Do technical analysis on ETH" +"Show RSI for Bitcoin" +"Analyze BTC price action" +``` + +### Social Sentiment + +Check community sentiment: + +``` +"What's the sentiment on ETH?" +"Is the community bullish on SOL?" +"Check social mentions for BNKR" +``` + +### Price Charts + +Generate price visualizations: + +``` +"Show me ETH price chart" +"Generate BTC chart for last week" +"Chart SOL price history" +``` + +### Trending Tokens + +Discover what's popular: + +``` +"What tokens are trending?" +"Show top gainers today" +"What's hot in crypto?" +``` + +## Prompt Examples + +### Price Queries + +``` +"What's the price of Ethereum?" +"How much is 1 BTC in USD?" +"Check BNKR price" +"What's SOL trading at?" +``` + +### Market Data + +``` +"Show market cap for ETH" +"What's the 24h volume for Bitcoin?" +"Get trading data for Solana" +"How many holders does BNKR have?" +``` + +### Technical Analysis + +``` +"Do technical analysis on Bitcoin" +"What's the RSI for ETH?" +"Analyze BTC price trends" +"Is ETH overbought?" +``` + +### Sentiment + +``` +"What's the sentiment on Solana?" +"Is the market bullish on ETH?" +"Check Twitter sentiment for BTC" +"How is the community feeling about BNKR?" +``` + +### Charts + +``` +"Show ETH price chart" +"Generate weekly BTC chart" +"Chart SOL price for last month" +"Visual of ETH performance" +``` + +### Discovery + +``` +"What tokens are trending today?" +"Show top gainers this week" +"What's hot on Base?" +"Find trending memecoins" +``` + +### Comparison + +``` +"Compare ETH vs SOL" +"Which is better: BTC or ETH?" +"Show ETH and BTC side by side" +``` + +## Data Points + +### Price Data + +| Metric | Description | +|--------|-------------| +| Price | Current USD price | +| 24h Change | Percentage change | +| 7d Change | Weekly performance | +| ATH | All-time high | +| ATL | All-time low | + +### Market Metrics + +| Metric | Description | +|--------|-------------| +| Market Cap | Total value | +| Volume (24h) | Trading volume | +| Circulating Supply | Tokens in market | +| Total Supply | All tokens | +| Holders | Number of wallets | + +### Technical Indicators + +| Indicator | Description | +|-----------|-------------| +| RSI | Relative Strength Index | +| MACD | Moving Average Convergence | +| MA | Moving Averages (50, 200) | +| Support/Resistance | Key price levels | + +## Response Format + +### Price Query + +```json +{ + "response": "Ethereum (ETH): $3,245.67\n24h: +2.3%\n7d: -1.5%\nMarket Cap: $390.2B" +} +``` + +### Technical Analysis + +```json +{ + "response": "ETH Technical Analysis:\n- RSI: 58 (Neutral)\n- MACD: Bullish crossover\n- 50 MA: $3,180 (above)\n- 200 MA: $2,950 (above)\n\nOutlook: Moderately bullish" +} +``` + +### Sentiment + +```json +{ + "response": "ETH Sentiment Analysis:\n- Social mentions: 12.5K (up 15%)\n- Sentiment: 67% Bullish\n- Key topics: ETF, staking, upgrades\n- Community mood: Optimistic" +} +``` + +### Chart + +Returns a URL or base64 image in `richData`: + +```json +{ + "response": "Here's the ETH price chart for the last 7 days:", + "richData": [{ + "type": "chart", + "url": "https://..." + }] +} +``` + +## Supported Chains + +Token research works across: +- **Base**: Native and ERC20 tokens +- **Polygon**: Native and ERC20 tokens +- **Ethereum**: All mainnet tokens +- **Solana**: SOL and SPL tokens +- **Unichain**: Emerging tokens + +## Token Search + +Find tokens by name or symbol: + +``` +"Search for BNKR token" +"Find tokens called Bankr" +"What is the contract for PEPE on Base?" +``` + +## Use Cases + +### Before Trading + +``` +"What's the price of ETH?" → Check current price +"Analyze ETH technicals" → Evaluate entry point +"Check ETH sentiment" → Gauge market mood +``` + +### Market Research + +``` +"What's trending today?" → Find opportunities +"Compare SOL vs ETH" → Evaluate options +"Show top Base tokens" → Discover new projects +``` + +### Portfolio Analysis + +``` +"How is BNKR performing?" → Track holdings +"Chart my ETH performance" → Visualize gains +"What's the outlook for SOL?" → Plan strategy +``` + +## Limitations + +- **Historical data**: Limited to available timeframes +- **Sentiment**: Based on available social data +- **New tokens**: May have limited data +- **Predictions**: Not investment advice diff --git a/bankr-agent/skills/bankr-nft-operations/SKILL.md b/bankr-agent/skills/bankr-nft-operations/SKILL.md new file mode 100644 index 0000000..eb09e1a --- /dev/null +++ b/bankr-agent/skills/bankr-nft-operations/SKILL.md @@ -0,0 +1,176 @@ +--- +name: Bankr NFT Operations +description: This skill should be used when the user asks to "buy NFT", "purchase NFT", "OpenSea", "NFT collection", "view my NFTs", "NFT holdings", "mint NFT", "NFT listings", or any NFT-related operation. Provides guidance on browsing, purchasing, and managing NFTs. +version: 1.0.0 +--- + +# Bankr NFT Operations + +Browse, purchase, and manage NFTs across chains. + +## Overview + +Bankr supports NFT operations through OpenSea integration: +- Browse NFT collections +- Find best listings +- Purchase NFTs +- View NFT holdings + +**Supported Chains**: Base, Ethereum, Polygon, and other EVM chains + +## Operations + +### Browse NFTs + +Search for NFT collections: + +``` +"Find NFTs from the Bored Ape collection" +"Search for CryptoPunks on OpenSea" +"Show me trending NFT collections" +``` + +### View Listings + +Find the best deals in a collection: + +``` +"What's the floor price for Pudgy Penguins?" +"Show cheapest NFTs in Azuki collection" +"Find listings under 0.1 ETH in Doodles" +``` + +### Buy NFTs + +Purchase an NFT: + +``` +"Buy the cheapest Bored Ape" +"Purchase this NFT: [OpenSea URL]" +"Buy floor NFT from CryptoPunks" +``` + +### View Holdings + +Check your NFT portfolio: + +``` +"Show my NFTs" +"What NFTs do I own?" +"List my NFT holdings on Base" +``` + +## Purchase Methods + +### By Collection Name + +``` +"Buy the floor NFT from Pudgy Penguins" +"Purchase cheapest NFT in Azuki collection" +``` + +### By OpenSea URL + +``` +"Buy this NFT: https://opensea.io/assets/ethereum/0x.../1234" +"Purchase the NFT at [URL]" +``` + +### By Specific Criteria + +``` +"Buy a Bored Ape under 30 ETH" +"Purchase the cheapest blue Pudgy Penguin" +``` + +## Prompt Examples + +### Browsing + +``` +"Search for NFT collections on Base" +"Find popular NFT projects" +"Show me NFTs similar to CryptoPunks" +"What are trending NFT collections?" +``` + +### Listings + +``` +"What's the floor price for Bored Apes?" +"Show the 5 cheapest NFTs in Azuki" +"Find NFT listings under 0.5 ETH" +"What are the best deals in Pudgy Penguins?" +``` + +### Buying + +``` +"Buy the cheapest NFT from Doodles" +"Purchase this OpenSea listing: [URL]" +"Buy a Bored Ape" +"Get me the floor NFT from CryptoPunks" +``` + +### Holdings + +``` +"Show my NFT collection" +"What NFTs do I own on Ethereum?" +"List my NFT holdings" +"Show NFTs in my wallet" +``` + +## Supported Operations + +- **Buy** - Purchase NFTs from marketplace listings +- **Transfer** - Send NFTs to another wallet +- **Mint** - Mint from supported platforms (Manifold, SeaDrop) +- **View** - Check your NFT holdings + +## Collection Resolution + +Bankr resolves collection names to OpenSea slugs: + +| Input | Resolved | +|-------|----------| +| "Bored Apes" | boredapeyachtclub | +| "BAYC" | boredapeyachtclub | +| "Pudgy Penguins" | pudgypenguins | +| "CryptoPunks" | cryptopunks | + +Supports common names, abbreviations, and variations. + +## Chain Considerations + +### Ethereum +- Most valuable collections +- Higher gas fees +- Primary OpenSea marketplace + +### Base +- Growing NFT ecosystem +- Very low gas fees +- Good for newer collections + +### Polygon +- Low gas costs +- Some popular collections +- Gaming NFTs + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Collection not found | Try alternative names | +| NFT already sold | Try another listing | +| Insufficient funds | Check balance | +| High gas | Wait or try L2 | + +## Safety Tips + +- **Verify collection** - Check official links +- **Check floor price** - Avoid overpaying +- **Review before buying** - Confirm the NFT +- **Beware of fakes** - Look for verified collections +- **Gas considerations** - Factor in transaction costs diff --git a/bankr-agent/skills/bankr-polymarket/SKILL.md b/bankr-agent/skills/bankr-polymarket/SKILL.md new file mode 100644 index 0000000..1d32a3f --- /dev/null +++ b/bankr-agent/skills/bankr-polymarket/SKILL.md @@ -0,0 +1,201 @@ +--- +name: Bankr Polymarket +description: This skill should be used when the user asks about "Polymarket", "prediction markets", "betting odds", "place a bet", "check odds", "market predictions", "what are the odds", "bet on election", "sports betting", or any prediction market operation. Provides guidance on searching markets, placing bets, and managing positions. +version: 1.0.0 +--- + +# Bankr Polymarket + +Interact with Polymarket prediction markets. + +## Overview + +Polymarket is a decentralized prediction market platform where users can: +- Search and discover markets +- View odds and market details +- Place bets (buy shares) +- Manage and redeem positions + +**Chain**: Polygon (requires USDC.e for betting) + +## Operations + +### Search Markets + +Find prediction markets by topic: + +``` +"Search Polymarket for election markets" +"What prediction markets are trending?" +"Find markets about the Super Bowl" +``` + +### Check Odds + +View current odds for specific events: + +``` +"What are the odds Trump wins the election?" +"Check the odds on the Eagles game" +"Show me the NYC mayor prediction" +``` + +### Place Bets + +Buy shares in a prediction outcome: + +``` +"Bet $10 on Yes for Trump winning" +"Place $5 on the Eagles to win" +"Buy shares in the election market" +``` + +### View Positions + +Check your current bets: + +``` +"Show my Polymarket positions" +"What bets do I have open?" +"Check my prediction market holdings" +``` + +### Redeem Positions + +Claim winnings from resolved markets: + +``` +"Redeem my Polymarket positions" +"Claim my winnings from the election market" +``` + +## Betting Details + +### Currency + +- Bets are placed in **USDC** (specifically USDC.e on Polygon) +- Auto-bridging: Bankr can bridge USDC from other chains if needed + +### Share System + +- You buy shares of "Yes" or "No" outcomes +- Share price reflects market probability +- If your outcome wins, shares pay $1 each +- Profit = $1 - purchase price (per share) + +### Example + +``` +Market: "Will it rain tomorrow?" +Yes shares: $0.60 (60% probability) +No shares: $0.40 (40% probability) + +Bet $10 on "Yes": +- Buy ~16.67 shares at $0.60 each +- If Yes wins: Get $16.67 (profit: $6.67) +- If No wins: Get $0 (lose $10) +``` + +## Prompt Examples + +### Searching Markets + +``` +"Search Polymarket for crypto markets" +"Find prediction markets about Bitcoin" +"What are the trending markets on Polymarket?" +"Show me sports betting markets" +``` + +### Checking Odds + +``` +"What are the odds Biden wins?" +"Check the probability of ETH reaching $5000" +"What's the current prediction for the Super Bowl?" +"Show odds for the upcoming election" +``` + +### Placing Bets + +``` +"Bet $10 on Trump winning" +"Place a $5 bet on Yes" +"Buy $20 of Yes shares on the election market" +"Bet on the Eagles to win this week" +``` + +### Managing Positions + +``` +"Show my Polymarket positions" +"What prediction market bets do I have?" +"Check my open positions" +"Redeem my winning positions" +``` + +## Response Handling + +### Market Search Results + +```json +{ + "response": "Found 5 markets about elections:\n1. Presidential Election 2024 - 65% Yes\n2. Senate Control - 52% Democrats\n..." +} +``` + +### Bet Confirmation + +```json +{ + "status": "completed", + "response": "Placed $10 bet on 'Yes' for Trump winning. Bought 15.38 shares at $0.65 each.", + "transactions": [...] +} +``` + +### Position Summary + +```json +{ + "response": "Your Polymarket positions:\n- Presidential Election: 20 Yes shares ($13 value)\n- Super Bowl: 10 No shares ($6.50 value)" +} +``` + +## Auto-Bridging + +If you don't have USDC on Polygon: + +1. Bankr detects insufficient USDC.e balance +2. Automatically bridges USDC from another chain +3. Converts to USDC.e if needed +4. Places the bet + +**Note**: This may add a small delay and gas costs. + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Market not found | Try different search terms | +| Insufficient USDC | Add USDC or let auto-bridge | +| Market closed | Can't bet on resolved markets | +| Outcome unclear | Check market details for exact outcomes | + +## Tips + +- **Research first**: Search and check odds before betting +- **Start small**: Test with small amounts first +- **Check liquidity**: Low-liquidity markets may have worse prices +- **Watch fees**: Gas costs on Polygon are low but exist +- **Redeem promptly**: Claim winnings after markets resolve + +## Market Types + +| Category | Examples | +|----------|----------| +| Politics | Elections, legislation, appointments | +| Sports | Game outcomes, championships | +| Crypto | Price predictions, ETF approvals | +| Culture | Awards, entertainment events | +| Science | Discoveries, climate events | diff --git a/bankr-agent/skills/bankr-portfolio/SKILL.md b/bankr-agent/skills/bankr-portfolio/SKILL.md new file mode 100644 index 0000000..f517a19 --- /dev/null +++ b/bankr-agent/skills/bankr-portfolio/SKILL.md @@ -0,0 +1,208 @@ +--- +name: Bankr Portfolio +description: This skill should be used when the user asks about "my balance", "portfolio", "token holdings", "check balance", "how much do I have", "wallet balance", "what tokens do I own", "show my holdings", or any balance/portfolio query. Provides guidance on checking balances across chains. +version: 1.0.0 +--- + +# Bankr Portfolio + +Query token balances and portfolio across all supported chains. + +## Overview + +Check your holdings across: +- **EVM Chains**: Base, Polygon, Ethereum, Unichain +- **Solana**: SOL and SPL tokens +- **Aggregated View**: Total portfolio value + +## Operations + +### Check Total Portfolio + +View all holdings across chains: + +``` +"Show my portfolio" +"What's my total balance?" +"How much crypto do I have?" +``` + +### Check Specific Chain + +View holdings on one chain: + +``` +"Show my Base balance" +"What do I have on Ethereum?" +"Check my Solana holdings" +``` + +### Check Specific Token + +View balance of a specific token: + +``` +"How much ETH do I have?" +"What's my USDC balance?" +"Check my BNKR holdings" +``` + +## Prompt Examples + +### Full Portfolio + +``` +"Show my portfolio" +"What's my total balance?" +"List all my crypto holdings" +"How much is my wallet worth?" +``` + +### Chain-Specific + +``` +"Show my Base balance" +"What tokens do I have on Polygon?" +"Check my Ethereum holdings" +"Show my Solana balance" +``` + +### Token-Specific + +``` +"How much ETH do I have?" +"What's my USDC balance?" +"Check my BNKR balance" +"How many SOL do I own?" +``` + +### Comparisons + +``` +"Where do I have the most ETH?" +"Which chain has my USDC?" +"Show my ETH across all chains" +``` + +## Response Format + +### Portfolio Summary + +```json +{ + "response": "Your portfolio ($12,345.67 total):\n\nBase:\n- ETH: 2.5 ($8,125.00)\n- USDC: 1,500.00 ($1,500.00)\n- BNKR: 50,000 ($500.00)\n\nEthereum:\n- ETH: 0.5 ($1,625.00)\n\nSolana:\n- SOL: 25 ($595.67)" +} +``` + +### Single Chain + +```json +{ + "response": "Your Base holdings:\n- ETH: 2.5 ($8,125.00)\n- USDC: 1,500.00 ($1,500.00)\n- BNKR: 50,000 ($500.00)\n\nTotal: $10,125.00" +} +``` + +### Single Token + +```json +{ + "response": "Your ETH balance:\n- Base: 2.5 ETH ($8,125.00)\n- Ethereum: 0.5 ETH ($1,625.00)\n- Total: 3.0 ETH ($9,750.00)" +} +``` + +## Supported Assets + +### Native Tokens + +| Chain | Token | +|-------|-------| +| Base | ETH | +| Polygon | MATIC | +| Ethereum | ETH | +| Unichain | ETH | +| Solana | SOL | + +### Common Tokens + +Bankr tracks balances for popular tokens: +- Stablecoins: USDC, USDT, DAI +- DeFi: UNI, AAVE, LINK +- Memecoins: DOGE, SHIB, PEPE +- Project tokens: BNKR, ARB, OP + +## Features + +### USD Valuation + +All balances include current USD value based on market prices. + +### Multi-Chain Aggregation + +See the same token across multiple chains: + +``` +"Show my USDC on all chains" +→ Base: 1,000 USDC +→ Polygon: 500 USDC +→ Ethereum: 250 USDC +→ Total: 1,750 USDC +``` + +### Real-Time Prices + +Values reflect current market prices at query time. + +## Use Cases + +### Before Trading + +Check if you have enough balance: + +``` +"Do I have enough ETH to swap for 100 USDC?" +"Check my USDC balance before I place a bet" +``` + +### Portfolio Review + +Regular check-ins on holdings: + +``` +"How's my portfolio doing?" +"What's my largest holding?" +"Show portfolio breakdown by chain" +``` + +### After Transactions + +Verify transaction completed: + +``` +"Did my ETH arrive?" +"Show my new BNKR balance" +``` + +## Common Questions + +### "How much [token] do I have?" + +Returns balance across all chains with USD value. + +### "What's my balance on [chain]?" + +Returns all token holdings on that specific chain. + +### "Show my portfolio" + +Returns complete breakdown by chain with USD totals. + +### "What tokens do I own?" + +Lists all tokens with non-zero balance. + +## Notes + +- **Read-only operation**: Balance queries don't execute transactions +- **Real-time data**: Prices and balances are current +- **All wallets**: Shows balance of connected wallet address +- **Dust filtering**: Very small balances may be excluded diff --git a/bankr-agent/skills/bankr-token-deployment/SKILL.md b/bankr-agent/skills/bankr-token-deployment/SKILL.md new file mode 100644 index 0000000..f9677c2 --- /dev/null +++ b/bankr-agent/skills/bankr-token-deployment/SKILL.md @@ -0,0 +1,271 @@ +--- +name: Bankr Token Deployment +description: This skill should be used when the user asks to "deploy token", "create token", "launch token", "Clanker", "claim fees", "token metadata", "update token", "mint new token", or any token deployment operation. Provides guidance on deploying ERC20 tokens via Clanker. +version: 1.0.0 +--- + +# Bankr Token Deployment + +Deploy and manage ERC20 tokens using Clanker. + +## Overview + +Clanker enables token deployment on: +- **Base**: Primary deployment chain +- **Unichain**: Secondary option + +## Operations + +### Deploy Token + +Create a new ERC20 token: + +``` +"Deploy a token called MyToken with symbol MTK" +"Create a new memecoin called DOGE2" +"Launch a token named BankrFan" +``` + +### Claim Fees + +Collect unclaimed trading fees: + +``` +"Claim fees for my token" +"Check unclaimed Clanker fees" +"Collect my token rewards" +``` + +### Update Metadata + +Modify token information: + +``` +"Update my token description" +"Change token social links" +"Add audit URL to my token" +``` + +### Update Image + +Change token logo: + +``` +"Update my token image" +"Change logo for MyToken" +``` + +## Deployment Details + +### Required Parameters + +| Parameter | Description | Example | +|-----------|-------------|---------| +| Name | Token name | "MyToken" | +| Symbol | Ticker (3-5 chars) | "MTK" | + +### Optional Parameters + +| Parameter | Description | +|-----------|-------------| +| Description | Token description | +| Image | Logo URL or upload | +| Website | Project website | +| Twitter | Twitter/X handle | +| Telegram | Telegram group | +| Discord | Discord server | + +## Prompt Examples + +### Deploying + +``` +"Deploy a token called BankrFan with symbol BFAN" +"Create a memecoin: name=DogeKiller, symbol=DOGEK" +"Launch a token named CryptoGems (GEMS)" +"Deploy new token: MyProject (PROJ)" +``` + +### With Metadata + +``` +"Deploy token MyToken (MTK) with description 'Community token for fans'" +"Create token with website myproject.com and Twitter @myproject" +"Launch token with logo [image URL]" +``` + +### Fee Management + +``` +"Claim fees for my token MTK" +"Check my Clanker fees" +"How much in unclaimed fees do I have?" +"Claim all my token fees" +``` + +### Legacy Fees + +``` +"Claim legacy Clanker fees" +"Check old token fees" +``` + +### Metadata Updates + +``` +"Update description for MyToken" +"Add Twitter link to my token" +"Update audit URL for MTK" +"Change my token's website" +``` + +### Image Updates + +``` +"Update logo for MyToken" +"Change my token image to [URL]" +``` + +### Reward Recipient + +``` +"Update reward recipient for my token" +"Change fee collection address" +``` + +## Rate Limits + +| User Type | Daily Limit | +|-----------|-------------| +| Standard Users | 1 token/day | +| Bankr Club Members | 10 tokens/day | + +## Response Format + +### Deployment Success + +```json +{ + "status": "completed", + "response": "Token deployed successfully!\n\nName: MyToken\nSymbol: MTK\nChain: Base\nContract: 0x1234...abcd\n\nYour token is now live and tradeable!", + "transactions": [{ + "type": "deploy_token", + "metadata": {...} + }] +} +``` + +### Fee Claim + +```json +{ + "response": "Fees claimed successfully!\n\nToken: MyToken (MTK)\nAmount: 0.5 ETH\nTransaction: 0x..." +} +``` + +### Fee Check + +```json +{ + "response": "Your unclaimed Clanker fees:\n\nMyToken (MTK): 0.5 ETH\nOtherToken (OTK): 0.1 ETH\n\nTotal: 0.6 ETH" +} +``` + +## Token Lifecycle + +### 1. Planning + +Before deploying: +- Choose memorable name and symbol +- Prepare logo/branding +- Write token description +- Set up social links + +### 2. Deployment + +``` +"Deploy token MyToken (MTK)" +``` + +Token is created with: +- Initial supply +- Trading enabled on DEX +- Fee mechanism active + +### 3. Management + +After deployment: +- Update metadata as needed +- Claim fees regularly +- Engage community + +## Fee Structure + +### Trading Fees + +- Small fee on each trade +- Accumulated for token creator +- Claimable anytime + +### Legacy Fees + +- Fees from older Clanker versions +- Claim separately with legacy command +- Base chain only + +## Best Practices + +### Naming + +- **Unique**: Stand out from others +- **Memorable**: Easy to remember +- **Clear**: Avoid confusion with established tokens + +### Symbol + +- 3-5 characters recommended +- All caps convention +- Avoid existing symbols + +### Metadata + +- Add description immediately +- Include social links +- Upload quality logo + +### Fee Management + +- Claim fees regularly +- Monitor trading activity +- Consider reinvestment + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Rate limit reached | Wait 24 hours or upgrade | +| Name taken | Choose different name | +| Symbol exists | Use unique symbol | +| Image upload failed | Check format/size | + +## Supported Chains + +### Base (Primary) + +- Full Clanker support +- Legacy fee claims +- Most liquidity + +### Unichain + +- Token deployment +- Fee management +- Growing ecosystem + +## Tips + +1. **Research first** - Check if name/symbol exists +2. **Quality branding** - Good logo matters +3. **Complete metadata** - Fill all fields +4. **Claim regularly** - Don't leave fees unclaimed +5. **Engage community** - Build around your token diff --git a/bankr-agent/skills/bankr-token-trading/SKILL.md b/bankr-agent/skills/bankr-token-trading/SKILL.md new file mode 100644 index 0000000..a325c8c --- /dev/null +++ b/bankr-agent/skills/bankr-token-trading/SKILL.md @@ -0,0 +1,180 @@ +--- +name: Bankr Token Trading +description: This skill should be used when the user asks to "buy crypto", "sell tokens", "swap ETH", "trade on Base", "exchange tokens", "cross-chain swap", "bridge tokens", "convert ETH to WETH", or any token trading operation. Provides guidance on supported chains, amount formats, and swap operations. +version: 1.0.0 +--- + +# Bankr Token Trading + +Execute token trades and swaps across multiple blockchains. + +## Supported Chains + +| Chain | Network | Native Token | +|-------|---------|--------------| +| Base | EVM | ETH | +| Polygon | EVM | MATIC | +| Ethereum | EVM (Mainnet) | ETH | +| Unichain | EVM | ETH | +| Solana | Solana | SOL | + +## Operations + +### Same-Chain Swaps + +Trade tokens on the same blockchain: + +``` +"Swap 0.1 ETH for USDC on Base" +"Buy $50 of BNKR on Base" +"Sell 100 USDC for ETH" +``` + +### Cross-Chain Swaps + +Trade tokens across different blockchains: + +``` +"Bridge 0.5 ETH from Ethereum to Base" +"Swap ETH on Mainnet for SOL on Solana" +"Move 100 USDC from Polygon to Base" +``` + +### ETH/WETH Conversion + +Convert between native ETH and wrapped ETH: + +``` +"Convert 0.1 ETH to WETH" +"Unwrap 0.5 WETH to ETH" +``` + +## Amount Formats + +Bankr accepts three amount formats: + +| Format | Example | Description | +|--------|---------|-------------| +| USD | `$50` | Dollar amount to spend | +| Percentage | `50%` | Percentage of your balance | +| Exact | `0.1 ETH` | Specific token amount | + +### Examples + +``` +"Buy $50 of ETH" → Spends $50 USD worth +"Sell 25% of my BNKR" → Sells quarter of holdings +"Swap 0.1 ETH for USDC" → Swaps exactly 0.1 ETH +``` + +## Trading Prompts + +### Buying Tokens + +``` +"Buy $100 of ETH on Base" +"Buy 0.05 ETH worth of BNKR" +"Purchase some Solana" +``` + +### Selling Tokens + +``` +"Sell all my BNKR for ETH" +"Sell $50 worth of USDC" +"Sell 50% of my ETH holdings" +``` + +### Swapping Tokens + +``` +"Swap 0.1 ETH for USDC on Base" +"Exchange 100 USDC for BNKR" +"Trade my MATIC for ETH on Polygon" +``` + +### Cross-Chain Operations + +``` +"Bridge 1 ETH from Mainnet to Base" +"Swap ETH on Ethereum for USDC on Polygon" +"Move my USDC from Polygon to Solana" +``` + +## Chain Selection + +### Default Behavior + +- If no chain specified, Bankr selects the most appropriate chain +- Base is preferred for most operations due to low fees +- Cross-chain routes are automatically optimized + +### Specifying Chains + +Include chain name in the prompt: + +``` +"Buy ETH on Polygon" +"Swap tokens on Ethereum mainnet" +"Trade SOL on Solana" +``` + +## Slippage + +- Default slippage tolerance is applied automatically +- For volatile tokens, Bankr adjusts slippage as needed +- If slippage is exceeded, the transaction fails safely + +## Response Handling + +Successful trades return: + +```json +{ + "status": "completed", + "response": "Successfully swapped 0.1 ETH for 324.56 USDC on Base", + "transactions": [{ + "type": "swap", + "metadata": { + "__ORIGINAL_TX_DATA__": { + "humanReadableMessage": "Swap 0.1 ETH for USDC", + "inputTokenTicker": "ETH", + "outputTokenTicker": "USDC", + "inputTokenAmount": "0.1", + "outputTokenAmount": "324.56" + } + } + }] +} +``` + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| Insufficient balance | Reduce amount or add funds | +| Token not found | Check token symbol/address | +| High slippage | Try smaller amounts | +| Network congestion | Wait and retry | + +## Example Prompts + +**Simple trades:** +- "Buy $50 of ETH" +- "Sell my BNKR for USDC" +- "Swap 0.1 ETH for USDC" + +**Chain-specific:** +- "Buy ETH on Base" +- "Swap SOL for USDC on Solana" +- "Trade on Polygon" + +**Cross-chain:** +- "Bridge ETH from Mainnet to Base" +- "Move USDC to Solana" +- "Swap ETH on Ethereum for SOL" + +**Advanced:** +- "Sell 50% of my ETH holdings" +- "Buy $100 of BNKR and stake it" +- "Convert all my WETH to ETH" diff --git a/bankr-agent/skills/bankr-transfers/SKILL.md b/bankr-agent/skills/bankr-transfers/SKILL.md new file mode 100644 index 0000000..d8b64d5 --- /dev/null +++ b/bankr-agent/skills/bankr-transfers/SKILL.md @@ -0,0 +1,146 @@ +--- +name: Bankr Transfers +description: This skill should be used when the user asks to "send tokens", "transfer ETH", "send to ENS", "transfer to wallet", "send to @username", "transfer to Farcaster", "send to Twitter handle", or any asset transfer operation. Provides guidance on recipient resolution and transfer formats. +version: 1.0.0 +--- + +# Bankr Transfers + +Transfer tokens to addresses, ENS names, or social handles. + +## Supported Transfers + +### EVM Chains +- Native tokens (ETH, MATIC) +- ERC20 tokens (USDC, BNKR, etc.) +- Supported on: Base, Polygon, Ethereum, Unichain + +### Solana +- Native SOL +- SPL tokens + +## Recipient Formats + +Bankr resolves recipients from multiple formats: + +| Format | Example | Description | +|--------|---------|-------------| +| Address | `0x1234...abcd` | Direct wallet address | +| ENS | `vitalik.eth` | Ethereum Name Service | +| Twitter | `@elonmusk` | Twitter/X username | +| Farcaster | `@dwr.eth` | Farcaster username | +| Telegram | `@username` | Telegram handle | + +### Resolution Priority + +When using social handles, Bankr: +1. Looks up the username on the platform +2. Finds their linked wallet address +3. Validates the address before sending + +## Transfer Prompts + +### To Address + +``` +"Send 0.1 ETH to 0x1234567890abcdef..." +"Transfer 100 USDC to 0xabcd..." +``` + +### To ENS Name + +``` +"Send 0.5 ETH to vitalik.eth" +"Transfer USDC to mydomain.eth" +``` + +### To Social Handle + +``` +"Send $50 of ETH to @elonmusk on Twitter" +"Transfer 0.1 ETH to @dwr.eth on Farcaster" +"Send 100 USDC to @username on Telegram" +``` + +## Amount Formats + +Same as trading - three formats supported: + +| Format | Example | Description | +|--------|---------|-------------| +| USD | `$50` | Dollar amount | +| Percentage | `50%` | Percentage of balance | +| Exact | `0.1 ETH` | Specific amount | + +### Examples + +``` +"Send $100 worth of ETH to vitalik.eth" +"Transfer 50% of my USDC to @friend" +"Send exactly 0.5 ETH to 0x..." +``` + +## Chain Selection + +### Automatic + +If not specified, Bankr selects the appropriate chain: +- Checks where recipient has activity +- Considers gas costs +- Prefers Base for low fees + +### Manual + +Specify chain in the prompt: + +``` +"Send ETH on Base to vitalik.eth" +"Transfer USDC on Polygon to 0x..." +"Send SOL on Solana to @username" +``` + +## Supported Transfer Types + +- **Native tokens** - ETH, MATIC, etc. +- **ERC20 tokens** - USDC, USDT, any token +- **NFTs** - See NFT Operations skill + +## Common Issues + +| Issue | Resolution | +|-------|------------| +| ENS not found | Verify the ENS name exists | +| Social handle not found | Check username is correct | +| No linked wallet | User hasn't linked wallet to social | +| Insufficient balance | Reduce amount or add funds | +| Invalid address | Check address format | + +## Security Notes + +- Always verify recipient before confirming +- Double-check addresses for transfers +- Social handle resolution shows the resolved address +- Large transfers may require additional confirmation + +## Example Prompts + +**To addresses:** +- "Send 0.5 ETH to 0x1234..." +- "Transfer 100 USDC to 0xabcd..." + +**To ENS:** +- "Send 1 ETH to vitalik.eth" +- "Transfer $50 of USDC to mydomain.eth" + +**To social handles:** +- "Send $20 of ETH to @friend on Twitter" +- "Transfer 0.1 ETH to @user on Farcaster" +- "Send USDC to @contact on Telegram" + +**With chain specified:** +- "Send ETH on Base to vitalik.eth" +- "Transfer USDC on Polygon to @friend" + +**Percentage amounts:** +- "Send 10% of my ETH to @friend" +- "Transfer half my USDC to vitalik.eth" From 9a77bfd1e01651a36bbd96d7381f42052d956ba7 Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 16:06:29 +0400 Subject: [PATCH 2/8] standardize skill names with plugin prefixes Add consistent naming convention across all plugins: - bankr-agent: "Bankr Agent - " - bankr-agent-dev: "Bankr Dev - " - x402-sdk-dev: "Bankr x402 SDK - " --- bankr-agent-dev/skills/bankr-api-basics/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-automation/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-client-patterns/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-market-research/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-nft-operations/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-polymarket/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-portfolio/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-project-templates/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-token-deployment/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-token-trading/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-transfers/SKILL.md | 2 +- bankr-agent/skills/bankr-automation/SKILL.md | 2 +- bankr-agent/skills/bankr-error-handling/SKILL.md | 2 +- bankr-agent/skills/bankr-job-workflow/SKILL.md | 2 +- bankr-agent/skills/bankr-leverage-trading/SKILL.md | 2 +- bankr-agent/skills/bankr-market-research/SKILL.md | 2 +- bankr-agent/skills/bankr-nft-operations/SKILL.md | 2 +- bankr-agent/skills/bankr-polymarket/SKILL.md | 2 +- bankr-agent/skills/bankr-portfolio/SKILL.md | 2 +- bankr-agent/skills/bankr-token-deployment/SKILL.md | 2 +- bankr-agent/skills/bankr-token-trading/SKILL.md | 2 +- bankr-agent/skills/bankr-transfers/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-balance-queries/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-capabilities/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-job-management/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-token-swaps/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md index 0ecd01a..d02be76 100644 --- a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md +++ b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr API Basics +name: Bankr Dev - API Basics description: Provides Bankr Agent API documentation including endpoints, job patterns, and TypeScript interfaces. Triggered by questions about "Bankr API", "Bankr Agent API", "how does Bankr work", "Bankr job status", "Bankr response format", or "building on Bankr". version: 0.1.0 --- diff --git a/bankr-agent-dev/skills/bankr-automation/SKILL.md b/bankr-agent-dev/skills/bankr-automation/SKILL.md index d25a1b4..b57302e 100644 --- a/bankr-agent-dev/skills/bankr-automation/SKILL.md +++ b/bankr-agent-dev/skills/bankr-automation/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Automation (Developer Guide) +name: Bankr Dev - Automation description: This skill should be used when building a limit order system, implementing DCA strategies programmatically, creating TWAP execution, or building a grid trading bot. Covers TypeScript prompt templates like `automationPrompts.dca()`, automation ID parsing, DcaStrategyBuilder and GridTradingBot classes, and retry patterns. Triggered by "limit order bot code", "DCA automation TypeScript", "TWAP implementation", "grid trading bot". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md b/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md index b1e40ae..4e466c9 100644 --- a/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md +++ b/bankr-agent-dev/skills/bankr-client-patterns/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Client Patterns +name: Bankr Dev - Client Patterns description: This skill should be used when the user asks to "implement Bankr client", "write bankr-client.ts", "create API client for Bankr", "common files for Bankr project", "package.json for Bankr", "tsconfig for Bankr", "Bankr TypeScript patterns", "Bankr response types", or needs the reusable client code and common project files for Bankr API integrations. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md index be0d01d..8f64df2 100644 --- a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Leverage Trading (Developer Guide) +name: Bankr Dev - Leverage Trading description: This skill should be used when building a leverage trading bot, implementing perpetual position management, creating risk management systems with stop-loss automation, or building an Avantis integration. Covers TypeScript prompt templates like `leveragePrompts.openLongWithRisk()`, liquidation price calculations, position PnL parsing, and LeverageTradingBot class with risk parameters. Triggered by "leverage bot code", "perpetual trading TypeScript", "Avantis integration", "stop loss automation". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-market-research/SKILL.md b/bankr-agent-dev/skills/bankr-market-research/SKILL.md index d7eb1c1..4f585fb 100644 --- a/bankr-agent-dev/skills/bankr-market-research/SKILL.md +++ b/bankr-agent-dev/skills/bankr-market-research/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Market Research (Developer Guide) +name: Bankr Dev - Market Research description: This skill should be used when building a price alert system, implementing technical analysis automation, creating sentiment tracking, or building a trending token discovery bot. Covers TypeScript prompt templates like `marketPrompts.technicalAnalysis()`, price/TA/sentiment parsing, trading signal generation, and MarketMonitor class with alert callbacks. Triggered by "price alert bot code", "market research TypeScript", "sentiment tracking automation", "technical analysis implementation". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md index 111852c..edb6b12 100644 --- a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md +++ b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr NFT Operations (Developer Guide) +name: Bankr Dev - NFT Operations description: This skill should be used when building an NFT sniping bot, implementing floor price monitoring, creating a collection sweeper, or automating NFT purchases via OpenSea. Covers TypeScript prompt templates like `nftPrompts.buyFloor()`, floor tracking with trend detection, and NftBot class with watchlist management. Triggered by "NFT bot code", "floor sweeper TypeScript", "OpenSea automation", "NFT sniping implementation". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md index 9e1c03c..4f0362c 100644 --- a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md +++ b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Polymarket (Developer Guide) +name: Bankr Dev - Polymarket description: This skill should be used when building a prediction market bot, implementing odds monitoring, creating an auto-betting system, or tracking Polymarket positions programmatically. Covers TypeScript prompt templates like `polymarketPrompts.betYes()`, odds parsing, expected value calculations, and PolymarketBot class with alert systems. Triggered by "Polymarket bot code", "betting prompt template", "odds tracking TypeScript", "prediction market automation". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md index 312d2c2..13ff3af 100644 --- a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md +++ b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Portfolio (Developer Guide) +name: Bankr Dev - Portfolio description: This skill should be used when building a portfolio dashboard, implementing balance monitoring across chains, creating allocation tracking, or building a rebalancing bot. Covers TypeScript prompt templates like `portfolioPrompts.chainBalance()`, portfolio parsing utilities, change detection algorithms, and PortfolioTracker class with analytics. Triggered by "portfolio tracker code", "balance monitoring TypeScript", "multi-chain dashboard", "rebalancing automation". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-project-templates/SKILL.md b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md index 3a58e20..b030035 100644 --- a/bankr-agent-dev/skills/bankr-project-templates/SKILL.md +++ b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Project Templates +name: Bankr Dev - Project Templates description: This skill should be used when the user asks to "scaffold a Bankr project", "create new Bankr bot", "build a Bankr web service", "create Bankr dashboard", "build Bankr CLI tool", "project structure for Bankr", "Bankr project types", or needs guidance on directory structures and templates for different types of Bankr API integrations. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md index f0b23da..59bf4bf 100644 --- a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Token Deployment (Developer Guide) +name: Bankr Dev - Token Deployment description: This skill should be used when building a token deployment system, implementing Clanker integration, creating fee auto-claiming, or automating token metadata updates. Covers TypeScript prompt templates like `tokenPrompts.deployWithSocials()`, deployment result parsing, batch deployment with rate limiting, and FeeAutoClaimer class. Triggered by "token deployment bot code", "Clanker integration TypeScript", "fee claiming automation", "batch token deployment". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md index a19d6d8..360a2dd 100644 --- a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Token Trading (Developer Guide) +name: Bankr Dev - Token Trading description: This skill should be used when building a trading bot, implementing token swaps programmatically, creating a DCA bot, building an arbitrage system, or automating cross-chain bridges. Covers TypeScript prompt templates like `tradingPrompts.buy()`, swap response parsing, and complete TradingBot class implementation. Triggered by "trading bot code", "swap prompt template", "TypeScript trading types", "programmatic token swaps". version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-transfers/SKILL.md b/bankr-agent-dev/skills/bankr-transfers/SKILL.md index 1017882..3aaed43 100644 --- a/bankr-agent-dev/skills/bankr-transfers/SKILL.md +++ b/bankr-agent-dev/skills/bankr-transfers/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Transfers (Developer Guide) +name: Bankr Dev - Transfers description: This skill should be used when building a payment bot, implementing batch transfers, creating a tip bot, automating payroll with ENS resolution, or building a distribution system. Covers TypeScript prompt templates like `transferPrompts.toEns()`, recipient validation patterns, and PaymentBot class with batch processing. Triggered by "payment bot code", "transfer prompt template", "ENS resolution TypeScript", "batch transfer implementation". version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-automation/SKILL.md b/bankr-agent/skills/bankr-automation/SKILL.md index 1f2df90..b80c100 100644 --- a/bankr-agent/skills/bankr-automation/SKILL.md +++ b/bankr-agent/skills/bankr-automation/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Automation +name: Bankr Agent - Automation description: This skill should be used when the user asks about "limit order", "stop loss", "DCA", "TWAP", "schedule", "automate", "recurring order", "price trigger", "cancel automation", "my automations", or any automated trading operation. Provides guidance on limit orders, scheduled commands, and automated strategies. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-error-handling/SKILL.md b/bankr-agent/skills/bankr-error-handling/SKILL.md index c76b6ff..36ede96 100644 --- a/bankr-agent/skills/bankr-error-handling/SKILL.md +++ b/bankr-agent/skills/bankr-error-handling/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Error Handling +name: Bankr Agent - Error Handling description: This skill should be used when encountering authentication errors, API key errors, 401 errors, "invalid API key", "BANKR_API_KEY not set", job failures, or any Bankr API errors. Provides setup instructions and troubleshooting guidance for resolving Bankr configuration issues. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-job-workflow/SKILL.md b/bankr-agent/skills/bankr-job-workflow/SKILL.md index 2e0604d..ffe9cb1 100644 --- a/bankr-agent/skills/bankr-job-workflow/SKILL.md +++ b/bankr-agent/skills/bankr-job-workflow/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Job Workflow +name: Bankr Agent - Job Workflow description: This skill should be used when executing Bankr requests, submitting prompts to Bankr API, polling for job status, checking job progress, using Bankr MCP tools, or understanding the submit-poll-complete workflow pattern. Provides the core asynchronous job pattern for all Bankr API operations. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-leverage-trading/SKILL.md b/bankr-agent/skills/bankr-leverage-trading/SKILL.md index c982c51..4e14461 100644 --- a/bankr-agent/skills/bankr-leverage-trading/SKILL.md +++ b/bankr-agent/skills/bankr-leverage-trading/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Leverage Trading +name: Bankr Agent - Leverage Trading description: This skill should be used when the user asks about "leverage trading", "long position", "short position", "Avantis", "derivatives", "forex trading", "commodities trading", "open a position", "close position", "stop loss", "take profit", or any leveraged trading operation. Provides guidance on Avantis perpetuals trading. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-market-research/SKILL.md b/bankr-agent/skills/bankr-market-research/SKILL.md index 802bdfe..55f9b2f 100644 --- a/bankr-agent/skills/bankr-market-research/SKILL.md +++ b/bankr-agent/skills/bankr-market-research/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Market Research +name: Bankr Agent - Market Research description: This skill should be used when the user asks about "token price", "market data", "technical analysis", "sentiment", "trending tokens", "price chart", "market cap", "token research", "what's the price of", "analyze token", or any market research query. Provides guidance on token research, analysis, and market intelligence. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-nft-operations/SKILL.md b/bankr-agent/skills/bankr-nft-operations/SKILL.md index eb09e1a..9f7e8ed 100644 --- a/bankr-agent/skills/bankr-nft-operations/SKILL.md +++ b/bankr-agent/skills/bankr-nft-operations/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr NFT Operations +name: Bankr Agent - NFT Operations description: This skill should be used when the user asks to "buy NFT", "purchase NFT", "OpenSea", "NFT collection", "view my NFTs", "NFT holdings", "mint NFT", "NFT listings", or any NFT-related operation. Provides guidance on browsing, purchasing, and managing NFTs. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-polymarket/SKILL.md b/bankr-agent/skills/bankr-polymarket/SKILL.md index 1d32a3f..c7fdd22 100644 --- a/bankr-agent/skills/bankr-polymarket/SKILL.md +++ b/bankr-agent/skills/bankr-polymarket/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Polymarket +name: Bankr Agent - Polymarket description: This skill should be used when the user asks about "Polymarket", "prediction markets", "betting odds", "place a bet", "check odds", "market predictions", "what are the odds", "bet on election", "sports betting", or any prediction market operation. Provides guidance on searching markets, placing bets, and managing positions. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-portfolio/SKILL.md b/bankr-agent/skills/bankr-portfolio/SKILL.md index f517a19..0e70b0b 100644 --- a/bankr-agent/skills/bankr-portfolio/SKILL.md +++ b/bankr-agent/skills/bankr-portfolio/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Portfolio +name: Bankr Agent - Portfolio description: This skill should be used when the user asks about "my balance", "portfolio", "token holdings", "check balance", "how much do I have", "wallet balance", "what tokens do I own", "show my holdings", or any balance/portfolio query. Provides guidance on checking balances across chains. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-token-deployment/SKILL.md b/bankr-agent/skills/bankr-token-deployment/SKILL.md index f9677c2..3603d90 100644 --- a/bankr-agent/skills/bankr-token-deployment/SKILL.md +++ b/bankr-agent/skills/bankr-token-deployment/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Token Deployment +name: Bankr Agent - Token Deployment description: This skill should be used when the user asks to "deploy token", "create token", "launch token", "Clanker", "claim fees", "token metadata", "update token", "mint new token", or any token deployment operation. Provides guidance on deploying ERC20 tokens via Clanker. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-token-trading/SKILL.md b/bankr-agent/skills/bankr-token-trading/SKILL.md index a325c8c..4acc001 100644 --- a/bankr-agent/skills/bankr-token-trading/SKILL.md +++ b/bankr-agent/skills/bankr-token-trading/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Token Trading +name: Bankr Agent - Token Trading description: This skill should be used when the user asks to "buy crypto", "sell tokens", "swap ETH", "trade on Base", "exchange tokens", "cross-chain swap", "bridge tokens", "convert ETH to WETH", or any token trading operation. Provides guidance on supported chains, amount formats, and swap operations. version: 1.0.0 --- diff --git a/bankr-agent/skills/bankr-transfers/SKILL.md b/bankr-agent/skills/bankr-transfers/SKILL.md index d8b64d5..1a9265e 100644 --- a/bankr-agent/skills/bankr-transfers/SKILL.md +++ b/bankr-agent/skills/bankr-transfers/SKILL.md @@ -1,5 +1,5 @@ --- -name: Bankr Transfers +name: Bankr Agent - Transfers description: This skill should be used when the user asks to "send tokens", "transfer ETH", "send to ENS", "transfer to wallet", "send to @username", "transfer to Farcaster", "send to Twitter handle", or any asset transfer operation. Provides guidance on recipient resolution and transfer formats. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md index 8feface..25d1af4 100644 --- a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md +++ b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Balance Queries +name: Bankr x402 SDK - Balance Queries description: This skill should be used when the user asks "what are my balances", "how much ETH do I have", "check my wallet", "show my tokens", "portfolio value", "what tokens do I own", "NFT holdings", "how much USDC", "get token balances", "wallet contents", or any question about token balances, wallet contents, portfolio values, or NFT holdings across chains using the Bankr SDK. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md index 955b962..bcc8305 100644 --- a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md +++ b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Capabilities +name: Bankr x402 SDK - Capabilities description: This skill should be used when the user asks "what can the SDK do", "what prompts does Bankr support", "SDK features", "supported operations", "what can I build with Bankr", "Bankr SDK capabilities", "what chains are supported", "what tokens can I trade", "SDK supported commands", or wants to understand the full range of operations available through the Bankr SDK. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-job-management/SKILL.md b/x402-sdk-dev/skills/sdk-job-management/SKILL.md index 959640a..9a50cb8 100644 --- a/x402-sdk-dev/skills/sdk-job-management/SKILL.md +++ b/x402-sdk-dev/skills/sdk-job-management/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Job Management +name: Bankr x402 SDK - Job Management description: This skill should be used when the user asks about "job status", "check if request completed", "cancel request", "why is my request taking so long", "poll for result", "batch requests", "retry failed request", "request timeout", "async operations", "job lifecycle", "manual polling", or needs advanced control over SDK async operations, manual job polling, batch processing, retry logic, or job cancellation. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md index f299078..9c4d3f5 100644 --- a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md +++ b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Token Swaps +name: Bankr x402 SDK - Token Swaps description: This skill should be used when the user asks to "swap tokens", "exchange ETH for USDC", "buy DEGEN", "sell tokens", "swap on Base", "trade crypto", "convert ETH to WETH", "exchange tokens", "token swap code", "0x routing", or any token swap operation. Also use for questions about ERC20 approvals, allowanceTarget, swap transaction execution, or building swap transactions with the Bankr SDK. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md index 9aacf51..908b598 100644 --- a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md +++ b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Transaction Builder +name: Bankr x402 SDK - Transaction Builder description: This skill should be used when the user asks to "send tokens", "transfer ETH", "send USDC to", "transfer NFT", "wrap ETH", "unwrap WETH", "bridge tokens", "mint NFT", "buy NFT", "approve token", "build transaction", "DeFi transaction", or needs to build transactions for transfers, approvals, NFT operations, cross-chain bridges, ETH/WETH conversions, or DeFi interactions beyond simple swaps using the Bankr SDK. version: 1.0.0 --- diff --git a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md index 8afc42d..0cc13f6 100644 --- a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md +++ b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md @@ -1,5 +1,5 @@ --- -name: SDK Wallet Operations +name: Bankr x402 SDK - Wallet Operations description: This skill should be used when the user asks to "set up the SDK", "initialize BankrClient", "configure wallet", "set up payment wallet", "connect wallet to Bankr", "get wallet address", "set up environment variables", "configure private key", "two wallet setup", "separate payment and trading wallets", or needs help with SDK client initialization, two-wallet configuration, wallet address derivation, environment setup, or BankrClient options. version: 1.0.0 --- From 2a43b03e8fa42ae408457143607195abc497130a Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 17:36:35 +0400 Subject: [PATCH 3/8] refactor: simplify all skills for agent API pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unnecessary implementation code from skills across all plugins. Agent APIs (like Bankr) accept natural language prompts - skills should focus on what prompts work, not how to parse responses. Removed: - Full bot class implementations - Response parsing code - Complex TypeScript types - Retry logic patterns - Duplicate prompt examples - JSON response structures (in user-facing skills) Kept: - Prompt patterns and templates - Operations tables - Simple usage examples - Supported chains/capabilities - Related skills references Changes: - bankr-agent-dev: 9 capability skills simplified (~67% reduction) - bankr-agent: 11 user skills simplified (~67% reduction) - x402-sdk-dev: 6 SDK skills simplified (~78% reduction) - bankr-api-basics: description format fix Total: ~9,825 → 2,986 lines (-70%) --- .../skills/bankr-api-basics/SKILL.md | 2 +- .../skills/bankr-automation/SKILL.md | 508 ++------------- .../skills/bankr-leverage-trading/SKILL.md | 440 +------------ .../skills/bankr-market-research/SKILL.md | 603 ++---------------- .../skills/bankr-nft-operations/SKILL.md | 415 +----------- .../skills/bankr-polymarket/SKILL.md | 367 +---------- .../skills/bankr-portfolio/SKILL.md | 512 +-------------- .../skills/bankr-token-deployment/SKILL.md | 558 ++-------------- .../skills/bankr-token-trading/SKILL.md | 223 +------ .../skills/bankr-transfers/SKILL.md | 325 +--------- bankr-agent/skills/bankr-automation/SKILL.md | 254 +------- .../skills/bankr-error-handling/SKILL.md | 183 +----- .../skills/bankr-job-workflow/SKILL.md | 170 +---- .../skills/bankr-leverage-trading/SKILL.md | 220 +------ .../skills/bankr-market-research/SKILL.md | 267 ++------ .../skills/bankr-nft-operations/SKILL.md | 164 +---- bankr-agent/skills/bankr-polymarket/SKILL.md | 191 +----- bankr-agent/skills/bankr-portfolio/SKILL.md | 211 +----- .../skills/bankr-token-deployment/SKILL.md | 263 +------- .../skills/bankr-token-trading/SKILL.md | 154 +---- bankr-agent/skills/bankr-transfers/SKILL.md | 111 +--- .../skills/sdk-balance-queries/SKILL.md | 309 ++------- x402-sdk-dev/skills/sdk-capabilities/SKILL.md | 427 ++----------- .../skills/sdk-job-management/SKILL.md | 399 ++---------- x402-sdk-dev/skills/sdk-token-swaps/SKILL.md | 429 ++----------- .../skills/sdk-transaction-builder/SKILL.md | 424 ++---------- .../skills/sdk-wallet-operations/SKILL.md | 506 ++------------- 27 files changed, 898 insertions(+), 7737 deletions(-) diff --git a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md index d02be76..6ca0f9c 100644 --- a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md +++ b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - API Basics -description: Provides Bankr Agent API documentation including endpoints, job patterns, and TypeScript interfaces. Triggered by questions about "Bankr API", "Bankr Agent API", "how does Bankr work", "Bankr job status", "Bankr response format", or "building on Bankr". +description: This skill should be used when the user asks about "Bankr API", "Bankr Agent API", "how does Bankr work", "Bankr job status", "Bankr response format", or "building on Bankr". Provides endpoint documentation, job patterns, and TypeScript interfaces. version: 0.1.0 --- diff --git a/bankr-agent-dev/skills/bankr-automation/SKILL.md b/bankr-agent-dev/skills/bankr-automation/SKILL.md index b57302e..2a7edd6 100644 --- a/bankr-agent-dev/skills/bankr-automation/SKILL.md +++ b/bankr-agent-dev/skills/bankr-automation/SKILL.md @@ -1,503 +1,67 @@ --- name: Bankr Dev - Automation -description: This skill should be used when building a limit order system, implementing DCA strategies programmatically, creating TWAP execution, or building a grid trading bot. Covers TypeScript prompt templates like `automationPrompts.dca()`, automation ID parsing, DcaStrategyBuilder and GridTradingBot classes, and retry patterns. Triggered by "limit order bot code", "DCA automation TypeScript", "TWAP implementation", "grid trading bot". +description: Automated order capability via the Bankr API. Create limit orders, stop losses, DCA schedules, and TWAP execution. Triggered by "automation prompts", "limit orders", "DCA patterns", "scheduled orders". version: 1.0.0 --- -# Automation - Developer Guide +# Automation Capability -Build bots and applications that create and manage automated orders via the Bankr API. +Create and manage automated orders via natural language prompts. -## Overview +## What You Can Do -Automation through Bankr supports: -- Limit orders (buy/sell at target price) -- Stop loss orders (sell on price drop) -- DCA (Dollar Cost Averaging) -- TWAP (Time-Weighted Average Price) -- Scheduled commands -- Solana trigger orders (Jupiter) +| Operation | Example Prompt | +|-----------|----------------| +| Limit buy | `Set a limit order to buy ETH at $3,000` | +| Limit buy with amount | `Set a limit order to buy $500 of ETH at $3,000` | +| Limit sell | `Limit sell my ETH when it hits $4,000` | +| Stop loss (price) | `Set stop loss for my ETH at $2,800` | +| Stop loss (percent) | `Stop loss: sell ETH if it drops 10%` | +| DCA | `DCA $100 into ETH every week` | +| DCA with duration | `DCA $50 into BTC every day for 1 month` | +| TWAP buy | `TWAP buy $5000 of ETH over 24 hours` | +| TWAP sell | `TWAP sell 1 ETH over 4 hours` | +| Scheduled command | `Every Monday, buy $100 of ETH` | +| View automations | `Show my automations` | +| View limit orders | `What limit orders do I have?` | +| Cancel automation | `Cancel automation abc123` | +| Cancel all | `Cancel all my automations` | -**Supported Chains:** Base, Polygon, Ethereum (EVM), Solana (Jupiter triggers) +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for automation operations -const automationPrompts = { - // Limit orders - limitBuy: (token: string, price: string, amount?: string) => - amount - ? `Set a limit order to buy ${amount} of ${token} at ${price}` - : `Set a limit order to buy ${token} at ${price}`, - - limitSell: (token: string, price: string, amount?: string) => - amount - ? `Limit sell ${amount} ${token} when it hits ${price}` - : `Limit sell ${token} when it hits ${price}`, - - // Stop loss - stopLoss: (token: string, price: string) => - `Set stop loss for my ${token} at ${price}`, - - stopLossPercent: (token: string, percent: number) => - `Stop loss: sell ${token} if it drops ${percent}%`, - - // DCA - dca: (amount: string, token: string, frequency: string) => - `DCA ${amount} into ${token} ${frequency}`, - - dcaWithDuration: (amount: string, token: string, frequency: string, duration: string) => - `DCA ${amount} into ${token} ${frequency} for ${duration}`, - - // TWAP - twap: (amount: string, token: string, duration: string) => - `TWAP buy ${amount} of ${token} over ${duration}`, - - twapSell: (amount: string, token: string, duration: string) => - `TWAP sell ${amount} ${token} over ${duration}`, - - // Scheduled commands - schedule: (command: string, schedule: string) => - `${schedule}, ${command}`, - - // Management - viewAutomations: () => "Show my automations", - viewLimitOrders: () => "What limit orders do I have?", - viewDcaOrders: () => "Show my DCA orders", - cancelAutomation: (id: string) => `Cancel automation ${id}`, - cancelAll: () => "Cancel all my automations", - - // History - automationHistory: () => "Show automation history", - executedOrders: () => "What orders executed today?", -}; - -// Frequency helpers -const FREQUENCIES = { - hourly: "every hour", - daily: "every day", - weekly: "every week", - monthly: "every month", - custom: (cron: string) => cron, -}; ``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface Automation { - id: string; - type: "limit" | "stop_loss" | "dca" | "twap" | "scheduled"; - token: string; - status: "active" | "triggered" | "cancelled" | "expired"; - params: Record; - createdAt: Date; - nextExecution?: Date; -} - -function parseAutomationCreated(response: string): { id: string; type: string } | null { - const idMatch = response.match(/Order ID:\s*(\w+)/i) || response.match(/ID:\s*(\w+)/i); - if (!idMatch) return null; - - const lower = response.toLowerCase(); - let type = "scheduled"; - if (lower.includes("limit")) type = "limit"; - else if (lower.includes("dca")) type = "dca"; - else if (lower.includes("stop")) type = "stop_loss"; - else if (lower.includes("twap")) type = "twap"; - - return { id: idMatch[1], type }; -} - -function parseAutomations(response: string): Automation[] { - const automations: Automation[] = []; - const sections = response.split(/\n\n?\d+\./); - - for (const section of sections) { - const idMatch = section.match(/\((\w+)\)/); - const statusMatch = section.match(/Status:\s*(\w+)/i); - if (!idMatch) continue; - - const lower = section.toLowerCase(); - let type: Automation["type"] = "scheduled"; - if (lower.includes("limit")) type = "limit"; - else if (lower.includes("dca")) type = "dca"; - else if (lower.includes("stop")) type = "stop_loss"; - else if (lower.includes("twap")) type = "twap"; - - automations.push({ - id: idMatch[1], - type, - token: "", - status: (statusMatch?.[1].toLowerCase() as Automation["status"]) || "active", - params: {}, - createdAt: new Date(), - }); - } - - return automations; -} - -async function handleAutomationResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Automation operation successful"); - console.log(result.response); - - const created = parseAutomationCreated(result.response || ""); - if (created) { - console.log(`Created ${created.type} automation: ${created.id}`); - } - } else if (result.status === "failed") { - console.error("Automation operation failed:", result.error); - } -} +Set a limit order to buy {token} at {price} +Set stop loss for my {token} at {price|percent} +DCA {amount} into {token} {frequency} [for {duration}] +TWAP buy {amount} of {token} over {duration} +Show my automations +Cancel automation {id} ``` -## TypeScript Types +**Frequencies:** every hour, every day, every week, every month -```typescript -// Automation-specific types -interface LimitOrderConfig { - token: string; - side: "buy" | "sell"; - price: number; - amount?: number; - amountUsd?: number; - expiresIn?: string; // e.g., "24h", "7d" -} - -interface StopLossConfig { - token: string; - triggerPrice?: number; - triggerPercent?: number; - sellAmount?: number; // Percentage of holdings -} - -interface DcaConfig { - token: string; - amountUsd: number; - frequency: "hourly" | "daily" | "weekly" | "monthly"; - duration?: string; // e.g., "1 month", "indefinite" - startDate?: Date; -} +**Supported chains:** Base, Polygon, Ethereum (EVM), Solana (Jupiter triggers) -interface TwapConfig { - token: string; - side: "buy" | "sell"; - totalAmount: number; - duration: string; // e.g., "24 hours", "4 hours" - intervals?: number; -} - -interface AutomationResult { - success: boolean; - automationId?: string; - type: string; - message: string; -} -``` - -## Bot Use Cases - -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Limit Order Bot | Entry/exit at prices | `Set limit order to buy ETH at $3,000` | -| Risk Manager | Auto stop losses | `Set stop loss for my ETH at $2,800` | -| DCA Bot | Regular accumulation | `DCA $100 into ETH every week` | -| Large Order Bot | Execute with TWAP | `TWAP buy $5000 of ETH over 24 hours` | -| Portfolio Bot | Scheduled rebalancing | Schedule rebalance commands | - -## Code Example: Automation Manager +## Usage ```typescript import { execute } from "./bankr-client"; -interface ManagedAutomation { - id: string; - type: string; - config: LimitOrderConfig | StopLossConfig | DcaConfig | TwapConfig; - createdAt: Date; - status: "active" | "triggered" | "cancelled"; -} - -class AutomationManager { - private automations: Map = new Map(); - - private async createAutomation( - type: string, - prompt: string, - config: LimitOrderConfig | StopLossConfig | DcaConfig | TwapConfig - ): Promise { - const result = await execute(prompt, (msg) => console.log(" >", msg)); - if (result.status !== "completed") { - return { success: false, type, message: result.error || `Failed to create ${type}` }; - } - - const created = parseAutomationCreated(result.response || ""); - if (!created) { - return { success: false, type, message: `Failed to parse ${type} response` }; - } - - this.automations.set(created.id, { id: created.id, type, config, createdAt: new Date(), status: "active" }); - return { success: true, automationId: created.id, type, message: result.response || `${type} created` }; - } - - async createLimitOrder(config: LimitOrderConfig): Promise { - const prompt = config.side === "buy" - ? automationPrompts.limitBuy(config.token, `$${config.price}`, config.amountUsd ? `$${config.amountUsd}` : undefined) - : automationPrompts.limitSell(config.token, `$${config.price}`, config.amount ? `${config.amount}` : undefined); - return this.createAutomation("limit", prompt, config); - } - - async createStopLoss(config: StopLossConfig): Promise { - const prompt = config.triggerPrice - ? automationPrompts.stopLoss(config.token, `$${config.triggerPrice}`) - : automationPrompts.stopLossPercent(config.token, config.triggerPercent || 10); - return this.createAutomation("stop_loss", prompt, config); - } - - async createDca(config: DcaConfig): Promise { - const prompt = config.duration - ? automationPrompts.dcaWithDuration(`$${config.amountUsd}`, config.token, FREQUENCIES[config.frequency], config.duration) - : automationPrompts.dca(`$${config.amountUsd}`, config.token, FREQUENCIES[config.frequency]); - return this.createAutomation("dca", prompt, config); - } - - async createTwap(config: TwapConfig): Promise { - const prompt = config.side === "buy" - ? automationPrompts.twap(`$${config.totalAmount}`, config.token, config.duration) - : automationPrompts.twapSell(`${config.totalAmount}`, config.token, config.duration); - return this.createAutomation("twap", prompt, config); - } - - async refreshAutomations(): Promise { - const result = await execute(automationPrompts.viewAutomations()); - return result.status === "completed" && result.response ? parseAutomations(result.response) : []; - } - - async cancelAutomation(id: string): Promise { - const result = await execute(automationPrompts.cancelAutomation(id)); - if (result.status === "completed") { - const automation = this.automations.get(id); - if (automation) automation.status = "cancelled"; - return true; - } - return false; - } - - getAutomation(id: string): ManagedAutomation | undefined { - return this.automations.get(id); - } - - // Get all local automations - getAllAutomations(): ManagedAutomation[] { - return Array.from(this.automations.values()); - } -} - -// Usage -const manager = new AutomationManager(); - // Create limit order -const limitResult = await manager.createLimitOrder({ - token: "ETH", - side: "buy", - price: 3000, - amountUsd: 500, -}); -console.log("Limit order:", limitResult); - -// Create stop loss -const stopResult = await manager.createStopLoss({ - token: "ETH", - triggerPercent: 10, -}); -console.log("Stop loss:", stopResult); +await execute("Set a limit order to buy $500 of ETH at $3,000"); // Create DCA -const dcaResult = await manager.createDca({ - token: "ETH", - amountUsd: 100, - frequency: "weekly", - duration: "3 months", -}); -console.log("DCA:", dcaResult); +await execute("DCA $100 into ETH every week for 3 months"); // Create TWAP -const twapResult = await manager.createTwap({ - token: "ETH", - side: "buy", - totalAmount: 5000, - duration: "24 hours", -}); -console.log("TWAP:", twapResult); - -// Check all automations -const automations = await manager.refreshAutomations(); -console.log("Active automations:", automations); -``` - -## DCA Strategy Builder - -```typescript -interface DcaStrategy { - name: string; - tokens: { token: string; allocation: number }[]; // allocation as percentage - totalAmountUsd: number; - frequency: "daily" | "weekly" | "monthly"; -} - -class DcaStrategyBuilder { - async executeStrategy( - strategy: DcaStrategy, - manager: AutomationManager - ): Promise { - const results: AutomationResult[] = []; - - for (const { token, allocation } of strategy.tokens) { - const amountUsd = (strategy.totalAmountUsd * allocation) / 100; - - const result = await manager.createDca({ - token, - amountUsd, - frequency: strategy.frequency, - }); - - results.push(result); - } - - return results; - } -} - -// Example: Create a diversified DCA strategy -const strategy: DcaStrategy = { - name: "Balanced Crypto DCA", - tokens: [ - { token: "BTC", allocation: 50 }, - { token: "ETH", allocation: 30 }, - { token: "SOL", allocation: 20 }, - ], - totalAmountUsd: 500, - frequency: "weekly", -}; - -const builder = new DcaStrategyBuilder(); -const results = await builder.executeStrategy(strategy, manager); -console.log("DCA strategy created:", results); -``` - -## Grid Trading Bot - -```typescript -interface GridConfig { - token: string; - lowerPrice: number; - upperPrice: number; - gridLines: number; - amountPerGrid: number; -} - -class GridTradingBot { - async setupGrid( - config: GridConfig, - manager: AutomationManager - ): Promise { - const results: AutomationResult[] = []; - const priceStep = (config.upperPrice - config.lowerPrice) / config.gridLines; - - // Create buy orders below current price - for (let i = 0; i < config.gridLines / 2; i++) { - const buyPrice = config.lowerPrice + priceStep * i; - - const result = await manager.createLimitOrder({ - token: config.token, - side: "buy", - price: buyPrice, - amountUsd: config.amountPerGrid, - }); - - results.push(result); - } - - // Create sell orders above current price - for (let i = config.gridLines / 2; i < config.gridLines; i++) { - const sellPrice = config.lowerPrice + priceStep * i; - - const result = await manager.createLimitOrder({ - token: config.token, - side: "sell", - price: sellPrice, - amountUsd: config.amountPerGrid, - }); - - results.push(result); - } - - return results; - } -} - -// Example: Set up grid trading -const gridBot = new GridTradingBot(); -const gridResults = await gridBot.setupGrid( - { - token: "ETH", - lowerPrice: 2800, - upperPrice: 3200, - gridLines: 10, - amountPerGrid: 50, - }, - manager -); -``` - -## Error Handling - -Common errors and how to handle them: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Order not triggering | Price never reached | Check threshold | -| Insufficient balance | Funds depleted | Check before creating | -| Order cancelled | Expired or conflict | Re-create if needed | -| Rate limit | Too many orders | Space out creation | - -```typescript -async function createWithRetry( - createFn: () => Promise, - maxRetries: number = 3 -): Promise { - for (let attempt = 1; attempt <= maxRetries; attempt++) { - const result = await createFn(); - - if (result.success) { - return result; - } - - // Check for retryable errors - if (result.message.includes("rate limit") || result.message.includes("timeout")) { - console.log(`Attempt ${attempt} failed, retrying...`); - await new Promise((r) => setTimeout(r, 5000 * attempt)); - continue; - } - - // Non-retryable error - return result; - } +await execute("TWAP buy $5000 of ETH over 24 hours"); - return { success: false, type: "unknown", message: "Max retries exceeded" }; -} +// View automations +await execute("Show my automations"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-token-trading` - Immediate trades -- `bankr-market-research` - Price data for setting triggers diff --git a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md index 8f64df2..1e87df7 100644 --- a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md @@ -1,434 +1,60 @@ --- name: Bankr Dev - Leverage Trading -description: This skill should be used when building a leverage trading bot, implementing perpetual position management, creating risk management systems with stop-loss automation, or building an Avantis integration. Covers TypeScript prompt templates like `leveragePrompts.openLongWithRisk()`, liquidation price calculations, position PnL parsing, and LeverageTradingBot class with risk parameters. Triggered by "leverage bot code", "perpetual trading TypeScript", "Avantis integration", "stop loss automation". +description: Perpetual trading capability via the Bankr API (Avantis integration). Open/close leveraged positions with stop loss and take profit. Triggered by "leverage prompts", "perpetual trading", "long/short positions", "Avantis patterns". version: 1.0.0 --- -# Leverage Trading - Developer Guide +# Leverage Trading Capability -Build bots and applications that trade perpetuals via Avantis and the Bankr API. +Trade perpetuals with leverage via natural language prompts. -## Overview +## What You Can Do -Leverage trading through Bankr (via Avantis) supports: -- Long and short positions -- Leverage from 1x to 100x+ -- Crypto, forex, and commodities markets -- Stop loss and take profit orders +| Operation | Example Prompt | +|-----------|----------------| +| Open long | `Open a 5x long on ETH with $100` | +| Open short | `Open a 3x short on BTC with $50` | +| Long with stop loss | `Open a 5x long on ETH with $100, stop loss at -10%` | +| Long with take profit | `Open a 5x long on ETH with $100, take profit at +20%` | +| Full risk management | `Open a 5x long on ETH with $100, stop loss at -10%, take profit at +20%` | +| View positions | `Show my Avantis positions` | +| Close position | `Close my ETH long position` | +| Close all | `Close all my Avantis positions` | +| Check PnL | `Check my PnL on Avantis` | -**Chain:** Base - -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for leverage trading operations -const leveragePrompts = { - // Open positions - openLong: (asset: string, leverage: number, collateral: string) => - `Open a ${leverage}x long on ${asset} with ${collateral}`, - - openShort: (asset: string, leverage: number, collateral: string) => - `Open a ${leverage}x short on ${asset} with ${collateral}`, - - // With risk management - openLongWithSL: (asset: string, leverage: number, collateral: string, stopLoss: string) => - `Open a ${leverage}x long on ${asset} with ${collateral}, stop loss at ${stopLoss}`, - - openLongWithTP: (asset: string, leverage: number, collateral: string, takeProfit: string) => - `Open a ${leverage}x long on ${asset} with ${collateral}, take profit at ${takeProfit}`, - - openLongWithRisk: ( - asset: string, - leverage: number, - collateral: string, - stopLoss: string, - takeProfit: string - ) => - `Open a ${leverage}x long on ${asset} with ${collateral}, stop loss at ${stopLoss}, take profit at ${takeProfit}`, +## Prompt Patterns - // View/close positions - viewPositions: () => "Show my Avantis positions", - closePosition: (asset: string, direction: "long" | "short") => - `Close my ${asset} ${direction} position`, - closeAllPositions: () => "Close all my Avantis positions", - - // Check PnL - checkPnl: () => "Check my PnL on Avantis", -}; - -// Asset categories -const SUPPORTED_ASSETS = { - crypto: ["BTC", "ETH", "SOL", "ARB", "AVAX", "BNB", "DOGE", "LINK", "OP", "MATIC"], - forex: ["EUR/USD", "GBP/USD", "USD/JPY", "AUD/USD", "USD/CAD"], - commodities: ["Gold", "Silver", "Oil", "Natural Gas"], -}; ``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface PositionInfo { - asset: string; - direction: "long" | "short"; - leverage: number; - collateral: number; - entryPrice: number; - liquidationPrice: number; - pnl: number; - pnlPercentage: number; -} - -// Parse position opened response -function parsePositionOpened(response: string): Partial | null { - // Example: "Opened 5x long on ETH with $100 collateral. Entry: $3,245.67. Liquidation: $2,596.54" - const match = response.match( - /Opened\s+(\d+)x\s+(long|short)\s+on\s+(\w+).+Entry:\s+\$([0-9,.]+).+Liquidation:\s+\$([0-9,.]+)/i - ); - - if (match) { - return { - leverage: parseInt(match[1]), - direction: match[2].toLowerCase() as "long" | "short", - asset: match[3], - entryPrice: parseFloat(match[4].replace(",", "")), - liquidationPrice: parseFloat(match[5].replace(",", "")), - }; - } - return null; -} - -// Parse positions list -function parsePositions(response: string): PositionInfo[] { - const positions: PositionInfo[] = []; - // Example: "- ETH Long 5x: +$23.45 (7.2%)" - const lines = response.split("\n").filter((l) => l.startsWith("-")); - - for (const line of lines) { - const match = line.match(/-\s+(\w+)\s+(Long|Short)\s+(\d+)x:\s+([+-]?\$[0-9.]+)\s+\(([+-]?[0-9.]+)%\)/i); - if (match) { - positions.push({ - asset: match[1], - direction: match[2].toLowerCase() as "long" | "short", - leverage: parseInt(match[3]), - collateral: 0, // Not in response - entryPrice: 0, - liquidationPrice: 0, - pnl: parseFloat(match[4].replace("$", "").replace("+", "")), - pnlPercentage: parseFloat(match[5].replace("+", "")), - }); - } - } - return positions; -} - -async function handleLeverageResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Leverage operation successful"); - console.log(result.response); - - // Handle transactions - if (result.transactions) { - for (const tx of result.transactions) { - if (tx.metadata.description) { - console.log(`Trade: ${tx.metadata.description}`); - } - } - } - } else if (result.status === "failed") { - console.error("Leverage operation failed:", result.error); - } -} -``` - -## TypeScript Types - -```typescript -// Leverage trading specific types -interface LeveragePosition { - asset: string; - direction: "long" | "short"; - leverage: number; - collateral: number; // USD - stopLoss?: number; // Price or percentage - takeProfit?: number; // Price or percentage -} - -interface PositionResult { - success: boolean; - asset: string; - direction: "long" | "short"; - leverage: number; - entryPrice: number; - liquidationPrice: number; - collateral: number; -} - -// Risk parameters -interface RiskParams { - maxLeverage: number; - maxPositionSize: number; // USD - defaultStopLoss: number; // Percentage - defaultTakeProfit: number; // Percentage -} +Open a {leverage}x {long|short} on {asset} with {collateral} +Open a {leverage}x long on {asset} with {collateral}, stop loss at {price|percent} +Close my {asset} {long|short} position +Show my Avantis positions ``` -## Bot Use Cases +**Supported assets:** +- Crypto: BTC, ETH, SOL, ARB, AVAX, BNB, DOGE, LINK, OP, MATIC +- Forex: EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CAD +- Commodities: Gold, Silver, Oil, Natural Gas -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Trend Follower | Long/short based on trend | `Open a 5x long on ETH with $100` | -| Mean Reversion | Fade extreme moves | `Short BTC with 3x leverage` | -| Scalper | Quick in/out trades | Open/close with tight SL/TP | -| Risk Manager | Monitor liquidation risk | `Show my Avantis positions` | -| Auto-Closer | Close at PnL targets | `Close my ETH long position` | +**Chain:** Base -## Code Example: Leverage Trading Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface TradingSignal { - asset: string; - direction: "long" | "short"; - confidence: number; // 0-1 -} - -class LeverageTradingBot { - private riskParams: RiskParams = { - maxLeverage: 10, - maxPositionSize: 500, - defaultStopLoss: 5, - defaultTakeProfit: 15, - }; - - calculatePositionSize(confidence: number): number { - return Math.min(this.riskParams.maxPositionSize * confidence, this.riskParams.maxPositionSize); - } - - calculateLeverage(confidence: number): number { - return Math.max(1, Math.min(Math.ceil(confidence * this.riskParams.maxLeverage), this.riskParams.maxLeverage)); - } - - async openPosition(signal: TradingSignal): Promise { - const collateral = this.calculatePositionSize(signal.confidence); - const leverage = this.calculateLeverage(signal.confidence); - - const prompt = leveragePrompts.openLongWithRisk( - signal.asset, - leverage, - `$${collateral}`, - `-${this.riskParams.defaultStopLoss}%`, - `+${this.riskParams.defaultTakeProfit}%` - ); - - const result = await execute(prompt, (msg) => console.log(" >", msg)); - if (result.status !== "completed") return null; - - const parsed = parsePositionOpened(result.response || ""); - if (!parsed) return null; +// Open leveraged position +await execute("Open a 5x long on ETH with $100, stop loss at -10%"); - return { - success: true, - asset: signal.asset, - direction: signal.direction, - leverage: parsed.leverage || leverage, - entryPrice: parsed.entryPrice || 0, - liquidationPrice: parsed.liquidationPrice || 0, - collateral, - }; - } - - async getPositions(): Promise { - const result = await execute(leveragePrompts.viewPositions()); - return result.status === "completed" && result.response ? parsePositions(result.response) : []; - } - - async closePosition(asset: string, direction: "long" | "short"): Promise { - return (await execute(leveragePrompts.closePosition(asset, direction))).status === "completed"; - } - - async closeAllPositions(): Promise { - return (await execute(leveragePrompts.closeAllPositions())).status === "completed"; - } - - async monitorPositions(): Promise { - const positions = await this.getPositions(); - - for (const position of positions) { - const shouldClose = - position.pnlPercentage <= -this.riskParams.defaultStopLoss || - position.pnlPercentage >= this.riskParams.defaultTakeProfit; - - if (shouldClose) { - await this.closePosition(position.asset, position.direction); - } - } - } -} - -// Usage -const bot = new LeverageTradingBot(); - -// Open a position based on a signal -const signal: TradingSignal = { - asset: "ETH", - direction: "long", - confidence: 0.7, -}; - -const position = await bot.openPosition(signal); -console.log("Opened position:", position); - -// Monitor positions periodically -setInterval(() => bot.monitorPositions(), 30000); - -// Get current positions -const positions = await bot.getPositions(); -console.log("Current positions:", positions); -``` - -## Risk Management - -```typescript -// Risk calculation utilities -function calculateLiquidationPrice( - entryPrice: number, - leverage: number, - direction: "long" | "short", - maintenanceMargin: number = 0.005 // 0.5% -): number { - if (direction === "long") { - // Liquidated when price drops enough to wipe collateral - return entryPrice * (1 - 1 / leverage + maintenanceMargin); - } else { - // Liquidated when price rises enough - return entryPrice * (1 + 1 / leverage - maintenanceMargin); - } -} - -function calculatePositionSize( - collateral: number, - leverage: number -): number { - return collateral * leverage; -} - -function calculatePnL( - entryPrice: number, - currentPrice: number, - positionSize: number, - direction: "long" | "short" -): number { - const priceDiff = currentPrice - entryPrice; - const pnl = direction === "long" ? priceDiff : -priceDiff; - return (pnl / entryPrice) * positionSize; -} - -function checkRisk( - collateral: number, - leverage: number, - accountBalance: number, - existingExposure: number -): { allowed: boolean; reason?: string } { - const positionSize = collateral * leverage; - const totalExposure = existingExposure + positionSize; - - if (totalExposure > accountBalance * 3) { - return { allowed: false, reason: "Exceeds maximum total exposure" }; - } - if (collateral > accountBalance * 0.2) { - return { allowed: false, reason: "Position too large for account size" }; - } - if (collateral > 100 && leverage > 10) { - return { allowed: false, reason: "Reduce leverage for larger positions" }; - } - - return { allowed: true }; -} -``` - -## Error Handling - -Common errors and how to handle them: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Insufficient collateral | Not enough funds | Reduce position size | -| Asset not supported | Invalid market | Check supported list | -| Liquidation | Price moved against | Position closed, log loss | -| High funding rate | Expensive to hold | Consider closing | - -```typescript -async function safeOpenPosition( - position: LeveragePosition, - accountBalance: number -): Promise { - // Risk check first - const riskCheck = checkRisk( - position.collateral, - position.leverage, - accountBalance, - 0 // Calculate existing exposure - ); - - if (!riskCheck.allowed) { - console.error("Risk check failed:", riskCheck.reason); - return null; - } - - // Validate asset - const allAssets = [ - ...SUPPORTED_ASSETS.crypto, - ...SUPPORTED_ASSETS.forex, - ...SUPPORTED_ASSETS.commodities, - ]; - - if (!allAssets.some((a) => position.asset.toUpperCase().includes(a.toUpperCase()))) { - console.error("Asset not supported:", position.asset); - return null; - } - - // Open position - const bot = new LeverageTradingBot(); - return await bot.openPosition({ - asset: position.asset, - direction: position.direction, - confidence: 1, // Use full specified size - }); -} -``` - -## Leverage Guidelines - -| Risk Level | Leverage | Use Case | -|------------|----------|----------| -| Conservative | 1-3x | Long-term trend following | -| Moderate | 3-10x | Swing trading | -| Aggressive | 10-25x | Short-term scalping | -| High Risk | 25x+ | Experienced traders only | - -```typescript -function getLeverageGuidance( - timeframe: "scalp" | "swing" | "position", - confidence: number -): number { - const baseLeverage = { - scalp: 15, - swing: 5, - position: 2, - }; +// Check positions +await execute("Show my Avantis positions"); - return Math.ceil(baseLeverage[timeframe] * confidence); -} +// Close position +await execute("Close my ETH long position"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-market-research` - Price data for trading decisions -- `bankr-portfolio` - Check balances before trading diff --git a/bankr-agent-dev/skills/bankr-market-research/SKILL.md b/bankr-agent-dev/skills/bankr-market-research/SKILL.md index 4f585fb..5a1cbca 100644 --- a/bankr-agent-dev/skills/bankr-market-research/SKILL.md +++ b/bankr-agent-dev/skills/bankr-market-research/SKILL.md @@ -1,580 +1,71 @@ --- name: Bankr Dev - Market Research -description: This skill should be used when building a price alert system, implementing technical analysis automation, creating sentiment tracking, or building a trending token discovery bot. Covers TypeScript prompt templates like `marketPrompts.technicalAnalysis()`, price/TA/sentiment parsing, trading signal generation, and MarketMonitor class with alert callbacks. Triggered by "price alert bot code", "market research TypeScript", "sentiment tracking automation", "technical analysis implementation". +description: Market data capability via the Bankr API. Query prices, market caps, technical analysis, sentiment, and trending tokens. Triggered by "market prompts", "price queries", "technical analysis", "sentiment checking". version: 1.0.0 --- -# Market Research - Developer Guide +# Market Research Capability + +Query market data and analysis via natural language prompts. + +## What You Can Do + +| Operation | Example Prompt | +|-----------|----------------| +| Token price | `What's the price of ETH?` | +| Market data | `Show me BTC market data` | +| Market cap | `What's the market cap of SOL?` | +| 24h volume | `What's the 24h volume for ETH?` | +| Holder count | `How many holders does BNKR have?` | +| Technical analysis | `Do technical analysis on BTC` | +| RSI | `What's the RSI for ETH?` | +| Price action | `Analyze SOL price action` | +| Sentiment | `What's the sentiment on ETH?` | +| Social mentions | `Check social mentions for DOGE` | +| Price chart | `Show ETH price chart` | +| Chart with period | `Show BTC price chart for 30d` | +| Trending tokens | `What tokens are trending today?` | +| Top gainers | `Show top gainers today` | +| Top losers | `Show top losers today` | +| Trending by chain | `What's trending on Base?` | +| Compare tokens | `Compare ETH vs SOL` | + +## Prompt Patterns -Build bots and applications that perform market research via the Bankr API. - -## Overview - -Market research through Bankr supports: -- Token price queries -- Market data (cap, volume, supply) -- Technical analysis indicators -- Social sentiment analysis -- Price charts -- Trending token discovery - -**Supported Chains:** All chains - data aggregated from multiple sources - -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for market research operations -const marketPrompts = { - // Price queries - price: (token: string) => `What's the price of ${token}?`, - priceWithDetails: (token: string) => `Show me ${token} market data`, - - // Market data - marketCap: (token: string) => `What's the market cap of ${token}?`, - volume: (token: string) => `What's the 24h volume for ${token}?`, - holders: (token: string) => `How many holders does ${token} have?`, - - // Technical analysis - technicalAnalysis: (token: string) => `Do technical analysis on ${token}`, - rsi: (token: string) => `What's the RSI for ${token}?`, - priceAction: (token: string) => `Analyze ${token} price action`, - - // Sentiment - sentiment: (token: string) => `What's the sentiment on ${token}?`, - socialMentions: (token: string) => `Check social mentions for ${token}`, - - // Charts - chart: (token: string, period?: string) => - period ? `Show ${token} price chart for ${period}` : `Show ${token} price chart`, - - // Discovery - trending: () => "What tokens are trending today?", - topGainers: () => "Show top gainers today", - topLosers: () => "Show top losers today", - trendingOnChain: (chain: string) => `What's trending on ${chain}?`, - - // Comparison - compare: (token1: string, token2: string) => `Compare ${token1} vs ${token2}`, -}; ``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse, RichData, Chart } from "./bankr-client"; - -interface PriceData { - token: string; - priceUsd: number; - change24h: number; - change7d?: number; - marketCap?: number; - volume24h?: number; - ath?: number; - atl?: number; -} - -interface TechnicalIndicators { - rsi: number; - rsiSignal: "oversold" | "neutral" | "overbought"; - macd: "bullish" | "bearish" | "neutral"; - ma50: number; - ma200: number; - trend: "bullish" | "bearish" | "neutral"; -} - -interface SentimentData { - overall: "bullish" | "bearish" | "neutral"; - bullishPercent: number; - socialMentions: number; - mentionChange: number; - keyTopics: string[]; -} - -// Parse price response -function parsePriceData(response: string, token: string): PriceData | null { - // Example: "Ethereum (ETH): $3,245.67\n24h: +2.3%\n7d: -1.5%\nMarket Cap: $390.2B" - const priceMatch = response.match(/\$([0-9,.]+)/); - const change24hMatch = response.match(/24h:\s*([+-]?[0-9.]+)%/); - const change7dMatch = response.match(/7d:\s*([+-]?[0-9.]+)%/); - const marketCapMatch = response.match(/Market Cap:\s*\$([0-9,.]+)([BMK])?/); - - if (!priceMatch) return null; - - let marketCap: number | undefined; - if (marketCapMatch) { - marketCap = parseFloat(marketCapMatch[1].replace(",", "")); - const suffix = marketCapMatch[2]; - if (suffix === "B") marketCap *= 1e9; - else if (suffix === "M") marketCap *= 1e6; - else if (suffix === "K") marketCap *= 1e3; - } - - return { - token, - priceUsd: parseFloat(priceMatch[1].replace(",", "")), - change24h: change24hMatch ? parseFloat(change24hMatch[1]) : 0, - change7d: change7dMatch ? parseFloat(change7dMatch[1]) : undefined, - marketCap, - }; -} - -// Parse technical analysis -function parseTechnicalAnalysis(response: string): TechnicalIndicators | null { - const rsiMatch = response.match(/RSI:\s*(\d+)\s*\((\w+)\)/i); - const macdMatch = response.match(/MACD:\s*(\w+)/i); - const ma50Match = response.match(/50\s*MA:\s*\$([0-9,.]+)/i); - const ma200Match = response.match(/200\s*MA:\s*\$([0-9,.]+)/i); - - if (!rsiMatch) return null; - - const rsi = parseInt(rsiMatch[1]); - - function getRsiSignal(value: number): "oversold" | "neutral" | "overbought" { - if (value < 30) return "oversold"; - if (value > 70) return "overbought"; - return "neutral"; - } - - function getMacdSignal(match: RegExpMatchArray | null): "bullish" | "bearish" | "neutral" { - const signal = match?.[1]?.toLowerCase() || ""; - if (signal.includes("bullish")) return "bullish"; - if (signal.includes("bearish")) return "bearish"; - return "neutral"; - } - - return { - rsi, - rsiSignal: getRsiSignal(rsi), - macd: getMacdSignal(macdMatch), - ma50: ma50Match ? parseFloat(ma50Match[1].replace(",", "")) : 0, - ma200: ma200Match ? parseFloat(ma200Match[1].replace(",", "")) : 0, - trend: "neutral", - }; -} - -// Parse sentiment -function parseSentiment(response: string): SentimentData | null { - // Example: "Sentiment: 67% Bullish\nSocial mentions: 12.5K (up 15%)" - const sentimentMatch = response.match(/(\d+)%\s*(Bullish|Bearish|Neutral)/i); - const mentionsMatch = response.match(/mentions:\s*([0-9.]+)K?\s*\((\w+)\s*(\d+)%\)/i); - - if (!sentimentMatch) return null; - - const bullishPercent = parseInt(sentimentMatch[1]); - let overall: "bullish" | "bearish" | "neutral" = "neutral"; - if (bullishPercent > 60) overall = "bullish"; - else if (bullishPercent < 40) overall = "bearish"; - - return { - overall, - bullishPercent, - socialMentions: mentionsMatch ? parseFloat(mentionsMatch[1]) * 1000 : 0, - mentionChange: mentionsMatch ? parseInt(mentionsMatch[3]) : 0, - keyTopics: [], // Extract from response if available - }; -} - -// Extract chart URL from rich data -function extractChartUrl(richData?: RichData[]): string | null { - if (!richData) return null; - const chart = richData.find((d) => d.type === "chart") as Chart | undefined; - return chart?.url || null; -} - -async function handleMarketResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Market research successful"); - console.log(result.response); - - // Check for charts - const chartUrl = extractChartUrl(result.richData); - if (chartUrl) { - console.log("Chart available:", chartUrl); - } - } else if (result.status === "failed") { - console.error("Market research failed:", result.error); - } -} -``` - -## TypeScript Types - -```typescript -// Market research specific types -interface PriceAlert { - token: string; - type: "above" | "below" | "change"; - threshold: number; - enabled: boolean; -} - -interface TokenWatchlist { - token: string; - addedAt: Date; - alertPrice?: number; - notes?: string; -} - -interface MarketSnapshot { - timestamp: Date; - prices: Map; - totalMarketCap?: number; -} +What's the price of {token}? +Show me {token} market data +Do technical analysis on {token} +What's the sentiment on {token}? +Show {token} price chart [for {period}] +What tokens are trending today? +Compare {token1} vs {token2} ``` -## Bot Use Cases +**Chart periods:** 1d, 7d, 30d, 90d, 1y -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Price Bot | Track token prices | `What's the price of ETH?` | -| Alert System | Notify on price changes | Poll + compare | -| TA Bot | Technical analysis | `Do technical analysis on BTC` | -| Sentiment Tracker | Monitor social mood | `What's the sentiment on SOL?` | -| Discovery Bot | Find trending tokens | `What tokens are trending?` | +**Supported chains:** All chains (data aggregated from multiple sources) -## Code Example: Market Monitor Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface PriceAlert { - token: string; - type: "above" | "below"; - threshold: number; - callback: (price: number, token: string) => void; -} - -class MarketMonitor { - private priceCache: Map = new Map(); - private alerts: PriceAlert[] = []; - private watchlist: string[] = []; - - async getPrice(token: string): Promise { - const result = await execute(marketPrompts.price(token)); - if (result.status !== "completed" || !result.response) return null; - - const data = parsePriceData(result.response, token); - if (data) this.priceCache.set(token, data); - return data; - } - - async getMarketData(token: string): Promise { - const result = await execute(marketPrompts.priceWithDetails(token)); - return result.status === "completed" && result.response ? parsePriceData(result.response, token) : null; - } - - async getTechnicalAnalysis(token: string): Promise { - const result = await execute(marketPrompts.technicalAnalysis(token)); - return result.status === "completed" && result.response ? parseTechnicalAnalysis(result.response) : null; - } - - async getSentiment(token: string): Promise { - const result = await execute(marketPrompts.sentiment(token)); - return result.status === "completed" && result.response ? parseSentiment(result.response) : null; - } - - async getChart(token: string, period = "7d"): Promise { - const result = await execute(marketPrompts.chart(token, period)); - return result.status === "completed" ? extractChartUrl(result.richData) : null; - } - - async getTrending(): Promise { - const result = await execute(marketPrompts.trending()); - if (result.status !== "completed" || !result.response) return []; - - return result.response - .split("\n") - .map((line) => line.match(/\d+\.\s*(\w+)/)?.[1]) - .filter((token): token is string => Boolean(token)); - } - - addAlert(alert: PriceAlert): void { - this.alerts.push(alert); - } - - addToWatchlist(token: string): void { - if (!this.watchlist.includes(token)) this.watchlist.push(token); - } - - async checkAlerts(): Promise { - for (const alert of this.alerts) { - const price = await this.getPrice(alert.token); - if (!price) continue; - - const triggered = - (alert.type === "above" && price.priceUsd >= alert.threshold) || - (alert.type === "below" && price.priceUsd <= alert.threshold); - - if (triggered) { - alert.callback(price.priceUsd, alert.token); - this.alerts = this.alerts.filter((a) => a !== alert); - } - } - } - - async updateWatchlist(): Promise> { - const updates = new Map(); - - for (const token of this.watchlist) { - const data = await this.getPrice(token); - if (data) updates.set(token, data); - await new Promise((r) => setTimeout(r, 1000)); - } - - return updates; - } - - getCachedPrice(token: string): PriceData | undefined { - return this.priceCache.get(token); - } -} - -// Usage -const monitor = new MarketMonitor(); - -// Get current price -const ethPrice = await monitor.getPrice("ETH"); -console.log("ETH price:", ethPrice); - -// Get technical analysis -const btcTa = await monitor.getTechnicalAnalysis("BTC"); -console.log("BTC TA:", btcTa); - -// Get sentiment -const solSentiment = await monitor.getSentiment("SOL"); -console.log("SOL sentiment:", solSentiment); - -// Set up alerts -monitor.addAlert({ - token: "ETH", - type: "below", - threshold: 3000, - callback: (price, token) => { - console.log(`ALERT: ${token} dropped to $${price}!`); - }, -}); - -// Check alerts periodically -setInterval(() => monitor.checkAlerts(), 60000); - -// Get trending -const trending = await monitor.getTrending(); -console.log("Trending tokens:", trending); -``` - -## Price Alert System - -```typescript -interface AlertConfig { - token: string; - conditions: AlertCondition[]; - notifyMethod: "console" | "webhook" | "callback"; - webhookUrl?: string; -} - -type AlertCondition = - | { type: "priceAbove"; value: number } - | { type: "priceBelow"; value: number } - | { type: "changeAbove"; value: number; period: "1h" | "24h" } - | { type: "changeBelow"; value: number; period: "1h" | "24h" }; - -class AlertSystem { - private configs: AlertConfig[] = []; - private priceHistory: Map = new Map(); - - addConfig(config: AlertConfig): void { - this.configs.push(config); - } - - async checkCondition( - condition: AlertCondition, - currentPrice: PriceData - ): Promise { - switch (condition.type) { - case "priceAbove": - return currentPrice.priceUsd >= condition.value; - case "priceBelow": - return currentPrice.priceUsd <= condition.value; - case "changeAbove": - return ( - (condition.period === "24h" ? currentPrice.change24h : 0) >= - condition.value - ); - case "changeBelow": - return ( - (condition.period === "24h" ? currentPrice.change24h : 0) <= - condition.value - ); - default: - return false; - } - } - - async notify(config: AlertConfig, price: PriceData): Promise { - const message = `Alert: ${config.token} at $${price.priceUsd} (${price.change24h}% 24h)`; - - switch (config.notifyMethod) { - case "console": - console.log(message); - break; - case "webhook": - if (config.webhookUrl) { - await fetch(config.webhookUrl, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ token: config.token, price, message }), - }); - } - break; - } - } -} -``` - -## Trading Signal Generation - -```typescript -interface TradingSignal { - token: string; - action: "buy" | "sell" | "hold"; - confidence: number; - reasons: string[]; - timestamp: Date; -} - -async function generateSignal( - monitor: MarketMonitor, - token: string -): Promise { - const [price, ta, sentiment] = await Promise.all([ - monitor.getPrice(token), - monitor.getTechnicalAnalysis(token), - monitor.getSentiment(token), - ]); - - const reasons: string[] = []; - let score = 0; - - // Technical indicators - if (ta) { - if (ta.rsiSignal === "oversold") { - score += 2; - reasons.push("RSI oversold (potential buy)"); - } else if (ta.rsiSignal === "overbought") { - score -= 2; - reasons.push("RSI overbought (potential sell)"); - } - - if (ta.macd === "bullish") { - score += 1; - reasons.push("MACD bullish"); - } else if (ta.macd === "bearish") { - score -= 1; - reasons.push("MACD bearish"); - } - } - - // Sentiment - if (sentiment) { - if (sentiment.overall === "bullish") { - score += 1; - reasons.push(`Sentiment bullish (${sentiment.bullishPercent}%)`); - } else if (sentiment.overall === "bearish") { - score -= 1; - reasons.push(`Sentiment bearish`); - } - } - - // Price momentum - if (price && price.change24h) { - if (price.change24h > 5) { - score += 1; - reasons.push(`Strong momentum (+${price.change24h}%)`); - } else if (price.change24h < -5) { - score -= 1; - reasons.push(`Negative momentum (${price.change24h}%)`); - } - } - - // Determine action - let action: "buy" | "sell" | "hold" = "hold"; - if (score >= 2) action = "buy"; - else if (score <= -2) action = "sell"; - - return { - token, - action, - confidence: Math.min(Math.abs(score) / 4, 1), - reasons, - timestamp: new Date(), - }; -} -``` - -## Error Handling - -Common errors and how to handle them in bots: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Token not found | Invalid symbol | Check symbol, try alternatives | -| Price unavailable | Delisted or new token | Skip or use external source | -| Chart generation failed | Server issue | Retry or skip chart | -| Sentiment data empty | Insufficient social data | Return neutral sentiment | -| Rate limited | Too many requests | Implement backoff, cache results | - -```typescript -async function safeGetPrice( - monitor: MarketMonitor, - token: string -): Promise { - try { - const price = await monitor.getPrice(token); - - if (!price) { - console.warn(`No price data for ${token}`); - return null; - } - - return price; - } catch (err) { - const error = err as Error; - - if (error.message.includes("not found")) { - console.error(`Token ${token} not found, check symbol`); - } else if (error.message.includes("rate limit")) { - console.error("Rate limited, implementing backoff"); - await new Promise((r) => setTimeout(r, 5000)); - } +// Price check +await execute("What's the price of ETH?"); - return null; - } -} +// Technical analysis +await execute("Do technical analysis on BTC"); -async function safeGetMarketData( - monitor: MarketMonitor, - token: string -): Promise<{ price?: PriceData; ta?: TechnicalIndicators; sentiment?: SentimentData }> { - const [price, ta, sentiment] = await Promise.allSettled([ - monitor.getPrice(token), - monitor.getTechnicalAnalysis(token), - monitor.getSentiment(token), - ]); +// Sentiment +await execute("What's the sentiment on SOL?"); - return { - price: price.status === "fulfilled" ? price.value || undefined : undefined, - ta: ta.status === "fulfilled" ? ta.value || undefined : undefined, - sentiment: sentiment.status === "fulfilled" ? sentiment.value || undefined : undefined, - }; -} +// Trending +await execute("What tokens are trending today?"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-token-trading` - Execute trades based on research -- `bankr-automation` - Set up automated responses to signals diff --git a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md index edb6b12..5146f5e 100644 --- a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md +++ b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md @@ -1,410 +1,57 @@ --- name: Bankr Dev - NFT Operations -description: This skill should be used when building an NFT sniping bot, implementing floor price monitoring, creating a collection sweeper, or automating NFT purchases via OpenSea. Covers TypeScript prompt templates like `nftPrompts.buyFloor()`, floor tracking with trend detection, and NftBot class with watchlist management. Triggered by "NFT bot code", "floor sweeper TypeScript", "OpenSea automation", "NFT sniping implementation". +description: NFT marketplace capability via the Bankr API (OpenSea integration). Browse collections, check floor prices, and purchase NFTs. Triggered by "NFT prompts", "floor price", "buy NFT", "OpenSea patterns". version: 1.0.0 --- -# NFT Operations - Developer Guide +# NFT Operations Capability -Build bots and applications that interact with NFTs via the Bankr API. +Interact with NFT marketplaces via natural language prompts. -## Overview +## What You Can Do -NFT operations through Bankr (via OpenSea) support: -- Browsing NFT collections -- Finding best listings and floor prices -- Purchasing NFTs -- Viewing NFT holdings +| Operation | Example Prompt | +|-----------|----------------| +| Search collection | `Find NFTs from Pudgy Penguins` | +| Trending NFTs | `Show me trending NFT collections` | +| Floor price | `What's the floor price for Azuki?` | +| Cheapest listings | `Show the 5 cheapest NFTs in BAYC` | +| Listings under price | `Find NFT listings under 5 ETH in CryptoPunks` | +| Buy floor | `Buy the floor NFT from Pudgy Penguins` | +| Buy by URL | `Buy this NFT: https://opensea.io/...` | +| Buy with budget | `Buy an Azuki NFT under 10 ETH` | +| View holdings | `Show my NFTs` | +| Holdings by chain | `Show my NFTs on Base` | -**Supported Chains:** Base, Ethereum, Polygon, and other EVM chains +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for NFT operations -const nftPrompts = { - // Browse collections - searchCollection: (collection: string) => `Find NFTs from the ${collection} collection`, - trendingCollections: () => "Show me trending NFT collections", - searchByChain: (chain: string) => `Search for NFT collections on ${chain}`, - - // Check listings - floorPrice: (collection: string) => `What's the floor price for ${collection}?`, - cheapestNfts: (collection: string, count: number = 5) => - `Show the ${count} cheapest NFTs in ${collection}`, - listingsUnder: (collection: string, price: string) => - `Find NFT listings under ${price} in ${collection}`, - - // Buy NFTs - buyFloor: (collection: string) => `Buy the floor NFT from ${collection}`, - buyCheapest: (collection: string) => `Buy the cheapest NFT from ${collection}`, - buyByUrl: (url: string) => `Buy this NFT: ${url}`, - buyWithBudget: (collection: string, maxPrice: string) => - `Buy a ${collection} NFT under ${maxPrice}`, - - // View holdings - viewHoldings: () => "Show my NFTs", - viewHoldingsOnChain: (chain: string) => `Show my NFTs on ${chain}`, - viewCollection: (collection: string) => `Show my NFTs from ${collection}`, -}; - -// Popular collections mapping -const COLLECTION_ALIASES: Record = { - "bored apes": "boredapeyachtclub", - "bayc": "boredapeyachtclub", - "pudgy penguins": "pudgypenguins", - "cryptopunks": "cryptopunks", - "azuki": "azuki", - "doodles": "doodles-official", - "milady": "milady", -}; -``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface NftListing { - tokenId: string; - collection: string; - price: number; - currency: string; - url?: string; -} - -interface NftHolding { - tokenId: string; - collection: string; - estimatedValue: number; - chain: string; -} - -// Parse listings from response -function parseListings(response: string): NftListing[] { - const listings: NftListing[] = []; - // Example: "1. #4521 - 8.5 ETH" - const lines = response.split("\n").filter((l) => l.match(/^\d+\./)); - - for (const line of lines) { - const match = line.match(/^(\d+)\.\s+#?(\d+)\s+-\s+([0-9.]+)\s+(\w+)/); - if (match) { - listings.push({ - tokenId: match[2], - collection: "", // From context - price: parseFloat(match[3]), - currency: match[4], - }); - } - } - return listings; -} - -// Parse floor price from response -function parseFloorPrice(response: string): { price: number; currency: string } | null { - // Example: "Pudgy Penguins floor price: 8.5 ETH" - const match = response.match(/floor\s*price:\s*([0-9.]+)\s*(\w+)/i); - if (match) { - return { - price: parseFloat(match[1]), - currency: match[2], - }; - } - return null; -} - -// Parse holdings from response -function parseHoldings(response: string): NftHolding[] { - const holdings: NftHolding[] = []; - // Example: "- Pudgy Penguin #4521 (8.5 ETH value)" - const lines = response.split("\n").filter((l) => l.startsWith("-")); - - for (const line of lines) { - const match = line.match(/-\s+(.+?)\s+#(\d+)\s+\(([0-9.]+)\s+(\w+)\s+value\)/); - if (match) { - holdings.push({ - collection: match[1], - tokenId: match[2], - estimatedValue: parseFloat(match[3]), - chain: "ethereum", // Default, may vary - }); - } - } - return holdings; -} - -async function handleNftResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("NFT operation successful"); - console.log(result.response); - - // Handle transactions - if (result.transactions) { - for (const tx of result.transactions) { - const data = tx.metadata.__ORIGINAL_TX_DATA__; - if (data) { - console.log(`${data.humanReadableMessage}`); - console.log(`Price: ${data.inputTokenAmount} ${data.inputTokenTicker}`); - } - } - } - } else if (result.status === "failed") { - console.error("NFT operation failed:", result.error); - } -} ``` - -## TypeScript Types - -```typescript -// NFT-specific types for your bot -interface NftPurchaseConfig { - collection: string; - maxPrice: number; // ETH - autoApprove: boolean; -} - -interface FloorTracker { - collection: string; - targetFloor: number; - currentFloor?: number; - lastChecked?: Date; -} - -interface PurchaseResult { - success: boolean; - tokenId: string; - collection: string; - price: number; - currency: string; - txHash?: string; -} +What's the floor price for {collection}? +Buy the floor NFT from {collection} +Show the {count} cheapest NFTs in {collection} +Buy this NFT: {opensea_url} +Show my NFTs [on {chain}] ``` -## Bot Use Cases +**Supported chains:** Base, Ethereum, Polygon (and other EVM chains) -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Floor Sweeper | Buy floor when cheap | `Buy the floor NFT from Pudgy Penguins` | -| Sniper | Watch for underpriced | `Find listings under 5 ETH in Azuki` | -| Portfolio Tracker | Monitor holdings | `Show my NFTs` | -| Deal Finder | Find bargains | `Show cheapest NFTs in BAYC` | - -## Code Example: NFT Monitoring Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface CollectionWatch { - collection: string; - targetFloor: number; // Buy if floor drops below this - maxBudget: number; // Max to spend - enabled: boolean; -} - -class NftBot { - private watchlist: CollectionWatch[] = []; - - async getFloorPrice(collection: string): Promise { - const result = await execute(nftPrompts.floorPrice(collection)); - if (result.status !== "completed" || !result.response) return null; - return parseFloorPrice(result.response)?.price || null; - } - - async getCheapestListings(collection: string, count = 5): Promise { - const result = await execute(nftPrompts.cheapestNfts(collection, count)); - return result.status === "completed" && result.response ? parseListings(result.response) : []; - } - - async buyFloor(collection: string): Promise { - const result = await execute(nftPrompts.buyFloor(collection), (msg) => console.log(" >", msg)); - if (result.status !== "completed") return null; - - const txData = result.transactions?.[0]?.metadata.__ORIGINAL_TX_DATA__; - if (!txData) return null; - - return { - success: true, - tokenId: "", - collection, - price: parseFloat(txData.inputTokenAmount), - currency: txData.inputTokenTicker, - }; - } - - async buyByUrl(url: string): Promise { - const result = await execute(nftPrompts.buyByUrl(url), (msg) => console.log(" >", msg)); - if (result.status !== "completed") return null; - return { success: true, tokenId: "", collection: "", price: 0, currency: "ETH" }; - } - - async getHoldings(): Promise { - const result = await execute(nftPrompts.viewHoldings()); - return result.status === "completed" && result.response ? parseHoldings(result.response) : []; - } - - addToWatchlist(watch: CollectionWatch): void { - this.watchlist.push(watch); - } - - async checkWatchlist(): Promise { - for (const watch of this.watchlist) { - if (!watch.enabled) continue; +// Check floor price +await execute("What's the floor price for Pudgy Penguins?"); - const floor = await this.getFloorPrice(watch.collection); - if (floor === null || floor > watch.targetFloor || floor > watch.maxBudget) continue; - - const purchase = await this.buyFloor(watch.collection); - if (purchase?.success) { - watch.enabled = false; - } - } - } -} - -// Usage -const bot = new NftBot(); - -// Check floor prices -const floor = await bot.getFloorPrice("Pudgy Penguins"); -console.log("Pudgy Penguins floor:", floor); - -// Get cheapest listings -const listings = await bot.getCheapestListings("Azuki", 5); -console.log("Cheapest Azuki:", listings); - -// Add to watchlist -bot.addToWatchlist({ - collection: "Pudgy Penguins", - targetFloor: 7.5, - maxBudget: 8, - enabled: true, -}); - -// Check watchlist periodically -setInterval(() => bot.checkWatchlist(), 60000); - -// Get holdings -const holdings = await bot.getHoldings(); -console.log("My NFTs:", holdings); -``` - -## Floor Tracking - -```typescript -interface FloorHistory { - timestamp: Date; - floor: number; -} - -class FloorTracker { - private history: Map = new Map(); - - async trackFloor(collection: string, bot: NftBot): Promise { - const floor = await bot.getFloorPrice(collection); - if (floor === null) return; - - const history = this.history.get(collection) || []; - history.push({ - timestamp: new Date(), - floor, - }); - - // Keep last 100 data points - if (history.length > 100) { - history.shift(); - } - - this.history.set(collection, history); - } - - getFloorTrend(collection: string): "up" | "down" | "stable" | null { - const history = this.history.get(collection); - if (!history || history.length < 2) return null; - - const recent = history.slice(-5); - const oldAvg = recent.slice(0, 2).reduce((a, b) => a + b.floor, 0) / 2; - const newAvg = recent.slice(-2).reduce((a, b) => a + b.floor, 0) / 2; - - const change = (newAvg - oldAvg) / oldAvg; - if (change > 0.05) return "up"; - if (change < -0.05) return "down"; - return "stable"; - } - - getLowestFloor(collection: string): number | null { - const history = this.history.get(collection); - if (!history || history.length === 0) return null; - return Math.min(...history.map((h) => h.floor)); - } -} -``` - -## Error Handling - -Common errors and how to handle them: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Collection not found | Invalid name | Try aliases | -| NFT already sold | Race condition | Try next listing | -| Insufficient funds | Not enough ETH | Check balance first | -| High gas | Network congestion | Wait or use L2 | - -```typescript -async function safePurchase( - collection: string, - maxPrice: number, - bot: NftBot -): Promise { - // Check floor first - const floor = await bot.getFloorPrice(collection); - if (floor === null) { - console.error("Could not get floor price"); - return null; - } - - if (floor > maxPrice) { - console.error(`Floor (${floor}) exceeds max price (${maxPrice})`); - return null; - } - - // Attempt purchase - const result = await bot.buyFloor(collection); - - if (!result?.success) { - // Try next cheapest if floor sold - const listings = await bot.getCheapestListings(collection, 3); - const affordable = listings.filter((l) => l.price <= maxPrice); - - if (affordable.length > 0) { - // Could implement buying by token ID here - console.log("Alternative listings found:", affordable); - } - } - - return result; -} -``` - -## Chain Selection for NFTs - -```typescript -const NFT_CHAINS = { - ethereum: { majorCollections: true, highGas: true }, - base: { majorCollections: false, highGas: false }, - polygon: { majorCollections: false, highGas: false }, -}; +// Buy floor NFT +await execute("Buy the floor NFT from Azuki"); -function recommendChain(budget: number): string { - return budget > 1 ? "Ethereum" : "Base"; -} +// View holdings +await execute("Show my NFTs on Ethereum"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-portfolio` - Check ETH balance before purchases diff --git a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md index 4f0362c..236d4b5 100644 --- a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md +++ b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md @@ -1,368 +1,55 @@ --- name: Bankr Dev - Polymarket -description: This skill should be used when building a prediction market bot, implementing odds monitoring, creating an auto-betting system, or tracking Polymarket positions programmatically. Covers TypeScript prompt templates like `polymarketPrompts.betYes()`, odds parsing, expected value calculations, and PolymarketBot class with alert systems. Triggered by "Polymarket bot code", "betting prompt template", "odds tracking TypeScript", "prediction market automation". +description: Prediction market capability via the Bankr API. Search markets, check odds, place bets, and manage positions on Polymarket. Triggered by "Polymarket prompts", "prediction market", "betting patterns", "odds checking". version: 1.0.0 --- -# Polymarket - Developer Guide +# Polymarket Capability -Build bots and applications that interact with Polymarket via the Bankr API. +Interact with Polymarket prediction markets via natural language prompts. -## Overview +## What You Can Do -Polymarket operations through Bankr support: -- Searching and discovering markets -- Checking odds and probabilities -- Placing bets (buying shares) -- Viewing and redeeming positions +| Operation | Example Prompt | +|-----------|----------------| +| Search markets | `Search Polymarket for election` | +| Trending markets | `What prediction markets are trending?` | +| Check odds | `What are the odds Trump wins?` | +| Market details | `Show details for the Super Bowl market` | +| Bet Yes | `Bet $10 on Yes for the election market` | +| Bet No | `Bet $5 on No for Bitcoin hitting 100k` | +| View positions | `Show my Polymarket positions` | +| Redeem winnings | `Redeem my Polymarket positions` | -**Chain:** Polygon (uses USDC.e for betting) - -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for Polymarket operations -const polymarketPrompts = { - // Search markets - search: (query: string) => `Search Polymarket for ${query}`, - trending: () => "What prediction markets are trending on Polymarket?", - - // Check odds - checkOdds: (event: string) => `What are the odds ${event}?`, - marketDetails: (market: string) => `Show me details for the ${market} market on Polymarket`, - - // Place bets - bet: (amount: string, outcome: string, market: string) => - `Bet ${amount} on ${outcome} for ${market}`, - betYes: (amount: string, market: string) => `Bet ${amount} on Yes for ${market}`, - betNo: (amount: string, market: string) => `Bet ${amount} on No for ${market}`, - - // Manage positions - viewPositions: () => "Show my Polymarket positions", - redeemPositions: () => "Redeem my Polymarket positions", - checkPosition: (market: string) => `Check my position on ${market}`, -}; - -// Bet amount helpers -const formatBetAmount = { - dollars: (amount: number) => `$${amount}`, - shares: (amount: number) => `${amount} shares`, -}; -``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface MarketInfo { - title: string; - yesPrice: number; - noPrice: number; - volume24h?: number; - liquidity?: number; -} - -interface Position { - market: string; - outcome: string; - shares: number; - avgPrice: number; - currentValue: number; - pnl: number; -} - -// Parse market search results -function parseMarketResults(response: string): MarketInfo[] { - // Response format varies, parse accordingly - const markets: MarketInfo[] = []; - // Parse the response text to extract market info - // Example: "1. Presidential Election 2024 - 65% Yes" - const lines = response.split("\n").filter((l) => l.match(/^\d+\./)); +## Prompt Patterns - for (const line of lines) { - const match = line.match(/^(\d+)\.\s+(.+?)\s+-\s+(\d+)%\s+(Yes|No)?/); - if (match) { - const yesPrice = parseInt(match[3]) / 100; - markets.push({ - title: match[2], - yesPrice, - noPrice: 1 - yesPrice, - }); - } - } - return markets; -} - -// Parse position results -function parsePositions(response: string): Position[] { - const positions: Position[] = []; - // Parse response text for position data - // Example: "- Presidential Election: 20 Yes shares ($13 value)" - const lines = response.split("\n").filter((l) => l.startsWith("-")); - - for (const line of lines) { - const match = line.match(/-\s+(.+?):\s+(\d+)\s+(Yes|No)\s+shares\s+\(\$([0-9.]+)\s+value\)/); - if (match) { - positions.push({ - market: match[1], - outcome: match[3], - shares: parseInt(match[2]), - avgPrice: 0, // Not always in response - currentValue: parseFloat(match[4]), - pnl: 0, // Calculate if needed - }); - } - } - return positions; -} - -async function handlePolymarketResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Polymarket operation successful"); - console.log(result.response); - - // Handle bet confirmations - if (result.transactions?.length) { - for (const tx of result.transactions) { - console.log(`Transaction: ${tx.type}`); - } - } - } else if (result.status === "failed") { - console.error("Polymarket operation failed:", result.error); - } -} ``` - -## TypeScript Types - -```typescript -// Polymarket-specific types for your bot -interface PolymarketBet { - market: string; - outcome: "yes" | "no"; - amount: number; // USD - expectedShares?: number; -} - -interface BetResult { - success: boolean; - shares: number; - avgPrice: number; - totalCost: number; - market: string; - outcome: string; -} - -interface MarketOdds { - market: string; - yesPrice: number; // 0-1 - noPrice: number; // 0-1 - yesProbability: number; // Percentage - noProbability: number; - timestamp: Date; -} +Search Polymarket for {query} +What are the odds {event}? +Bet {amount} on {Yes|No} for {market} +Show my Polymarket positions +Redeem my Polymarket positions ``` -## Bot Use Cases - -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Odds Tracker | Monitor odds changes | `What are the odds Trump wins?` | -| Auto-Bettor | Bet when odds hit target | `Bet $10 on Yes for election` | -| Arbitrage | Find mispriced markets | Search + compare odds | -| Portfolio Tracker | Monitor all positions | `Show my Polymarket positions` | -| Auto-Redeemer | Claim winning positions | `Redeem my Polymarket positions` | +**Chain:** Polygon (uses USDC.e for betting) -## Code Example: Prediction Market Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface OddsAlert { - market: string; - outcome: "yes" | "no"; - targetOdds: number; // Price at which to bet - betAmount: number; -} - -class PolymarketBot { - private alerts: OddsAlert[] = []; - - async searchMarkets(query: string): Promise { - const result = await execute(polymarketPrompts.search(query)); - return result.status === "completed" && result.response ? parseMarketResults(result.response) : []; - } - - async getOdds(event: string): Promise { - const result = await execute(polymarketPrompts.checkOdds(event)); - if (result.status !== "completed" || !result.response) return null; - - const match = result.response.match(/(\d+)%\s+Yes/); - if (!match) return null; - - const yesPct = parseInt(match[1]); - return { - market: event, - yesPrice: yesPct / 100, - noPrice: 1 - yesPct / 100, - yesProbability: yesPct, - noProbability: 100 - yesPct, - timestamp: new Date(), - }; - } - - async placeBet(bet: PolymarketBet): Promise { - const prompt = bet.outcome === "yes" - ? polymarketPrompts.betYes(`$${bet.amount}`, bet.market) - : polymarketPrompts.betNo(`$${bet.amount}`, bet.market); - - const result = await execute(prompt, (msg) => console.log(" >", msg)); - if (result.status !== "completed") return null; - - const sharesMatch = result.response?.match(/(\d+\.?\d*)\s+shares/); - const priceMatch = result.response?.match(/\$([0-9.]+)\s+each/); - - return { - success: true, - shares: sharesMatch ? parseFloat(sharesMatch[1]) : 0, - avgPrice: priceMatch ? parseFloat(priceMatch[1]) : 0, - totalCost: bet.amount, - market: bet.market, - outcome: bet.outcome, - }; - } - - async getPositions(): Promise { - const result = await execute(polymarketPrompts.viewPositions()); - return result.status === "completed" && result.response ? parsePositions(result.response) : []; - } - - async redeemPositions(): Promise { - return (await execute(polymarketPrompts.redeemPositions())).status === "completed"; - } - - addAlert(alert: OddsAlert): void { - this.alerts.push(alert); - } - - async checkAlerts(): Promise { - for (const alert of this.alerts) { - const odds = await this.getOdds(alert.market); - if (!odds) continue; - - const currentPrice = alert.outcome === "yes" ? odds.yesPrice : odds.noPrice; - if (currentPrice <= alert.targetOdds) { - await this.placeBet({ market: alert.market, outcome: alert.outcome, amount: alert.betAmount }); - this.alerts = this.alerts.filter((a) => a !== alert); - } - } - } -} - -// Usage -const bot = new PolymarketBot(); - -// Search for markets -const markets = await bot.searchMarkets("election"); -console.log("Found markets:", markets); - // Check odds -const odds = await bot.getOdds("Trump wins the election"); -console.log("Current odds:", odds); +await execute("What are the odds Trump wins the election?"); // Place a bet -const betResult = await bot.placeBet({ - market: "Presidential Election 2024", - outcome: "yes", - amount: 10, -}); -console.log("Bet result:", betResult); - -// Set up alerts -bot.addAlert({ - market: "Super Bowl", - outcome: "yes", - targetOdds: 0.45, // Bet when Yes shares are at 45 cents - betAmount: 20, -}); - -// Check alerts periodically -setInterval(() => bot.checkAlerts(), 60000); -``` - -## Error Handling - -Common errors and how to handle them in bots: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Market not found | Invalid search | Try different terms | -| Insufficient USDC | Not enough funds | Check balance first | -| Market closed | Already resolved | Skip and remove | -| Low liquidity | Thin order book | Use smaller amounts | - -```typescript -async function safeBet(bot: PolymarketBot, bet: PolymarketBet): Promise { - const odds = await bot.getOdds(bet.market); - if (!odds) return null; - - const price = bet.outcome === "yes" ? odds.yesPrice : odds.noPrice; - if (price < 0.01 || price > 0.99) return null; // Market likely closed - - return bot.placeBet(bet); -} -``` - -## Calculating Expected Value - -```typescript -interface BetAnalysis { - expectedValue: number; - breakEvenProbability: number; - potentialProfit: number; - potentialLoss: number; -} - -function analyzeBet( - amount: number, - price: number, - yourProbability: number -): BetAnalysis { - // Shares you get for your bet - const shares = amount / price; - - // If you win, each share pays $1 - const potentialProfit = shares - amount; - const potentialLoss = amount; - - // Expected value - const expectedValue = yourProbability * potentialProfit - (1 - yourProbability) * potentialLoss; - - // Break-even probability (when EV = 0) - const breakEvenProbability = price; - - return { - expectedValue, - breakEvenProbability, - potentialProfit, - potentialLoss, - }; -} +await execute("Bet $10 on Yes for Presidential Election 2024"); -// Example: Should you bet $100 on Yes at 60 cents if you think probability is 70%? -const analysis = analyzeBet(100, 0.6, 0.7); -console.log(analysis); -// expectedValue: ~16.67 (positive = good bet) -// breakEvenProbability: 0.6 (60%) -// potentialProfit: ~66.67 -// potentialLoss: 100 +// View positions +await execute("Show my Polymarket positions"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-portfolio` - Check USDC balance for betting diff --git a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md index 13ff3af..f07e075 100644 --- a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md +++ b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md @@ -1,505 +1,61 @@ --- name: Bankr Dev - Portfolio -description: This skill should be used when building a portfolio dashboard, implementing balance monitoring across chains, creating allocation tracking, or building a rebalancing bot. Covers TypeScript prompt templates like `portfolioPrompts.chainBalance()`, portfolio parsing utilities, change detection algorithms, and PortfolioTracker class with analytics. Triggered by "portfolio tracker code", "balance monitoring TypeScript", "multi-chain dashboard", "rebalancing automation". +description: Portfolio query capability via the Bankr API. Check balances, holdings, and valuations across all chains. Triggered by "portfolio prompts", "balance checking", "holdings query", "multi-chain balances". version: 1.0.0 --- -# Portfolio - Developer Guide +# Portfolio Capability -Build bots and applications that query portfolio data via the Bankr API. +Query portfolio data and balances via natural language prompts. -## Overview +## What You Can Do -Portfolio operations through Bankr support: -- Total portfolio value across all chains -- Chain-specific balances -- Token-specific holdings -- Real-time USD valuations +| Operation | Example Prompt | +|-----------|----------------| +| Total portfolio | `Show my portfolio` | +| Total balance | `What's my total balance?` | +| All holdings | `List all my crypto holdings` | +| Wallet value | `How much is my wallet worth?` | +| Chain balance | `Show my Base balance` | +| Chain holdings | `What tokens do I have on Polygon?` | +| Token balance | `How much ETH do I have?` | +| Token across chains | `Show my USDC on all chains` | +| Largest holding | `What's my largest holding?` | +| Token location | `Where do I have the most ETH?` | -**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for portfolio operations -const portfolioPrompts = { - // Full portfolio - totalPortfolio: () => "Show my portfolio", - totalBalance: () => "What's my total balance?", - allHoldings: () => "List all my crypto holdings", - portfolioValue: () => "How much is my wallet worth?", - - // Chain-specific - chainBalance: (chain: string) => `Show my ${chain} balance`, - chainHoldings: (chain: string) => `What tokens do I have on ${chain}?`, - - // Token-specific - tokenBalance: (token: string) => `How much ${token} do I have?`, - tokenAcrossChains: (token: string) => `Show my ${token} on all chains`, - - // Comparisons - largestHolding: () => "What's my largest holding?", - tokenLocation: (token: string) => `Where do I have the most ${token}?`, -}; - -// Chain constants -const CHAINS = ["Base", "Polygon", "Ethereum", "Unichain", "Solana"] as const; -type Chain = (typeof CHAINS)[number]; ``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface TokenBalance { - token: string; - amount: number; - valueUsd: number; - chain: string; -} - -interface ChainBalance { - chain: string; - totalValueUsd: number; - tokens: TokenBalance[]; -} - -interface Portfolio { - totalValueUsd: number; - chains: ChainBalance[]; - lastUpdated: Date; -} - -// Parse full portfolio response -function parsePortfolio(response: string): Portfolio { - const portfolio: Portfolio = { - totalValueUsd: 0, - chains: [], - lastUpdated: new Date(), - }; - - // Example format: - // "Your portfolio ($12,345.67 total): - // - // Base: - // - ETH: 2.5 ($8,125.00) - // - USDC: 1,500.00 ($1,500.00)" - - // Extract total - const totalMatch = response.match(/\(\$([0-9,.]+)\s+total\)/); - if (totalMatch) { - portfolio.totalValueUsd = parseFloat(totalMatch[1].replace(",", "")); - } - - // Parse by chain - const chainSections = response.split(/\n\n(?=[A-Za-z]+:)/); - - for (const section of chainSections) { - const chainMatch = section.match(/^([A-Za-z]+):/); - if (!chainMatch) continue; - - const chainBalance: ChainBalance = { - chain: chainMatch[1], - totalValueUsd: 0, - tokens: [], - }; - - // Parse token lines - const tokenLines = section.split("\n").filter((l) => l.startsWith("-")); - for (const line of tokenLines) { - const match = line.match(/-\s+(\w+):\s+([0-9,.]+)\s+\(\$([0-9,.]+)\)/); - if (match) { - const valueUsd = parseFloat(match[3].replace(",", "")); - chainBalance.tokens.push({ - token: match[1], - amount: parseFloat(match[2].replace(",", "")), - valueUsd, - chain: chainBalance.chain, - }); - chainBalance.totalValueUsd += valueUsd; - } - } - - if (chainBalance.tokens.length > 0) { - portfolio.chains.push(chainBalance); - } - } - - return portfolio; -} - -// Parse single token balance -function parseTokenBalance(response: string, token: string): TokenBalance[] { - const balances: TokenBalance[] = []; - - // Example: "Your ETH balance: - // - Base: 2.5 ETH ($8,125.00) - // - Ethereum: 0.5 ETH ($1,625.00)" - - const lines = response.split("\n").filter((l) => l.startsWith("-")); - for (const line of lines) { - const match = line.match(/-\s+(\w+):\s+([0-9,.]+)\s+\w+\s+\(\$([0-9,.]+)\)/); - if (match) { - balances.push({ - token, - chain: match[1], - amount: parseFloat(match[2].replace(",", "")), - valueUsd: parseFloat(match[3].replace(",", "")), - }); - } - } - - return balances; -} - -async function handlePortfolioResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Portfolio query successful"); - console.log(result.response); - } else if (result.status === "failed") { - console.error("Portfolio query failed:", result.error); - } -} -``` - -## TypeScript Types - -```typescript -// Portfolio-specific types for your bot -interface PortfolioSnapshot { - timestamp: Date; - totalValueUsd: number; - holdings: TokenBalance[]; -} - -interface BalanceChange { - token: string; - chain: string; - previousAmount: number; - currentAmount: number; - change: number; - changePercent: number; -} - -interface PortfolioAlert { - type: "balance_drop" | "balance_rise" | "token_received" | "token_sent"; - token: string; - chain: string; - amount: number; - threshold: number; -} +Show my portfolio +What's my total balance? +Show my {chain} balance +How much {token} do I have? +Show my {token} on all chains +What tokens do I have on {chain}? ``` -## Bot Use Cases +**Supported chains:** Base, Polygon, Ethereum, Unichain, Solana -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Dashboard | Display portfolio | `Show my portfolio` | -| Balance Check | Pre-trade validation | `How much ETH do I have?` | -| Chain Monitor | Track specific chain | `Show my Base balance` | -| Token Tracker | Follow specific token | `Show my USDC on all chains` | -| Alert System | Monitor for changes | Compare snapshots | - -## Code Example: Portfolio Tracker +## Usage ```typescript import { execute } from "./bankr-client"; -class PortfolioTracker { - private snapshots: PortfolioSnapshot[] = []; - - async getPortfolio(): Promise { - const result = await execute(portfolioPrompts.totalPortfolio()); - return result.status === "completed" && result.response ? parsePortfolio(result.response) : null; - } - - async getChainBalance(chain: string): Promise { - const result = await execute(portfolioPrompts.chainBalance(chain)); - if (result.status !== "completed" || !result.response) return null; - const portfolio = parsePortfolio(result.response); - return portfolio.chains.find((c) => c.chain.toLowerCase() === chain.toLowerCase()) || null; - } - - async getTokenBalance(token: string): Promise { - const result = await execute(portfolioPrompts.tokenBalance(token)); - return result.status === "completed" && result.response ? parseTokenBalance(result.response, token) : []; - } - - async takeSnapshot(): Promise { - const portfolio = await this.getPortfolio(); - if (!portfolio) return null; - - const snapshot: PortfolioSnapshot = { - timestamp: new Date(), - totalValueUsd: portfolio.totalValueUsd, - holdings: portfolio.chains.flatMap((c) => c.tokens), - }; - - this.snapshots.push(snapshot); - if (this.snapshots.length > 100) this.snapshots.shift(); - - return snapshot; - } - - detectChanges(): BalanceChange[] { - if (this.snapshots.length < 2) return []; - - const previous = this.snapshots[this.snapshots.length - 2]; - const current = this.snapshots[this.snapshots.length - 1]; - const changes: BalanceChange[] = []; - - for (const holding of current.holdings) { - const prev = previous.holdings.find((h) => h.token === holding.token && h.chain === holding.chain); - const previousAmount = prev?.amount || 0; - const change = holding.amount - previousAmount; - - if (Math.abs(change) > 0.0001) { - changes.push({ - token: holding.token, - chain: holding.chain, - previousAmount, - currentAmount: holding.amount, - change, - changePercent: previousAmount > 0 ? (change / previousAmount) * 100 : 100, - }); - } - } - - for (const holding of previous.holdings) { - const stillExists = current.holdings.find((h) => h.token === holding.token && h.chain === holding.chain); - if (!stillExists && holding.amount > 0.0001) { - changes.push({ - token: holding.token, - chain: holding.chain, - previousAmount: holding.amount, - currentAmount: 0, - change: -holding.amount, - changePercent: -100, - }); - } - } - - return changes; - } - - async hasEnoughBalance(token: string, amount: number, chain?: string): Promise<{ enough: boolean; available: number; chain?: string }> { - const balances = await this.getTokenBalance(token); - - if (chain) { - const chainBalance = balances.find((b) => b.chain.toLowerCase() === chain.toLowerCase()); - const available = chainBalance?.amount || 0; - return { enough: available >= amount, available, chain }; - } - - const best = [...balances].sort((a, b) => b.amount - a.amount)[0]; - return best - ? { enough: best.amount >= amount, available: best.amount, chain: best.chain } - : { enough: false, available: 0 }; - } - - getValueHistory(): { timestamp: Date; value: number }[] { - return this.snapshots.map((s) => ({ timestamp: s.timestamp, value: s.totalValueUsd })); - } -} - -// Usage -const tracker = new PortfolioTracker(); - -// Get full portfolio -const portfolio = await tracker.getPortfolio(); -console.log("Total value:", portfolio?.totalValueUsd); -console.log("Chains:", portfolio?.chains.map((c) => c.chain)); - -// Check specific token -const ethBalances = await tracker.getTokenBalance("ETH"); -console.log("ETH holdings:", ethBalances); - -// Take periodic snapshots -setInterval(async () => { - await tracker.takeSnapshot(); - const changes = tracker.detectChanges(); - if (changes.length > 0) { - console.log("Balance changes detected:", changes); - } -}, 60000); - -// Check before trading -const canTrade = await tracker.hasEnoughBalance("ETH", 0.1, "Base"); -console.log("Can trade 0.1 ETH on Base:", canTrade); -``` - -## Portfolio Analytics - -```typescript -// Portfolio analysis utilities -function calculateAllocation(portfolio: Portfolio): Map { - const allocation = new Map(); - - for (const chain of portfolio.chains) { - for (const token of chain.tokens) { - const current = allocation.get(token.token) || 0; - allocation.set(token.token, current + token.valueUsd); - } - } - - // Convert to percentages - for (const [token, value] of allocation) { - allocation.set(token, (value / portfolio.totalValueUsd) * 100); - } - - return allocation; -} - -function getTopHoldings(portfolio: Portfolio, count: number = 5): TokenBalance[] { - const allTokens = portfolio.chains.flatMap((c) => c.tokens); - return allTokens.sort((a, b) => b.valueUsd - a.valueUsd).slice(0, count); -} - -function calculateChainExposure(portfolio: Portfolio): Map { - const exposure = new Map(); - - for (const chain of portfolio.chains) { - exposure.set(chain.chain, (chain.totalValueUsd / portfolio.totalValueUsd) * 100); - } - - return exposure; -} - -// Rebalancing suggestions -interface RebalanceSuggestion { - action: "buy" | "sell"; - token: string; - amount: number; - reason: string; -} - -function suggestRebalance( - portfolio: Portfolio, - targetAllocation: Map -): RebalanceSuggestion[] { - const suggestions: RebalanceSuggestion[] = []; - const currentAllocation = calculateAllocation(portfolio); - - for (const [token, targetPct] of targetAllocation) { - const currentPct = currentAllocation.get(token) || 0; - const diff = targetPct - currentPct; - - if (Math.abs(diff) > 2) { - // Only suggest if >2% off - const amount = (Math.abs(diff) / 100) * portfolio.totalValueUsd; - suggestions.push({ - action: diff > 0 ? "buy" : "sell", - token, - amount, - reason: `Currently ${currentPct.toFixed(1)}%, target ${targetPct}%`, - }); - } - } - - return suggestions; -} -``` - -## Dashboard Data Structure - -```typescript -// Data structure for building dashboards -interface DashboardData { - summary: { - totalValueUsd: number; - totalValueChange24h: number; - totalValueChangePercent24h: number; - }; - holdings: { - token: string; - totalAmount: number; - totalValueUsd: number; - priceUsd: number; - change24h: number; - chains: { chain: string; amount: number }[]; - }[]; - chainBreakdown: { - chain: string; - valueUsd: number; - percentage: number; - tokenCount: number; - }[]; - recentActivity: BalanceChange[]; -} - -async function buildDashboardData(tracker: PortfolioTracker): Promise { - const portfolio = await tracker.getPortfolio(); - if (!portfolio) throw new Error("Failed to fetch portfolio"); - - const history = tracker.getValueHistory(); - const value24hAgo = history.length > 24 ? history[history.length - 25]?.value : history[0]?.value; - const valueChange = portfolio.totalValueUsd - (value24hAgo || portfolio.totalValueUsd); - - return { - summary: { - totalValueUsd: portfolio.totalValueUsd, - totalValueChange24h: valueChange, - totalValueChangePercent24h: value24hAgo ? (valueChange / value24hAgo) * 100 : 0, - }, - holdings: [], // Aggregate tokens across chains - chainBreakdown: portfolio.chains.map((c) => ({ - chain: c.chain, - valueUsd: c.totalValueUsd, - percentage: (c.totalValueUsd / portfolio.totalValueUsd) * 100, - tokenCount: c.tokens.length, - })), - recentActivity: tracker.detectChanges(), - }; -} -``` - -## Error Handling - -Common errors and how to handle them in bots: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Empty response | No holdings found | Return empty portfolio | -| Chain unavailable | RPC issues | Skip chain, retry later | -| Token not recognized | Unknown token in wallet | Log warning, include raw data | -| Price data unavailable | Market data gap | Use last known price or mark as stale | -| Timeout | Large portfolio | Increase timeout, paginate if possible | - -```typescript -async function safeGetPortfolio(tracker: PortfolioTracker): Promise { - try { - const portfolio = await tracker.getPortfolio(); - - if (!portfolio || portfolio.chains.length === 0) { - console.warn("Empty portfolio returned"); - return { - totalValueUsd: 0, - chains: [], - lastUpdated: new Date(), - }; - } +// Full portfolio +await execute("Show my portfolio"); - return portfolio; - } catch (err) { - const error = err as Error; +// Chain-specific +await execute("Show my Base balance"); - if (error.message.includes("timeout")) { - console.error("Portfolio query timed out, retrying with longer timeout"); - // Implement retry logic - } +// Token-specific +await execute("How much ETH do I have?"); - console.error("Portfolio error:", error.message); - return null; - } -} +// Token across chains +await execute("Show my USDC on all chains"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-token-trading` - Trade based on portfolio data -- `bankr-market-research` - Price data for valuations diff --git a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md index 59bf4bf..8c9b513 100644 --- a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md @@ -1,547 +1,65 @@ --- name: Bankr Dev - Token Deployment -description: This skill should be used when building a token deployment system, implementing Clanker integration, creating fee auto-claiming, or automating token metadata updates. Covers TypeScript prompt templates like `tokenPrompts.deployWithSocials()`, deployment result parsing, batch deployment with rate limiting, and FeeAutoClaimer class. Triggered by "token deployment bot code", "Clanker integration TypeScript", "fee claiming automation", "batch token deployment". +description: Token deployment capability via the Bankr API (Clanker integration). Deploy ERC20 tokens, update metadata, and claim trading fees. Triggered by "deployment prompts", "Clanker patterns", "token creation", "fee claiming". version: 1.0.0 --- -# Token Deployment - Developer Guide +# Token Deployment Capability -Build bots and applications that deploy and manage tokens via Clanker and the Bankr API. +Deploy and manage tokens via natural language prompts. -## Overview +## What You Can Do -Token deployment through Bankr (via Clanker) supports: -- Deploy new ERC20 tokens -- Update token metadata -- Update token images -- Claim trading fees -- Manage reward recipients +| Operation | Example Prompt | +|-----------|----------------| +| Deploy token | `Deploy a token called MyToken with symbol MTK` | +| Deploy with description | `Deploy token MyToken (MTK) with description: A community token` | +| Deploy with socials | `Deploy token MyToken (MTK) with website https://mytoken.xyz and Twitter @mytoken` | +| Check fees | `Check my Clanker fees` | +| Claim fees | `Claim all my Clanker fees` | +| Claim for token | `Claim fees for my token MTK` | +| Claim legacy fees | `Claim legacy Clanker fees` | +| Update description | `Update description for MTK: New description here` | +| Update socials | `Update MTK Twitter to @newhandle` | +| Update image | `Update logo for MTK to https://...` | +| Update reward recipient | `Update reward recipient for MTK to 0x...` | -**Supported Chains:** Base (primary), Unichain (secondary) +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for token deployment operations -const tokenPrompts = { - // Deploy token - deploy: (name: string, symbol: string) => - `Deploy a token called ${name} with symbol ${symbol}`, - - deployWithDescription: (name: string, symbol: string, description: string) => - `Deploy a token called ${name} (${symbol}) with description: ${description}`, - - deployWithSocials: ( - name: string, - symbol: string, - options: { website?: string; twitter?: string; telegram?: string } - ) => { - let prompt = `Deploy token ${name} (${symbol})`; - if (options.website) prompt += ` with website ${options.website}`; - if (options.twitter) prompt += ` and Twitter @${options.twitter}`; - if (options.telegram) prompt += ` and Telegram @${options.telegram}`; - return prompt; - }, - - // Fee management - checkFees: () => "Check my Clanker fees", - claimFees: (token?: string) => - token ? `Claim fees for my token ${token}` : "Claim all my Clanker fees", - claimLegacyFees: () => "Claim legacy Clanker fees", - - // Metadata updates - updateDescription: (token: string, description: string) => - `Update description for ${token}: ${description}`, - updateSocials: (token: string, socials: { twitter?: string; website?: string }) => { - let prompt = `Update ${token}`; - if (socials.twitter) prompt += ` Twitter to @${socials.twitter}`; - if (socials.website) prompt += ` website to ${socials.website}`; - return prompt; - }, - updateImage: (token: string, imageUrl: string) => - `Update logo for ${token} to ${imageUrl}`, - - // Reward recipient - updateRewardRecipient: (token: string, address: string) => - `Update reward recipient for ${token} to ${address}`, -}; -``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -interface DeployedToken { - name: string; - symbol: string; - contractAddress: string; - chain: string; - deployedAt: Date; -} - -interface TokenFees { - token: string; - symbol: string; - unclaimedAmount: number; - currency: string; -} - -// Parse deployment response -function parseDeploymentResult(response: string): DeployedToken | null { - // Example: "Token deployed successfully!\n\nName: MyToken\nSymbol: MTK\nChain: Base\nContract: 0x1234...abcd" - const nameMatch = response.match(/Name:\s*(.+)/); - const symbolMatch = response.match(/Symbol:\s*(\w+)/); - const chainMatch = response.match(/Chain:\s*(\w+)/); - const contractMatch = response.match(/Contract:\s*(0x[a-fA-F0-9]+)/); - - if (!contractMatch) return null; - - return { - name: nameMatch?.[1] || "", - symbol: symbolMatch?.[1] || "", - contractAddress: contractMatch[1], - chain: chainMatch?.[1] || "Base", - deployedAt: new Date(), - }; -} - -// Parse fees response -function parseFees(response: string): TokenFees[] { - const fees: TokenFees[] = []; - // Example: "Your unclaimed Clanker fees:\n\nMyToken (MTK): 0.5 ETH\nOtherToken (OTK): 0.1 ETH" - const lines = response.split("\n").filter((l) => l.includes(":") && l.includes("ETH")); - - for (const line of lines) { - const match = line.match(/(.+?)\s*\((\w+)\):\s*([0-9.]+)\s*(\w+)/); - if (match) { - fees.push({ - token: match[1].trim(), - symbol: match[2], - unclaimedAmount: parseFloat(match[3]), - currency: match[4], - }); - } - } - - return fees; -} - -// Parse claim response -function parseClaimResult(response: string): { amount: number; currency: string } | null { - // Example: "Fees claimed successfully!\n\nToken: MyToken (MTK)\nAmount: 0.5 ETH" - const amountMatch = response.match(/Amount:\s*([0-9.]+)\s*(\w+)/); - if (amountMatch) { - return { - amount: parseFloat(amountMatch[1]), - currency: amountMatch[2], - }; - } - return null; -} - -async function handleDeploymentResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Token operation successful"); - console.log(result.response); - - const deployed = parseDeploymentResult(result.response || ""); - if (deployed) { - console.log(`Token deployed: ${deployed.symbol} at ${deployed.contractAddress}`); - } - } else if (result.status === "failed") { - console.error("Token operation failed:", result.error); - } -} ``` - -## TypeScript Types - -```typescript -// Token deployment specific types -interface TokenConfig { - name: string; - symbol: string; - description?: string; - imageUrl?: string; - website?: string; - twitter?: string; - telegram?: string; - discord?: string; -} - -interface DeploymentResult { - success: boolean; - token?: DeployedToken; - error?: string; -} - -interface FeeClaimResult { - success: boolean; - amount: number; - currency: string; - txHash?: string; -} - -// Rate limits -const RATE_LIMITS = { - standard: 1, // tokens per day - bankrClub: 10, // tokens per day -}; +Deploy a token called {name} with symbol {symbol} +Deploy token {name} ({symbol}) with description: {description} +Deploy token {name} ({symbol}) with website {url} and Twitter @{handle} +Check my Clanker fees +Claim all my Clanker fees +Update description for {symbol}: {new_description} +Update {symbol} Twitter to @{handle} ``` -## Bot Use Cases +**Supported chains:** Base (primary), Unichain (secondary) -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Token Launcher | Deploy new tokens | `Deploy token MyToken (MTK)` | -| Fee Claimer | Auto-claim fees | `Claim all my Clanker fees` | -| Metadata Manager | Update token info | `Update description for MTK` | -| Batch Deployer | Launch multiple tokens | Multiple deploy calls | +**Rate limits:** +- Standard: 1 token per day +- Bankr Club: 10 tokens per day -## Code Example: Token Manager +## Usage ```typescript import { execute } from "./bankr-client"; -class TokenManager { - private deployedTokens: DeployedToken[] = []; - - async deployToken(config: TokenConfig): Promise { - let prompt: string; - if (config.website || config.twitter || config.telegram) { - prompt = tokenPrompts.deployWithSocials(config.name, config.symbol, { - website: config.website, - twitter: config.twitter, - telegram: config.telegram, - }); - } else if (config.description) { - prompt = tokenPrompts.deployWithDescription(config.name, config.symbol, config.description); - } else { - prompt = tokenPrompts.deploy(config.name, config.symbol); - } - - const result = await execute(prompt, (msg) => console.log(" >", msg)); - if (result.status !== "completed") { - return { success: false, error: result.error || "Failed to deploy token" }; - } - - const token = parseDeploymentResult(result.response || ""); - if (!token) return { success: false, error: "Failed to parse deployment response" }; - - this.deployedTokens.push(token); - return { success: true, token }; - } - - async checkFees(): Promise { - const result = await execute(tokenPrompts.checkFees()); - return result.status === "completed" && result.response ? parseFees(result.response) : []; - } - - async claimFees(token?: string): Promise { - const result = await execute(tokenPrompts.claimFees(token)); - if (result.status !== "completed") return { success: false, amount: 0, currency: "ETH" }; - - const claimed = parseClaimResult(result.response || ""); - return claimed - ? { success: true, amount: claimed.amount, currency: claimed.currency } - : { success: false, amount: 0, currency: "ETH" }; - } - - async claimAllFees(): Promise { - const fees = await this.checkFees(); - const results: FeeClaimResult[] = []; - - for (const fee of fees) { - if (fee.unclaimedAmount > 0) { - results.push(await this.claimFees(fee.symbol)); - await new Promise((r) => setTimeout(r, 3000)); - } - } - - return results; - } - - async updateMetadata(symbol: string, updates: { description?: string; twitter?: string; website?: string }): Promise { - if (updates.description) { - const result = await execute(tokenPrompts.updateDescription(symbol, updates.description)); - if (result.status !== "completed") return false; - } - - if (updates.twitter || updates.website) { - const result = await execute(tokenPrompts.updateSocials(symbol, { twitter: updates.twitter, website: updates.website })); - if (result.status !== "completed") return false; - } - - return true; - } - - async updateImage(symbol: string, imageUrl: string): Promise { - return (await execute(tokenPrompts.updateImage(symbol, imageUrl))).status === "completed"; - } - - getDeployedTokens(): DeployedToken[] { - return this.deployedTokens; - } -} - -// Usage -const manager = new TokenManager(); - -// Deploy a token -const deployResult = await manager.deployToken({ - name: "MyAwesomeToken", - symbol: "MAT", - description: "A community token for awesome people", - website: "https://mytoken.xyz", - twitter: "mytoken", -}); - -console.log("Deployment result:", deployResult); - -// Check fees -const fees = await manager.checkFees(); -console.log("Unclaimed fees:", fees); - -// Claim all fees -const claimResults = await manager.claimAllFees(); -console.log("Claimed fees:", claimResults); - -// Update metadata -await manager.updateMetadata("MAT", { - description: "Updated description for the token", - twitter: "newhandle", -}); -``` - -## Batch Token Deployment - -```typescript -interface BatchDeployConfig { - tokens: TokenConfig[]; - delayBetween: number; // milliseconds - maxPerDay: number; -} - -class BatchDeployer { - private deployed: DeployedToken[] = []; - private deployedToday = 0; - - async deployBatch( - configs: TokenConfig[], - manager: TokenManager, - options: { delayMs: number; maxPerDay: number } - ): Promise { - const results: DeploymentResult[] = []; - - for (const config of configs) { - if (this.deployedToday >= options.maxPerDay) break; - - const result = await manager.deployToken(config); - results.push(result); - - if (result.success && result.token) { - this.deployed.push(result.token); - this.deployedToday++; - } - - await new Promise((r) => setTimeout(r, options.delayMs)); - } - - return results; - } - - resetDailyCount(): void { - this.deployedToday = 0; - } -} - -// Example: Batch deploy tokens -const deployer = new BatchDeployer(); -const tokens: TokenConfig[] = [ - { name: "Token One", symbol: "ONE" }, - { name: "Token Two", symbol: "TWO" }, - { name: "Token Three", symbol: "THREE" }, -]; - -const batchResults = await deployer.deployBatch(tokens, manager, { - delayMs: 10000, // 10 seconds between deploys - maxPerDay: RATE_LIMITS.standard, -}); -``` - -## Fee Auto-Claimer - -```typescript -interface FeeClaimerConfig { - checkInterval: number; // milliseconds - minClaimAmount: number; // minimum ETH to trigger claim - autoClaimLegacy: boolean; -} - -class FeeAutoClaimer { - private isRunning = false; - private intervalId?: NodeJS.Timeout; - - constructor(private manager: TokenManager, private config: FeeClaimerConfig) {} - - start(): void { - if (this.isRunning) return; - this.isRunning = true; - - this.intervalId = setInterval(() => this.checkAndClaim(), this.config.checkInterval); - this.checkAndClaim(); - } - - stop(): void { - if (this.intervalId) { - clearInterval(this.intervalId); - this.intervalId = undefined; - } - this.isRunning = false; - } - - private async checkAndClaim(): Promise { - const fees = await this.manager.checkFees(); - const totalUnclaimed = fees.reduce((sum, f) => sum + f.unclaimedAmount, 0); - - if (totalUnclaimed >= this.config.minClaimAmount) { - const results = await this.manager.claimAllFees(); - const totalClaimed = results.filter((r) => r.success).reduce((sum, r) => sum + r.amount, 0); - console.log(`Claimed ${totalClaimed} ETH`); - } - - if (this.config.autoClaimLegacy) { - await execute(tokenPrompts.claimLegacyFees()); - } - } -} - -// Usage -const claimer = new FeeAutoClaimer(manager, { - checkInterval: 3600000, // Check every hour - minClaimAmount: 0.01, // Claim when > 0.01 ETH accumulated - autoClaimLegacy: true, -}); - -claimer.start(); -``` - -## Token Naming Validation - -```typescript -interface NamingValidation { - valid: boolean; - errors: string[]; - suggestions?: string[]; -} - -function validateTokenConfig(config: TokenConfig): NamingValidation { - const errors: string[] = []; - const suggestions: string[] = []; - - // Check symbol - if (config.symbol.length < 2) { - errors.push("Symbol too short (min 2 characters)"); - } - if (config.symbol.length > 5) { - errors.push("Symbol too long (max 5 characters)"); - } - if (!/^[A-Z0-9]+$/.test(config.symbol.toUpperCase())) { - errors.push("Symbol should be alphanumeric"); - } - - // Check name - if (config.name.length < 2) { - errors.push("Name too short"); - } - if (config.name.length > 32) { - errors.push("Name too long (max 32 characters)"); - } - - // Check for common issues - const commonSymbols = ["ETH", "BTC", "USDC", "USDT", "SOL", "BNKR"]; - if (commonSymbols.includes(config.symbol.toUpperCase())) { - errors.push("Symbol conflicts with major token"); - suggestions.push(`Consider: ${config.symbol}2, x${config.symbol}`); - } - - return { - valid: errors.length === 0, - errors, - suggestions: suggestions.length > 0 ? suggestions : undefined, - }; -} - -// Example usage -const validation = validateTokenConfig({ - name: "My Token", - symbol: "MTK", -}); - -if (!validation.valid) { - console.log("Validation errors:", validation.errors); - if (validation.suggestions) { - console.log("Suggestions:", validation.suggestions); - } -} else { - console.log("Config is valid, ready to deploy"); -} -``` - -## Error Handling - -Common errors and how to handle them: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Rate limit reached | Daily limit exceeded | Wait 24 hours or upgrade | -| Name taken | Duplicate name | Choose different name | -| Symbol exists | Duplicate symbol | Choose different symbol | -| Image upload failed | Invalid format/size | Validate before upload | - -```typescript -async function safeDeployToken( - config: TokenConfig, - manager: TokenManager -): Promise { - // Validate first - const validation = validateTokenConfig(config); - if (!validation.valid) { - return { - success: false, - error: `Validation failed: ${validation.errors.join(", ")}`, - }; - } - - // Attempt deployment - const result = await manager.deployToken(config); +// Deploy token +await execute("Deploy a token called MyToken with symbol MTK"); - if (!result.success) { - // Handle specific errors - if (result.error?.includes("rate limit")) { - return { - success: false, - error: "Daily deployment limit reached. Try again in 24 hours.", - }; - } - if (result.error?.includes("name taken") || result.error?.includes("symbol exists")) { - return { - success: false, - error: "Name or symbol already exists. Please choose a different one.", - }; - } - } +// With socials +await execute("Deploy token MyToken (MTK) with website https://mytoken.xyz and Twitter @mytoken"); - return result; -} +// Check and claim fees +await execute("Check my Clanker fees"); +await execute("Claim all my Clanker fees"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-token-trading` - Trade deployed tokens -- `bankr-market-research` - Track token performance diff --git a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md index 360a2dd..21f3624 100644 --- a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md @@ -1,220 +1,55 @@ --- name: Bankr Dev - Token Trading -description: This skill should be used when building a trading bot, implementing token swaps programmatically, creating a DCA bot, building an arbitrage system, or automating cross-chain bridges. Covers TypeScript prompt templates like `tradingPrompts.buy()`, swap response parsing, and complete TradingBot class implementation. Triggered by "trading bot code", "swap prompt template", "TypeScript trading types", "programmatic token swaps". +description: Token swap and trading capability via the Bankr API. Covers same-chain swaps, cross-chain bridges, ETH/WETH conversions, and multiple amount formats. Triggered by "trading prompts", "swap patterns", "buy/sell tokens", "bridge tokens". version: 1.0.0 --- -# Token Trading - Developer Guide +# Token Trading Capability -Build bots and applications that trade tokens via the Bankr API. +Execute token swaps and trades via natural language prompts. -## Overview +## What You Can Do -Token trading through Bankr supports: -- Same-chain swaps (buy/sell tokens) -- Cross-chain bridges and swaps -- ETH/WETH conversions -- Multiple amount formats (USD, percentage, exact) +| Operation | Example Prompt | +|-----------|----------------| +| Buy tokens | `Buy $50 of ETH` | +| Sell tokens | `Sell 10% of my USDC` | +| Swap tokens | `Swap 0.1 ETH for USDC` | +| Cross-chain bridge | `Bridge 100 USDC from Ethereum to Base` | +| Cross-chain swap | `Swap ETH on Ethereum for USDC on Polygon` | +| Wrap ETH | `Convert 1 ETH to WETH` | +| Unwrap WETH | `Convert 1 WETH to ETH` | -**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for trading operations -const tradingPrompts = { - // Same-chain swaps - buy: (amount: string, token: string, chain?: string) => - chain ? `Buy ${amount} of ${token} on ${chain}` : `Buy ${amount} of ${token}`, - - sell: (amount: string, token: string, chain?: string) => - chain ? `Sell ${amount} of ${token} on ${chain}` : `Sell ${amount} of ${token}`, - - swap: (fromAmount: string, fromToken: string, toToken: string, chain?: string) => - chain - ? `Swap ${fromAmount} ${fromToken} for ${toToken} on ${chain}` - : `Swap ${fromAmount} ${fromToken} for ${toToken}`, - - // Cross-chain - bridge: (amount: string, token: string, fromChain: string, toChain: string) => - `Bridge ${amount} ${token} from ${fromChain} to ${toChain}`, - - crossChainSwap: (fromToken: string, fromChain: string, toToken: string, toChain: string) => - `Swap ${fromToken} on ${fromChain} for ${toToken} on ${toChain}`, - - // ETH/WETH conversion - wrapEth: (amount: string) => `Convert ${amount} ETH to WETH`, - unwrapWeth: (amount: string) => `Convert ${amount} WETH to ETH`, -}; - -// Amount format helpers -const formatAmount = { - usd: (dollars: number) => `$${dollars}`, - percentage: (pct: number) => `${pct}%`, - exact: (amount: number, token: string) => `${amount} ${token}`, -}; -``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -async function handleTradeResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Trade successful:", result.response); - - // Process executed transactions - if (result.transactions) { - for (const tx of result.transactions) { - const data = tx.metadata.__ORIGINAL_TX_DATA__; - if (data) { - console.log(data.humanReadableMessage); - console.log(`${data.inputTokenAmount} ${data.inputTokenTicker} → ${data.outputTokenTicker}`); - } else if (tx.metadata.description) { - console.log(tx.metadata.description); - } - } - } - } else if (result.status === "failed") { - console.error("Trade failed:", result.error); - } -} ``` - -## TypeScript Types - -Reference `bankr-client-patterns` skill for complete types. Key trading types: - -```typescript -// Transaction types for trading -type TradingTransaction = - | SwapTransaction - | ApprovalTransaction - | ConvertEthToWethTransaction - | ConvertWethToEthTransaction - | SwapCrossChainTransaction; - -// Swap transaction metadata -interface SwapMetadata { - __ORIGINAL_TX_DATA__: { - chain: string; - humanReadableMessage: string; - inputTokenAddress: string; - inputTokenAmount: string; - inputTokenTicker: string; - outputTokenAddress: string; - outputTokenAmount: string; - outputTokenTicker: string; - receiver: string; - }; - approvalRequired?: boolean; - approvalTx?: { to: string; data: string }; -} +Buy {amount} of {token} [on {chain}] +Sell {amount} of {token} [on {chain}] +Swap {amount} {fromToken} for {toToken} [on {chain}] +Bridge {amount} {token} from {sourceChain} to {destChain} ``` -## Bot Use Cases +**Amount formats:** +- USD: `$50`, `$100` +- Percentage: `10%`, `50%` +- Exact: `0.5 ETH`, `100 USDC` -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| DCA Bot | Regular purchases at intervals | `Buy $100 of ETH` | -| Dip Buyer | Buy when price drops | `Buy $50 of ETH on Base` | -| Arbitrage | Cross-chain price differences | `Swap ETH on Ethereum for USDC on Polygon` | -| Rebalancer | Maintain portfolio ratios | `Sell 10% of my ETH for USDC` | -| Auto-Sell | Take profits at targets | `Sell $500 worth of BNKR` | +**Supported chains:** Base, Polygon, Ethereum, Unichain, Solana -## Code Example: Trading Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface TradeConfig { - token: string; - chain: string; - buyAmount: string; -} - -class TradingBot { - constructor(private config: TradeConfig) {} - - async executeBuy(): Promise { - const prompt = tradingPrompts.buy(`$${this.config.buyAmount}`, this.config.token, this.config.chain); - const result = await execute(prompt, (msg) => console.log(" >", msg)); - await handleTradeResponse(result); - } - - async executeSell(percentage: number): Promise { - const prompt = tradingPrompts.sell(`${percentage}%`, this.config.token, this.config.chain); - const result = await execute(prompt, (msg) => console.log(" >", msg)); - await handleTradeResponse(result); - } - - async executeSwap(fromToken: string, toToken: string, amount: string): Promise { - const prompt = tradingPrompts.swap(amount, fromToken, toToken, this.config.chain); - const result = await execute(prompt, (msg) => console.log(" >", msg)); - await handleTradeResponse(result); - } -} - -// Usage -const bot = new TradingBot({ token: "ETH", chain: "Base", buyAmount: "50" }); -await bot.executeBuy(); -``` - -## Error Handling - -Common errors and how to handle them in bots: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| Insufficient balance | Not enough funds | Log and skip, or adjust amount | -| Token not found | Invalid symbol | Verify token exists, use contract address | -| High slippage | Price moved too much | Retry with smaller amount | -| Network congestion | Chain is busy | Implement retry with backoff | - -```typescript -async function executeTradeWithRetry(prompt: string, maxRetries = 3): Promise { - for (let attempt = 1; attempt <= maxRetries; attempt++) { - const result = await execute(prompt); - - if (result.status === "completed") return result; - - const error = result.error || ""; - const isRetryable = error.includes("slippage") || error.includes("congestion"); - - if (!isRetryable || attempt === maxRetries) { - console.error(`Trade failed: ${error}`); - return result; - } - - console.log(`Attempt ${attempt} failed, retrying...`); - await new Promise((r) => setTimeout(r, 5000 * attempt)); - } - return null; -} -``` - -## Chain Selection - -```typescript -const CHAINS = { - base: { native: "ETH", lowFees: true }, - polygon: { native: "MATIC", lowFees: true }, - ethereum: { native: "ETH", lowFees: false }, - solana: { native: "SOL", lowFees: true }, - unichain: { native: "ETH", lowFees: true }, -}; +// Simple trade +await execute("Buy $50 of ETH on Base"); -function selectChain(preferLowFees = true): string { - return preferLowFees ? "Base" : "Ethereum"; -} +// Cross-chain +await execute("Bridge 100 USDC from Ethereum to Base"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals -- `bankr-automation` - Limit orders and scheduled trades - `bankr-market-research` - Price data for trading decisions diff --git a/bankr-agent-dev/skills/bankr-transfers/SKILL.md b/bankr-agent-dev/skills/bankr-transfers/SKILL.md index 3aaed43..8a80c2f 100644 --- a/bankr-agent-dev/skills/bankr-transfers/SKILL.md +++ b/bankr-agent-dev/skills/bankr-transfers/SKILL.md @@ -1,323 +1,56 @@ --- name: Bankr Dev - Transfers -description: This skill should be used when building a payment bot, implementing batch transfers, creating a tip bot, automating payroll with ENS resolution, or building a distribution system. Covers TypeScript prompt templates like `transferPrompts.toEns()`, recipient validation patterns, and PaymentBot class with batch processing. Triggered by "payment bot code", "transfer prompt template", "ENS resolution TypeScript", "batch transfer implementation". +description: Token transfer capability via the Bankr API. Supports wallet addresses, ENS names, and social handles with automatic resolution. Triggered by "transfer prompts", "send tokens", "payment patterns", "ENS resolution". version: 1.0.0 --- -# Transfers - Developer Guide +# Transfers Capability -Build bots and applications that transfer tokens via the Bankr API. +Send tokens to any recipient via natural language prompts. -## Overview +## What You Can Do -Token transfers through Bankr support: -- Direct wallet addresses (0x...) -- ENS name resolution (vitalik.eth) -- Social handle resolution (@username on Twitter, Farcaster, Telegram) -- Multiple chains and token types +| Operation | Example Prompt | +|-----------|----------------| +| Send to address | `Send 0.1 ETH to 0x1234...abcd` | +| Send to ENS | `Send $50 USDC to vitalik.eth` | +| Send to Twitter | `Send $5 ETH to @username on Twitter` | +| Send to Farcaster | `Send 10 USDC to @user on Farcaster` | +| Send to Telegram | `Send 0.01 ETH to @user on Telegram` | +| Percentage send | `Send 10% of my ETH to 0x...` | -**Supported Chains:** Base, Polygon, Ethereum, Unichain, Solana +## Prompt Patterns -> **Note:** All types shown in this skill are for reference. Import canonical types from `bankr-client.ts` (see `bankr-client-patterns` skill). Response parsing functions are examples based on typical formats - test against real API responses and add fallback handling for production use. - -## Prompt Templates - -```typescript -// Prompt builders for transfer operations -const transferPrompts = { - // To address - toAddress: (amount: string, token: string, address: string, chain?: string) => - chain - ? `Send ${amount} ${token} to ${address} on ${chain}` - : `Send ${amount} ${token} to ${address}`, - - // To ENS name - toEns: (amount: string, token: string, ens: string, chain?: string) => - chain - ? `Send ${amount} ${token} to ${ens} on ${chain}` - : `Send ${amount} ${token} to ${ens}`, - - // To social handle - toSocial: (amount: string, token: string, handle: string, platform: string) => - `Send ${amount} ${token} to ${handle} on ${platform}`, -}; - -// Recipient format helpers -const formatRecipient = { - address: (addr: string) => addr, - ens: (name: string) => name, - social: (handle: string, platform: string) => `@${handle.replace("@", "")} on ${platform}`, -}; ``` - -## Response Handling - -```typescript -import { execute, JobStatusResponse } from "./bankr-client"; - -async function handleTransferResponse(result: JobStatusResponse) { - if (result.status === "completed") { - console.log("Transfer successful:", result.response); - - // Process executed transactions - if (result.transactions) { - for (const tx of result.transactions) { - const data = tx.metadata.__ORIGINAL_TX_DATA__; - if (data) { - console.log(`Sent ${data.inputTokenAmount} ${data.inputTokenTicker}`); - console.log(`To: ${data.receiver}`); - console.log(`Message: ${data.humanReadableMessage}`); - } - } - } - } else if (result.status === "failed") { - console.error("Transfer failed:", result.error); - } -} - -// Extract resolved address from response -function extractResolvedAddress(result: JobStatusResponse): string | null { - if (result.transactions?.[0]) { - return result.transactions[0].metadata.__ORIGINAL_TX_DATA__.receiver; - } - return null; -} +Send {amount} {token} to {recipient} [on {chain}] ``` -## TypeScript Types +**Recipient formats:** +- Wallet address: `0x1234...abcd` +- ENS name: `vitalik.eth`, `name.eth` +- Social handle: `@username on Twitter/Farcaster/Telegram` -Reference `bankr-client-patterns` skill for complete types. Key transfer types: +**Amount formats:** +- USD: `$50`, `$100` +- Percentage: `10%`, `50%` +- Exact: `0.5 ETH`, `100 USDC` -```typescript -// Transaction types for transfers -type TransferTransaction = - | TransferEthTransaction - | TransferErc20Transaction - | TransferNftTransaction; +**Supported chains:** Base, Polygon, Ethereum, Unichain, Solana -// Transfer transaction metadata -interface TransferMetadata { - __ORIGINAL_TX_DATA__: { - chain: string; - humanReadableMessage: string; - inputTokenAddress: string; - inputTokenAmount: string; - inputTokenTicker: string; - receiver: string; // Resolved address - }; -} -``` - -## Bot Use Cases - -| Use Case | Description | Example Prompt | -|----------|-------------|----------------| -| Payroll Bot | Scheduled payments to team | `Send $500 USDC to 0x...` | -| Tip Bot | Reward users via social | `Send $5 ETH to @user on Twitter` | -| Distribution Bot | Airdrop to multiple addresses | `Send 100 BNKR to vitalik.eth` | -| Allowance Bot | Regular transfers to wallets | `Send 10% of my ETH to 0x...` | - -## Code Example: Payment Bot +## Usage ```typescript import { execute } from "./bankr-client"; -interface Payment { - recipient: string; - recipientType: "address" | "ens" | "twitter" | "farcaster"; - amount: string; - token: string; - chain?: string; -} - -class PaymentBot { - async processPayment(payment: Payment): Promise { - const prompt = this.buildPrompt(payment); - const result = await execute(prompt, (msg) => console.log(" >", msg)); - - if (result.status === "completed") { - console.log("Payment sent to:", extractResolvedAddress(result)); - return true; - } - - console.error("Payment failed:", result.error); - return false; - } - - private buildPrompt(payment: Payment): string { - const { recipient, recipientType, amount, token, chain } = payment; - - switch (recipientType) { - case "address": - case "ens": - return transferPrompts.toAddress(amount, token, recipient, chain); - case "twitter": - case "farcaster": - return transferPrompts.toSocial(amount, token, formatRecipient.social(recipient, recipientType), recipientType); - default: - return transferPrompts.toAddress(amount, token, recipient, chain); - } - } - - async processBatch(payments: Payment[]): Promise<{ success: number; failed: number }> { - let success = 0; - let failed = 0; - - for (const payment of payments) { - const result = await this.processPayment(payment); - if (result) { - success++; - } else { - failed++; - } - - // Add delay between transfers to avoid rate limiting - await new Promise((r) => setTimeout(r, 3000)); - } - - return { success, failed }; - } -} - -// Usage -const bot = new PaymentBot(); - -// Single payment -await bot.processPayment({ - recipient: "vitalik.eth", - recipientType: "ens", - amount: "0.01", - token: "ETH", - chain: "Base", -}); - -// Batch payments -const payments: Payment[] = [ - { recipient: "0x1234...", recipientType: "address", amount: "100", token: "USDC" }, - { recipient: "alice.eth", recipientType: "ens", amount: "0.05", token: "ETH" }, - { recipient: "bob", recipientType: "twitter", amount: "$10", token: "ETH" }, -]; - -const results = await bot.processBatch(payments); -console.log(`Completed: ${results.success} success, ${results.failed} failed`); -``` - -## Recipient Resolution - -Bankr resolves recipients automatically. Here's how to validate before sending: - -```typescript -// Validate recipient format -function validateRecipient(recipient: string): { - type: "address" | "ens" | "social"; - valid: boolean; - normalized: string; -} { - // Ethereum address - if (/^0x[a-fA-F0-9]{40}$/.test(recipient)) { - return { type: "address", valid: true, normalized: recipient.toLowerCase() }; - } - - // ENS name - if (recipient.endsWith(".eth")) { - return { type: "ens", valid: true, normalized: recipient.toLowerCase() }; - } - - // Social handle (starts with @) - if (recipient.startsWith("@")) { - return { type: "social", valid: true, normalized: recipient }; - } - - return { type: "address", valid: false, normalized: recipient }; -} - -// Resolution may fail for these reasons: -const RESOLUTION_ERRORS = { - ENS_NOT_FOUND: "ENS name does not exist", - NO_LINKED_WALLET: "Social handle has no linked wallet", - INVALID_ADDRESS: "Address format is invalid", -}; -``` - -## Error Handling - -Common errors and how to handle them in bots: - -| Error | Cause | Bot Response | -|-------|-------|--------------| -| ENS not found | Invalid ENS name | Verify ENS exists | -| No linked wallet | Social user hasn't linked | Skip or notify user | -| Insufficient balance | Not enough funds | Check balance first | -| Invalid address | Malformed address | Validate format | - -```typescript -async function safeTransfer( - recipient: string, - amount: string, - token: string -): Promise<{ success: boolean; error?: string }> { - const validation = validateRecipient(recipient); - if (!validation.valid) { - return { success: false, error: "Invalid recipient format" }; - } - - const result = await execute(`Send ${amount} ${token} to ${recipient}`); - - if (result.status === "completed") { - return { success: true }; - } - - const error = result.error || "Unknown error"; - if (error.includes("not found") || error.includes("no linked wallet")) { - return { success: false, error: "Recipient could not be resolved" }; - } - if (error.includes("Insufficient")) { - return { success: false, error: "Insufficient balance" }; - } - - return { success: false, error }; -} -``` - -## Security Considerations - -```typescript -// Best practices for transfer bots -const TRANSFER_LIMITS = { - maxSingleTransfer: 1000, // USD - maxDailyTotal: 10000, // USD - requireConfirmation: 500, // Above this, require extra verification -}; - -function checkTransferLimits( - amountUsd: number, - dailyTotalUsd: number -): { allowed: boolean; reason?: string } { - if (amountUsd > TRANSFER_LIMITS.maxSingleTransfer) { - return { allowed: false, reason: "Exceeds single transfer limit" }; - } - if (dailyTotalUsd + amountUsd > TRANSFER_LIMITS.maxDailyTotal) { - return { allowed: false, reason: "Exceeds daily limit" }; - } - return { allowed: true }; -} +// To ENS +await execute("Send 0.1 ETH to vitalik.eth on Base"); -// Always log transfers for audit -function logTransfer(payment: Payment, result: JobStatusResponse) { - console.log(JSON.stringify({ - timestamp: new Date().toISOString(), - recipient: payment.recipient, - amount: payment.amount, - token: payment.token, - status: result.status, - jobId: result.jobId, - resolvedAddress: result.transactions?.[0]?.metadata.__ORIGINAL_TX_DATA__.receiver, - })); -} +// To social handle +await execute("Send $5 ETH to @user on Twitter"); ``` ## Related Skills -- `bankr-client-patterns` - Client code and TypeScript types +- `bankr-client-patterns` - Client setup and execute function - `bankr-api-basics` - API fundamentals - `bankr-portfolio` - Check balances before transfers diff --git a/bankr-agent/skills/bankr-automation/SKILL.md b/bankr-agent/skills/bankr-automation/SKILL.md index b80c100..b3d6426 100644 --- a/bankr-agent/skills/bankr-automation/SKILL.md +++ b/bankr-agent/skills/bankr-automation/SKILL.md @@ -8,258 +8,60 @@ version: 1.0.0 Set up automated orders and scheduled trading strategies. -## Overview - -Bankr supports various automation types: -- **Limit Orders**: Execute at target price -- **Stop Loss**: Sell when price drops -- **DCA**: Dollar Cost Averaging -- **TWAP**: Time-Weighted Average Price -- **Scheduled Commands**: Cron-based automation -- **Solana Triggers**: Jupiter trigger orders - ## Order Types ### Limit Orders - -Execute a trade when price reaches a target: - -``` -"Set a limit order to buy ETH at $3,000" -"Buy 0.5 ETH when price drops to $2,800" -"Limit order: sell BNKR when it hits $0.02" -``` - -**Parameters**: -- Token to buy/sell -- Target price -- Amount +Execute at target price: +- "Set a limit order to buy ETH at $3,000" +- "Limit order: sell BNKR when it hits $0.02" ### Stop Loss Orders - Automatically sell to limit losses: - -``` -"Set stop loss for my ETH at $2,500" -"Stop loss: sell 50% of BNKR if it drops 20%" -"Protect my SOL with stop loss at $150" -``` - -**Parameters**: -- Token to sell -- Trigger price or percentage -- Amount to sell +- "Set stop loss for my ETH at $2,500" +- "Stop loss: sell 50% of BNKR if it drops 20%" ### DCA (Dollar Cost Averaging) - Invest fixed amounts at regular intervals: - -``` -"DCA $100 into ETH every week" -"Set up daily $50 Bitcoin purchases" -"Start a DCA: buy $25 of BNKR every day" -``` - -**Parameters**: -- Token to buy -- Amount per purchase -- Frequency (daily, weekly, monthly) -- Duration (optional) +- "DCA $100 into ETH every week" +- "Set up daily $50 Bitcoin purchases" ### TWAP (Time-Weighted Average Price) - -Spread a large order over time: - -``` -"TWAP: buy $1000 of ETH over 24 hours" -"Execute $500 ETH purchase using TWAP" -"Spread my sell order over 4 hours" -``` - -**Parameters**: -- Token and amount -- Total duration -- Number of intervals +Spread large orders over time: +- "TWAP: buy $1000 of ETH over 24 hours" +- "Spread my sell order over 4 hours" ### Scheduled Commands - Run any Bankr command on a schedule: +- "Every morning, check my portfolio" +- "At 9am daily, check ETH price" -``` -"Every morning, check my portfolio" -"Schedule a weekly rebalance" -"At 9am daily, check ETH price" -``` - -**Parameters**: -- Command to execute -- Schedule (cron or description) - -## Prompt Examples - -### Limit Orders - -``` -"Set a limit order to buy ETH at $3,000" -"Limit buy 0.5 BTC when price hits $90,000" -"Create limit sell for BNKR at $0.02" -"Buy SOL when it drops to $180" -``` - -### Stop Loss - -``` -"Set stop loss on my ETH at $2,800" -"Stop loss: sell all BNKR if it drops 30%" -"Protect my position with 15% stop loss" -"Stop loss for SOL at $140" -``` - -### DCA - -``` -"Set up DCA: $100 into ETH weekly" -"Start daily DCA of $50 into Bitcoin" -"DCA $25 into BNKR every day for a month" -"Begin weekly $200 ETH accumulation" -``` - -### TWAP - -``` -"TWAP buy $5000 of ETH over 48 hours" -"Spread my $2000 BTC purchase over 24 hours" -"Execute TWAP sell of 1000 USDC over 4 hours" -``` - -### Scheduled - -``` -"Every day at 9am, check ETH price" -"Weekly on Monday, show my portfolio" -"Schedule daily portfolio check" -``` +## Managing Automations -### Managing Automations +**View:** +- "Show my automations" +- "What limit orders do I have?" -``` -"Show my automations" -"What limit orders do I have?" -"Cancel my ETH stop loss" -"List all my scheduled orders" -``` +**Cancel:** +- "Cancel my ETH limit order" +- "Stop my DCA into Bitcoin" ## Chain Support -### EVM Chains (Base, Polygon, Ethereum) - -All order types supported: -- Limit orders -- Stop loss -- DCA -- TWAP -- Scheduled commands - -### Solana - -Uses Jupiter Trigger API: -- Limit orders -- Stop loss -- DCA orders - -## Automation Management - -### View Automations - -``` -"Show my automations" -"List my active orders" -"What DCA orders do I have?" -"Check my limit orders" -``` - -### Cancel Automations - -``` -"Cancel my ETH limit order" -"Remove stop loss on BNKR" -"Stop my DCA into Bitcoin" -"Cancel all my automations" -``` - -### Check History - -``` -"Show automation history" -"What orders executed today?" -"Check DCA execution history" -``` - -## Response Format - -### Order Created - -```json -{ - "status": "completed", - "response": "Limit order created:\n- Buy 0.5 ETH when price reaches $3,000\n- Order ID: lmt_ABC123\n\nYou'll be notified when it executes." -} -``` - -### Automation List - -```json -{ - "response": "Your active automations:\n\n1. Limit Order (lmt_ABC123)\n Buy 0.5 ETH at $3,000\n Status: Waiting\n\n2. DCA (dca_XYZ789)\n $100 → ETH weekly\n Next: Monday 9:00 AM\n\n3. Stop Loss (sl_DEF456)\n Sell ETH if price < $2,500\n Status: Active" -} -``` - -## Best Practices - -### Limit Orders - -- Set realistic target prices -- Consider market liquidity -- Monitor for partial fills - -### Stop Loss - -- Don't set too tight (normal volatility) -- Consider trailing stop loss for profits -- Review periodically - -### DCA - -- Good for long-term accumulation -- Reduces timing risk -- Set and forget approach - -### TWAP - -- Use for large orders -- Minimizes market impact -- Better average price +- **EVM Chains** (Base, Polygon, Ethereum): All order types supported +- **Solana**: Uses Jupiter Trigger API for limit orders, stop loss, and DCA ## Common Issues | Issue | Resolution | |-------|------------| | Order not triggering | Check price threshold | -| Insufficient balance | Ensure funds available | -| Order cancelled | May expire or conflict | -| Network issues | Orders resume automatically | - -## Fees - -- **Order creation**: Minimal gas -- **Execution**: Standard trading fees -- **DCA**: Per-transaction fees apply -- **Cancellation**: Small gas cost +| Insufficient balance | Ensure funds available when order executes | +| Order cancelled | May expire or conflict with other orders | ## Tips -1. **Start small** - Test with small amounts first -2. **Set alerts** - Get notified on execution -3. **Review regularly** - Update orders as needed -4. **Combine strategies** - DCA + stop loss -5. **Consider fees** - Factor into order sizes +1. Start small - test with small amounts first +2. Set alerts - get notified on execution +3. Review regularly - update orders as market changes +4. Combine strategies - DCA + stop loss works well +5. Factor in fees - consider per-transaction costs for DCA diff --git a/bankr-agent/skills/bankr-error-handling/SKILL.md b/bankr-agent/skills/bankr-error-handling/SKILL.md index 36ede96..cabb7dc 100644 --- a/bankr-agent/skills/bankr-error-handling/SKILL.md +++ b/bankr-agent/skills/bankr-error-handling/SKILL.md @@ -10,17 +10,13 @@ Resolve Bankr API errors and authentication issues. ## Authentication Errors (401) -The most common error is an authentication failure due to missing or invalid API key. - ### Symptoms - - HTTP 401 status code -- Error message: "Invalid API key" or "Unauthorized" -- Job submission fails immediately +- "Invalid API key" or "Unauthorized" message -### Resolution Steps +### Resolution -Present these setup instructions clearly to the user: +Present these setup instructions to the user: **Step 1: Create an API Key** ``` @@ -31,9 +27,6 @@ Visit https://bankr.bot/api to create a new API key ```bash # Add to shell profile (~/.zshrc or ~/.bashrc) export BANKR_API_KEY=bk_your_api_key_here - -# Or create .env file in project root -BANKR_API_KEY=bk_your_api_key_here ``` **Step 3: Restart Claude Code** @@ -41,183 +34,45 @@ BANKR_API_KEY=bk_your_api_key_here Close and reopen the terminal/Claude Code session ``` -### Important - -- **DO NOT retry** when authentication fails -- The user must fix their API key configuration first -- Do not attempt alternative methods or workarounds - -## Job Failure Errors - -When a job completes with `status: "failed"`: +**Important**: Do NOT retry when authentication fails. User must fix API key first. -### Check the Error Field - -The `error` field contains the failure reason: - -```json -{ - "status": "failed", - "error": "Insufficient balance for transaction" -} -``` - -### Common Job Failures +## Common Job Failures | Error | Cause | Resolution | |-------|-------|------------| -| Insufficient balance | Not enough tokens for trade | Check balance, reduce amount | -| Token not found | Invalid token symbol/address | Verify token exists on chain | -| Slippage exceeded | Price moved too much | Retry or increase slippage | -| Transaction reverted | On-chain execution failed | Check transaction details | +| Insufficient balance | Not enough tokens | Check balance, reduce amount | +| Token not found | Invalid symbol/address | Verify token exists on chain | +| Slippage exceeded | Price moved too much | Retry or try smaller amount | +| Transaction reverted | On-chain failure | Check transaction details | | Rate limit exceeded | Too many requests | Wait and retry | -| Unsupported operation | Feature not available | Try alternative approach | - -### Suggesting Alternatives - -When a job fails, consider: -- Reducing the trade amount -- Trying a different chain -- Splitting into smaller transactions -- Checking token liquidity -## API Request Errors - -Errors that occur before job creation: - -### HTTP Status Codes +## HTTP Status Codes | Code | Meaning | Action | |------|---------|--------| | 400 | Bad request | Check prompt format | | 401 | Unauthorized | Fix API key (see above) | -| 402 | Payment required | x402 payment failed | -| 404 | Not found | Invalid endpoint | +| 402 | Payment required | Ensure wallet has BNKR on Base | | 429 | Rate limited | Wait and retry | | 500 | Server error | Retry after delay | -### x402 Payment Errors (402) - -Bankr uses x402 micropayments on Base chain: - -```json -{ - "x402Version": 1, - "error": "Payment required", - "accepts": [{ - "scheme": "exact", - "network": "base", - "asset": "0x22af33fe49fd1fa80c7149773dde5890d3c76f3b" - }] -} -``` - -**Resolution**: -- Ensure wallet has BNKR tokens on Base -- Check privateKey is configured for payments -- Typical cost: ~$0.01 USD per request - ## Troubleshooting Checklist -When errors occur, verify: - -1. **API Key Configuration** - - [ ] BANKR_API_KEY environment variable is set - - [ ] Key starts with `bk_` - - [ ] Key is not expired or revoked - - [ ] Claude Code was restarted after setting - -2. **Network/Connectivity** - - [ ] Internet connection is working - - [ ] api.bankr.bot is reachable - - [ ] No firewall blocking requests - -3. **Request Format** - - [ ] Prompt is not empty - - [ ] Prompt is under 10,000 characters - - [ ] No invalid characters - -4. **For Trading Operations** - - [ ] Wallet has sufficient balance - - [ ] Token exists on specified chain - - [ ] Recipient address is valid (for transfers) - -## Error Response Format - -All errors follow this structure: - -```json -{ - "success": false, - "error": "Error message describing the issue", - "message": "Additional context or instructions" -} -``` - -For job failures: - -```json -{ - "success": true, - "jobId": "job_ABC123", - "status": "failed", - "error": "Specific failure reason", - "prompt": "Original request" -} -``` +1. **API Key**: Set, starts with `bk_`, Claude Code restarted after setting +2. **Network**: Internet working, api.bankr.bot reachable +3. **For Trading**: Wallet has sufficient balance, token exists on chain ## Reporting Errors to Users -When presenting errors: - -1. **Be clear**: State what went wrong simply -2. **Be actionable**: Provide specific fix steps -3. **Don't over-explain**: Avoid technical jargon unless needed -4. **Offer alternatives**: Suggest what they can do instead - -### Example Error Responses +1. State what went wrong simply +2. Provide specific fix steps +3. Avoid technical jargon +4. Suggest alternatives -**Authentication Error**: +**Example**: ``` Your Bankr API key is not configured. To set it up: 1. Visit https://bankr.bot/api to create an API key 2. Set BANKR_API_KEY in your environment 3. Restart Claude Code ``` - -**Insufficient Balance**: -``` -You don't have enough ETH for this trade. Your current balance -is 0.05 ETH but the trade requires 0.1 ETH. Try a smaller amount -or add more ETH to your wallet. -``` - -**Token Not Found**: -``` -I couldn't find a token called "XYZ" on Base. Did you mean one of these? -- XYZ Protocol (XYZ) on Ethereum -- XYZ Token (XYZT) on Polygon -``` - -## Recovery Strategies - -### For Transient Errors - -Network issues, rate limits, server errors: -- Wait 5-10 seconds -- Retry the request once -- If still failing, inform user - -### For Configuration Errors - -API key, environment issues: -- Guide user through setup -- Do not retry until fixed -- Verify fix before continuing - -### For Business Logic Errors - -Insufficient balance, unsupported operations: -- Explain the limitation -- Suggest alternatives -- Help user adjust their request diff --git a/bankr-agent/skills/bankr-job-workflow/SKILL.md b/bankr-agent/skills/bankr-job-workflow/SKILL.md index ffe9cb1..3710915 100644 --- a/bankr-agent/skills/bankr-job-workflow/SKILL.md +++ b/bankr-agent/skills/bankr-job-workflow/SKILL.md @@ -6,178 +6,68 @@ version: 1.0.0 # Bankr Job Workflow -Execute Bankr API operations using the asynchronous job pattern via MCP tools. +Execute Bankr API operations using MCP tools with the asynchronous job pattern. -## Core Concept +## Core Pattern: Submit-Poll-Complete -All Bankr operations follow a **submit-poll-complete** pattern: +1. **Submit** - Send prompt via `bankr_agent_submit_prompt`, receive job ID +2. **Poll** - Check status via `bankr_agent_get_job_status` every 2 seconds +3. **Complete** - Report results when status is terminal -1. **Submit** - Send natural language prompt, receive job ID -2. **Poll** - Check status every 2 seconds until terminal state -3. **Complete** - Report results when status is completed/failed/cancelled - -## Available MCP Tools +## MCP Tools ### `bankr_agent_submit_prompt` - Submit a natural language prompt to start a job. - -``` -bankr_agent_submit_prompt(prompt: string) -> { jobId: string } -``` - -**Input**: Natural language request (e.g., "Buy $50 of ETH on Base") -**Output**: Job ID for tracking (e.g., "job_ABC123...") +- **Input**: Natural language request (e.g., "Buy $50 of ETH on Base") +- **Output**: Job ID for tracking ### `bankr_agent_get_job_status` - -Check the current status of a job. - -``` -bankr_agent_get_job_status(jobId: string) -> JobStatusResponse -``` - -**Response fields**: -- `status`: "pending" | "processing" | "completed" | "failed" | "cancelled" +Check job status. Response includes: +- `status`: pending | processing | completed | failed | cancelled - `response`: Text answer (when completed) - `transactions`: Array of executed transactions -- `richData`: Images or charts (base64 or URL) - `statusUpdates`: Progress messages during execution - `error`: Error message (when failed) ### `bankr_agent_cancel_job` - Cancel a running job. -``` -bankr_agent_cancel_job(jobId: string) -> JobStatusResponse -``` - -**Note**: Cancellation is idempotent - returns success even if already cancelled. - -## Workflow Steps - -### Step 1: Submit the Request - -Submit the user's request as a natural language prompt: - -``` -1. Call bankr_agent_submit_prompt with the user's request -2. Store the returned jobId for polling -3. Inform user that request was submitted -``` - -### Step 2: Poll for Status - -Poll every 2 seconds until a terminal state: - -``` -1. Call bankr_agent_get_job_status with jobId -2. Check statusUpdates array for new messages -3. Report any new status updates to the user -4. If status is terminal (completed/failed/cancelled), proceed to Step 3 -5. Otherwise, wait 2 seconds and repeat -``` - -**Status Update Handling**: -- Track the last reported update count -- Only report NEW updates to avoid repetition -- Updates show what the agent is doing (e.g., "Analyzing market data...", "Preparing transaction...") - -### Step 3: Report Results - -Handle the terminal state appropriately: - -**If completed**: -- Share the `response` text with the user -- If `transactions` exist, explain what was executed -- If `richData` exists (images/charts), mention it's available - -**If failed**: -- Report the `error` message clearly -- Suggest alternatives if applicable -- If authentication error, load `bankr-error-handling` skill - -**If cancelled**: -- Confirm cancellation to the user - ## Job Status States -| Status | Meaning | Action | -|--------|---------|--------| -| `pending` | Job queued, not started | Keep polling | -| `processing` | Job running | Keep polling, report statusUpdates | -| `completed` | Finished successfully | Read response and transactions | -| `failed` | Error occurred | Check error field | -| `cancelled` | User cancelled | No further action | +| Status | Action | +|--------|--------| +| `pending` | Keep polling | +| `processing` | Keep polling, report statusUpdates | +| `completed` | Read response and transactions | +| `failed` | Check error field | +| `cancelled` | No further action | -## Timing Guidelines +## Timing - **Poll interval**: 2 seconds - **Typical completion**: 30 seconds to 2 minutes -- **Maximum wait**: 4-5 minutes before suggesting cancellation -- Jobs involving complex trades or analysis take longer +- **Suggest cancellation**: After 3+ minutes for simple queries ## Output Guidelines -Present results based on query type: - | Query Type | Output Format | |------------|---------------| -| Price queries | State price clearly with token symbol (e.g., "ETH is $3,245.67") | -| Trades | Confirm what was traded, amounts, transaction details | +| Price queries | State price clearly (e.g., "ETH is $3,245.67") | +| Trades | Confirm amounts and transaction details | | Market analysis | Summarize key insights concisely | -| Polymarket | State odds clearly with relevant context | +| Polymarket | State odds with context | | Balances | List holdings with USD values | | Errors | Explain clearly, suggest alternatives | -## Cancellation - -When user requests cancellation: - -``` -1. Call bankr_agent_cancel_job with the jobId -2. Confirm cancellation to user -3. Do not continue polling -``` - -**When to suggest cancellation**: -- Job running longer than expected (>3 minutes for simple queries) -- User indicates they want to stop -- User wants to modify their request - -## Example Workflow +## Status Update Handling -``` -User: "What's the price of Bitcoin?" - -1. Submit: bankr_agent_submit_prompt("What's the price of Bitcoin?") - -> jobId: "job_XYZ789" - -2. Poll: bankr_agent_get_job_status("job_XYZ789") - -> status: "processing", statusUpdates: ["Fetching price data..."] - -> Report: "Fetching price data..." - -3. Poll again (2s later): - -> status: "completed", response: "Bitcoin (BTC) is trading at $97,245.32..." - -4. Report: "Bitcoin (BTC) is currently trading at $97,245.32" -``` +- Track last reported update count +- Only report NEW updates to avoid repetition +- Updates show agent progress (e.g., "Analyzing market data...") ## Error Recovery -If polling fails or connection is lost: - -1. Retry the status check after a brief delay -2. If multiple failures, inform user of connectivity issues -3. The job continues running server-side regardless -4. Can resume polling with the same jobId - -## Integration with Capability Skills - -This workflow skill handles execution. Load the appropriate capability skill first to understand: -- What operations are supported -- Required parameters and formats -- Chain-specific considerations - -Then use this workflow to execute the request. +If polling fails: +1. Retry after brief delay +2. Job continues server-side regardless +3. Can resume polling with same jobId diff --git a/bankr-agent/skills/bankr-leverage-trading/SKILL.md b/bankr-agent/skills/bankr-leverage-trading/SKILL.md index 4e14461..a10f5db 100644 --- a/bankr-agent/skills/bankr-leverage-trading/SKILL.md +++ b/bankr-agent/skills/bankr-leverage-trading/SKILL.md @@ -10,195 +10,43 @@ Trade with leverage using Avantis perpetuals on Base. ## Overview -Avantis is a decentralized perpetuals exchange offering: -- Long and short positions -- Up to 100x+ leverage -- Crypto, forex, and commodities markets -- Stop loss and take profit orders +Avantis offers long/short positions with up to 100x leverage on crypto, forex, and commodities. **Chain**: Base ## Supported Markets -### Crypto - -``` -BTC, ETH, SOL, ARB, AVAX, BNB, DOGE, LINK, OP, MATIC, etc. -``` - -### Forex - -``` -EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CAD, etc. -``` - -### Commodities - -``` -Gold (XAU), Silver (XAG), Oil (WTI), Natural Gas, etc. -``` - -## Operations - -### Open Long Position - -Profit when price goes up: - -``` -"Open a 5x long on ETH with $100" -"Long Bitcoin with 10x leverage" -"Buy ETH with leverage" -``` - -### Open Short Position - -Profit when price goes down: - -``` -"Short ETH with 5x leverage and $50" -"Open a short position on Bitcoin" -"Go short on Gold with 3x leverage" -``` - -### View Positions - -Check open positions: - -``` -"Show my Avantis positions" -"What leveraged positions do I have?" -"Check my open trades" -``` - -### Close Positions - -Exit a position: - -``` -"Close my ETH long" -"Exit all my Avantis positions" -"Close my Bitcoin short" -``` - -## Position Parameters - -### Leverage - -- **Default**: 1x (if not specified) -- **Range**: 1x to 100x+ depending on asset -- Higher leverage = higher risk - -``` -"Long ETH with 5x leverage" → 5x -"Short BTC 10x" → 10x -"Long SOL" → 1x (default) -``` - -### Collateral - -Specify the amount to use as collateral: - -``` -"Long ETH with $100 and 5x leverage" -"Short BTC using 0.1 ETH as collateral" -``` - -### Stop Loss - -Automatically close position to limit losses: - -``` -"Long ETH 5x with stop loss at $3000" -"Short BTC with 10% stop loss" -``` - -### Take Profit - -Automatically close position to lock in gains: - -``` -"Long ETH 5x with take profit at $4000" -"Short BTC with 20% take profit" -``` - -### Combined - -``` -"Long ETH 5x with $100, stop loss at $3000, take profit at $4000" -``` +- **Crypto**: BTC, ETH, SOL, ARB, AVAX, BNB, DOGE, LINK, OP, MATIC +- **Forex**: EUR/USD, GBP/USD, USD/JPY, AUD/USD, USD/CAD +- **Commodities**: Gold (XAU), Silver (XAG), Oil (WTI), Natural Gas ## Prompt Examples -### Opening Positions - -``` -"Open a 5x long on ETH with $100" -"Short Bitcoin with 10x leverage and $50 collateral" -"Long Gold with 2x leverage" -"Go long on EUR/USD with 20x" -"Open a short position on Oil" -``` - -### With Risk Management - -``` -"Long ETH 5x with stop loss at -10%" -"Short BTC 10x with take profit at 20%" -"Long SOL 3x with SL at $150 and TP at $200" -``` +**Open positions:** +- "Open a 5x long on ETH with $100" +- "Short Bitcoin with 10x leverage" +- "Long Gold with 2x leverage" -### Checking Positions +**With risk management:** +- "Long ETH 5x with stop loss at $3000" +- "Short BTC 10x with take profit at 20%" +- "Long SOL 3x with SL at $150 and TP at $200" -``` -"Show my Avantis positions" -"What leverage positions do I have open?" -"Check my PnL on Avantis" -"List my open trades" -``` +**View/close positions:** +- "Show my Avantis positions" +- "Close my ETH long" +- "Exit all my Avantis positions" -### Closing Positions - -``` -"Close my ETH long position" -"Exit all Avantis positions" -"Close my short on Bitcoin" -``` - -## Response Handling - -### Position Opened - -```json -{ - "status": "completed", - "response": "Opened 5x long on ETH with $100 collateral. Entry: $3,245.67. Liquidation: $2,596.54", - "transactions": [{ - "type": "avantisTrade", - "metadata": { - "chainId": 8453, - "description": "Open 5x long ETH-USD" - } - }] -} -``` - -### Position Summary - -```json -{ - "response": "Your Avantis positions:\n- ETH Long 5x: +$23.45 (7.2%)\n- BTC Short 3x: -$12.30 (-4.1%)" -} -``` - -## Risk Management - -### Liquidation +## Position Parameters -- Positions are liquidated if losses exceed collateral -- Higher leverage = closer liquidation price -- Monitor positions and use stop losses +| Parameter | Description | Example | +|-----------|-------------|---------| +| Leverage | 1x to 100x (default: 1x) | "5x leverage" | +| Collateral | Amount to use | "$100", "0.1 ETH" | +| Stop Loss | Auto-close to limit losses | "stop loss at $3000" | +| Take Profit | Auto-close to lock gains | "take profit at $4000" | -### Leverage Guidelines +## Leverage Guidelines | Risk Level | Leverage | Use Case | |------------|----------|----------| @@ -207,14 +55,6 @@ Automatically close position to lock in gains: | Aggressive | 10-25x | Short-term scalps | | High Risk | 25x+ | Experienced only | -### Best Practices - -1. **Start with low leverage** (2-5x) -2. **Always use stop loss** to limit downside -3. **Don't over-leverage** - position sizing matters -4. **Monitor positions** - markets move fast -5. **Understand liquidation** - know your risk - ## Common Issues | Issue | Resolution | @@ -224,10 +64,10 @@ Automatically close position to lock in gains: | Liquidation | Position closed, collateral lost | | High funding rate | Consider shorter hold time | -## Fees - -- **Opening fee**: Small percentage of position size -- **Closing fee**: Small percentage of position size -- **Funding rate**: Periodic fee based on market conditions -- Gas costs on Base (very low) +## Risk Management Tips +1. Start with low leverage (2-5x) +2. Always use stop loss to limit downside +3. Don't over-leverage - position sizing matters +4. Monitor positions - markets move fast +5. Understand liquidation risk diff --git a/bankr-agent/skills/bankr-market-research/SKILL.md b/bankr-agent/skills/bankr-market-research/SKILL.md index 55f9b2f..2c4fa6f 100644 --- a/bankr-agent/skills/bankr-market-research/SKILL.md +++ b/bankr-agent/skills/bankr-market-research/SKILL.md @@ -8,9 +8,8 @@ version: 1.0.0 Research tokens and analyze market data. -## Overview +## Capabilities -Bankr provides comprehensive market intelligence: - Token search across chains - Price and market data - Technical analysis @@ -18,251 +17,67 @@ Bankr provides comprehensive market intelligence: - Price charts - Trending tokens -## Operations - -### Price Queries - -Get current token prices: - -``` -"What's the price of ETH?" -"How much is Bitcoin worth?" -"Check the SOL price" -``` - -### Market Data - -Get comprehensive token data: - -``` -"Show me ETH market data" -"What's the market cap of BNKR?" -"Get volume for Solana" -``` - -### Technical Analysis - -Analyze price patterns: - -``` -"Do technical analysis on ETH" -"Show RSI for Bitcoin" -"Analyze BTC price action" -``` - -### Social Sentiment - -Check community sentiment: - -``` -"What's the sentiment on ETH?" -"Is the community bullish on SOL?" -"Check social mentions for BNKR" -``` - -### Price Charts - -Generate price visualizations: - -``` -"Show me ETH price chart" -"Generate BTC chart for last week" -"Chart SOL price history" -``` - -### Trending Tokens - -Discover what's popular: - -``` -"What tokens are trending?" -"Show top gainers today" -"What's hot in crypto?" -``` - ## Prompt Examples -### Price Queries - -``` -"What's the price of Ethereum?" -"How much is 1 BTC in USD?" -"Check BNKR price" -"What's SOL trading at?" -``` - -### Market Data - -``` -"Show market cap for ETH" -"What's the 24h volume for Bitcoin?" -"Get trading data for Solana" -"How many holders does BNKR have?" -``` - -### Technical Analysis - -``` -"Do technical analysis on Bitcoin" -"What's the RSI for ETH?" -"Analyze BTC price trends" -"Is ETH overbought?" -``` +**Price queries:** +- "What's the price of ETH?" +- "How much is Bitcoin worth?" -### Sentiment +**Market data:** +- "Show me ETH market data" +- "What's the market cap of BNKR?" -``` -"What's the sentiment on Solana?" -"Is the market bullish on ETH?" -"Check Twitter sentiment for BTC" -"How is the community feeling about BNKR?" -``` +**Technical analysis:** +- "Do technical analysis on ETH" +- "Show RSI for Bitcoin" +- "Is ETH overbought?" -### Charts +**Sentiment:** +- "What's the sentiment on ETH?" +- "Is the community bullish on SOL?" -``` -"Show ETH price chart" -"Generate weekly BTC chart" -"Chart SOL price for last month" -"Visual of ETH performance" -``` +**Charts:** +- "Show me ETH price chart" +- "Generate BTC chart for last week" -### Discovery +**Discovery:** +- "What tokens are trending?" +- "Show top gainers today" +- "Compare ETH vs SOL" -``` -"What tokens are trending today?" -"Show top gainers this week" -"What's hot on Base?" -"Find trending memecoins" -``` - -### Comparison - -``` -"Compare ETH vs SOL" -"Which is better: BTC or ETH?" -"Show ETH and BTC side by side" -``` - -## Data Points +## Data Available ### Price Data - -| Metric | Description | -|--------|-------------| -| Price | Current USD price | -| 24h Change | Percentage change | -| 7d Change | Weekly performance | -| ATH | All-time high | -| ATL | All-time low | +- Current USD price +- 24h / 7d change +- All-time high/low ### Market Metrics - -| Metric | Description | -|--------|-------------| -| Market Cap | Total value | -| Volume (24h) | Trading volume | -| Circulating Supply | Tokens in market | -| Total Supply | All tokens | -| Holders | Number of wallets | +- Market cap +- 24h volume +- Circulating/total supply +- Number of holders ### Technical Indicators - -| Indicator | Description | -|-----------|-------------| -| RSI | Relative Strength Index | -| MACD | Moving Average Convergence | -| MA | Moving Averages (50, 200) | -| Support/Resistance | Key price levels | - -## Response Format - -### Price Query - -```json -{ - "response": "Ethereum (ETH): $3,245.67\n24h: +2.3%\n7d: -1.5%\nMarket Cap: $390.2B" -} -``` - -### Technical Analysis - -```json -{ - "response": "ETH Technical Analysis:\n- RSI: 58 (Neutral)\n- MACD: Bullish crossover\n- 50 MA: $3,180 (above)\n- 200 MA: $2,950 (above)\n\nOutlook: Moderately bullish" -} -``` - -### Sentiment - -```json -{ - "response": "ETH Sentiment Analysis:\n- Social mentions: 12.5K (up 15%)\n- Sentiment: 67% Bullish\n- Key topics: ETF, staking, upgrades\n- Community mood: Optimistic" -} -``` - -### Chart - -Returns a URL or base64 image in `richData`: - -```json -{ - "response": "Here's the ETH price chart for the last 7 days:", - "richData": [{ - "type": "chart", - "url": "https://..." - }] -} -``` +- RSI (Relative Strength Index) +- MACD +- Moving averages (50, 200) +- Support/resistance levels ## Supported Chains -Token research works across: -- **Base**: Native and ERC20 tokens -- **Polygon**: Native and ERC20 tokens -- **Ethereum**: All mainnet tokens -- **Solana**: SOL and SPL tokens -- **Unichain**: Emerging tokens +Token research works across Base, Polygon, Ethereum, Solana, and Unichain. ## Token Search Find tokens by name or symbol: - -``` -"Search for BNKR token" -"Find tokens called Bankr" -"What is the contract for PEPE on Base?" -``` - -## Use Cases - -### Before Trading - -``` -"What's the price of ETH?" → Check current price -"Analyze ETH technicals" → Evaluate entry point -"Check ETH sentiment" → Gauge market mood -``` - -### Market Research - -``` -"What's trending today?" → Find opportunities -"Compare SOL vs ETH" → Evaluate options -"Show top Base tokens" → Discover new projects -``` - -### Portfolio Analysis - -``` -"How is BNKR performing?" → Track holdings -"Chart my ETH performance" → Visualize gains -"What's the outlook for SOL?" → Plan strategy -``` +- "Search for BNKR token" +- "Find tokens called Bankr" +- "What is the contract for PEPE on Base?" ## Limitations -- **Historical data**: Limited to available timeframes -- **Sentiment**: Based on available social data -- **New tokens**: May have limited data -- **Predictions**: Not investment advice +- Historical data limited to available timeframes +- Sentiment based on available social data +- New tokens may have limited data +- Not investment advice diff --git a/bankr-agent/skills/bankr-nft-operations/SKILL.md b/bankr-agent/skills/bankr-nft-operations/SKILL.md index 9f7e8ed..f309224 100644 --- a/bankr-agent/skills/bankr-nft-operations/SKILL.md +++ b/bankr-agent/skills/bankr-nft-operations/SKILL.md @@ -6,157 +6,52 @@ version: 1.0.0 # Bankr NFT Operations -Browse, purchase, and manage NFTs across chains. +Browse, purchase, and manage NFTs across chains via OpenSea integration. -## Overview - -Bankr supports NFT operations through OpenSea integration: -- Browse NFT collections -- Find best listings -- Purchase NFTs -- View NFT holdings - -**Supported Chains**: Base, Ethereum, Polygon, and other EVM chains +**Supported Chains**: Base, Ethereum, Polygon ## Operations -### Browse NFTs - -Search for NFT collections: - -``` -"Find NFTs from the Bored Ape collection" -"Search for CryptoPunks on OpenSea" -"Show me trending NFT collections" -``` - -### View Listings - -Find the best deals in a collection: - -``` -"What's the floor price for Pudgy Penguins?" -"Show cheapest NFTs in Azuki collection" -"Find listings under 0.1 ETH in Doodles" -``` - -### Buy NFTs - -Purchase an NFT: - -``` -"Buy the cheapest Bored Ape" -"Purchase this NFT: [OpenSea URL]" -"Buy floor NFT from CryptoPunks" -``` - -### View Holdings - -Check your NFT portfolio: - -``` -"Show my NFTs" -"What NFTs do I own?" -"List my NFT holdings on Base" -``` - -## Purchase Methods - -### By Collection Name - -``` -"Buy the floor NFT from Pudgy Penguins" -"Purchase cheapest NFT in Azuki collection" -``` - -### By OpenSea URL - -``` -"Buy this NFT: https://opensea.io/assets/ethereum/0x.../1234" -"Purchase the NFT at [URL]" -``` - -### By Specific Criteria - -``` -"Buy a Bored Ape under 30 ETH" -"Purchase the cheapest blue Pudgy Penguin" -``` +- **Browse** - Search NFT collections +- **View Listings** - Find best deals and floor prices +- **Buy** - Purchase NFTs from marketplace listings +- **View Holdings** - Check your NFT portfolio +- **Transfer** - Send NFTs to another wallet +- **Mint** - Mint from supported platforms (Manifold, SeaDrop) ## Prompt Examples -### Browsing - -``` -"Search for NFT collections on Base" -"Find popular NFT projects" -"Show me NFTs similar to CryptoPunks" -"What are trending NFT collections?" -``` - -### Listings - -``` -"What's the floor price for Bored Apes?" -"Show the 5 cheapest NFTs in Azuki" -"Find NFT listings under 0.5 ETH" -"What are the best deals in Pudgy Penguins?" -``` - -### Buying +**Browse NFTs:** +- "Find NFTs from the Bored Ape collection" +- "Show me trending NFT collections" -``` -"Buy the cheapest NFT from Doodles" -"Purchase this OpenSea listing: [URL]" -"Buy a Bored Ape" -"Get me the floor NFT from CryptoPunks" -``` +**View listings:** +- "What's the floor price for Pudgy Penguins?" +- "Show cheapest NFTs in Azuki collection" -### Holdings +**Buy NFTs:** +- "Buy the cheapest Bored Ape" +- "Purchase this NFT: [OpenSea URL]" -``` -"Show my NFT collection" -"What NFTs do I own on Ethereum?" -"List my NFT holdings" -"Show NFTs in my wallet" -``` - -## Supported Operations - -- **Buy** - Purchase NFTs from marketplace listings -- **Transfer** - Send NFTs to another wallet -- **Mint** - Mint from supported platforms (Manifold, SeaDrop) -- **View** - Check your NFT holdings +**View holdings:** +- "Show my NFTs" +- "What NFTs do I own on Ethereum?" ## Collection Resolution -Bankr resolves collection names to OpenSea slugs: +Bankr resolves common names and abbreviations: | Input | Resolved | |-------|----------| -| "Bored Apes" | boredapeyachtclub | -| "BAYC" | boredapeyachtclub | +| "Bored Apes" / "BAYC" | boredapeyachtclub | | "Pudgy Penguins" | pudgypenguins | | "CryptoPunks" | cryptopunks | -Supports common names, abbreviations, and variations. - ## Chain Considerations -### Ethereum -- Most valuable collections -- Higher gas fees -- Primary OpenSea marketplace - -### Base -- Growing NFT ecosystem -- Very low gas fees -- Good for newer collections - -### Polygon -- Low gas costs -- Some popular collections -- Gaming NFTs +- **Ethereum**: Most valuable collections, higher gas +- **Base**: Growing ecosystem, very low gas +- **Polygon**: Low gas, gaming NFTs ## Common Issues @@ -169,8 +64,7 @@ Supports common names, abbreviations, and variations. ## Safety Tips -- **Verify collection** - Check official links -- **Check floor price** - Avoid overpaying -- **Review before buying** - Confirm the NFT -- **Beware of fakes** - Look for verified collections -- **Gas considerations** - Factor in transaction costs +- Verify collection through official links +- Check floor price to avoid overpaying +- Look for verified collections +- Factor in gas costs diff --git a/bankr-agent/skills/bankr-polymarket/SKILL.md b/bankr-agent/skills/bankr-polymarket/SKILL.md index c7fdd22..94ebfac 100644 --- a/bankr-agent/skills/bankr-polymarket/SKILL.md +++ b/bankr-agent/skills/bankr-polymarket/SKILL.md @@ -10,168 +10,49 @@ Interact with Polymarket prediction markets. ## Overview -Polymarket is a decentralized prediction market platform where users can: -- Search and discover markets -- View odds and market details -- Place bets (buy shares) -- Manage and redeem positions +Polymarket is a decentralized prediction market where users can search markets, view odds, place bets, and manage positions. -**Chain**: Polygon (requires USDC.e for betting) +**Chain**: Polygon (uses USDC.e for betting) -## Operations - -### Search Markets - -Find prediction markets by topic: - -``` -"Search Polymarket for election markets" -"What prediction markets are trending?" -"Find markets about the Super Bowl" -``` - -### Check Odds - -View current odds for specific events: - -``` -"What are the odds Trump wins the election?" -"Check the odds on the Eagles game" -"Show me the NYC mayor prediction" -``` - -### Place Bets - -Buy shares in a prediction outcome: - -``` -"Bet $10 on Yes for Trump winning" -"Place $5 on the Eagles to win" -"Buy shares in the election market" -``` - -### View Positions - -Check your current bets: - -``` -"Show my Polymarket positions" -"What bets do I have open?" -"Check my prediction market holdings" -``` - -### Redeem Positions - -Claim winnings from resolved markets: +## Prompt Examples -``` -"Redeem my Polymarket positions" -"Claim my winnings from the election market" -``` +**Search markets:** +- "Search Polymarket for election markets" +- "What prediction markets are trending?" -## Betting Details +**Check odds:** +- "What are the odds Trump wins the election?" +- "Check the odds on the Eagles game" -### Currency +**Place bets:** +- "Bet $10 on Yes for Trump winning" +- "Place $5 on the Eagles to win" -- Bets are placed in **USDC** (specifically USDC.e on Polygon) -- Auto-bridging: Bankr can bridge USDC from other chains if needed +**View/redeem positions:** +- "Show my Polymarket positions" +- "Redeem my Polymarket positions" -### Share System +## How Betting Works - You buy shares of "Yes" or "No" outcomes -- Share price reflects market probability +- Share price reflects market probability (e.g., $0.60 = 60% chance) - If your outcome wins, shares pay $1 each - Profit = $1 - purchase price (per share) -### Example - -``` -Market: "Will it rain tomorrow?" -Yes shares: $0.60 (60% probability) -No shares: $0.40 (40% probability) - -Bet $10 on "Yes": -- Buy ~16.67 shares at $0.60 each -- If Yes wins: Get $16.67 (profit: $6.67) -- If No wins: Get $0 (lose $10) -``` - -## Prompt Examples - -### Searching Markets - -``` -"Search Polymarket for crypto markets" -"Find prediction markets about Bitcoin" -"What are the trending markets on Polymarket?" -"Show me sports betting markets" -``` - -### Checking Odds - -``` -"What are the odds Biden wins?" -"Check the probability of ETH reaching $5000" -"What's the current prediction for the Super Bowl?" -"Show odds for the upcoming election" -``` - -### Placing Bets - -``` -"Bet $10 on Trump winning" -"Place a $5 bet on Yes" -"Buy $20 of Yes shares on the election market" -"Bet on the Eagles to win this week" -``` - -### Managing Positions - -``` -"Show my Polymarket positions" -"What prediction market bets do I have?" -"Check my open positions" -"Redeem my winning positions" -``` - -## Response Handling - -### Market Search Results - -```json -{ - "response": "Found 5 markets about elections:\n1. Presidential Election 2024 - 65% Yes\n2. Senate Control - 52% Democrats\n..." -} -``` - -### Bet Confirmation - -```json -{ - "status": "completed", - "response": "Placed $10 bet on 'Yes' for Trump winning. Bought 15.38 shares at $0.65 each.", - "transactions": [...] -} -``` - -### Position Summary - -```json -{ - "response": "Your Polymarket positions:\n- Presidential Election: 20 Yes shares ($13 value)\n- Super Bowl: 10 No shares ($6.50 value)" -} -``` +**Example**: Bet $10 on "Yes" at $0.60 = ~16.67 shares. If Yes wins, get $16.67 (profit $6.67). ## Auto-Bridging -If you don't have USDC on Polygon: +If you don't have USDC on Polygon, Bankr automatically bridges from another chain. -1. Bankr detects insufficient USDC.e balance -2. Automatically bridges USDC from another chain -3. Converts to USDC.e if needed -4. Places the bet +## Market Types -**Note**: This may add a small delay and gas costs. +| Category | Examples | +|----------|----------| +| Politics | Elections, legislation | +| Sports | Game outcomes, championships | +| Crypto | Price predictions, ETF approvals | +| Culture | Awards, entertainment events | ## Common Issues @@ -180,22 +61,10 @@ If you don't have USDC on Polygon: | Market not found | Try different search terms | | Insufficient USDC | Add USDC or let auto-bridge | | Market closed | Can't bet on resolved markets | -| Outcome unclear | Check market details for exact outcomes | ## Tips -- **Research first**: Search and check odds before betting -- **Start small**: Test with small amounts first -- **Check liquidity**: Low-liquidity markets may have worse prices -- **Watch fees**: Gas costs on Polygon are low but exist -- **Redeem promptly**: Claim winnings after markets resolve - -## Market Types - -| Category | Examples | -|----------|----------| -| Politics | Elections, legislation, appointments | -| Sports | Game outcomes, championships | -| Crypto | Price predictions, ETF approvals | -| Culture | Awards, entertainment events | -| Science | Discoveries, climate events | +- Search and check odds before betting +- Start with small amounts to test +- Check market liquidity for best prices +- Redeem promptly after markets resolve diff --git a/bankr-agent/skills/bankr-portfolio/SKILL.md b/bankr-agent/skills/bankr-portfolio/SKILL.md index 0e70b0b..24a4b40 100644 --- a/bankr-agent/skills/bankr-portfolio/SKILL.md +++ b/bankr-agent/skills/bankr-portfolio/SKILL.md @@ -8,201 +8,60 @@ version: 1.0.0 Query token balances and portfolio across all supported chains. -## Overview +## Supported Chains -Check your holdings across: -- **EVM Chains**: Base, Polygon, Ethereum, Unichain -- **Solana**: SOL and SPL tokens -- **Aggregated View**: Total portfolio value - -## Operations - -### Check Total Portfolio - -View all holdings across chains: - -``` -"Show my portfolio" -"What's my total balance?" -"How much crypto do I have?" -``` - -### Check Specific Chain - -View holdings on one chain: - -``` -"Show my Base balance" -"What do I have on Ethereum?" -"Check my Solana holdings" -``` - -### Check Specific Token - -View balance of a specific token: - -``` -"How much ETH do I have?" -"What's my USDC balance?" -"Check my BNKR holdings" -``` - -## Prompt Examples - -### Full Portfolio - -``` -"Show my portfolio" -"What's my total balance?" -"List all my crypto holdings" -"How much is my wallet worth?" -``` - -### Chain-Specific - -``` -"Show my Base balance" -"What tokens do I have on Polygon?" -"Check my Ethereum holdings" -"Show my Solana balance" -``` - -### Token-Specific - -``` -"How much ETH do I have?" -"What's my USDC balance?" -"Check my BNKR balance" -"How many SOL do I own?" -``` - -### Comparisons - -``` -"Where do I have the most ETH?" -"Which chain has my USDC?" -"Show my ETH across all chains" -``` - -## Response Format - -### Portfolio Summary - -```json -{ - "response": "Your portfolio ($12,345.67 total):\n\nBase:\n- ETH: 2.5 ($8,125.00)\n- USDC: 1,500.00 ($1,500.00)\n- BNKR: 50,000 ($500.00)\n\nEthereum:\n- ETH: 0.5 ($1,625.00)\n\nSolana:\n- SOL: 25 ($595.67)" -} -``` - -### Single Chain - -```json -{ - "response": "Your Base holdings:\n- ETH: 2.5 ($8,125.00)\n- USDC: 1,500.00 ($1,500.00)\n- BNKR: 50,000 ($500.00)\n\nTotal: $10,125.00" -} -``` - -### Single Token - -```json -{ - "response": "Your ETH balance:\n- Base: 2.5 ETH ($8,125.00)\n- Ethereum: 0.5 ETH ($1,625.00)\n- Total: 3.0 ETH ($9,750.00)" -} -``` - -## Supported Assets - -### Native Tokens - -| Chain | Token | -|-------|-------| +| Chain | Native Token | +|-------|-------------| | Base | ETH | | Polygon | MATIC | | Ethereum | ETH | | Unichain | ETH | | Solana | SOL | -### Common Tokens - -Bankr tracks balances for popular tokens: -- Stablecoins: USDC, USDT, DAI -- DeFi: UNI, AAVE, LINK -- Memecoins: DOGE, SHIB, PEPE -- Project tokens: BNKR, ARB, OP - -## Features +## Prompt Examples -### USD Valuation +**Full portfolio:** +- "Show my portfolio" +- "What's my total balance?" +- "How much crypto do I have?" -All balances include current USD value based on market prices. +**Chain-specific:** +- "Show my Base balance" +- "What tokens do I have on Polygon?" -### Multi-Chain Aggregation +**Token-specific:** +- "How much ETH do I have?" +- "What's my USDC balance?" +- "Show my ETH across all chains" -See the same token across multiple chains: +## Features -``` -"Show my USDC on all chains" -→ Base: 1,000 USDC -→ Polygon: 500 USDC -→ Ethereum: 250 USDC -→ Total: 1,750 USDC -``` +- **USD Valuation**: All balances include current USD value +- **Multi-Chain Aggregation**: See the same token across all chains +- **Real-Time Prices**: Values reflect current market prices -### Real-Time Prices +## Common Tokens Tracked -Values reflect current market prices at query time. +- **Stablecoins**: USDC, USDT, DAI +- **DeFi**: UNI, AAVE, LINK +- **Memecoins**: DOGE, SHIB, PEPE +- **Project tokens**: BNKR, ARB, OP ## Use Cases -### Before Trading - -Check if you have enough balance: - -``` -"Do I have enough ETH to swap for 100 USDC?" -"Check my USDC balance before I place a bet" -``` - -### Portfolio Review - -Regular check-ins on holdings: - -``` -"How's my portfolio doing?" -"What's my largest holding?" -"Show portfolio breakdown by chain" -``` - -### After Transactions - -Verify transaction completed: - -``` -"Did my ETH arrive?" -"Show my new BNKR balance" -``` - -## Common Questions - -### "How much [token] do I have?" - -Returns balance across all chains with USD value. - -### "What's my balance on [chain]?" - -Returns all token holdings on that specific chain. - -### "Show my portfolio" - -Returns complete breakdown by chain with USD totals. +**Before trading:** +- "Do I have enough ETH to swap for 100 USDC?" -### "What tokens do I own?" +**Portfolio review:** +- "What's my largest holding?" +- "Show portfolio breakdown by chain" -Lists all tokens with non-zero balance. +**After transactions:** +- "Did my ETH arrive?" +- "Show my new BNKR balance" ## Notes -- **Read-only operation**: Balance queries don't execute transactions -- **Real-time data**: Prices and balances are current -- **All wallets**: Shows balance of connected wallet address -- **Dust filtering**: Very small balances may be excluded +- Balance queries are read-only (no transactions) +- Shows balance of connected wallet address +- Very small balances (dust) may be excluded diff --git a/bankr-agent/skills/bankr-token-deployment/SKILL.md b/bankr-agent/skills/bankr-token-deployment/SKILL.md index 3603d90..18a41c3 100644 --- a/bankr-agent/skills/bankr-token-deployment/SKILL.md +++ b/bankr-agent/skills/bankr-token-deployment/SKILL.md @@ -8,130 +8,39 @@ version: 1.0.0 Deploy and manage ERC20 tokens using Clanker. -## Overview +## Supported Chains -Clanker enables token deployment on: -- **Base**: Primary deployment chain +- **Base**: Primary deployment chain, full Clanker support - **Unichain**: Secondary option -## Operations - -### Deploy Token - -Create a new ERC20 token: - -``` -"Deploy a token called MyToken with symbol MTK" -"Create a new memecoin called DOGE2" -"Launch a token named BankrFan" -``` - -### Claim Fees - -Collect unclaimed trading fees: - -``` -"Claim fees for my token" -"Check unclaimed Clanker fees" -"Collect my token rewards" -``` - -### Update Metadata - -Modify token information: +## Deployment Parameters -``` -"Update my token description" -"Change token social links" -"Add audit URL to my token" -``` - -### Update Image - -Change token logo: - -``` -"Update my token image" -"Change logo for MyToken" -``` - -## Deployment Details - -### Required Parameters - -| Parameter | Description | Example | -|-----------|-------------|---------| -| Name | Token name | "MyToken" | -| Symbol | Ticker (3-5 chars) | "MTK" | - -### Optional Parameters - -| Parameter | Description | -|-----------|-------------| -| Description | Token description | -| Image | Logo URL or upload | -| Website | Project website | -| Twitter | Twitter/X handle | -| Telegram | Telegram group | -| Discord | Discord server | +| Parameter | Required | Description | +|-----------|----------|-------------| +| Name | Yes | Token name (e.g., "MyToken") | +| Symbol | Yes | Ticker, 3-5 chars (e.g., "MTK") | +| Description | No | Token description | +| Image | No | Logo URL or upload | +| Website | No | Project website | +| Twitter | No | Twitter/X handle | +| Telegram | No | Telegram group | ## Prompt Examples -### Deploying +**Deploy tokens:** +- "Deploy a token called BankrFan with symbol BFAN" +- "Create a memecoin: name=DogeKiller, symbol=DOGEK" +- "Deploy token with website myproject.com and Twitter @myproject" -``` -"Deploy a token called BankrFan with symbol BFAN" -"Create a memecoin: name=DogeKiller, symbol=DOGEK" -"Launch a token named CryptoGems (GEMS)" -"Deploy new token: MyProject (PROJ)" -``` +**Claim fees:** +- "Claim fees for my token MTK" +- "Check my Clanker fees" +- "Claim legacy Clanker fees" -### With Metadata - -``` -"Deploy token MyToken (MTK) with description 'Community token for fans'" -"Create token with website myproject.com and Twitter @myproject" -"Launch token with logo [image URL]" -``` - -### Fee Management - -``` -"Claim fees for my token MTK" -"Check my Clanker fees" -"How much in unclaimed fees do I have?" -"Claim all my token fees" -``` - -### Legacy Fees - -``` -"Claim legacy Clanker fees" -"Check old token fees" -``` - -### Metadata Updates - -``` -"Update description for MyToken" -"Add Twitter link to my token" -"Update audit URL for MTK" -"Change my token's website" -``` - -### Image Updates - -``` -"Update logo for MyToken" -"Change my token image to [URL]" -``` - -### Reward Recipient - -``` -"Update reward recipient for my token" -"Change fee collection address" -``` +**Update metadata:** +- "Update description for MyToken" +- "Add Twitter link to my token" +- "Update logo for MyToken" ## Rate Limits @@ -140,104 +49,11 @@ Change token logo: | Standard Users | 1 token/day | | Bankr Club Members | 10 tokens/day | -## Response Format - -### Deployment Success - -```json -{ - "status": "completed", - "response": "Token deployed successfully!\n\nName: MyToken\nSymbol: MTK\nChain: Base\nContract: 0x1234...abcd\n\nYour token is now live and tradeable!", - "transactions": [{ - "type": "deploy_token", - "metadata": {...} - }] -} -``` - -### Fee Claim - -```json -{ - "response": "Fees claimed successfully!\n\nToken: MyToken (MTK)\nAmount: 0.5 ETH\nTransaction: 0x..." -} -``` - -### Fee Check - -```json -{ - "response": "Your unclaimed Clanker fees:\n\nMyToken (MTK): 0.5 ETH\nOtherToken (OTK): 0.1 ETH\n\nTotal: 0.6 ETH" -} -``` - -## Token Lifecycle - -### 1. Planning - -Before deploying: -- Choose memorable name and symbol -- Prepare logo/branding -- Write token description -- Set up social links - -### 2. Deployment - -``` -"Deploy token MyToken (MTK)" -``` - -Token is created with: -- Initial supply -- Trading enabled on DEX -- Fee mechanism active - -### 3. Management - -After deployment: -- Update metadata as needed -- Claim fees regularly -- Engage community - ## Fee Structure -### Trading Fees - -- Small fee on each trade -- Accumulated for token creator -- Claimable anytime - -### Legacy Fees - -- Fees from older Clanker versions -- Claim separately with legacy command -- Base chain only - -## Best Practices - -### Naming - -- **Unique**: Stand out from others -- **Memorable**: Easy to remember -- **Clear**: Avoid confusion with established tokens - -### Symbol - -- 3-5 characters recommended -- All caps convention -- Avoid existing symbols - -### Metadata - -- Add description immediately -- Include social links -- Upload quality logo - -### Fee Management - -- Claim fees regularly -- Monitor trading activity -- Consider reinvestment +- Small fee on each trade, accumulated for token creator +- Claimable anytime via "Claim fees for my token" +- Legacy fees (older Clanker versions) claimed separately ## Common Issues @@ -248,24 +64,9 @@ After deployment: | Symbol exists | Use unique symbol | | Image upload failed | Check format/size | -## Supported Chains - -### Base (Primary) - -- Full Clanker support -- Legacy fee claims -- Most liquidity - -### Unichain - -- Token deployment -- Fee management -- Growing ecosystem - -## Tips +## Best Practices -1. **Research first** - Check if name/symbol exists -2. **Quality branding** - Good logo matters -3. **Complete metadata** - Fill all fields -4. **Claim regularly** - Don't leave fees unclaimed -5. **Engage community** - Build around your token +- Choose unique, memorable name and symbol +- Add description and social links immediately +- Upload quality logo +- Claim fees regularly diff --git a/bankr-agent/skills/bankr-token-trading/SKILL.md b/bankr-agent/skills/bankr-token-trading/SKILL.md index 4acc001..a4d7350 100644 --- a/bankr-agent/skills/bankr-token-trading/SKILL.md +++ b/bankr-agent/skills/bankr-token-trading/SKILL.md @@ -10,114 +10,43 @@ Execute token trades and swaps across multiple blockchains. ## Supported Chains -| Chain | Network | Native Token | -|-------|---------|--------------| -| Base | EVM | ETH | -| Polygon | EVM | MATIC | -| Ethereum | EVM (Mainnet) | ETH | -| Unichain | EVM | ETH | -| Solana | Solana | SOL | - -## Operations - -### Same-Chain Swaps - -Trade tokens on the same blockchain: - -``` -"Swap 0.1 ETH for USDC on Base" -"Buy $50 of BNKR on Base" -"Sell 100 USDC for ETH" -``` - -### Cross-Chain Swaps - -Trade tokens across different blockchains: - -``` -"Bridge 0.5 ETH from Ethereum to Base" -"Swap ETH on Mainnet for SOL on Solana" -"Move 100 USDC from Polygon to Base" -``` - -### ETH/WETH Conversion - -Convert between native ETH and wrapped ETH: - -``` -"Convert 0.1 ETH to WETH" -"Unwrap 0.5 WETH to ETH" -``` +| Chain | Native Token | +|-------|--------------| +| Base | ETH | +| Polygon | MATIC | +| Ethereum | ETH | +| Unichain | ETH | +| Solana | SOL | ## Amount Formats -Bankr accepts three amount formats: - | Format | Example | Description | |--------|---------|-------------| | USD | `$50` | Dollar amount to spend | | Percentage | `50%` | Percentage of your balance | | Exact | `0.1 ETH` | Specific token amount | -### Examples - -``` -"Buy $50 of ETH" → Spends $50 USD worth -"Sell 25% of my BNKR" → Sells quarter of holdings -"Swap 0.1 ETH for USDC" → Swaps exactly 0.1 ETH -``` - -## Trading Prompts - -### Buying Tokens - -``` -"Buy $100 of ETH on Base" -"Buy 0.05 ETH worth of BNKR" -"Purchase some Solana" -``` +## Prompt Examples -### Selling Tokens - -``` -"Sell all my BNKR for ETH" -"Sell $50 worth of USDC" -"Sell 50% of my ETH holdings" -``` - -### Swapping Tokens - -``` -"Swap 0.1 ETH for USDC on Base" -"Exchange 100 USDC for BNKR" -"Trade my MATIC for ETH on Polygon" -``` +**Same-chain swaps:** +- "Swap 0.1 ETH for USDC on Base" +- "Buy $50 of BNKR on Base" +- "Sell 50% of my ETH holdings" -### Cross-Chain Operations +**Cross-chain swaps:** +- "Bridge 0.5 ETH from Ethereum to Base" +- "Move 100 USDC from Polygon to Solana" -``` -"Bridge 1 ETH from Mainnet to Base" -"Swap ETH on Ethereum for USDC on Polygon" -"Move my USDC from Polygon to Solana" -``` +**ETH/WETH conversion:** +- "Convert 0.1 ETH to WETH" +- "Unwrap 0.5 WETH to ETH" ## Chain Selection -### Default Behavior - - If no chain specified, Bankr selects the most appropriate chain - Base is preferred for most operations due to low fees - Cross-chain routes are automatically optimized - -### Specifying Chains - -Include chain name in the prompt: - -``` -"Buy ETH on Polygon" -"Swap tokens on Ethereum mainnet" -"Trade SOL on Solana" -``` +- Include chain name in prompt to specify: "Buy ETH on Polygon" ## Slippage @@ -125,29 +54,6 @@ Include chain name in the prompt: - For volatile tokens, Bankr adjusts slippage as needed - If slippage is exceeded, the transaction fails safely -## Response Handling - -Successful trades return: - -```json -{ - "status": "completed", - "response": "Successfully swapped 0.1 ETH for 324.56 USDC on Base", - "transactions": [{ - "type": "swap", - "metadata": { - "__ORIGINAL_TX_DATA__": { - "humanReadableMessage": "Swap 0.1 ETH for USDC", - "inputTokenTicker": "ETH", - "outputTokenTicker": "USDC", - "inputTokenAmount": "0.1", - "outputTokenAmount": "324.56" - } - } - }] -} -``` - ## Common Issues | Issue | Resolution | @@ -156,25 +62,3 @@ Successful trades return: | Token not found | Check token symbol/address | | High slippage | Try smaller amounts | | Network congestion | Wait and retry | - -## Example Prompts - -**Simple trades:** -- "Buy $50 of ETH" -- "Sell my BNKR for USDC" -- "Swap 0.1 ETH for USDC" - -**Chain-specific:** -- "Buy ETH on Base" -- "Swap SOL for USDC on Solana" -- "Trade on Polygon" - -**Cross-chain:** -- "Bridge ETH from Mainnet to Base" -- "Move USDC to Solana" -- "Swap ETH on Ethereum for SOL" - -**Advanced:** -- "Sell 50% of my ETH holdings" -- "Buy $100 of BNKR and stake it" -- "Convert all my WETH to ETH" diff --git a/bankr-agent/skills/bankr-transfers/SKILL.md b/bankr-agent/skills/bankr-transfers/SKILL.md index 1a9265e..236d1fc 100644 --- a/bankr-agent/skills/bankr-transfers/SKILL.md +++ b/bankr-agent/skills/bankr-transfers/SKILL.md @@ -10,19 +10,11 @@ Transfer tokens to addresses, ENS names, or social handles. ## Supported Transfers -### EVM Chains -- Native tokens (ETH, MATIC) -- ERC20 tokens (USDC, BNKR, etc.) -- Supported on: Base, Polygon, Ethereum, Unichain - -### Solana -- Native SOL -- SPL tokens +- **EVM Chains**: Base, Polygon, Ethereum, Unichain (ETH, MATIC, ERC20 tokens) +- **Solana**: SOL and SPL tokens ## Recipient Formats -Bankr resolves recipients from multiple formats: - | Format | Example | Description | |--------|---------|-------------| | Address | `0x1234...abcd` | Direct wallet address | @@ -31,79 +23,37 @@ Bankr resolves recipients from multiple formats: | Farcaster | `@dwr.eth` | Farcaster username | | Telegram | `@username` | Telegram handle | -### Resolution Priority - -When using social handles, Bankr: -1. Looks up the username on the platform -2. Finds their linked wallet address -3. Validates the address before sending - -## Transfer Prompts - -### To Address - -``` -"Send 0.1 ETH to 0x1234567890abcdef..." -"Transfer 100 USDC to 0xabcd..." -``` - -### To ENS Name - -``` -"Send 0.5 ETH to vitalik.eth" -"Transfer USDC to mydomain.eth" -``` - -### To Social Handle - -``` -"Send $50 of ETH to @elonmusk on Twitter" -"Transfer 0.1 ETH to @dwr.eth on Farcaster" -"Send 100 USDC to @username on Telegram" -``` +Social handles are resolved to linked wallet addresses before sending. ## Amount Formats -Same as trading - three formats supported: - | Format | Example | Description | |--------|---------|-------------| | USD | `$50` | Dollar amount | | Percentage | `50%` | Percentage of balance | | Exact | `0.1 ETH` | Specific amount | -### Examples - -``` -"Send $100 worth of ETH to vitalik.eth" -"Transfer 50% of my USDC to @friend" -"Send exactly 0.5 ETH to 0x..." -``` +## Prompt Examples -## Chain Selection - -### Automatic - -If not specified, Bankr selects the appropriate chain: -- Checks where recipient has activity -- Considers gas costs -- Prefers Base for low fees +**To addresses:** +- "Send 0.5 ETH to 0x1234..." +- "Transfer 100 USDC to 0xabcd..." -### Manual +**To ENS:** +- "Send 1 ETH to vitalik.eth" +- "Transfer $50 of USDC to mydomain.eth" -Specify chain in the prompt: +**To social handles:** +- "Send $20 of ETH to @friend on Twitter" +- "Transfer 0.1 ETH to @user on Farcaster" -``` -"Send ETH on Base to vitalik.eth" -"Transfer USDC on Polygon to 0x..." -"Send SOL on Solana to @username" -``` +**With chain specified:** +- "Send ETH on Base to vitalik.eth" +- "Send 10% of my ETH to @friend" -## Supported Transfer Types +## Chain Selection -- **Native tokens** - ETH, MATIC, etc. -- **ERC20 tokens** - USDC, USDT, any token -- **NFTs** - See NFT Operations skill +If not specified, Bankr selects automatically based on recipient activity and gas costs. Specify chain in prompt if needed. ## Common Issues @@ -113,34 +63,9 @@ Specify chain in the prompt: | Social handle not found | Check username is correct | | No linked wallet | User hasn't linked wallet to social | | Insufficient balance | Reduce amount or add funds | -| Invalid address | Check address format | ## Security Notes - Always verify recipient before confirming -- Double-check addresses for transfers - Social handle resolution shows the resolved address - Large transfers may require additional confirmation - -## Example Prompts - -**To addresses:** -- "Send 0.5 ETH to 0x1234..." -- "Transfer 100 USDC to 0xabcd..." - -**To ENS:** -- "Send 1 ETH to vitalik.eth" -- "Transfer $50 of USDC to mydomain.eth" - -**To social handles:** -- "Send $20 of ETH to @friend on Twitter" -- "Transfer 0.1 ETH to @user on Farcaster" -- "Send USDC to @contact on Telegram" - -**With chain specified:** -- "Send ETH on Base to vitalik.eth" -- "Transfer USDC on Polygon to @friend" - -**Percentage amounts:** -- "Send 10% of my ETH to @friend" -- "Transfer half my USDC to vitalik.eth" diff --git a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md index 25d1af4..2600232 100644 --- a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md +++ b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md @@ -6,290 +6,75 @@ version: 1.0.0 # SDK Balance Queries -Query multi-chain token balances and portfolio data with AI-powered analysis using the Bankr SDK and x402 micropayments. +Query multi-chain token balances and portfolio data using natural language prompts. -## Overview +## Operations -The Bankr SDK provides a simple natural language interface for querying token balances, portfolio values, and NFT holdings across multiple blockchains. Balance queries are processed through the AI backend and return rich, formatted responses with optional charts and analysis cards. +| Operation | Example Prompt | Notes | +|-----------|----------------|-------| +| Single token balance | "How much USDC do I have?" | Fastest query type | +| Multi-token balance | "Show my ETH, USDC, and DEGEN balances" | Single chain | +| All tokens on chain | "What tokens do I have on Base?" | Lists all holdings | +| Multi-chain balances | "Show my balances across all chains" | Slower, queries all | +| Portfolio value | "What's my total portfolio value in USD?" | USD conversion | +| Token value | "How much is my DEGEN worth?" | Single token USD | +| NFT holdings | "Show me my NFT collections" | Lists collections | +| NFT floor prices | "What's the floor price of my NFTs?" | External API calls | -**Key capabilities:** -- Multi-chain balance queries (Base, Ethereum, Polygon, Solana) -- Token balance lookup by symbol or contract -- Portfolio valuation in USD -- NFT collection holdings and floor prices -- Rich data responses with charts and analysis +## Prompt Patterns -## Basic Query +``` +# Token Balances +"What are my token balances?" +"How much [TOKEN] do I have?" +"Show my [TOKEN] balance on [CHAIN]" +"What's my balance of token 0x..." + +# Multi-Chain +"Show my balances across all chains" +"What are my balances on Base and Ethereum?" +"Compare my USDC holdings across all chains" + +# Portfolio Value +"What's my total portfolio value in USD?" +"How much is my [TOKEN] worth in USD?" +"What's the total value of my Base holdings?" + +# NFTs +"Show me my NFT collections" +"How many Pudgy Penguins do I own?" +"What's the floor price of my NFTs?" +``` -Initialize the BankrClient and query balances using natural language prompts: +## Usage ```typescript import { BankrClient } from "@bankr/sdk"; const client = new BankrClient({ privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, }); const result = await client.promptAndWait({ - prompt: "What are my token balances?", + prompt: "What are my token balances on Base?", }); console.log(result.response); // "You have 150.5 USDC, 0.25 ETH, 1000 DEGEN on Base..." ``` -## Query Examples - -### Single Token Queries - -Query specific token balances on a particular chain: - -```typescript -// Specific token on default chain (Base) -const usdcBalance = await client.promptAndWait({ - prompt: "How much USDC do I have?", -}); - -// Specific token on specific chain -const ethBalance = await client.promptAndWait({ - prompt: "How much ETH do I have on Ethereum mainnet?", -}); - -// Token by contract address -const tokenBalance = await client.promptAndWait({ - prompt: "What's my balance of token 0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed?", -}); -``` - -### Multi-Token Queries - -Query multiple tokens in a single request: - -```typescript -// Multiple specific tokens -const balances = await client.promptAndWait({ - prompt: "Show me my ETH, USDC, and DEGEN balances", -}); - -// All tokens on a chain -const allOnBase = await client.promptAndWait({ - prompt: "What tokens do I have on Base?", -}); -``` - -### Multi-Chain Queries - -Query balances across multiple blockchains: - -```typescript -// All chains -const allChains = await client.promptAndWait({ - prompt: "Show my balances across all chains", -}); - -// Specific chains -const ethAndBase = await client.promptAndWait({ - prompt: "What are my balances on Base and Ethereum?", -}); - -// Compare holdings -const comparison = await client.promptAndWait({ - prompt: "Compare my USDC holdings across all chains", -}); -``` - -### Portfolio Value Queries - -Get USD valuations of holdings: - -```typescript -// Total portfolio value -const totalValue = await client.promptAndWait({ - prompt: "What's my total portfolio value in USD?", -}); - -// Specific token value -const degenValue = await client.promptAndWait({ - prompt: "How much is my DEGEN worth in USD?", -}); - -// Chain-specific value -const baseValue = await client.promptAndWait({ - prompt: "What's the total value of my Base holdings?", -}); -``` - -### NFT Queries - -Query NFT holdings and valuations: - -```typescript -// List NFT collections -const nftCollections = await client.promptAndWait({ - prompt: "Show me my NFT collections", -}); - -// NFT floor prices -const floorPrices = await client.promptAndWait({ - prompt: "What's the floor price of my NFTs?", -}); - -// Specific collection -const pudgyInfo = await client.promptAndWait({ - prompt: "How many Pudgy Penguins do I own?", -}); -``` - -## Query Different Wallet - -Query balances for a wallet other than the configured context wallet: - -```typescript -// Override wallet for this query only -const result = await client.promptAndWait({ - prompt: "What are the balances in this wallet?", - walletAddress: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", -}); - -// Query specific wallet with specific tokens -const otherWallet = await client.promptAndWait({ - prompt: "How much ETH and USDC does this address have?", - walletAddress: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", -}); -``` - -## Rich Data Responses - -Balance queries may return rich data including charts and analysis cards. Handle these appropriately: - -```typescript -const result = await client.promptAndWait({ - prompt: "Show my portfolio breakdown", -}); - -// Check for rich data -if (result.richData && result.richData.length > 0) { - for (const data of result.richData) { - switch (data.type) { - case "chart": - console.log(`Portfolio chart: ${data.url}`); - // Display chart image from URL - break; - case "social-card": - console.log(`Analysis card: ${data.text}`); - // Display card content - break; - case "table": - console.log(`Data table: ${JSON.stringify(data.rows)}`); - // Render table data - break; - } - } -} -``` - -## Response Structure - -Balance query responses follow the standard SDK response format: - -```typescript -interface BalanceQueryResponse { - status: "completed" | "failed" | "pending" | "processing"; - response: string; // Human-readable balance summary - richData?: RichDataItem[]; // Charts, cards, tables - jobId: string; // Job identifier - processingTime?: number; // Time in milliseconds -} - -interface RichDataItem { - type: "chart" | "social-card" | "table" | "image"; - url?: string; // For charts/images - text?: string; // For cards - rows?: any[]; // For tables -} -``` - ## Supported Chains -Balance queries support the following blockchain networks: - -| Chain | Default | Notes | -|-------|---------|-------| -| Base | Yes | Primary chain, fastest responses | -| Ethereum | No | Mainnet ERC20 and NFTs | -| Polygon | No | L2 tokens and NFTs | -| Solana | No | SPL tokens and NFTs | - -Specify chain in natural language: "on Base", "on Ethereum", "on mainnet", "on Polygon", "on Solana" - -## Response Times - -Expected response times vary by query complexity: - -| Query Type | Typical Time | Notes | -|------------|--------------|-------| -| Single token balance | 2-3 seconds | Fastest | -| Multiple tokens | 3-5 seconds | Single chain | -| Multi-chain query | 5-10 seconds | Queries all chains | -| Portfolio valuation | 3-5 seconds | Includes USD conversion | -| NFT holdings | 5-10 seconds | Fetches metadata | -| NFT floor prices | 8-12 seconds | External API calls | - -## Error Handling - -Handle common balance query errors: - -```typescript -const result = await client.promptAndWait({ - prompt: "What are my balances?", - timeout: 30000, // 30 second timeout -}); - -if (result.status === "failed") { - const error = result.error; - - if (error?.includes("Invalid address")) { - console.error("The wallet address format is invalid"); - } else if (error?.includes("Rate limited")) { - console.error("Too many requests, try again later"); - } else if (error?.includes("Chain not supported")) { - console.error("The specified chain is not supported"); - } else { - console.error(`Balance query failed: ${error}`); - } - return; -} - -console.log(result.response); -``` - -## Best Practices +| Chain | Notes | +|-------|-------| +| Base | Default chain, fastest responses | +| Ethereum | Mainnet ERC20 and NFTs | +| Polygon | L2 tokens and NFTs | +| Solana | SPL tokens and NFTs | -1. **Use specific queries**: "How much USDC on Base?" is faster than "Show all balances everywhere" -2. **Cache responses**: Balance data is valid for short periods; avoid redundant queries -3. **Handle timeouts**: Set appropriate timeouts for multi-chain queries (longer) vs single token (shorter) -4. **Check status**: Always verify `result.status === "completed"` before using response data -5. **Process rich data**: Display charts and cards when available for better UX +Specify chain in prompt: "on Base", "on Ethereum", "on Polygon", "on Solana" -## Cost +## Related Skills -Each balance query costs $0.01 USDC via x402 micropayments, regardless of complexity. The payment wallet must have sufficient USDC on Base to cover query costs. - -## Common Prompt Patterns - -Effective prompts for balance queries: - -```typescript -// Recommended patterns -"What are my token balances on Base?" -"How much ETH do I have?" -"Show my USDC balance across all chains" -"What's my total portfolio value?" -"List my NFT holdings" - -// Less effective (still work but slower) -"Can you check what tokens I might have?" -"I'm wondering about my balances" -"Tell me everything about my wallet" -``` +- **sdk-wallet-operations**: Client setup and configuration +- **sdk-capabilities**: Full list of supported operations diff --git a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md index bcc8305..5730f22 100644 --- a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md +++ b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md @@ -6,401 +6,78 @@ version: 1.0.0 # SDK Capabilities -Complete guide to all operations supported by the Bankr SDK. The SDK accepts natural language prompts and returns transaction data for execution. - -## Overview - -The Bankr SDK provides AI-powered Web3 operations through natural language prompts. The SDK operates in **wallet mode**, meaning it returns transaction data for you to sign and execute rather than executing transactions directly. - -**Key features:** -- Natural language interface (no complex API calls) -- Multi-chain support (EVM chains: Base, Ethereum, Polygon) -- Transaction building with optimal 0x routing -- Market data and analysis -- x402 micropayments ($0.01 USDC per request) +Complete guide to operations supported by the Bankr SDK. The SDK accepts natural language prompts and returns transaction data for execution. + +## Supported Operations + +| Category | Operation | Example Prompt | +|----------|-----------|----------------| +| **Swaps** | Token swap | "Swap 0.1 ETH to USDC" | +| | Value-based buy | "Buy $100 of DEGEN" | +| | Percentage swap | "Swap 50% of my ETH to USDC" | +| **Transfers** | ERC20 transfer | "Send 100 USDC to 0x..." | +| | ETH transfer | "Send 0.1 ETH to @username" | +| | NFT transfer | "Send my Bored Ape #123 to 0x..." | +| **Wrapping** | Wrap ETH | "Wrap 1 ETH" | +| | Unwrap WETH | "Unwrap 1 WETH" | +| **Cross-Chain** | Bridge (EVM only) | "Bridge 100 USDC from Ethereum to Base" | +| **Leverage** | Long position | "Buy $50 of ETH/USD with 5x leverage" | +| | Short position | "Short $10 of GOLD" | +| | Close position | "Close all my BTC/USD positions" | +| **NFTs** | Buy NFT | "Buy the cheapest Tiny Dino NFT" | +| | List for sale | "List my Bored Ape for 10 ETH" | +| | Mint (Manifold) | "Mint from Manifold at 0x..." | +| | Mint (SeaDrop) | "Mint from SeaDrop at 0x..." | +| **Staking** | Stake BNKR | "Stake 1000 BNKR" | +| | Unstake | "Unstake my BNKR" | +| **Queries** | Balances | "What are my balances?" | +| | NFT holdings | "What NFTs do I own?" | +| | Token price | "Price of ETH" | +| | Token analysis | "Analyze DEGEN" | + +## NOT Supported + +| Feature | Alternative | +|---------|-------------| +| Polymarket betting | Use https://bankr.bot directly | +| Limit orders | Use https://swap.bankr.bot | +| DCA/TWAP orders | Use https://swap.bankr.bot | +| Solana cross-chain | EVM chains only | +| Bankr Earn | Use Bankr terminal | ## Supported Chains -| Chain | Native Token | Notes | -|-------|-------------|-------| -| Base | ETH | Default chain, lowest fees | -| Ethereum | ETH | Mainnet | -| Polygon | MATIC | L2, low fees | - -**Note:** Solana cross-chain swaps are NOT supported via SDK. The SDK operates in wallet mode which has limited Solana support. - ---- - -## SUPPORTED Operations - -### Token Swaps - -Exchange tokens on the same chain using 0x routing. - -**Example prompts:** -``` -"Swap 0.1 ETH to USDC" -"Exchange 100 USDC for WETH" -"Swap 1000 DEGEN to ETH" -"Swap 50% of my ETH to USDC" -"Sell all my DEGEN" -"Swap 0.1 ETH to USDC on Base" -"Exchange 100 USDC for WETH on Polygon" -"Buy $100 of ETH" -"Buy $5 of DEGEN" -"Purchase $50 worth of BNKR" -``` - -### ERC20 Transfers - -Send ERC20 tokens to addresses or social usernames. - -**Example prompts:** -``` -"Send 100 USDC to 0x1234..." -"Transfer 50 BNKR to @farcasteruser" -"Send 100 USDC to @username" -``` - -### Native Token Transfers - -Send ETH/MATIC to addresses. - -**Example prompts:** -``` -"Send 0.1 ETH to 0xabcd..." -"Transfer 0.5 ETH to @username" -``` - -### ETH/WETH Conversion - -Wrap and unwrap ETH. - -**Example prompts:** -``` -"Wrap 1 ETH" -"Convert 0.5 ETH to WETH" -"Unwrap 1 WETH" -"Convert WETH to ETH" -``` - -### Cross-Chain Swaps (EVM Only) - -Bridge or swap tokens across EVM chains. **Solana cross-chain is NOT supported.** - -**Example prompts:** -``` -"Swap 10 USDC on Base to USDC on Polygon" -"Bridge 1 ETH from Ethereum to Base" -"Swap 100 USDC on Polygon to ETH on Mainnet" -``` - -### Avantis Leveraged Trading - -Trade commodities, forex, and crypto with leverage on Base. - -**Available assets:** BTC/USD, ETH/USD, GOLD, SILVER, OIL, EUR/USD, GBP/USD, and more. - -**Example prompts:** -``` -"Buy $5 of BTC/USD" -"Short $10 of GOLD" -"Long $50 of ETH/USD" -"Buy $10 of GOLD with 5x leverage" -"Short BTC/USD with 10x leverage" -"Buy $25 of OIL with 10x leverage and 5% stop loss" -"Long $50 of ETH/USD with take profit at 150%" -"Buy $100 of BTC/USD with stop loss if price drops by $5000" -``` - -### Close Avantis Positions - -**Example prompts:** -``` -"Close all my BTC/USD positions" -"Close all my OIL positions" -"Close my ETH/USD position" -"Close $50 of my GOLD position" -"Close my Bitcoin long" -``` - -### View Avantis Positions - -**Example prompts:** -``` -"Show my Avantis positions" -"What are my Avantis positions" -"View my Avantis portfolio" -"What positions do I have on Avantis" -"Show my closed Avantis trades" -``` - -### Buy NFTs - -Purchase NFTs from OpenSea. - -**Example prompts:** -``` -"Buy the cheapest Tiny Dino NFT" -"Get me an OK Computer NFT" -"Purchase the floor BasedPunk" -"Buy this NFT: https://opensea.io/collection/okcomputers" -"Purchase token #1234 from BasePaint" -``` - -### Transfer NFTs - -Send NFTs to other addresses. - -**Example prompts:** -``` -"Send my Bored Ape #123 to 0x..." -"Transfer NFT to @username" -``` - -### List NFTs for Sale - -List your NFTs on OpenSea. - -**Example prompts:** -``` -"List my Bored Ape for 10 ETH" -"Sell my NFT for 5 ETH" -``` - -### Cancel NFT Listings - -**Example prompts:** -``` -"Cancel my NFT listing" -"Remove my Bored Ape from sale" -``` - -### Accept NFT Offers - -**Example prompts:** -``` -"Accept offer on my NFT" -"Accept the highest offer on my Bored Ape" -``` - -### Mint NFTs (SeaDrop) - -Mint NFTs via SeaDrop protocol. - -**Example prompts:** -``` -"Mint from the SeaDrop collection at 0x..." -``` +| Chain | Native Token | Default | +|-------|-------------|---------| +| Base | ETH | Yes | +| Ethereum | ETH | No | +| Polygon | MATIC | No | -### Mint NFTs (Manifold) - -Mint NFTs via Manifold. - -**Example prompts:** -``` -"Mint the Manifold NFT at 0x..." -``` - -### BNKR Staking - -Stake and unstake BNKR tokens. - -**Example prompts:** -``` -"Stake 1000 BNKR" -"Unstake my BNKR" -"How much BNKR do I have staked?" -``` - -### View Automations - -View your active automations. - -**Example prompts:** -``` -"Show my automations" -"What automations do I have?" -``` - -### Cancel Automations - -Cancel existing automations. - -**Example prompts:** -``` -"Cancel my automation" -"Stop all my automations" -``` - -### Balance Queries - -Check token balances. - -**Example prompts:** -``` -"What are my balances?" -"Show my balances on Base" -"What tokens do I hold?" -"Balances on Polygon" -``` - -### NFT Balances - -Check NFT holdings. - -**Example prompts:** -``` -"What NFTs do I own?" -"Show my NFTs on Base" -"Do I have any Bored Apes?" -``` - -### NFT Listings Discovery - -Browse NFT listings. - -**Example prompts:** -``` -"Show me the cheapest Bored Apes" -"What are the top 5 CryptoPunk listings" -"Show me NFTs from BasedPunks" -"What's the floor price for Azuki" -``` - -### Token Analysis - -Get price, market cap, volume, technical analysis, and social sentiment. - -**Example prompts:** -``` -"Price of ETH" -"What's BTC trading at?" -"Market cap of BNKR" -"Volume of USDC" -"Analyze ETH" -"TA for BNKR" -"Chart analysis for DEGEN" -``` - -### Token Discovery - -Find trending tokens. - -**Example prompts:** -``` -"What tokens do you recommend on Base?" -"Top tokens on Polygon today" -"Best coins on mainnet right now" -"Trending tokens on Base" -``` - ---- - -## NOT SUPPORTED Operations - -The following features are not available via the SDK: - -### Polymarket - -Not supported via SDK: -- Placing bets -- Selling positions -- Redeeming winnings - -Use the Bankr trading wallet directly at https://bankr.bot - -### Limit Orders - -Not supported via SDK. Use https://swap.bankr.bot to place limit orders. - -### Automated Orders - -Not supported via SDK: -- Stop orders -- TWAP (Time-Weighted Average Price) orders -- DCA (Dollar-Cost Averaging) orders - -Use https://swap.bankr.bot to set up automated orders. - -### Bankr Earn - -Not supported via SDK. Use the Bankr terminal to manage earn. - -### Featured NFT Mints - -Some featured mints require the Bankr trading wallet and are not available via SDK. - -### Solana Cross-Chain Swaps - -Solana cross-chain swaps are not supported via SDK. Only EVM chains (Base, Ethereum, Polygon) are supported. - -## Transaction Types - -The SDK returns transactions with a `type` field. Use this to identify and handle different operations: - -| Type | Description | -|------|-------------| -| `swap` | Token exchange via 0x routing | -| `approval` | ERC20 token approval | -| `transfer_erc20` | ERC20 token transfer | -| `transfer_eth` | Native ETH transfer | -| `convert_eth_to_weth` | Wrap ETH to WETH | -| `convert_weth_to_eth` | Unwrap WETH to ETH | -| `transfer_nft` | NFT transfer | -| `mint_manifold_nft` | Mint via Manifold | -| `mint_seadrop_nft` | Mint via SeaDrop | -| `buy_nft` | Purchase NFT | -| `avantisTrade` | Avantis leveraged trade | -| `swapCrossChain` | Cross-chain swap (EVM only) | -| `manage_bankr_staking` | BNKR staking | - ---- - -## Usage Pattern +## Usage ```typescript import { BankrClient } from "@bankr/sdk"; const client = new BankrClient({ privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, }); const result = await client.promptAndWait({ prompt: "Swap 0.1 ETH to USDC on Base", }); -if (result.status === "completed") { - // For trading operations: execute the returned transaction - if (result.transactions?.length) { - const swapTx = result.transactions.find(tx => tx.type === "swap"); - - // Handle approval if needed - if (swapTx?.metadata.approvalRequired) { - await wallet.sendTransaction(swapTx.metadata.approvalTx); - } - - // Execute the swap - const tx = swapTx.metadata.transaction; - await wallet.sendTransaction(tx); - } - - // For queries: read the response - console.log(result.response); +if (result.status === "completed" && result.transactions?.length) { + // Execute the returned transaction with your wallet + await wallet.sendTransaction(result.transactions[0].metadata.transaction); } ``` ---- - ## Cost -Each request costs $0.01 USDC via x402 micropayments. The payment wallet must have USDC on Base chain. +Each request costs $0.01 USDC via x402 micropayments. Gas fees for transactions are paid separately. -| Requests | Cost | -|----------|------| -| 100 | $1.00 | -| 1,000 | $10.00 | -| 10,000 | $100.00 | +## Related Skills -Gas fees for executing transactions are paid separately from the user's wallet. +- **sdk-token-swaps**: Token swap patterns and approval handling +- **sdk-transaction-builder**: Building transfers, NFT ops, bridges +- **sdk-balance-queries**: Portfolio and balance queries diff --git a/x402-sdk-dev/skills/sdk-job-management/SKILL.md b/x402-sdk-dev/skills/sdk-job-management/SKILL.md index 9a50cb8..d971baa 100644 --- a/x402-sdk-dev/skills/sdk-job-management/SKILL.md +++ b/x402-sdk-dev/skills/sdk-job-management/SKILL.md @@ -6,407 +6,96 @@ version: 1.0.0 # SDK Job Management -Manage asynchronous jobs in the Bankr SDK: submit, poll, check status, cancel, and handle batch operations. +Manage asynchronous jobs: submit, poll, check status, cancel, and batch operations. -## Overview +## SDK Methods -The Bankr SDK processes requests asynchronously through a job-based system. Each request creates a job that progresses through a lifecycle from submission to completion. Understanding job management enables advanced control over SDK operations including manual polling, batch processing, and retry strategies. +| Method | Description | Use Case | +|--------|-------------|----------| +| `promptAndWait()` | Submit and wait for result | **Recommended** for most cases | +| `prompt()` | Submit, return immediately | Background processing | +| `pollJob()` | Poll until job completes | Manual job tracking | +| `getJobStatus()` | Check status once | Custom polling logic | +| `cancelJob()` | Cancel pending/processing job | Stop unwanted jobs | -**Key capabilities:** -- Submit jobs and receive job IDs -- Poll for job completion -- Check job status at any time -- Cancel pending or processing jobs -- Batch multiple requests efficiently -- Implement retry logic for failed jobs - -## Recommended: promptAndWait - -For most use cases, use `promptAndWait` which handles job submission and polling automatically: - -```typescript -import { BankrClient } from "@bankr/sdk"; - -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, -}); - -const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC", - timeout: 60000, // Optional: custom timeout (default 5 min) -}); +## Job Lifecycle -if (result.status === "completed") { - console.log(result.response); - console.log(result.transactions); -} ``` - -The `promptAndWait` method: -1. Submits the job to the API -2. Polls for completion at regular intervals -3. Returns when job completes, fails, or times out - -## Manual Job Control - -For advanced use cases, use manual job control methods to manage the job lifecycle directly. - -### Submit Job - -Submit a job and receive a job ID without waiting for completion: - -```typescript -const response = await client.prompt({ - prompt: "What are trending tokens?", -}); - -console.log(response.jobId); // "job_abc123def456" -console.log(response.status); // "pending" +pending → processing → completed + ↘ failed + ↘ cancelled ``` -The `prompt` method returns immediately with job metadata, allowing the application to continue other work while the job processes. - -### Check Job Status - -Query the current status of a job at any time: - -```typescript -const status = await client.getJobStatus("job_abc123def456"); - -console.log(status); -// { -// jobId: "job_abc123def456", -// status: "completed", -// prompt: "What are trending tokens?", -// response: "The trending tokens on Base are...", -// transactions: [], -// richData: [...], -// processingTime: 5230 -// } -``` +| State | Cancellable | Description | +|-------|-------------|-------------| +| pending | Yes | Awaiting processing | +| processing | Yes | Actively processing | +| completed | No | Finished successfully | +| failed | No | Encountered error | +| cancelled | No | Cancelled by user | -### Poll Until Complete +## Usage Examples -Poll a job until it reaches a terminal state (completed, failed, or cancelled): +### Recommended: promptAndWait ```typescript -const result = await client.pollJob({ - jobId: "job_abc123def456", - interval: 2000, // Poll every 2 seconds (default) - maxAttempts: 150, // Maximum poll attempts (default: ~5 min at 2s) - timeout: 300000, // Overall timeout in ms (default: 5 min) +const result = await client.promptAndWait({ + prompt: "Swap 0.1 ETH to USDC", + timeout: 60000, }); if (result.status === "completed") { console.log(result.response); -} else if (result.status === "failed") { - console.error(result.error); } ``` -### Cancel Job - -Cancel a pending or processing job: +### Manual Job Control ```typescript -const cancelResult = await client.cancelJob("job_abc123def456"); +// Submit without waiting +const { jobId } = await client.prompt({ prompt: "What are trending tokens?" }); -console.log(cancelResult); -// { -// status: "cancelled", -// cancelledAt: "2024-01-15T10:30:00.000Z", -// jobId: "job_abc123def456" -// } -``` +// Check status later +const status = await client.getJobStatus(jobId); -**Important**: Only jobs in `pending` or `processing` states can be cancelled. Completed or failed jobs cannot be cancelled. - -## Job Lifecycle - -Jobs progress through the following states: - -``` -pending → processing → completed - ↘ failed - ↘ cancelled +// Or poll until complete +const result = await client.pollJob({ jobId, timeout: 60000 }); ``` -| State | Description | Cancellable | -|-------|-------------|-------------| -| pending | Job submitted, awaiting processing | Yes | -| processing | Job actively being processed | Yes | -| completed | Job finished successfully | No | -| failed | Job encountered an error | No | -| cancelled | Job was cancelled by user | No | - -## Job Status Response - -The complete job status response interface: +### Cancel Job ```typescript -interface JobStatusResponse { - jobId: string; - status: "pending" | "processing" | "completed" | "failed" | "cancelled"; - prompt: string; // Original prompt - response?: string; // AI response (when completed) - transactions?: Transaction[]; // Transaction data (when applicable) - richData?: RichDataItem[]; // Charts, cards, tables - error?: string; // Error message (when failed) - processingTime?: number; // Time in milliseconds - cancellable?: boolean; // Whether job can be cancelled - createdAt?: string; // ISO timestamp - completedAt?: string; // ISO timestamp (when terminal) -} - -interface Transaction { - type: string; - metadata: { - __ORIGINAL_TX_DATA__: object; - transaction: object; - allowanceTarget?: string; - }; -} - -interface RichDataItem { - type: "chart" | "social-card" | "table" | "image"; - url?: string; - text?: string; - rows?: any[]; -} +const { jobId } = await client.prompt({ prompt: "..." }); +await client.cancelJob(jobId); ``` -## Batch Job Processing - -Submit multiple jobs in parallel for efficient batch processing: +### Batch Processing ```typescript -const prompts = [ - "What is the price of ETH?", - "What is the price of BTC?", - "What are trending tokens on Base?", -]; +const prompts = ["Price of ETH", "Price of BTC", "Price of SOL"]; -// Submit all jobs in parallel +// Submit all in parallel const jobs = await Promise.all( prompts.map(prompt => client.prompt({ prompt })) ); -console.log(`Submitted ${jobs.length} jobs`); -// ["job_abc123", "job_def456", "job_ghi789"] - -// Wait for all jobs to complete +// Wait for all to complete const results = await Promise.all( jobs.map(job => client.pollJob({ jobId: job.jobId })) ); - -// Process results -results.forEach((result, index) => { - console.log(`Query: ${prompts[index]}`); - console.log(`Result: ${result.response}`); -}); -``` - -### Batch with Concurrency Limit - -For large batches, limit concurrent jobs to avoid rate limiting: - -```typescript -async function batchWithLimit(prompts: string[], concurrency: number = 5) { - const results: any[] = []; - - for (let i = 0; i < prompts.length; i += concurrency) { - const batch = prompts.slice(i, i + concurrency); - - // Submit batch - const jobs = await Promise.all( - batch.map(prompt => client.prompt({ prompt })) - ); - - // Wait for batch - const batchResults = await Promise.all( - jobs.map(job => client.pollJob({ jobId: job.jobId })) - ); - - results.push(...batchResults); - - // Optional: delay between batches - if (i + concurrency < prompts.length) { - await new Promise(r => setTimeout(r, 1000)); - } - } - - return results; -} - -const results = await batchWithLimit(hundredPrompts, 10); -``` - -## Retry Pattern - -Implement retry logic for failed jobs with exponential backoff: - -```typescript -async function withRetry( - prompt: string, - maxRetries: number = 3, - baseDelay: number = 1000 -): Promise { - for (let attempt = 0; attempt < maxRetries; attempt++) { - try { - const result = await client.promptAndWait({ - prompt, - timeout: 60000, - }); - - if (result.status === "completed") { - return result; - } - - // Job failed, prepare for retry - console.log(`Attempt ${attempt + 1} failed: ${result.error}`); - - } catch (error) { - console.log(`Attempt ${attempt + 1} threw error: ${error}`); - } - - // Exponential backoff before retry - if (attempt < maxRetries - 1) { - const delay = baseDelay * Math.pow(2, attempt); - console.log(`Waiting ${delay}ms before retry...`); - await new Promise(r => setTimeout(r, delay)); - } - } - - throw new Error(`Failed after ${maxRetries} attempts`); -} - -// Usage -try { - const result = await withRetry("Swap 0.1 ETH to USDC"); - console.log(result.response); -} catch (error) { - console.error("All retries exhausted:", error); -} -``` - -## Timeout Handling - -Handle timeouts gracefully in long-running operations: - -```typescript -async function withTimeout( - prompt: string, - timeoutMs: number = 60000 -): Promise { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), timeoutMs); - - try { - const { jobId } = await client.prompt({ prompt }); - - // Poll with abort signal - const result = await client.pollJob({ - jobId, - timeout: timeoutMs, - }); - - clearTimeout(timeoutId); - return result; - - } catch (error) { - clearTimeout(timeoutId); - - if (error.name === "AbortError") { - throw new Error(`Request timed out after ${timeoutMs}ms`); - } - throw error; - } -} ``` ## Timing Guidelines -Expected processing times by operation type: - -| Operation | Typical Time | Timeout Recommendation | -|-----------|--------------|------------------------| +| Operation | Typical Time | Recommended Timeout | +|-----------|--------------|---------------------| | Price queries | 2-5s | 15s | | Balance checks | 2-5s | 15s | | Token swaps | 5-15s | 60s | | Cross-chain bridges | 10-30s | 120s | -| Complex analysis | 10-30s | 60s | | NFT operations | 5-15s | 60s | -Adjust polling intervals and timeouts based on operation type: - -```typescript -// Fast query - short timeout, fast polling -const price = await client.promptAndWait({ - prompt: "Price of ETH", - timeout: 15000, -}); - -// Swap operation - longer timeout -const swap = await client.promptAndWait({ - prompt: "Swap 1 ETH to USDC", - timeout: 60000, -}); - -// Manual polling with custom interval for slow operations -const bridge = await client.pollJob({ - jobId: bridgeJobId, - interval: 5000, // Slower polling for slow operations - timeout: 120000, // 2 minute timeout for bridges -}); -``` - -## Error Handling - -Handle job-related errors appropriately: - -```typescript -try { - const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC", - }); - - switch (result.status) { - case "completed": - console.log("Success:", result.response); - break; - - case "failed": - console.error("Job failed:", result.error); - // Optionally retry - break; - - case "cancelled": - console.log("Job was cancelled"); - break; - } - -} catch (error) { - if (error.message.includes("timeout")) { - console.error("Request timed out"); - } else if (error.message.includes("rate limit")) { - console.error("Rate limited, try again later"); - } else { - console.error("Unexpected error:", error); - } -} -``` - -## Cost - -Each job costs $0.01 USDC via x402 micropayments, charged at job submission time regardless of final status. Cancelled and failed jobs still incur the charge. - -## Best Practices +## Related Skills -1. **Use promptAndWait for simple cases**: Manual job control is only needed for advanced scenarios -2. **Set appropriate timeouts**: Match timeout to expected operation duration -3. **Implement retry logic**: Some failures are transient and succeed on retry -4. **Batch efficiently**: Group related queries but respect rate limits -5. **Handle all terminal states**: Check for completed, failed, and cancelled -6. **Clean up cancelled jobs**: Do not continue polling cancelled jobs -7. **Log job IDs**: Store job IDs for debugging and support requests +- **sdk-wallet-operations**: Client setup and configuration +- **sdk-capabilities**: Full list of supported operations diff --git a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md index 9c4d3f5..9c111c7 100644 --- a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md +++ b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md @@ -6,423 +6,96 @@ version: 1.0.0 # SDK Token Swaps -Build and execute multi-chain token swaps with AI-powered 0x routing using the Bankr SDK. +Build and execute token swaps with AI-powered 0x routing. -## Overview +## Prompt Patterns -The Bankr SDK provides a natural language interface for token swaps across multiple chains. Swaps are routed through 0x protocol for optimal pricing and executed via smart contract transactions. The SDK handles route finding, price quotes, and transaction building automatically. +| Pattern | Example | +|---------|---------| +| Amount-based | "Swap 0.1 ETH to USDC" | +| Value-based | "Buy $100 worth of DEGEN" | +| Percentage | "Swap 50% of my ETH to USDC" | +| Sell all | "Sell all my DEGEN" | +| Chain-specific | "Swap ETH to USDC on Polygon" | -**Key capabilities:** -- Natural language swap requests -- Multi-chain support (Base, Ethereum, Polygon, Solana) -- 0x-powered routing for best prices -- Automatic transaction building -- ERC20 approval handling guidance - -## CRITICAL: ERC20 Approval Requirement - -For ERC20 token swaps (selling any token other than native ETH), you must approve the token before executing the swap. The SDK provides two approaches: - -### Recommended: Use `approvalTx` (Simplified) - -The SDK returns a pre-built approval transaction when needed: - -```typescript -import { BankrClient } from "@bankr/sdk"; - -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, -}); - -const result = await client.promptAndWait({ - prompt: "Swap 100 USDC to WETH on Base" -}); - -const swapTx = result.transactions?.find(tx => tx.type === "swap"); - -if (swapTx?.metadata.approvalRequired) { - // Step 1: Execute the pre-built approval transaction - await wallet.sendTransaction(swapTx.metadata.approvalTx); - - // Step 2: Execute the swap transaction - await wallet.sendTransaction(swapTx.metadata.transaction); -} else { - // No approval needed (ETH swap or already approved) - await wallet.sendTransaction(swapTx.metadata.transaction); -} -``` - -### Alternative: Manual Approval with `allowanceTarget` - -For more control, use the `allowanceTarget` to build your own approval: - -```typescript -const swapTx = result.transactions?.find(tx => tx.type === "swap"); - -if (swapTx?.metadata.allowanceTarget) { - // Build your own approval transaction - await approveERC20( - inputTokenAddress, - swapTx.metadata.allowanceTarget, - swapAmount - ); - - await wallet.sendTransaction(swapTx.metadata.transaction); -} -``` - -### Approval Fields Reference - -| Field | Type | Description | -|-------|------|-------------| -| `approvalRequired` | `boolean` | Whether approval is needed before swap | -| `approvalTx` | `{ to: string, data: string }` | Pre-built approval transaction (ready to send) | -| `allowanceTarget` | `string` | 0x AllowanceHolder address (for manual approval) | - -**Important References:** -- [0x AllowanceHolder Documentation](https://0x.org/docs/introduction/0x-cheat-sheet#allowanceholder-recommended) -- [0x Settler Contract Addresses](https://github.com/0xProject/0x-settler/blob/master/README.md#allowanceholder-addresses) - -## Basic Swap - -Initialize the client and execute a simple swap: - -```typescript -import { BankrClient } from "@bankr/sdk"; - -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, -}); - -const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC on Base", -}); - -if (result.status === "completed" && result.transactions) { - const tx = result.transactions[0].metadata.transaction; - // Execute transaction with viem/ethers -} ``` - -## Swap Prompt Formats - -The SDK understands various natural language formats for swap requests: - -### Amount-Based Swaps - -Specify exact token amounts to swap: - -```typescript -// Swap specific amount of input token +# Amount Swaps "Swap 0.1 ETH to USDC" "Exchange 100 USDC for WETH" "Swap 1000 DEGEN to ETH" -// With chain specification -"Swap 0.1 ETH to USDC on Base" -"Exchange 100 USDC for WETH on Ethereum" -``` - -### Value-Based Swaps - -Specify USD value to buy or sell: - -```typescript -// Buy tokens by USD value +# Value Swaps "Buy $100 worth of DEGEN" "Purchase $50 of ETH" -// Sell tokens by USD value -"Sell $500 of ETH for USDC" -"Exchange $200 worth of DEGEN to USDC" -``` - -### Percentage-Based Swaps - -Swap a percentage of holdings: - -```typescript -// Percentage of holdings +# Percentage Swaps "Swap 50% of my ETH to USDC" "Sell 25% of my DEGEN" -"Exchange half my USDC for ETH" -``` - -### Chain-Specific Swaps - -Explicitly specify the chain: - -```typescript -// Base (default) -"Swap ETH to USDC on Base" - -// Ethereum mainnet -"Swap ETH to USDC on Ethereum" -"Exchange USDC for WETH on mainnet" -// Polygon -"Swap MATIC to USDC on Polygon" - -// Solana -"Swap SOL to USDC on Solana" -``` - -## Multi-Chain Support - -Supported blockchain networks for swaps: - -| Chain | Native Token | Notes | -|-------|-------------|-------| -| Base | ETH | Default chain, lowest fees | -| Ethereum | ETH | Mainnet, higher gas | -| Polygon | MATIC | L2, low fees | -| Solana | SOL | Alternative ecosystem | - -Base is the default chain. Specify other chains explicitly in the prompt. - -## Swap Response Structure - -Swap responses include transaction data ready for execution: - -```typescript -interface SwapTransaction { - type: "swap"; - metadata: { - __ORIGINAL_TX_DATA__: { - chain: string; // "base", "ethereum", etc. - humanReadableMessage: string; // "Swap 0.1 ETH for ~250 USDC" - inputTokenAddress: string; // Input token contract address - inputTokenAmount: string; // "0.1" - inputTokenTicker: string; // "ETH" - outputTokenAddress: string; // Output token contract address - outputTokenTicker: string; // "USDC" - receiver: string; // Receiving wallet address - }; - // Approval handling (for ERC20 swaps) - approvalRequired?: boolean; // Whether approval needed before swap - approvalTx?: { // Pre-built approval transaction - to: string; - data: string; - }; - allowanceTarget?: string; // 0x AllowanceHolder (for manual approval) - // Swap transaction - transaction: { - chainId: number; // Chain ID (8453 for Base) - to: string; // Contract address - data: string; // Encoded transaction data - gas: string; // Gas limit - gasPrice?: string; // Gas price in wei - value: string; // ETH value to send (wei) - }; - }; -} -``` - -## Execute Swap with Viem - -Complete example using viem to execute a swap: - -```typescript -import { createWalletClient, createPublicClient, http } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; -import { base } from "viem/chains"; - -// Initialize wallet -const account = privateKeyToAccount(process.env.WALLET_PK as `0x${string}`); -const walletClient = createWalletClient({ - account, - chain: base, - transport: http(), -}); -const publicClient = createPublicClient({ - chain: base, - transport: http(), -}); - -// Get swap transaction from SDK -const result = await client.promptAndWait({ - prompt: "Swap 100 USDC to WETH" -}); - -if (result.status !== "completed" || !result.transactions?.length) { - throw new Error("Swap failed or no transactions returned"); -} - -const swapTx = result.transactions.find(tx => tx.type === "swap"); -const tx = swapTx.metadata.transaction; - -// Handle ERC20 approval if needed (using pre-built approvalTx) -if (swapTx.metadata.approvalRequired && swapTx.metadata.approvalTx) { - const approvalHash = await walletClient.sendTransaction({ - to: swapTx.metadata.approvalTx.to as `0x${string}`, - data: swapTx.metadata.approvalTx.data as `0x${string}`, - }); - await publicClient.waitForTransactionReceipt({ hash: approvalHash }); - console.log(`Approval confirmed: ${approvalHash}`); -} - -// Execute swap -const hash = await walletClient.sendTransaction({ - to: tx.to as `0x${string}`, - data: tx.data as `0x${string}`, - value: BigInt(tx.value), - gas: BigInt(tx.gas), -}); - -console.log(`Swap transaction: ${hash}`); +# Chain-Specific +"Swap 0.1 ETH to USDC on Base" +"Exchange 100 USDC for WETH on Ethereum" ``` -## Execute Swap with Ethers +## ERC20 Approval Handling -Complete example using ethers.js v6: +For ERC20 swaps (selling tokens other than ETH), approval is required before the swap. ```typescript -import { ethers } from "ethers"; - -// Initialize wallet -const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); -const wallet = new ethers.Wallet(process.env.WALLET_PK, provider); - -// Get swap transaction const result = await client.promptAndWait({ - prompt: "Swap 100 USDC to WETH" + prompt: "Swap 100 USDC to WETH", }); const swapTx = result.transactions?.find(tx => tx.type === "swap"); -const tx = swapTx?.metadata.transaction; - -if (!tx) { - throw new Error("No transaction data"); -} -// Handle ERC20 approval if needed (using pre-built approvalTx) -if (swapTx.metadata.approvalRequired && swapTx.metadata.approvalTx) { - const approveTx = await wallet.sendTransaction({ - to: swapTx.metadata.approvalTx.to, - data: swapTx.metadata.approvalTx.data, - }); - await approveTx.wait(); - console.log(`Approval confirmed: ${approveTx.hash}`); +// Check if approval is needed +if (swapTx?.metadata.approvalRequired) { + // Execute pre-built approval transaction first + await wallet.sendTransaction(swapTx.metadata.approvalTx); } -// Execute swap -const swapTransaction = await wallet.sendTransaction({ - to: tx.to, - data: tx.data, - value: BigInt(tx.value), - gasLimit: BigInt(tx.gas), -}); - -console.log(`Swap transaction: ${swapTransaction.hash}`); -await swapTransaction.wait(); +// Then execute the swap +await wallet.sendTransaction(swapTx.metadata.transaction); ``` -## Error Handling - -Handle common swap errors: - -```typescript -const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC" -}); - -// Check status -if (result.status === "failed") { - const error = result.error || "Unknown error"; +## Approval Fields - if (error.includes("Insufficient balance")) { - console.error("Not enough tokens to swap"); - } else if (error.includes("No route found")) { - console.error("No swap route available for this pair"); - } else if (error.includes("Slippage")) { - console.error("Price moved too much, try again"); - } else { - console.error(`Swap failed: ${error}`); - } - return; -} - -// Check for transactions -if (!result.transactions?.length) { - console.error("No swap transactions returned"); - return; -} - -// Verify transaction data -const tx = result.transactions[0].metadata.transaction; -if (!tx.to || !tx.data) { - console.error("Invalid transaction data"); - return; -} +| Field | Description | +|-------|-------------| +| `approvalRequired` | Whether approval needed before swap | +| `approvalTx` | Pre-built approval transaction (ready to send) | +| `allowanceTarget` | 0x AllowanceHolder address (for manual approval) | -// Proceed with execution -console.log(result.response); -``` +## Usage -## Verifying Swap Before Execution +```typescript +import { BankrClient } from "@bankr/sdk"; -Always verify transaction details before signing: +const client = new BankrClient({ + privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, +}); -```typescript const result = await client.promptAndWait({ - prompt: "Swap 100 USDC to ETH" + prompt: "Swap 0.1 ETH to USDC on Base", }); -const swapTx = result.transactions?.[0]; -const txData = swapTx?.metadata.__ORIGINAL_TX_DATA__; - -console.log("Swap details:"); -console.log(` From: ${txData.inputTokenAmount} ${txData.inputTokenTicker}`); -console.log(` To: ${txData.outputTokenTicker}`); -console.log(` Chain: ${txData.chain}`); -console.log(` Receiver: ${txData.receiver}`); -console.log(` Message: ${txData.humanReadableMessage}`); - -// Verify receiver is correct -if (txData.receiver !== expectedWallet) { - throw new Error("Receiver wallet mismatch!"); -} - -// Verify chain is correct -if (txData.chain !== "base") { - console.warn(`Swap is on ${txData.chain}, not Base`); +if (result.status === "completed" && result.transactions?.length) { + const tx = result.transactions[0].metadata.transaction; + await wallet.sendTransaction(tx); } ``` -## Swap Best Practices - -1. **Always check allowanceTarget**: ERC20 swaps require approval before execution -2. **Verify transaction details**: Check amounts, tokens, and receiver before signing -3. **Handle approvals properly**: Approve exact amounts or use infinite approval carefully -4. **Check response status**: Always verify `result.status === "completed"` -5. **Use appropriate timeouts**: Swap quotes expire; set reasonable timeouts (60s recommended) -6. **Handle slippage**: Large swaps may need retries if price moves -7. **Test on testnets**: Verify integration before mainnet transactions - -## Common Token Addresses - -For reference when building approval transactions: - -| Token | Base Address | -|-------|-------------| -| USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` | -| WETH | `0x4200000000000000000000000000000000000006` | -| DEGEN | `0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed` | - -## Cost - -Each swap request costs $0.01 USDC via x402 micropayments. This covers the SDK query; gas fees for the actual swap transaction are paid separately from the executing wallet. - -## Response Times +## Supported Chains -Expected response times for swap operations: +| Chain | Native Token | Default | +|-------|-------------|---------| +| Base | ETH | Yes | +| Ethereum | ETH | No | +| Polygon | MATIC | No | +| Solana | SOL | No | -| Operation | Typical Time | -|-----------|--------------| -| Simple swap quote | 3-5 seconds | -| Complex routing | 5-10 seconds | -| Multi-hop routes | 8-15 seconds | +## Related Skills -Set timeouts accordingly: 60 seconds recommended for swap operations. +- **sdk-capabilities**: Full list of supported operations +- **sdk-transaction-builder**: Other transaction types (transfers, NFTs) +- **sdk-wallet-operations**: Client setup and configuration diff --git a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md index 908b598..bf3222a 100644 --- a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md +++ b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md @@ -6,416 +6,90 @@ version: 1.0.0 # SDK Transaction Builder -Build complex blockchain transactions with AI assistance using the Bankr SDK. - -## Overview - -The Bankr SDK supports building various transaction types beyond simple token swaps. Use natural language prompts to generate transaction data for transfers, NFT operations, cross-chain bridges, and DeFi interactions. The SDK returns ready-to-execute transaction objects. - -**Key capabilities:** -- Token transfers (ERC20 and native) -- NFT transfers, mints, and purchases -- ETH/WETH wrapping and unwrapping -- Cross-chain token bridges -- ERC20 approvals -- DeFi protocol interactions +Build blockchain transactions for transfers, NFTs, bridges, and DeFi operations. ## Transaction Types -The SDK supports the following transaction types: - -| Type | Description | Use Case | -|------|-------------|----------| -| `swap` | Token swaps | Exchange one token for another | -| `approval` | ERC20 approvals | Grant spending permission | -| `transfer_erc20` | ERC20 transfers | Send tokens to address | -| `transfer_eth` | ETH transfers | Send native ETH | -| `convert_eth_to_weth` | Wrap ETH | Convert ETH to WETH | -| `convert_weth_to_eth` | Unwrap WETH | Convert WETH to ETH | -| `transfer_nft` | NFT transfers | Send NFT to address | -| `mint_manifold_nft` | Manifold mints | Mint from Manifold contracts | -| `mint_seadrop_nft` | SeaDrop mints | Mint from SeaDrop contracts | -| `buy_nft` | NFT purchases | Buy NFT from marketplace | -| `swapCrossChain` | Cross-chain bridges | Move tokens between chains | -| `avantisTrade` | Avantis perpetuals | Trade perpetual futures | -| `manage_bankr_staking` | Bankr staking | Stake/unstake BANKR tokens | - -## ERC20 Transfers +| Type | Description | Example Prompt | +|------|-------------|----------------| +| `transfer_erc20` | Send ERC20 tokens | "Send 100 USDC to 0x..." | +| `transfer_eth` | Send native ETH | "Send 0.1 ETH to 0x..." | +| `convert_eth_to_weth` | Wrap ETH | "Wrap 0.5 ETH" | +| `convert_weth_to_eth` | Unwrap WETH | "Unwrap 1 WETH" | +| `transfer_nft` | Send NFT | "Transfer my NFT #123 to 0x..." | +| `buy_nft` | Purchase NFT | "Buy the cheapest Pudgy Penguin" | +| `mint_manifold_nft` | Mint from Manifold | "Mint from Manifold at 0x..." | +| `mint_seadrop_nft` | Mint from SeaDrop | "Mint from SeaDrop at 0x..." | +| `swapCrossChain` | Bridge tokens | "Bridge 100 USDC from Ethereum to Base" | -Send ERC20 tokens to another address: +## Prompt Patterns -```typescript -import { BankrClient } from "@bankr/sdk"; - -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, -}); - -const result = await client.promptAndWait({ - prompt: "Send 100 USDC to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", -}); - -if (result.status === "completed" && result.transactions) { - const tx = result.transactions.find(t => t.type === "transfer_erc20"); - // Execute transaction -} ``` - -### Transfer Prompt Examples - -```typescript -// Specific amount +# Transfers "Send 100 USDC to 0x742d35..." "Transfer 0.5 ETH to vitalik.eth" - -// With chain specification "Send 50 USDC to 0x123... on Base" -"Transfer 100 MATIC on Polygon to 0x456..." - -// Multiple recipients (separate requests) -"Send 25 USDC to 0xAlice..." -"Send 25 USDC to 0xBob..." -``` - -## Native ETH Transfers - -Send native ETH: - -```typescript -const result = await client.promptAndWait({ - prompt: "Send 0.1 ETH to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", -}); - -const tx = result.transactions?.find(t => t.type === "transfer_eth"); -``` - -## ETH/WETH Conversions - -Wrap ETH to WETH or unwrap WETH to ETH: - -```typescript -// Wrap ETH to WETH -const wrapResult = await client.promptAndWait({ - prompt: "Wrap 0.5 ETH to WETH", -}); -const wrapTx = wrapResult.transactions?.find( - t => t.type === "convert_eth_to_weth" -); +# ETH/WETH +"Wrap 0.5 ETH to WETH" +"Unwrap 1 WETH to ETH" -// Unwrap WETH to ETH -const unwrapResult = await client.promptAndWait({ - prompt: "Unwrap 1 WETH to ETH", -}); - -const unwrapTx = unwrapResult.transactions?.find( - t => t.type === "convert_weth_to_eth" -); -``` - -### When to Wrap/Unwrap - -- **Wrap ETH**: Some DeFi protocols and swaps require WETH instead of native ETH -- **Unwrap WETH**: Convert back to native ETH for transfers or gas payments - -## NFT Operations - -### Transfer NFT - -Send an NFT to another address: - -```typescript -const result = await client.promptAndWait({ - prompt: "Transfer my Pudgy Penguin #1234 to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", -}); - -const tx = result.transactions?.find(t => t.type === "transfer_nft"); -``` - -### Mint NFT - -Mint from supported platforms: - -```typescript -// Manifold mint -const manifoldMint = await client.promptAndWait({ - prompt: "Mint NFT from Manifold contract 0xabc123...", -}); +# NFTs +"Transfer my Pudgy Penguin #1234 to 0x..." +"Buy the cheapest Pudgy Penguin on OpenSea" +"Mint NFT from Manifold contract 0x..." -// SeaDrop mint -const seadropMint = await client.promptAndWait({ - prompt: "Mint from SeaDrop collection 0xdef456...", -}); -``` - -### Buy NFT - -Purchase NFT from marketplace: - -```typescript -const result = await client.promptAndWait({ - prompt: "Buy the cheapest Pudgy Penguin on OpenSea", -}); - -const buyTx = result.transactions?.find(t => t.type === "buy_nft"); - -if (buyTx) { - console.log(`Price: ${buyTx.metadata.__ORIGINAL_TX_DATA__.inputTokenAmount}`); - // Execute purchase transaction -} -``` - -## Cross-Chain Bridges - -Bridge tokens between chains: - -```typescript -const result = await client.promptAndWait({ - prompt: "Bridge 100 USDC from Ethereum to Base", -}); - -const bridgeTx = result.transactions?.find(t => t.type === "swapCrossChain"); - -if (bridgeTx) { - const txData = bridgeTx.metadata.__ORIGINAL_TX_DATA__; - console.log(`From: ${txData.chain}`); - console.log(`Amount: ${txData.inputTokenAmount} ${txData.inputTokenTicker}`); - console.log(`Receiver: ${txData.receiver}`); -} -``` - -### Bridge Prompt Examples - -```typescript -// Specific chains +# Cross-Chain "Bridge 100 USDC from Ethereum to Base" "Move 0.5 ETH from Base to Ethereum" - -// With amount -"Bridge $500 worth of ETH from Polygon to Base" ``` -**Note**: Cross-chain bridges take longer (10-30 seconds for quote, plus on-chain confirmation time). - -## ERC20 Approvals - -Build approval transactions for token spending: +## Usage ```typescript -const result = await client.promptAndWait({ - prompt: "Approve Uniswap to spend my USDC", -}); - -const approvalTx = result.transactions?.find(t => t.type === "approval"); -``` - -## Transaction Metadata - -All transactions include metadata for verification: - -```typescript -interface TransactionMetadata { - __ORIGINAL_TX_DATA__: { - chain: string; // Target chain - humanReadableMessage: string; // Human description - inputTokenAmount: string; // Amount being sent/swapped - inputTokenTicker: string; // Token symbol - outputTokenTicker: string; // Output token (for swaps) - receiver: string; // Recipient address - }; - transaction: { - chainId: number; // Chain ID (8453 = Base) - to: string; // Contract/recipient address - data: string; // Encoded call data - gas: string; // Gas limit - gasPrice: string; // Gas price (wei) - value: string; // Native value (wei) - }; - allowanceTarget?: string; // For swaps requiring approval -} -``` - -## Multi-Step Workflows - -Complex operations may require multiple transactions: - -```typescript -// Example: Wrap ETH then swap WETH to USDC - -// Step 1: Wrap ETH -const wrapResult = await client.promptAndWait({ - prompt: "Wrap 1 ETH to WETH", -}); -const wrapTx = wrapResult.transactions?.[0]; - -// Execute wrap transaction -const wrapHash = await wallet.sendTransaction(wrapTx.metadata.transaction); -await publicClient.waitForTransactionReceipt({ hash: wrapHash }); - -// Step 2: Swap WETH to USDC -const swapResult = await client.promptAndWait({ - prompt: "Swap 1 WETH to USDC", -}); -const swapTx = swapResult.transactions?.[0]; - -// Handle approval if needed -if (swapTx.metadata.allowanceTarget) { - await approveToken(wethAddress, swapTx.metadata.allowanceTarget, amount); -} - -// Execute swap -const swapHash = await wallet.sendTransaction(swapTx.metadata.transaction); -``` - -## Transaction Validation - -Validate transaction data before execution: - -```typescript -function validateTransaction(tx: any): boolean { - const txData = tx.metadata?.transaction; - - // Check required fields - if (!txData) { - console.error("Missing transaction data"); - return false; - } - - if (!txData.to) { - console.error("Missing 'to' address"); - return false; - } - - if (!txData.data && !txData.value) { - console.error("Missing data and value"); - return false; - } - - if (!txData.chainId) { - console.error("Missing chainId"); - return false; - } - - return true; -} - -// Usage -const result = await client.promptAndWait({ prompt: "..." }); - -if (result.transactions?.every(validateTransaction)) { - // All transactions valid, proceed with execution - for (const tx of result.transactions) { - await executeTx(tx); - } -} else { - console.error("Invalid transaction data"); -} -``` - -## Execute with Viem - -Execute any transaction type with viem: - -```typescript -import { createWalletClient, createPublicClient, http } from "viem"; -import { privateKeyToAccount } from "viem/accounts"; -import { base } from "viem/chains"; +import { BankrClient } from "@bankr/sdk"; -const account = privateKeyToAccount(process.env.WALLET_PK as `0x${string}`); -const walletClient = createWalletClient({ - account, - chain: base, - transport: http(), -}); -const publicClient = createPublicClient({ - chain: base, - transport: http(), +const client = new BankrClient({ + privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, }); -async function executeTransaction(tx: any) { - const txData = tx.metadata.transaction; - - const hash = await walletClient.sendTransaction({ - to: txData.to as `0x${string}`, - data: txData.data as `0x${string}`, - value: BigInt(txData.value || "0"), - gas: BigInt(txData.gas), - }); - - const receipt = await publicClient.waitForTransactionReceipt({ hash }); - return receipt; -} - -// Execute all transactions in result +// Transfer tokens const result = await client.promptAndWait({ - prompt: "Send 100 USDC to 0x742d35...", + prompt: "Send 100 USDC to 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", }); if (result.status === "completed" && result.transactions) { - for (const tx of result.transactions) { - const receipt = await executeTransaction(tx); - console.log(`Transaction ${tx.type}: ${receipt.transactionHash}`); - } + const tx = result.transactions[0].metadata.transaction; + await wallet.sendTransaction(tx); } ``` -## Error Handling +## Transaction Metadata -Handle transaction-specific errors: +All transactions include metadata for verification: ```typescript -const result = await client.promptAndWait({ - prompt: "Send 100 USDC to 0x742d35...", -}); - -if (result.status === "failed") { - const error = result.error || ""; - - if (error.includes("Insufficient balance")) { - console.error("Not enough tokens for this transfer"); - } else if (error.includes("Invalid address")) { - console.error("The recipient address is invalid"); - } else if (error.includes("NFT not found")) { - console.error("The specified NFT was not found in wallet"); - } else if (error.includes("Bridge not supported")) { - console.error("This chain pair is not supported for bridging"); - } else { - console.error(`Transaction failed: ${error}`); - } - return; -} +const tx = result.transactions[0]; +const meta = tx.metadata.__ORIGINAL_TX_DATA__; -if (!result.transactions?.length) { - console.error("No transactions generated"); - return; -} +console.log(`Chain: ${meta.chain}`); +console.log(`Amount: ${meta.inputTokenAmount} ${meta.inputTokenTicker}`); +console.log(`To: ${meta.receiver}`); +console.log(`Message: ${meta.humanReadableMessage}`); ``` ## Timing Guidelines -Expected response times by transaction type: - -| Transaction Type | Typical Time | -|-----------------|--------------| -| ERC20 transfer | 2-5 seconds | -| ETH transfer | 2-5 seconds | -| ETH/WETH wrap/unwrap | 2-5 seconds | -| NFT transfer | 3-5 seconds | -| NFT purchase | 5-10 seconds | -| NFT mint | 5-10 seconds | -| Cross-chain bridge | 10-30 seconds | - -## Best Practices - -1. **Validate transactions**: Always check transaction data before signing -2. **Verify recipients**: Double-check recipient addresses in metadata -3. **Handle multi-step flows**: Wait for each transaction to confirm before the next -4. **Set appropriate timeouts**: Longer timeouts for bridges and NFT operations -5. **Check status**: Always verify `result.status === "completed"` -6. **Log transaction hashes**: Store hashes for debugging and tracking -7. **Test thoroughly**: Verify transaction flows on testnets before mainnet +| Operation | Typical Time | +|-----------|--------------| +| ERC20/ETH transfer | 2-5s | +| Wrap/Unwrap | 2-5s | +| NFT transfer | 3-5s | +| NFT purchase | 5-10s | +| Cross-chain bridge | 10-30s | -## Cost +## Related Skills -Each transaction request costs $0.01 USDC via x402 micropayments. This covers the SDK query; actual gas fees are paid separately from the executing wallet. +- **sdk-token-swaps**: Token swap patterns and approval handling +- **sdk-capabilities**: Full list of supported operations +- **sdk-wallet-operations**: Client setup and configuration diff --git a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md index 0cc13f6..8f77a18 100644 --- a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md +++ b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md @@ -6,68 +6,17 @@ version: 1.0.0 # SDK Wallet Operations -Initialize and manage the BankrClient with proper wallet configuration for the Bankr SDK. - -## Overview - -The BankrClient is the main entry point for interacting with the Bankr SDK. Proper wallet configuration is essential for x402 micropayments and transaction building. The SDK supports a two-wallet system that separates payment concerns from transaction execution. - -**Key concepts:** -- Payment wallet: Signs x402 USDC payments (required) -- Context wallet: Receives swapped tokens and NFTs (optional) -- Two-wallet separation for enhanced security -- Environment-based configuration - -## SDK Methods Summary - -The BankrClient provides 6 core methods: - -| Method | Description | Use Case | -|--------|-------------|----------| -| `promptAndWait()` | Submit prompt and wait for result | **Recommended** for most use cases | -| `prompt()` | Submit prompt, return immediately | Background processing | -| `pollJob()` | Poll until job completes | Manual job tracking | -| `getJobStatus()` | Check job status once | Custom polling logic | -| `cancelJob()` | Cancel a pending/processing job | Stop unwanted jobs | -| `getWalletAddress()` | Get derived wallet address | Verify payment wallet | - -```typescript -// Most common pattern -const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC", -}); - -// Get wallet address (no API call) -const address = client.getWalletAddress(); -``` +Initialize and configure the BankrClient with proper wallet setup. ## Two-Wallet System -The Bankr SDK uses two distinct wallet concepts: - -### Payment Wallet (`privateKey`) - -The payment wallet is **required** and used for: -- Signing x402 micropayments ($0.01 USDC per request) -- Authenticating with the Bankr API -- Must have USDC balance on Base chain - -The private key is used to derive the wallet address and sign payment transactions. - -### Context Wallet (`walletAddress`) - -The context wallet is **optional** and used for: -- Receiving swapped tokens -- Receiving purchased NFTs -- Providing context for balance queries -- Can be different from the payment wallet - -If not specified, the context wallet defaults to the address derived from the payment wallet's private key. +| Wallet | Purpose | Required | +|--------|---------|----------| +| Payment (`privateKey`) | Signs x402 micropayments ($0.01/request) | Yes | +| Context (`walletAddress`) | Receives swapped tokens, NFTs | No (defaults to payment wallet) | ## Basic Setup -Minimal configuration using a single wallet for both payments and receiving: - ```typescript import { BankrClient } from "@bankr/sdk"; @@ -75,449 +24,72 @@ const client = new BankrClient({ privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, }); -// Get the derived wallet address -const walletAddress = client.getWalletAddress(); -console.log(`Using wallet: ${walletAddress}`); -``` - -This configuration: -- Uses the private key for x402 payments -- Derives the wallet address from the private key -- Uses the same address for receiving tokens - -## Full Configuration - -Complete configuration with all available options: - -```typescript -import { BankrClient } from "@bankr/sdk"; - -const client = new BankrClient({ - // Required: Payment wallet private key - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - - // Optional: Override receiving wallet address - walletAddress: process.env.BANKR_WALLET_ADDRESS, - - // Optional: API base URL (default: production) - baseUrl: "https://api.bankr.bot", - - // Optional: Request timeout in milliseconds (default: 600000 = 10 min) - timeout: 600000, +const result = await client.promptAndWait({ + prompt: "What are my balances?", }); ``` -## Separate Wallets Pattern +## Separate Wallets (Recommended) -For enhanced security, use separate wallets for payments and receiving: +For enhanced security, use different wallets for payments and receiving: ```typescript const client = new BankrClient({ // Hot wallet with minimal USDC for payments privateKey: process.env.PAYMENT_WALLET_PK as `0x${string}`, - - // Cold wallet or trading wallet receives tokens + // Cold/trading wallet receives tokens walletAddress: process.env.RECEIVING_WALLET, }); - -// Payment wallet (hot): pays $0.01 per request -// Receiving wallet (cold): receives swapped USDC, purchased NFTs, etc. -const result = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC", -}); -// USDC goes to RECEIVING_WALLET, not PAYMENT_WALLET -``` - -### Benefits of Separate Wallets - -1. **Security**: Payment wallet exposure is limited to small USDC amounts -2. **Risk management**: Trading funds stay in a separate, more secure wallet -3. **Flexibility**: Different security models for different purposes -4. **Auditability**: Clear separation of payment and trading activities - -### Recommended Setup - -``` -Payment Wallet (Hot): -- Small USDC balance ($5-10 recommended) -- Used only for x402 payments -- Private key in environment - -Receiving Wallet (Cold/Trading): -- Holds main trading funds -- Receives swap outputs -- Can be hardware wallet or multi-sig -- Only address needed (no private key exposed) -``` - -## Per-Request Wallet Override - -Override the receiving wallet for individual requests: - -```typescript -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.DEFAULT_WALLET, -}); - -// Use default wallet -const result1 = await client.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC", -}); - -// Override wallet for this request only -const result2 = await client.promptAndWait({ - prompt: "Buy $100 of DEGEN", - walletAddress: "0xDifferentWallet123...", -}); - -// Back to default wallet -const result3 = await client.promptAndWait({ - prompt: "What are my balances?", -}); ``` -## Configuration Interface +## Configuration Options -Complete TypeScript interface for BankrClient configuration: +| Option | Type | Required | Description | +|--------|------|----------|-------------| +| `privateKey` | `0x${string}` | Yes | Payment wallet private key | +| `walletAddress` | `string` | No | Override receiving wallet | +| `baseUrl` | `string` | No | API endpoint (default: production) | +| `timeout` | `number` | No | Request timeout ms (default: 600000) | -```typescript -interface BankrClientConfig { - /** - * Private key for x402 payment signing. - * Must be a valid Ethereum private key with 0x prefix. - * Required field. - */ - privateKey: `0x${string}`; - - /** - * Wallet address for receiving tokens and providing context. - * If not provided, derived from privateKey. - * Optional field. - */ - walletAddress?: string; - - /** - * API base URL. - * Default: "https://api.bankr.bot" - * Optional field. - */ - baseUrl?: string; - - /** - * Request timeout in milliseconds. - * Default: 600000 (10 minutes) - * Optional field. - */ - timeout?: number; -} -``` +## SDK Methods -## Prompt Options +| Method | Description | +|--------|-------------| +| `promptAndWait()` | Submit prompt and wait for result | +| `prompt()` | Submit prompt, return immediately | +| `pollJob()` | Poll until job completes | +| `getJobStatus()` | Check job status once | +| `cancelJob()` | Cancel pending/processing job | +| `getWalletAddress()` | Get context wallet address | -Options available when making requests: - -```typescript -interface PromptOptions { - /** - * Natural language prompt for the AI. - * Required field. - */ - prompt: string; - - /** - * Override the context wallet for this request only. - * Optional field. - */ - walletAddress?: string; - - /** - * Convert transaction data to XMTP-compatible format. - * Useful for messaging-based transaction flows. - * Default: false - * Optional field. - */ - xmtp?: boolean; -} -``` - -### XMTP Integration - -Enable XMTP format for transaction data when building messaging-based flows: +## Per-Request Override ```typescript +// Override wallet for a single request const result = await client.promptAndWait({ prompt: "Swap 0.1 ETH to USDC", - xmtp: true, // Convert transaction to XMTP format + walletAddress: "0xDifferentWallet...", }); - -// Transaction data formatted for XMTP messaging -console.log(result.transactions); ``` ## Environment Setup -Configure environment variables for SDK usage: - -### Required Variables - -```bash -# Payment wallet private key (must have USDC on Base) -# Format: 64 hex characters with 0x prefix -BANKR_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef -``` - -### Optional Variables - ```bash -# Receiving wallet address (defaults to payment wallet address) -BANKR_WALLET_ADDRESS=0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0 - -# API endpoint (defaults to production) -BANKR_API_URL=https://api.bankr.bot -``` - -### .env File Example - -```bash -# .env +# Required BANKR_PRIVATE_KEY=0x...your_payment_wallet_key... -BANKR_WALLET_ADDRESS=0x...your_receiving_wallet_address... -``` - -Load with dotenv: - -```typescript -import "dotenv/config"; -import { BankrClient } from "@bankr/sdk"; -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, -}); -``` - -## Validation Helper - -Validate configuration before creating the client: - -```typescript -function createValidatedClient(): BankrClient { - const pk = process.env.BANKR_PRIVATE_KEY; - - // Validate private key format - if (!pk) { - throw new Error("BANKR_PRIVATE_KEY environment variable is not set"); - } - - if (!pk.startsWith("0x")) { - throw new Error("Private key must start with 0x prefix"); - } - - if (pk.length !== 66) { - throw new Error("Private key must be 64 hex characters (66 with 0x prefix)"); - } - - // Validate hex characters - const hexRegex = /^0x[0-9a-fA-F]{64}$/; - if (!hexRegex.test(pk)) { - throw new Error("Private key contains invalid characters"); - } - - // Validate wallet address if provided - const walletAddress = process.env.BANKR_WALLET_ADDRESS; - if (walletAddress) { - const addressRegex = /^0x[0-9a-fA-F]{40}$/; - if (!addressRegex.test(walletAddress)) { - throw new Error("Invalid wallet address format"); - } - } - - return new BankrClient({ - privateKey: pk as `0x${string}`, - walletAddress, - }); -} - -// Usage -try { - const client = createValidatedClient(); - console.log(`Client initialized with wallet: ${client.getWalletAddress()}`); -} catch (error) { - console.error(`Configuration error: ${error.message}`); - process.exit(1); -} -``` - -## Address Derivation - -Get the wallet address derived from the private key: - -```typescript -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, -}); - -// Get address derived from private key -const derivedAddress = client.getWalletAddress(); -console.log(`Derived address: ${derivedAddress}`); - -// If walletAddress was provided, it overrides the derived address -const clientWithOverride = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: "0xCustomAddress...", -}); - -// Returns the override address, not the derived one -const contextAddress = clientWithOverride.getWalletAddress(); -console.log(`Context address: ${contextAddress}`); +# Optional +BANKR_WALLET_ADDRESS=0x...your_receiving_wallet... ``` ## Security Best Practices -### Never Commit Private Keys - -```bash -# Add to .gitignore -.env -.env.local -*.env -``` - -### Use Environment Variables - -```typescript -// Good: Use environment variables -const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, -}); - -// Bad: Hardcoded private key (NEVER do this) -const client = new BankrClient({ - privateKey: "0x1234...", // Security risk! -}); -``` - -### Minimize Payment Wallet Balance - -Keep only small amounts in the payment wallet: +1. **Never commit private keys** - Use environment variables +2. **Minimize payment wallet balance** - Keep only $1-2 USDC +3. **Use separate wallets** - Payment (hot) vs receiving (cold) +4. **Rotate keys periodically** - If payment wallet compromised -``` -Recommended: $1-2 USDC on Base -Purpose: Covers 100-200 API requests -Refill: When balance drops below $0.20 -``` - -### Separate Wallet Responsibilities - -``` -Payment Wallet: -- Hot wallet (private key in env) -- Minimal funds -- Single purpose: API payments - -Trading Wallet: -- Could be hardware wallet -- Main trading funds -- Only address exposed to SDK -``` - -### Rotate Keys Periodically - -If the payment wallet is compromised: -1. Transfer remaining USDC to new wallet -2. Generate new private key -3. Update environment variables -4. Fund new wallet with small USDC amount - -## Error Handling - -Handle initialization errors: - -```typescript -try { - const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - }); - - // Verify client is functional - const result = await client.promptAndWait({ - prompt: "What is 1 + 1?", - timeout: 10000, - }); - - console.log("Client initialized successfully"); - -} catch (error) { - if (error.message.includes("Invalid private key")) { - console.error("Private key format is incorrect"); - } else if (error.message.includes("Insufficient USDC")) { - console.error("Payment wallet needs USDC on Base"); - } else if (error.message.includes("Network error")) { - console.error("Cannot connect to Bankr API"); - } else { - console.error("Initialization failed:", error.message); - } -} -``` - -## Testing Configuration - -Test wallet configuration without making API calls: - -```typescript -import { BankrClient } from "@bankr/sdk"; - -function testConfiguration() { - const client = new BankrClient({ - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - walletAddress: process.env.BANKR_WALLET_ADDRESS, - }); +## Related Skills - const address = client.getWalletAddress(); - - console.log("Configuration Test:"); - console.log(` Payment wallet: ${maskAddress(getPaymentAddress(client))}`); - console.log(` Context wallet: ${maskAddress(address)}`); - console.log(` API endpoint: ${client.baseUrl || "default"}`); - console.log(` Timeout: ${client.timeout || 600000}ms`); - - return true; -} - -function maskAddress(address: string): string { - return `${address.slice(0, 6)}...${address.slice(-4)}`; -} - -testConfiguration(); -``` - -## Common Issues - -### Missing Private Key - -``` -Error: BANKR_PRIVATE_KEY environment variable is not set -Solution: Set the environment variable or check .env file loading -``` - -### Invalid Key Format - -``` -Error: Private key must start with 0x prefix -Solution: Ensure key includes 0x prefix and is 66 characters total -``` - -### Insufficient USDC - -``` -Error: Insufficient USDC balance for payment -Solution: Fund payment wallet with USDC on Base chain -``` - -### Wrong Chain - -``` -Error: USDC must be on Base chain -Solution: Bridge USDC to Base or swap on Base -``` +- **sdk-capabilities**: Full list of supported operations +- **sdk-job-management**: Async job handling and polling From 3559cc58728a6a79c1e0c26708ba45e488893c34 Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 17:42:58 +0400 Subject: [PATCH 4/8] fix: standardize skill descriptions and remove redundant command field - Update 9 bankr-agent-dev capability skill descriptions to follow "This skill should be used when..." pattern - Remove redundant `name` field from x402-sdk-dev init-sdk command (command name is derived from filename) --- bankr-agent-dev/skills/bankr-automation/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-market-research/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-nft-operations/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-polymarket/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-portfolio/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-token-deployment/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-token-trading/SKILL.md | 2 +- bankr-agent-dev/skills/bankr-transfers/SKILL.md | 2 +- x402-sdk-dev/commands/init-sdk.md | 1 - 10 files changed, 9 insertions(+), 10 deletions(-) diff --git a/bankr-agent-dev/skills/bankr-automation/SKILL.md b/bankr-agent-dev/skills/bankr-automation/SKILL.md index 2a7edd6..4897802 100644 --- a/bankr-agent-dev/skills/bankr-automation/SKILL.md +++ b/bankr-agent-dev/skills/bankr-automation/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Automation -description: Automated order capability via the Bankr API. Create limit orders, stop losses, DCA schedules, and TWAP execution. Triggered by "automation prompts", "limit orders", "DCA patterns", "scheduled orders". +description: This skill should be used when building automated trading systems, implementing limit orders, or adding DCA/TWAP functionality. Covers limit orders, stop losses, DCA schedules, and TWAP execution. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md index 1e87df7..3892720 100644 --- a/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-leverage-trading/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Leverage Trading -description: Perpetual trading capability via the Bankr API (Avantis integration). Open/close leveraged positions with stop loss and take profit. Triggered by "leverage prompts", "perpetual trading", "long/short positions", "Avantis patterns". +description: This skill should be used when building perpetual trading bots, implementing leverage functionality, or adding position management. Covers Avantis integration, long/short positions, and risk controls. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-market-research/SKILL.md b/bankr-agent-dev/skills/bankr-market-research/SKILL.md index 5a1cbca..54acf95 100644 --- a/bankr-agent-dev/skills/bankr-market-research/SKILL.md +++ b/bankr-agent-dev/skills/bankr-market-research/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Market Research -description: Market data capability via the Bankr API. Query prices, market caps, technical analysis, sentiment, and trending tokens. Triggered by "market prompts", "price queries", "technical analysis", "sentiment checking". +description: This skill should be used when building market data displays, implementing price feeds, or adding technical analysis. Covers prices, market caps, technical analysis, sentiment, and trending tokens. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md index 5146f5e..0624152 100644 --- a/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md +++ b/bankr-agent-dev/skills/bankr-nft-operations/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - NFT Operations -description: NFT marketplace capability via the Bankr API (OpenSea integration). Browse collections, check floor prices, and purchase NFTs. Triggered by "NFT prompts", "floor price", "buy NFT", "OpenSea patterns". +description: This skill should be used when building NFT marketplace integrations, implementing collection browsing, or adding floor price tracking. Covers OpenSea integration, floor prices, and NFT purchases. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md index 236d4b5..71ac137 100644 --- a/bankr-agent-dev/skills/bankr-polymarket/SKILL.md +++ b/bankr-agent-dev/skills/bankr-polymarket/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Polymarket -description: Prediction market capability via the Bankr API. Search markets, check odds, place bets, and manage positions on Polymarket. Triggered by "Polymarket prompts", "prediction market", "betting patterns", "odds checking". +description: This skill should be used when building prediction market integrations, implementing betting functionality, or querying Polymarket odds. Covers market search, odds checking, and position management. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md index f07e075..7414c6e 100644 --- a/bankr-agent-dev/skills/bankr-portfolio/SKILL.md +++ b/bankr-agent-dev/skills/bankr-portfolio/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Portfolio -description: Portfolio query capability via the Bankr API. Check balances, holdings, and valuations across all chains. Triggered by "portfolio prompts", "balance checking", "holdings query", "multi-chain balances". +description: This skill should be used when building portfolio dashboards, implementing balance checking, or adding multi-chain holdings views. Covers balances, holdings, and valuations across chains. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md index 8c9b513..8b2f363 100644 --- a/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-deployment/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Token Deployment -description: Token deployment capability via the Bankr API (Clanker integration). Deploy ERC20 tokens, update metadata, and claim trading fees. Triggered by "deployment prompts", "Clanker patterns", "token creation", "fee claiming". +description: This skill should be used when building token launch tools, implementing Clanker integration, or adding fee claiming functionality. Covers ERC20 deployment, metadata updates, and trading fees. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md index 21f3624..6199174 100644 --- a/bankr-agent-dev/skills/bankr-token-trading/SKILL.md +++ b/bankr-agent-dev/skills/bankr-token-trading/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Token Trading -description: Token swap and trading capability via the Bankr API. Covers same-chain swaps, cross-chain bridges, ETH/WETH conversions, and multiple amount formats. Triggered by "trading prompts", "swap patterns", "buy/sell tokens", "bridge tokens". +description: This skill should be used when building trading bots, implementing swap functionality, or adding cross-chain bridge support. Covers same-chain swaps, cross-chain bridges, ETH/WETH conversions, and amount formats. version: 1.0.0 --- diff --git a/bankr-agent-dev/skills/bankr-transfers/SKILL.md b/bankr-agent-dev/skills/bankr-transfers/SKILL.md index 8a80c2f..c5b0d37 100644 --- a/bankr-agent-dev/skills/bankr-transfers/SKILL.md +++ b/bankr-agent-dev/skills/bankr-transfers/SKILL.md @@ -1,6 +1,6 @@ --- name: Bankr Dev - Transfers -description: Token transfer capability via the Bankr API. Supports wallet addresses, ENS names, and social handles with automatic resolution. Triggered by "transfer prompts", "send tokens", "payment patterns", "ENS resolution". +description: This skill should be used when building payment systems, implementing token transfers, or adding ENS/social handle resolution. Supports wallet addresses, ENS names, and social handles. version: 1.0.0 --- diff --git a/x402-sdk-dev/commands/init-sdk.md b/x402-sdk-dev/commands/init-sdk.md index d38ae07..ea211c4 100644 --- a/x402-sdk-dev/commands/init-sdk.md +++ b/x402-sdk-dev/commands/init-sdk.md @@ -1,5 +1,4 @@ --- -name: init-sdk description: Initialize Bankr SDK in current project - installs package, creates client file, sets up environment allowed-tools: - Read From dff6a56bc8838c19c0b8672e1ba60e397f8212e8 Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 19:09:08 +0400 Subject: [PATCH 5/8] docs: add alternative installation for other coding tools Add bunx skills add command for Cursor, OpenCode, Gemini CLI, Antigravity, etc. Clarify that only skills are compatible with other platforms. --- README.md | 12 +++++++++++- bankr-agent-dev/README.md | 12 +++++++++++- bankr-agent/README.md | 10 ++++++++++ x402-sdk-dev/README.md | 22 +++++++++++++++++++--- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4d2d448..af6336a 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ _Maintained by the Bankr team._ ## Installation +### Claude Code + First, add the marketplace: ```bash @@ -63,10 +65,18 @@ claude plugin install bankr-agent-dev@bankr-claude-plugins claude plugin install bankr-x402-sdk-dev@bankr-claude-plugins ``` +### Other Coding Tools (Cursor, OpenCode, Gemini CLI, Antigravity, etc.) + +Only skills are compatible with other platforms. Agents, commands, hooks, and MCP servers require Claude Code. + +```bash +bunx skills add BankrBot/claude-plugins +``` + ## Requirements - Claude Code CLI -- Node.js 18+ +- Node.js 20+ - USDC on Base (for x402 payments) ## Links diff --git a/bankr-agent-dev/README.md b/bankr-agent-dev/README.md index 31784a9..4304449 100644 --- a/bankr-agent-dev/README.md +++ b/bankr-agent-dev/README.md @@ -14,15 +14,25 @@ This plugin helps developers scaffold and build applications that interact with ## Prerequisites - Bankr API key (get one at https://bankr.bot/api) -- Node.js 18+ and npm/bun +- Node.js 20+ and npm/bun ## Installation +### Claude Code + ```bash claude plugin marketplace add BankrBot/claude-plugins claude plugin install bankr-agent-dev@bankr-claude-plugins ``` +### Other Coding Tools (Cursor, OpenCode, Gemini CLI, Antigravity, etc.) + +Only skills are compatible with other platforms. Agents, commands, hooks, and MCP servers require Claude Code. + +```bash +bunx skills add BankrBot/claude-plugins +``` + ## Usage ### Scaffold a New Project diff --git a/bankr-agent/README.md b/bankr-agent/README.md index def6dbc..ff1c5e3 100644 --- a/bankr-agent/README.md +++ b/bankr-agent/README.md @@ -30,11 +30,21 @@ Integration with the Bankr API for crypto trading, market analysis, and Polymark ``` 3. Install the plugin in Claude Code: + + **Claude Code:** ```bash claude plugin marketplace add BankrBot/claude-plugins claude plugin install bankr-agent@bankr-claude-plugins ``` + **Other Coding Tools (Cursor, OpenCode, Gemini CLI, Antigravity, etc.):** + + Only skills are compatible with other platforms. Agents, commands, hooks, and MCP servers require Claude Code. + + ```bash + bunx skills add BankrBot/claude-plugins + ``` + ## Usage The bankr-agent automatically triggers on: diff --git a/x402-sdk-dev/README.md b/x402-sdk-dev/README.md index c6336bd..245e12a 100644 --- a/x402-sdk-dev/README.md +++ b/x402-sdk-dev/README.md @@ -16,15 +16,31 @@ Claude Code integration for [@bankr/sdk](https://www.npmjs.com/package/@bankr/sd ## Quick Start +### 1. Install Plugin + +**Claude Code:** ```bash -# 1. Install plugin claude plugin marketplace add BankrBot/claude-plugins claude plugin install bankr-x402-sdk-dev@bankr-claude-plugins +``` + +**Other Coding Tools (Cursor, OpenCode, Gemini CLI, Antigravity, etc.):** + +Only skills are compatible with other platforms. Agents, commands, hooks, and MCP servers require Claude Code. + +```bash +bunx skills add BankrBot/claude-plugins +``` + +### 2. Install SDK -# 2. Install SDK +```bash npm install @bankr/sdk +``` + +### 3. Configure Environment -# 3. Configure environment +```bash export BANKR_PRIVATE_KEY=0x... # Required: pays $0.01 USDC per request (needs USDC on Base) export BANKR_WALLET_ADDRESS=0x... # Optional: receives swapped tokens export BANKR_API_URL=https://api.bankr.bot # Optional From 21bfc0b7e365021c5c7869c926af3056ac34ed71 Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 21:41:04 +0400 Subject: [PATCH 6/8] refactor: replace init-sdk with scaffold command in x402-sdk-dev Replace the simple init-sdk command with a full project scaffolding system similar to bankr-agent-dev. The new scaffold command creates complete project structures for different use cases (bot, web-service, dashboard, cli) with all necessary files and configurations. New skills added: - x402-project-templates: directory structures for each project type - x402-client-patterns: reusable client code, executor, and common files --- x402-sdk-dev/README.md | 12 +- x402-sdk-dev/commands/init-sdk.md | 269 ------------ x402-sdk-dev/commands/scaffold.md | 57 +++ .../skills/x402-client-patterns/SKILL.md | 402 ++++++++++++++++++ .../skills/x402-project-templates/SKILL.md | 306 +++++++++++++ 5 files changed, 773 insertions(+), 273 deletions(-) delete mode 100644 x402-sdk-dev/commands/init-sdk.md create mode 100644 x402-sdk-dev/commands/scaffold.md create mode 100644 x402-sdk-dev/skills/x402-client-patterns/SKILL.md create mode 100644 x402-sdk-dev/skills/x402-project-templates/SKILL.md diff --git a/x402-sdk-dev/README.md b/x402-sdk-dev/README.md index 245e12a..d73d12b 100644 --- a/x402-sdk-dev/README.md +++ b/x402-sdk-dev/README.md @@ -56,6 +56,8 @@ export BANKR_API_URL=https://api.bankr.bot # Optional | `sdk-balance-queries` | Token balances, portfolio values | | `sdk-transaction-builder` | Transfers, approvals, NFTs, DeFi | | `sdk-job-management` | Async job control and monitoring | +| `x402-project-templates` | Directory structures for bot, web-service, dashboard, cli projects | +| `x402-client-patterns` | Reusable client code, executor, and common project files | ## Agent @@ -65,14 +67,16 @@ export BANKR_API_URL=https://api.bankr.bot # Optional | Command | Description | |---------|-------------| -| `/bankr-x402-sdk-dev:init-sdk [path]` | Initialize SDK in your project - installs package, creates client file, sets up .env | +| `/bankr-x402-sdk-dev:scaffold [type]` | Scaffold a complete project using the Bankr x402 SDK | -**Quick setup:** +**Project types:** `bot`, `web-service`, `dashboard`, `cli` + +**Quick start:** ```bash -/bankr-x402-sdk-dev:init-sdk +/bankr-x402-sdk-dev:scaffold bot ``` -This auto-detects your package manager and TypeScript setup, then creates a ready-to-use `bankr-client.ts` file. +This creates a complete project with `bankr-client.ts`, transaction executor, package.json, tsconfig.json, and environment configuration. ## Basic Usage diff --git a/x402-sdk-dev/commands/init-sdk.md b/x402-sdk-dev/commands/init-sdk.md deleted file mode 100644 index ea211c4..0000000 --- a/x402-sdk-dev/commands/init-sdk.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -description: Initialize Bankr SDK in current project - installs package, creates client file, sets up environment -allowed-tools: - - Read - - Write - - Edit - - Bash - - Glob - - Grep -argument-hint: "[output-path]" ---- - -# Initialize Bankr SDK - -Set up the Bankr SDK in the user's project with proper configuration. - -## Arguments - -- `[output-path]` (optional): Directory for the client file. Defaults to `src/` if it exists, otherwise project root. - -## Workflow - -### Step 1: Detect Project Configuration - -Check the project setup: - -```bash -# Check for package.json (required) -ls package.json - -# Detect package manager from lockfiles -ls package-lock.json 2>/dev/null # npm -ls yarn.lock 2>/dev/null # yarn -ls pnpm-lock.yaml 2>/dev/null # pnpm -ls bun.lockb 2>/dev/null # bun -``` - -**Package manager priority:** bun.lockb > pnpm-lock.yaml > yarn.lock > package-lock.json > default to npm - -Check for TypeScript: -```bash -ls tsconfig.json 2>/dev/null -``` - -If `tsconfig.json` exists, use TypeScript (`.ts`). Otherwise use JavaScript (`.js`). - -### Step 2: Check if SDK Already Installed - -```bash -grep -q "@bankr/sdk" package.json -``` - -If not found, install it using the detected package manager: - -| Manager | Command | -|---------|---------| -| npm | `npm install @bankr/sdk` | -| yarn | `yarn add @bankr/sdk` | -| pnpm | `pnpm add @bankr/sdk` | -| bun | `bun add @bankr/sdk` | - -### Step 3: Determine Output Path - -1. If user provided `[output-path]`, use that -2. Else if `src/` directory exists, use `src/` -3. Else if `lib/` directory exists, use `lib/` -4. Else use project root - -### Step 4: Create Client File - -Create the appropriate file based on TypeScript detection. - -**For TypeScript (`bankr-client.ts`):** - -```typescript -import { BankrClient } from "@bankr/sdk"; - -/** - * Bankr SDK Client - * - * Provides AI-powered Web3 operations with x402 micropayments. - * Each API request costs $0.01 USDC (paid from payment wallet on Base). - * - * Environment Variables: - * BANKR_PRIVATE_KEY - Required: Payment wallet private key (needs USDC on Base) - * BANKR_WALLET_ADDRESS - Optional: Receiving wallet (defaults to payment wallet) - * BANKR_API_URL - Optional: API endpoint (defaults to https://api.bankr.bot) - * - * @example - * ```typescript - * import { bankrClient } from "./bankr-client"; - * - * // Token swap - * const swap = await bankrClient.promptAndWait({ - * prompt: "Swap 0.1 ETH to USDC on Base", - * }); - * - * // Check balances - * const balances = await bankrClient.promptAndWait({ - * prompt: "What are my token balances?", - * }); - * - * // The SDK returns transaction data - execute with viem/ethers - * if (swap.status === "completed" && swap.transactions) { - * const tx = swap.transactions[0].metadata.transaction; - * // await wallet.sendTransaction(tx); - * } - * ``` - * - * @see https://www.npmjs.com/package/@bankr/sdk - * @see https://docs.bankr.bot - */ - -// Validate required environment variable -if (!process.env.BANKR_PRIVATE_KEY) { - throw new Error( - "BANKR_PRIVATE_KEY environment variable is required. " + - "This wallet pays $0.01 USDC per request and must have USDC on Base." - ); -} - -export const bankrClient = new BankrClient({ - // Required: Payment wallet private key - // This wallet pays $0.01 USDC per API request (must have USDC on Base) - privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, - - // Optional: Override receiving wallet address - // If not set, tokens are sent to the payment wallet address - walletAddress: process.env.BANKR_WALLET_ADDRESS, - - // Optional: API endpoint (defaults to production) - ...(process.env.BANKR_API_URL && { baseUrl: process.env.BANKR_API_URL }), -}); - -// Export the wallet address for reference -export const bankrWalletAddress = bankrClient.getWalletAddress(); -``` - -**For JavaScript (`bankr-client.js`):** - -```javascript -const { BankrClient } = require("@bankr/sdk"); - -/** - * Bankr SDK Client - * - * Provides AI-powered Web3 operations with x402 micropayments. - * Each API request costs $0.01 USDC (paid from payment wallet on Base). - * - * Environment Variables: - * BANKR_PRIVATE_KEY - Required: Payment wallet private key (needs USDC on Base) - * BANKR_WALLET_ADDRESS - Optional: Receiving wallet (defaults to payment wallet) - * BANKR_API_URL - Optional: API endpoint (defaults to https://api.bankr.bot) - * - * @example - * ```javascript - * const { bankrClient } = require("./bankr-client"); - * - * // Token swap - * const swap = await bankrClient.promptAndWait({ - * prompt: "Swap 0.1 ETH to USDC on Base", - * }); - * - * // Check balances - * const balances = await bankrClient.promptAndWait({ - * prompt: "What are my token balances?", - * }); - * ``` - * - * @see https://www.npmjs.com/package/@bankr/sdk - * @see https://docs.bankr.bot - */ - -// Validate required environment variable -if (!process.env.BANKR_PRIVATE_KEY) { - throw new Error( - "BANKR_PRIVATE_KEY environment variable is required. " + - "This wallet pays $0.01 USDC per request and must have USDC on Base." - ); -} - -const bankrClient = new BankrClient({ - // Required: Payment wallet private key - privateKey: process.env.BANKR_PRIVATE_KEY, - - // Optional: Override receiving wallet address - walletAddress: process.env.BANKR_WALLET_ADDRESS, - - // Optional: API endpoint - ...(process.env.BANKR_API_URL && { baseUrl: process.env.BANKR_API_URL }), -}); - -// Export the client and wallet address -module.exports = { - bankrClient, - bankrWalletAddress: bankrClient.getWalletAddress(), -}; -``` - -### Step 5: Create/Update .env.example - -Check if `.env.example` exists. If it does, append the Bankr variables (if not already present). If it doesn't exist, create it. - -```bash -# .env.example content to add: - -# Bankr SDK Configuration -# See: https://docs.bankr.bot - -# Required: Payment wallet private key -# This wallet pays $0.01 USDC per API request (must have USDC on Base) -# Format: 64 hex characters with 0x prefix -BANKR_PRIVATE_KEY=0x - -# Optional: Receiving wallet address -# Tokens from swaps/purchases go here. Defaults to payment wallet if not set. -# BANKR_WALLET_ADDRESS=0x - -# Optional: API endpoint override (defaults to https://api.bankr.bot) -# BANKR_API_URL=https://api.bankr.bot -``` - -### Step 6: Check .gitignore - -Verify `.env` is in `.gitignore` to prevent committing secrets: - -```bash -grep -q "^\.env$" .gitignore 2>/dev/null || grep -q "\.env" .gitignore 2>/dev/null -``` - -If not found, warn the user to add `.env` to `.gitignore`. - -### Step 7: Summary - -After completing all steps, show a summary: - -``` -Bankr SDK initialized successfully! - -Created: - - {output-path}/bankr-client.{ts|js} - - .env.example (updated with Bankr variables) - -Next steps: - 1. Copy .env.example to .env - 2. Add your payment wallet private key to BANKR_PRIVATE_KEY - 3. Fund the wallet with USDC on Base ($1-2 recommended) - 4. Import and use: - - import { bankrClient } from "{output-path}/bankr-client"; - - const result = await bankrClient.promptAndWait({ - prompt: "Swap 0.1 ETH to USDC on Base", - }); - -Documentation: https://docs.bankr.bot -``` - -## Error Handling - -- **No package.json**: "This command must be run in a Node.js project with package.json" -- **SDK install fails**: Show the error and suggest manual installation -- **File already exists**: Ask user if they want to overwrite - -## Tips - -- If the user specifies a custom path like `lib/services`, create the directory if needed -- Preserve existing content in .env.example, only append new variables -- Use ES modules syntax if package.json has `"type": "module"` (even for .js files) diff --git a/x402-sdk-dev/commands/scaffold.md b/x402-sdk-dev/commands/scaffold.md new file mode 100644 index 0000000..7efffb4 --- /dev/null +++ b/x402-sdk-dev/commands/scaffold.md @@ -0,0 +1,57 @@ +--- +description: Scaffold a new project that uses the Bankr x402 SDK +argument-hint: [project-type] +allowed-tools: Read, Write, Bash, AskUserQuestion, Glob, Grep +--- + +# x402 SDK Project Scaffold + +Create a complete TypeScript/Node.js project scaffold for building on the Bankr x402 SDK. + +## Process + +1. **Determine project type** - If `$ARGUMENTS` specifies a type, use it. Otherwise, ask the user. + + Load the `x402-project-templates` skill for available types: + - **bot** - Automated trading bot, price monitor, portfolio rebalancer, scheduled task + - **web-service** - HTTP API that wraps Bankr SDK for mobile apps or integrations + - **dashboard** - Web UI for portfolio tracking, swap interface, monitoring + - **cli** - Command-line tool for Bankr operations + +2. **Ask for project details**: + - Project name (kebab-case, e.g., `my-trading-bot`) + - Brief description of what it will do + - Any specific SDK operations it will use (swaps, transfers, queries, NFTs, leverage) + +3. **Create project structure**: + - Load `x402-project-templates` skill for the directory structure + - Load `x402-client-patterns` skill for common files and client code + - Create all directories using `mkdir -p` + - Write each file using the Write tool + - Customize based on user's description + +4. **Explain next steps**: + - How to set up the payment wallet (private key with USDC on Base) + - How to run the project (`npm install && npm run dev`) + - What to customize first based on their use case + +## Skills to Load + +**Core Skills (always load):** +- `x402-project-templates` - Directory structures for each project type +- `x402-client-patterns` - bankr-client.ts and common files (package.json, tsconfig.json, .env.example, .gitignore) +- `sdk-capabilities` - SDK operation reference + +**Capability Skills (load based on project purpose):** +- `sdk-token-swaps` - For trading bots: swap patterns, approval handling +- `sdk-transaction-builder` - For custom transfers, NFT ops, bridges +- `sdk-balance-queries` - For dashboards: portfolio queries, balance tracking +- `sdk-wallet-operations` - For multi-wallet setups +- `sdk-job-management` - For advanced: job polling, cancellation + +## Implementation Notes + +- Create all directories first using `mkdir -p` +- Write each file using the Write tool +- Include helpful comments in generated code +- Generate a README.md with setup instructions and usage examples diff --git a/x402-sdk-dev/skills/x402-client-patterns/SKILL.md b/x402-sdk-dev/skills/x402-client-patterns/SKILL.md new file mode 100644 index 0000000..4c8544b --- /dev/null +++ b/x402-sdk-dev/skills/x402-client-patterns/SKILL.md @@ -0,0 +1,402 @@ +--- +name: Bankr x402 SDK - Client Patterns +description: This skill should be used when the user asks to "implement Bankr SDK client", "write bankr-client.ts", "create SDK client setup", "common files for SDK project", "package.json for Bankr SDK", "tsconfig for Bankr", "SDK TypeScript patterns", "execute SDK transactions", or needs the reusable client code and common project files for Bankr SDK integrations. +version: 1.0.0 +--- + +# x402 SDK Client Patterns + +Reusable client code and common files for Bankr SDK projects. + +## bankr-client.ts + +The core SDK client module for all Bankr SDK projects: + +```typescript +import "dotenv/config"; +import { BankrClient } from "@bankr/sdk"; + +// ============================================ +// Validation +// ============================================ + +if (!process.env.BANKR_PRIVATE_KEY) { + throw new Error( + "BANKR_PRIVATE_KEY environment variable is required. " + + "This wallet pays $0.01 USDC per request (needs USDC on Base)." + ); +} + +// ============================================ +// Client Setup +// ============================================ + +/** + * Bankr SDK Client + * + * Provides AI-powered Web3 operations with x402 micropayments. + * Each API request costs $0.01 USDC (paid from payment wallet on Base). + * + * @example + * ```typescript + * import { bankrClient } from "./bankr-client"; + * + * // Token swap + * const swap = await bankrClient.promptAndWait({ + * prompt: "Swap 0.1 ETH to USDC on Base", + * }); + * + * // Check balances + * const balances = await bankrClient.promptAndWait({ + * prompt: "What are my token balances?", + * }); + * ``` + * + * @see https://www.npmjs.com/package/@bankr/sdk + */ +export const bankrClient = new BankrClient({ + // Required: Payment wallet private key + // This wallet pays $0.01 USDC per API request (must have USDC on Base) + privateKey: process.env.BANKR_PRIVATE_KEY as `0x${string}`, + + // Optional: Override receiving wallet address + // If not set, tokens are sent to the payment wallet address + walletAddress: process.env.BANKR_WALLET_ADDRESS, + + // Optional: API endpoint (defaults to production) + ...(process.env.BANKR_API_URL && { baseUrl: process.env.BANKR_API_URL }), +}); + +// Export the wallet address for reference +export const walletAddress = bankrClient.getWalletAddress(); + +// ============================================ +// Types (re-exported from SDK) +// ============================================ + +export type { JobStatusResponse, Transaction } from "@bankr/sdk"; +``` + +--- + +## executor.ts + +Transaction execution helper using viem: + +```typescript +import { createWalletClient, http, type WalletClient } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { base, mainnet, polygon } from "viem/chains"; +import type { Transaction } from "@bankr/sdk"; + +// Chain configuration +const chains = { + 8453: base, + 1: mainnet, + 137: polygon, +} as const; + +// Create wallet client for transaction execution +const account = privateKeyToAccount( + process.env.BANKR_PRIVATE_KEY as `0x${string}` +); + +function getWalletClient(chainId: number): WalletClient { + const chain = chains[chainId as keyof typeof chains]; + if (!chain) { + throw new Error(`Unsupported chain ID: ${chainId}`); + } + + return createWalletClient({ + account, + chain, + transport: http(), + }); +} + +/** + * Execute a transaction returned by the Bankr SDK + * + * @example + * ```typescript + * const result = await bankrClient.promptAndWait({ + * prompt: "Swap 0.1 ETH to USDC", + * }); + * + * if (result.transactions?.length) { + * const hash = await executeTransaction(result.transactions[0]); + * console.log("Transaction:", hash); + * } + * ``` + */ +export async function executeTransaction(tx: Transaction): Promise { + const txData = tx.metadata.transaction; + const client = getWalletClient(txData.chainId); + + console.log(`Executing ${tx.type} on chain ${txData.chainId}...`); + + const hash = await client.sendTransaction({ + to: txData.to as `0x${string}`, + data: txData.data as `0x${string}`, + value: BigInt(txData.value || "0"), + gas: BigInt(txData.gas), + }); + + console.log(`Transaction submitted: ${hash}`); + return hash; +} + +/** + * Execute all transactions from a Bankr result + */ +export async function executeAllTransactions( + transactions: Transaction[] +): Promise { + const hashes: string[] = []; + + for (const tx of transactions) { + const hash = await executeTransaction(tx); + hashes.push(hash); + } + + return hashes; +} +``` + +--- + +## Common Files + +### package.json + +Base package.json for all Bankr SDK projects: + +```json +{ + "name": "{project-name}", + "version": "0.1.0", + "description": "{description}", + "type": "module", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "start": "node dist/index.js", + "dev": "tsx src/index.ts" + }, + "dependencies": { + "@bankr/sdk": "^1.0.0", + "dotenv": "^16.3.1", + "viem": "^2.0.0" + }, + "devDependencies": { + "@types/node": "^20.10.0", + "tsx": "^4.7.0", + "typescript": "^5.3.0" + } +} +``` + +#### Framework-Specific Dependencies + +Add based on project template: + +**Web Service (Express):** +```json +"dependencies": { + "express": "^4.18.0" +}, +"devDependencies": { + "@types/express": "^4.17.21" +} +``` + +**CLI:** +```json +"dependencies": { + "commander": "^12.0.0" +} +``` + +--- + +### tsconfig.json + +TypeScript configuration: + +```json +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} +``` + +--- + +### .env.example + +Environment variables template: + +```bash +# Bankr SDK Configuration +# See: https://docs.bankr.bot + +# Required: Payment wallet private key +# This wallet pays $0.01 USDC per API request (must have USDC on Base) +# Format: 64 hex characters with 0x prefix +BANKR_PRIVATE_KEY=0x + +# Optional: Receiving wallet address +# Tokens from swaps/purchases go here. Defaults to payment wallet if not set. +# BANKR_WALLET_ADDRESS=0x + +# Optional: API endpoint override (defaults to https://api.bankr.bot) +# BANKR_API_URL=https://api.bankr.bot +``` + +--- + +### .gitignore + +Standard ignore patterns: + +``` +# Dependencies +node_modules/ + +# Build output +dist/ + +# Environment +.env +.env.local +.env.*.local + +# Logs +*.log +npm-debug.log* + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Testing +coverage/ +``` + +--- + +## Usage Patterns + +### Basic Usage + +```typescript +import { bankrClient } from "./bankr-client"; + +const result = await bankrClient.promptAndWait({ + prompt: "What is the price of ETH?", + onStatusUpdate: (msg) => console.log("Progress:", msg), +}); + +console.log(result.response); +``` + +### With Transaction Execution + +```typescript +import { bankrClient } from "./bankr-client"; +import { executeTransaction } from "./executor"; + +const result = await bankrClient.promptAndWait({ + prompt: "Swap 0.1 ETH to USDC on Base", +}); + +if (result.status === "completed" && result.transactions?.length) { + // Review before executing + console.log("Transaction ready:", result.transactions[0].type); + console.log("Details:", result.transactions[0].metadata.__ORIGINAL_TX_DATA__); + + // Execute + const hash = await executeTransaction(result.transactions[0]); + console.log("Executed:", hash); +} +``` + +### With Error Handling + +```typescript +import { bankrClient } from "./bankr-client"; +import { executeAllTransactions } from "./executor"; + +async function performSwap(prompt: string) { + try { + const result = await bankrClient.promptAndWait({ + prompt, + onStatusUpdate: console.log, + }); + + if (result.status === "completed") { + console.log("Success:", result.response); + + if (result.transactions?.length) { + const hashes = await executeAllTransactions(result.transactions); + console.log("Transactions:", hashes); + } + } else if (result.status === "failed") { + console.error("Failed:", result.error); + } + } catch (error) { + console.error("Error:", error.message); + } +} +``` + +### Query Without Transactions + +```typescript +import { bankrClient } from "./bankr-client"; + +// Balance queries don't return transactions +const balances = await bankrClient.promptAndWait({ + prompt: "What are my balances on Base?", +}); + +console.log(balances.response); + +// Price queries +const price = await bankrClient.promptAndWait({ + prompt: "Price of DEGEN", +}); + +console.log(price.response); +``` + +--- + +## SDK Reference + +Consult the `sdk-capabilities` skill for: +- Complete operation reference +- Supported chains and tokens +- Example prompts for each operation + +Consult the `sdk-token-swaps` skill for: +- Swap patterns and approval handling +- Transaction execution details diff --git a/x402-sdk-dev/skills/x402-project-templates/SKILL.md b/x402-sdk-dev/skills/x402-project-templates/SKILL.md new file mode 100644 index 0000000..7d949b1 --- /dev/null +++ b/x402-sdk-dev/skills/x402-project-templates/SKILL.md @@ -0,0 +1,306 @@ +--- +name: Bankr x402 SDK - Project Templates +description: This skill should be used when the user asks to "scaffold a Bankr SDK project", "create new SDK bot", "build a Bankr web service", "create Bankr dashboard", "build Bankr CLI tool", "project structure for SDK", "x402 project types", or needs guidance on directory structures and templates for different types of Bankr SDK integrations. +version: 1.0.0 +--- + +# x402 SDK Project Templates + +Directory structures and templates for Bankr SDK projects using x402 micropayments. + +## Available Templates + +| Template | Use Case | Key Features | +|----------|----------|--------------| +| **bot** | Automated tasks | Polling loop, scheduler, transaction execution | +| **web-service** | HTTP APIs | REST endpoints, async handling, webhook support | +| **dashboard** | Web UIs | Frontend + backend, portfolio display | +| **cli** | Command-line tools | Subcommands, interactive prompts | + +## Bot Template + +For automated trading bots, price monitors, portfolio rebalancers, and scheduled tasks. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # Main entry point with scheduler +│ ├── bankr-client.ts # Bankr SDK client (from x402-client-patterns skill) +│ ├── executor.ts # Transaction execution with viem/ethers +│ ├── types.ts # TypeScript interfaces +│ └── config.ts # Configuration loading +└── scripts/ + └── run.sh # Convenience script +``` + +### Key Features + +- **Polling loop**: Configurable interval for recurring operations +- **Transaction execution**: Built-in viem integration for sending txs +- **Status streaming**: Real-time job progress updates +- **Error handling**: Automatic retries with backoff +- **Graceful shutdown**: Handles SIGINT/SIGTERM + +### Use Cases + +- Price monitoring and alerts +- Automated swap strategies +- Portfolio rebalancing +- Scheduled market analysis +- DCA-like automation + +### Entry Point Pattern (index.ts) + +```typescript +import { bankrClient } from "./bankr-client"; +import { executeTransaction } from "./executor"; + +const INTERVAL = 60000; // 1 minute + +async function runBot() { + console.log("Starting Bankr SDK bot..."); + + while (true) { + try { + const result = await bankrClient.promptAndWait({ + prompt: "Check ETH price", + onStatusUpdate: (msg) => console.log("Status:", msg), + }); + + if (result.status === "completed") { + console.log("Result:", result.response); + + // Execute transactions if returned + if (result.transactions?.length) { + for (const tx of result.transactions) { + await executeTransaction(tx); + } + } + } + } catch (error) { + console.error("Error:", error); + } + + await new Promise((r) => setTimeout(r, INTERVAL)); + } +} + +runBot(); +``` + +--- + +## Web Service Template + +For HTTP APIs that wrap Bankr SDK for mobile apps or integrations. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # Server entry point +│ ├── server.ts # Express/Fastify server setup +│ ├── routes/ +│ │ ├── health.ts # Health check endpoint +│ │ ├── swap.ts # Swap endpoints +│ │ └── portfolio.ts # Portfolio endpoints +│ ├── bankr-client.ts # Bankr SDK client +│ ├── types.ts # TypeScript interfaces +│ └── config.ts # Configuration loading +└── scripts/ + └── run.sh +``` + +### Key Features + +- **REST API endpoints**: Clean API design +- **Request validation**: Input sanitization +- **Async handling**: Non-blocking SDK operations +- **Rate limiting**: Prevent abuse +- **CORS**: Cross-origin support + +### Use Cases + +- API gateway for Bankr SDK +- Mobile app backend +- Trading API for integrations +- Webhook-driven automation + +### Additional Dependencies + +```json +{ + "dependencies": { + "express": "^4.18.0" + } +} +``` + +--- + +## Dashboard Template + +For web UIs with portfolio tracking, swap interfaces, or monitoring. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── server/ +│ ├── index.ts # Backend server +│ ├── bankr-client.ts # Bankr SDK client +│ ├── routes/ +│ │ └── api.ts # API routes for frontend +│ └── types.ts +├── public/ +│ ├── index.html # Main HTML page +│ ├── styles.css # Basic styles +│ └── app.js # Frontend JavaScript +└── scripts/ + └── run.sh +``` + +### Key Features + +- **Simple frontend**: HTML/CSS/JS (no build step required) +- **Backend API**: Express server for SDK operations +- **Portfolio display**: Token balances and values +- **Swap interface**: Execute swaps through UI + +### Use Cases + +- Portfolio tracking dashboard +- Personal trading interface +- Market monitoring +- Position management + +--- + +## CLI Template + +For command-line tools with subcommands and interactive features. + +### Directory Structure + +``` +{project-name}/ +├── package.json +├── tsconfig.json +├── .env.example +├── .gitignore +├── README.md +├── src/ +│ ├── index.ts # CLI entry with commander.js +│ ├── commands/ +│ │ ├── swap.ts # Swap commands +│ │ ├── balance.ts # Balance query commands +│ │ └── send.ts # Transfer commands +│ ├── bankr-client.ts # Bankr SDK client +│ ├── executor.ts # Transaction execution +│ └── types.ts +└── scripts/ + └── run.sh +``` + +### Key Features + +- **Commander.js**: CLI framework with subcommands +- **Interactive prompts**: User input when needed +- **Progress indicators**: Status during SDK calls +- **Colored output**: Better UX +- **Transaction confirmation**: Review before execute + +### Use Cases + +- Personal trading tool +- Scripting and automation +- Quick balance checks +- Batch swap operations + +### Additional Dependencies + +```json +{ + "dependencies": { + "commander": "^12.0.0" + } +} +``` + +### CLI Pattern (index.ts) + +```typescript +import { program } from "commander"; +import { swap } from "./commands/swap"; +import { balance } from "./commands/balance"; + +program + .name("bankr-cli") + .description("CLI for Bankr SDK operations") + .version("1.0.0"); + +program + .command("balance") + .description("Get wallet balances") + .action(balance); + +program + .command("swap ") + .description("Swap tokens") + .option("-c, --chain ", "Target chain", "base") + .option("-y, --yes", "Skip confirmation") + .action(swap); + +program.parse(); +``` + +--- + +## Choosing a Template + +| Need | Recommended Template | +|------|---------------------| +| Automated recurring tasks | **bot** | +| HTTP API for mobile/web | **web-service** | +| Visual interface | **dashboard** | +| Terminal-based tool | **cli** | +| Price alerts | **bot** | +| Portfolio viewer | **dashboard** | +| Quick trades | **cli** | + +## Common Files + +All templates share common files. Load the `x402-client-patterns` skill for: +- `bankr-client.ts` - SDK client setup +- `executor.ts` - Transaction execution +- `package.json` - Base dependencies +- `tsconfig.json` - TypeScript config +- `.env.example` - Environment template +- `.gitignore` - Standard ignores + +## Next Steps After Scaffolding + +1. **Install dependencies**: `npm install` +2. **Configure wallet**: Copy `.env.example` to `.env` and add `BANKR_PRIVATE_KEY` +3. **Fund wallet**: Add USDC on Base ($1-2 recommended for API costs) +4. **Customize**: Modify the template for your use case +5. **Run**: `npm run dev` for development +6. **Build**: `npm run build` for production From d304be67987767425bb58905d38376a98047ad5b Mon Sep 17 00:00:00 2001 From: sidrisov Date: Fri, 23 Jan 2026 22:10:35 +0400 Subject: [PATCH 7/8] feat: add bun/npm package manager preference to scaffold commands Add package manager selection to both scaffold commands, allowing users to choose between bun (recommended) and npm. Updated all related docs and skills to show both options for install, dev, and build commands. --- bankr-agent-dev/commands/scaffold.md | 3 ++- bankr-agent-dev/skills/bankr-project-templates/SKILL.md | 6 +++--- x402-sdk-dev/README.md | 2 ++ x402-sdk-dev/agents/sdk-assistant.md | 2 ++ x402-sdk-dev/commands/scaffold.md | 3 ++- x402-sdk-dev/skills/x402-project-templates/SKILL.md | 6 +++--- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/bankr-agent-dev/commands/scaffold.md b/bankr-agent-dev/commands/scaffold.md index 307e95c..06058a5 100644 --- a/bankr-agent-dev/commands/scaffold.md +++ b/bankr-agent-dev/commands/scaffold.md @@ -22,6 +22,7 @@ Create a complete TypeScript/Node.js project scaffold for building on the Bankr - Project name (kebab-case, e.g., `my-trading-bot`) - Brief description of what it will do - Any specific Bankr operations it will use (trading, prices, polymarket, defi) + - Package manager preference: **bun** (recommended - faster) or **npm** 3. **Create project structure**: - Load `bankr-project-templates` skill for the directory structure @@ -32,7 +33,7 @@ Create a complete TypeScript/Node.js project scaffold for building on the Bankr 4. **Explain next steps**: - How to get a Bankr API key (https://bankr.bot/api) - - How to run the project (`npm install && npm run dev`) + - How to run the project (use selected package manager: `bun install && bun dev` or `npm install && npm run dev`) - What to customize first based on their use case ## Skills to Load diff --git a/bankr-agent-dev/skills/bankr-project-templates/SKILL.md b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md index b030035..ec6f59b 100644 --- a/bankr-agent-dev/skills/bankr-project-templates/SKILL.md +++ b/bankr-agent-dev/skills/bankr-project-templates/SKILL.md @@ -315,8 +315,8 @@ All templates share common files. Load the `bankr-client-patterns` skill for: ## Next Steps After Scaffolding -1. **Install dependencies**: `npm install` +1. **Install dependencies**: `bun install` or `npm install` 2. **Configure API key**: Copy `.env.example` to `.env` and add `BANKR_API_KEY` 3. **Customize**: Modify the template for your use case -4. **Run**: `npm run dev` for development -5. **Build**: `npm run build` for production +4. **Run**: `bun dev` or `npm run dev` for development +5. **Build**: `bun run build` or `npm run build` for production diff --git a/x402-sdk-dev/README.md b/x402-sdk-dev/README.md index d73d12b..993fc08 100644 --- a/x402-sdk-dev/README.md +++ b/x402-sdk-dev/README.md @@ -35,6 +35,8 @@ bunx skills add BankrBot/claude-plugins ### 2. Install SDK ```bash +bun add @bankr/sdk +# or npm install @bankr/sdk ``` diff --git a/x402-sdk-dev/agents/sdk-assistant.md b/x402-sdk-dev/agents/sdk-assistant.md index 3efefdc..89b6e1c 100644 --- a/x402-sdk-dev/agents/sdk-assistant.md +++ b/x402-sdk-dev/agents/sdk-assistant.md @@ -51,6 +51,8 @@ Load these skills based on user needs: **Install:** ```bash +bun add @bankr/sdk +# or npm install @bankr/sdk ``` diff --git a/x402-sdk-dev/commands/scaffold.md b/x402-sdk-dev/commands/scaffold.md index 7efffb4..58f0e9c 100644 --- a/x402-sdk-dev/commands/scaffold.md +++ b/x402-sdk-dev/commands/scaffold.md @@ -22,6 +22,7 @@ Create a complete TypeScript/Node.js project scaffold for building on the Bankr - Project name (kebab-case, e.g., `my-trading-bot`) - Brief description of what it will do - Any specific SDK operations it will use (swaps, transfers, queries, NFTs, leverage) + - Package manager preference: **bun** (recommended - faster) or **npm** 3. **Create project structure**: - Load `x402-project-templates` skill for the directory structure @@ -32,7 +33,7 @@ Create a complete TypeScript/Node.js project scaffold for building on the Bankr 4. **Explain next steps**: - How to set up the payment wallet (private key with USDC on Base) - - How to run the project (`npm install && npm run dev`) + - How to run the project (use selected package manager: `bun install && bun dev` or `npm install && npm run dev`) - What to customize first based on their use case ## Skills to Load diff --git a/x402-sdk-dev/skills/x402-project-templates/SKILL.md b/x402-sdk-dev/skills/x402-project-templates/SKILL.md index 7d949b1..3355955 100644 --- a/x402-sdk-dev/skills/x402-project-templates/SKILL.md +++ b/x402-sdk-dev/skills/x402-project-templates/SKILL.md @@ -298,9 +298,9 @@ All templates share common files. Load the `x402-client-patterns` skill for: ## Next Steps After Scaffolding -1. **Install dependencies**: `npm install` +1. **Install dependencies**: `bun install` or `npm install` 2. **Configure wallet**: Copy `.env.example` to `.env` and add `BANKR_PRIVATE_KEY` 3. **Fund wallet**: Add USDC on Base ($1-2 recommended for API costs) 4. **Customize**: Modify the template for your use case -5. **Run**: `npm run dev` for development -6. **Build**: `npm run build` for production +5. **Run**: `bun dev` or `npm run dev` for development +6. **Build**: `bun run build` or `npm run build` for production From 8ab5ae9baa24d43c1206ce7ce8a67579ccb1c91a Mon Sep 17 00:00:00 2001 From: sidrisov Date: Sat, 24 Jan 2026 00:58:27 +0400 Subject: [PATCH 8/8] chore: bump plugin and skill versions to 1.x.x - Bump bankr-agent and bankr-agent-dev plugins from 0.1.1 to 1.0.0 - Bump bankr-api-basics skill from 0.1.0 to 1.0.0 - Bump x402-sdk-dev plugin from 1.1.0 to 1.2.0 - Bump existing x402-sdk-dev skills from 1.0.0 to 1.1.0 - Bump bankr-agent MCP server from 0.1.1 to 1.0.0 --- bankr-agent-dev/.claude-plugin/plugin.json | 2 +- bankr-agent-dev/skills/bankr-api-basics/SKILL.md | 2 +- bankr-agent/.claude-plugin/plugin.json | 2 +- bankr-agent/mcp-server/package.json | 2 +- x402-sdk-dev/.claude-plugin/plugin.json | 2 +- x402-sdk-dev/skills/sdk-balance-queries/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-capabilities/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-job-management/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-token-swaps/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md | 2 +- x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bankr-agent-dev/.claude-plugin/plugin.json b/bankr-agent-dev/.claude-plugin/plugin.json index 64133f9..aca15bd 100644 --- a/bankr-agent-dev/.claude-plugin/plugin.json +++ b/bankr-agent-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "bankr-agent-dev", - "version": "0.1.1", + "version": "1.0.0", "description": "Developer toolkit for building applications on top of the Bankr Agent API - scaffold projects, understand API patterns, and build integrations", "author": { "name": "Bankr Team" diff --git a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md index 6ca0f9c..4e01ca0 100644 --- a/bankr-agent-dev/skills/bankr-api-basics/SKILL.md +++ b/bankr-agent-dev/skills/bankr-api-basics/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr Dev - API Basics description: This skill should be used when the user asks about "Bankr API", "Bankr Agent API", "how does Bankr work", "Bankr job status", "Bankr response format", or "building on Bankr". Provides endpoint documentation, job patterns, and TypeScript interfaces. -version: 0.1.0 +version: 1.0.0 --- # Bankr Agent API Essentials diff --git a/bankr-agent/.claude-plugin/plugin.json b/bankr-agent/.claude-plugin/plugin.json index ab8c650..f20a0b8 100644 --- a/bankr-agent/.claude-plugin/plugin.json +++ b/bankr-agent/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "bankr-agent", - "version": "0.1.1", + "version": "1.0.0", "description": "Integration with Bankr API for crypto trading, market analysis, and Polymarket predictions", "author": { "name": "Bankr Team" diff --git a/bankr-agent/mcp-server/package.json b/bankr-agent/mcp-server/package.json index 9a4a784..e266291 100644 --- a/bankr-agent/mcp-server/package.json +++ b/bankr-agent/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "bankr-agent-mcp-server", - "version": "0.1.1", + "version": "1.0.0", "description": "MCP server for Bankr Agent API integration", "type": "module", "main": "dist/index.js", diff --git a/x402-sdk-dev/.claude-plugin/plugin.json b/x402-sdk-dev/.claude-plugin/plugin.json index e2c0a25..7d6d5d1 100644 --- a/x402-sdk-dev/.claude-plugin/plugin.json +++ b/x402-sdk-dev/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "bankr-x402-sdk-dev", - "version": "1.1.0", + "version": "1.2.0", "description": "Bankr SDK integration for AI-assisted Web3 development with multi-chain DeFi and x402 micropayments", "author": { "name": "Bankr", diff --git a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md index 2600232..6a1f98d 100644 --- a/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md +++ b/x402-sdk-dev/skills/sdk-balance-queries/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Balance Queries description: This skill should be used when the user asks "what are my balances", "how much ETH do I have", "check my wallet", "show my tokens", "portfolio value", "what tokens do I own", "NFT holdings", "how much USDC", "get token balances", "wallet contents", or any question about token balances, wallet contents, portfolio values, or NFT holdings across chains using the Bankr SDK. -version: 1.0.0 +version: 1.1.0 --- # SDK Balance Queries diff --git a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md index 5730f22..eb4fdc8 100644 --- a/x402-sdk-dev/skills/sdk-capabilities/SKILL.md +++ b/x402-sdk-dev/skills/sdk-capabilities/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Capabilities description: This skill should be used when the user asks "what can the SDK do", "what prompts does Bankr support", "SDK features", "supported operations", "what can I build with Bankr", "Bankr SDK capabilities", "what chains are supported", "what tokens can I trade", "SDK supported commands", or wants to understand the full range of operations available through the Bankr SDK. -version: 1.0.0 +version: 1.1.0 --- # SDK Capabilities diff --git a/x402-sdk-dev/skills/sdk-job-management/SKILL.md b/x402-sdk-dev/skills/sdk-job-management/SKILL.md index d971baa..00d8215 100644 --- a/x402-sdk-dev/skills/sdk-job-management/SKILL.md +++ b/x402-sdk-dev/skills/sdk-job-management/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Job Management description: This skill should be used when the user asks about "job status", "check if request completed", "cancel request", "why is my request taking so long", "poll for result", "batch requests", "retry failed request", "request timeout", "async operations", "job lifecycle", "manual polling", or needs advanced control over SDK async operations, manual job polling, batch processing, retry logic, or job cancellation. -version: 1.0.0 +version: 1.1.0 --- # SDK Job Management diff --git a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md index 9c111c7..d74d01c 100644 --- a/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md +++ b/x402-sdk-dev/skills/sdk-token-swaps/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Token Swaps description: This skill should be used when the user asks to "swap tokens", "exchange ETH for USDC", "buy DEGEN", "sell tokens", "swap on Base", "trade crypto", "convert ETH to WETH", "exchange tokens", "token swap code", "0x routing", or any token swap operation. Also use for questions about ERC20 approvals, allowanceTarget, swap transaction execution, or building swap transactions with the Bankr SDK. -version: 1.0.0 +version: 1.1.0 --- # SDK Token Swaps diff --git a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md index bf3222a..0f40ff2 100644 --- a/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md +++ b/x402-sdk-dev/skills/sdk-transaction-builder/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Transaction Builder description: This skill should be used when the user asks to "send tokens", "transfer ETH", "send USDC to", "transfer NFT", "wrap ETH", "unwrap WETH", "bridge tokens", "mint NFT", "buy NFT", "approve token", "build transaction", "DeFi transaction", or needs to build transactions for transfers, approvals, NFT operations, cross-chain bridges, ETH/WETH conversions, or DeFi interactions beyond simple swaps using the Bankr SDK. -version: 1.0.0 +version: 1.1.0 --- # SDK Transaction Builder diff --git a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md index 8f77a18..eaec0f2 100644 --- a/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md +++ b/x402-sdk-dev/skills/sdk-wallet-operations/SKILL.md @@ -1,7 +1,7 @@ --- name: Bankr x402 SDK - Wallet Operations description: This skill should be used when the user asks to "set up the SDK", "initialize BankrClient", "configure wallet", "set up payment wallet", "connect wallet to Bankr", "get wallet address", "set up environment variables", "configure private key", "two wallet setup", "separate payment and trading wallets", or needs help with SDK client initialization, two-wallet configuration, wallet address derivation, environment setup, or BankrClient options. -version: 1.0.0 +version: 1.1.0 --- # SDK Wallet Operations