-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into hide-secrets
- Loading branch information
Showing
38 changed files
with
2,623 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Binance Plugin for Eliza | ||
|
||
This plugin enables Eliza to interact with the Binance cryptocurrency exchange, providing capabilities for checking prices, executing trades, and managing spot wallet balances. | ||
|
||
## Features | ||
|
||
- 📊 Real-time cryptocurrency price checks | ||
- 💱 Spot trading (market and limit orders) | ||
- 💰 Wallet balance inquiries | ||
- ✅ Comprehensive error handling | ||
- 🔒 Secure API integration | ||
|
||
## Prerequisites | ||
|
||
1. **Binance Account**: You need a Binance account to use this plugin | ||
2. **API Keys**: Generate API keys from your Binance account: | ||
- Go to your Binance account settings | ||
- Navigate to API Management | ||
- Create a new API key | ||
- Enable spot trading permissions | ||
- Store your API key and secret securely | ||
|
||
## Configuration | ||
|
||
Set the following environment variables: | ||
|
||
```env | ||
BINANCE_API_KEY=your_api_key | ||
BINANCE_SECRET_KEY=your_secret_key | ||
``` | ||
|
||
## Installation | ||
|
||
Add the plugin to your Eliza configuration: | ||
|
||
```json | ||
{ | ||
"plugins": ["@elizaos/plugin-binance"] | ||
} | ||
``` | ||
|
||
## Available Actions | ||
|
||
The plugin provides the following actions: | ||
|
||
1. **GET_PRICE**: Check cryptocurrency prices | ||
|
||
- Example: "What's the current price of Bitcoin?" | ||
- Example: "Check ETH price in USDT" | ||
|
||
2. **EXECUTE_SPOT_TRADE**: Execute spot trades | ||
|
||
- Example: "Buy 0.1 BTC at market price" | ||
- Example: "Sell 100 USDT worth of ETH" | ||
|
||
3. **GET_SPOT_BALANCE**: Check wallet balances | ||
- Example: "What's my BTC balance?" | ||
- Example: "Show all my wallet balances" | ||
|
||
## Important Notes | ||
|
||
1. **API Rate Limits**: Binance implements rate limiting: | ||
|
||
- 1200 requests per minute for most endpoints | ||
- Some endpoints have specific weight limits | ||
- The plugin handles rate limiting errors appropriately | ||
|
||
2. **Minimum Order Sizes**: Binance enforces minimum order sizes and notional values: | ||
|
||
- Minimum order size varies by trading pair | ||
- Minimum notional value (quantity × price) must be met | ||
- The plugin validates these requirements before order execution | ||
|
||
3. **Error Handling**: The plugin provides detailed error messages for: | ||
- Invalid API credentials | ||
- Insufficient balance | ||
- Invalid trading pairs | ||
- Minimum notional value not met | ||
- Other API-specific errors | ||
|
||
## Service Architecture | ||
|
||
The plugin is organized into specialized services: | ||
|
||
- `PriceService`: Handles price-related operations | ||
- `TradeService`: Manages trading operations | ||
- `AccountService`: Handles balance and account operations | ||
- `BaseService`: Provides common functionality |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "@elizaos/plugin-binance", | ||
"version": "0.1.0", | ||
"type": "module", | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": { | ||
"import": { | ||
"@elizaos/source": "./src/index.ts", | ||
"types": "./dist/index.d.ts", | ||
"default": "./dist/index.js" | ||
} | ||
} | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"dependencies": { | ||
"@elizaos/core": "workspace:*", | ||
"@binance/connector": "^3.6.0", | ||
"zod": "^3.22.4" | ||
}, | ||
"devDependencies": { | ||
"tsup": "8.3.5", | ||
"@types/node": "^20.0.0" | ||
}, | ||
"scripts": { | ||
"build": "tsup --format esm --dts", | ||
"dev": "tsup --format esm --dts --watch", | ||
"lint": "eslint --fix --cache ." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { | ||
ActionExample, | ||
composeContext, | ||
elizaLogger, | ||
generateObjectDeprecated, | ||
HandlerCallback, | ||
IAgentRuntime, | ||
Memory, | ||
ModelClass, | ||
State, | ||
type Action, | ||
} from "@elizaos/core"; | ||
import { BinanceService } from "../services"; | ||
|
||
const priceCheckTemplate = `Look at ONLY your LAST RESPONSE message in this conversation, where you just said which cryptocurrency price you would check. | ||
Based on ONLY that last message, provide the trading symbol. | ||
For example: | ||
- If your last message was "I'll check the current Ethereum price..." -> return "ETH" | ||
- If your last message was "I'll check the current Solana price..." -> return "SOL" | ||
- If your last message was "I'll check the current Bitcoin price..." -> return "BTC" | ||
\`\`\`json | ||
{ | ||
"symbol": "<symbol from your LAST response only>", | ||
"quoteCurrency": "<quote currency from your LAST response, or USDT if none mentioned>" | ||
} | ||
\`\`\` | ||
Last part of conversation: | ||
{{recentMessages}}`; | ||
|
||
export const priceCheck: Action = { | ||
name: "GET_PRICE", | ||
similes: [ | ||
"CHECK_PRICE", | ||
"PRICE_CHECK", | ||
"GET_CRYPTO_PRICE", | ||
"CRYPTO_PRICE", | ||
"CHECK_CRYPTO_PRICE", | ||
"PRICE_LOOKUP", | ||
"CURRENT_PRICE", | ||
], | ||
description: "Get current price information for a cryptocurrency pair", | ||
validate: async () => true, // Public endpoint | ||
handler: async ( | ||
runtime: IAgentRuntime, | ||
message: Memory, | ||
state: State, | ||
_options: Record<string, unknown>, | ||
callback?: HandlerCallback | ||
): Promise<boolean> => { | ||
try { | ||
// Initialize or update state | ||
state = !state | ||
? await runtime.composeState(message) | ||
: await runtime.updateRecentMessageState(state); | ||
|
||
const context = composeContext({ | ||
state, | ||
template: priceCheckTemplate, | ||
}); | ||
|
||
const rawContent = await generateObjectDeprecated({ | ||
runtime, | ||
context, | ||
modelClass: ModelClass.SMALL, | ||
}); | ||
|
||
if (!rawContent?.symbol) { | ||
throw new Error( | ||
"Could not determine which cryptocurrency to check" | ||
); | ||
} | ||
|
||
// Ensure the content has the required shape | ||
const content = { | ||
symbol: rawContent.symbol.toString().toUpperCase().trim(), | ||
quoteCurrency: (rawContent.quoteCurrency || "USDT") | ||
.toString() | ||
.toUpperCase() | ||
.trim(), | ||
}; | ||
|
||
if (content.symbol.length < 2 || content.symbol.length > 10) { | ||
throw new Error("Invalid cryptocurrency symbol"); | ||
} | ||
|
||
const binanceService = new BinanceService(); | ||
const priceData = await binanceService.getPrice(content); | ||
|
||
if (callback) { | ||
callback({ | ||
text: `The current ${content.symbol} price is ${BinanceService.formatPrice(priceData.price)} ${content.quoteCurrency}`, | ||
content: priceData, | ||
}); | ||
} | ||
|
||
return true; | ||
} catch (error) { | ||
elizaLogger.error("Error in price check:", error); | ||
if (callback) { | ||
const errorMessage = error.message.includes("Invalid API key") | ||
? "Unable to connect to Binance API" | ||
: error.message.includes("Invalid symbol") | ||
? `Sorry, could not find price for the cryptocurrency symbol you provided` | ||
: `Sorry, I encountered an error: ${error.message}`; | ||
|
||
callback({ | ||
text: errorMessage, | ||
content: { error: error.message }, | ||
}); | ||
} | ||
return false; | ||
} | ||
}, | ||
examples: [ | ||
[ | ||
{ | ||
user: "{{user1}}", | ||
content: { | ||
text: "What's the current price of Bitcoin?", | ||
}, | ||
}, | ||
{ | ||
user: "{{agent}}", | ||
content: { | ||
text: "I'll check the current Bitcoin price for you right away.", | ||
action: "GET_PRICE", | ||
}, | ||
}, | ||
{ | ||
user: "{{agent}}", | ||
content: { | ||
text: "The current BTC price is 42,150.25 USDT", | ||
}, | ||
}, | ||
], | ||
[ | ||
{ | ||
user: "{{user1}}", | ||
content: { | ||
text: "Can you check ETH price in EUR?", | ||
}, | ||
}, | ||
{ | ||
user: "{{agent}}", | ||
content: { | ||
text: "I'll fetch the current Ethereum price in euros for you.", | ||
action: "GET_PRICE", | ||
}, | ||
}, | ||
{ | ||
user: "{{agent}}", | ||
content: { | ||
text: "The current ETH price is 2,245.80 EUR", | ||
}, | ||
}, | ||
], | ||
] as ActionExample[][], | ||
} as Action; |
Oops, something went wrong.