Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make plugin-memeooorr publish ready #1

Merged
merged 19 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/common_checks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: main_workflow

on:
push:
branches:
- development
- main
pull_request:

jobs:
scan:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: |
wget https://github.com/zricethezav/gitleaks/releases/download/v8.10.1/gitleaks_8.10.1_linux_x64.tar.gz && \
tar -xzf gitleaks_8.10.1_linux_x64.tar.gz && \
sudo install gitleaks /usr/bin && \
gitleaks detect --report-format json --report-path leak_report -v
26 changes: 26 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Title for the gitleaks configuration file.
title = "Custom Gitleaks configuration"

# You have basically two options for your custom configuration:
#
# 1. define your own configuration, default rules do not apply
#
# use e.g., the default configuration as starting point:
# https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml
#
# 2. extend a configuration, the rules are overwritten or extended
#
# When you extend a configuration the extended rules take precedence over the
# default rules. I.e., if there are duplicate rules in both the extended
# configuration and the default configuration the extended rules or
# attributes of them will override the default rules.
# Another thing to know with extending configurations is you can chain
# together multiple configuration files to a depth of 2. Allowlist arrays are
# appended and can contain duplicates.

# useDefault and path can NOT be used at the same time. Choose one.
[extend]
# useDefault will extend the default gitleaks config built in to the binary
# the latest version is located at:
# https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml
useDefault = true
3 changes: 3 additions & 0 deletions .gitleaksignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
378cbc8c71476cd4bbe81c09f780efa7ae4f9b6e:src/actions/tokenDecisionAction.ts:generic-api-key:174
85ed0f3a738dcc9f1d00e2f8ea107dcdab876a8d:src/actions/balanceOfAction.ts:generic-api-key:59
dc06a6f907376b7b912b76f74e05de6e63f11385:src/actions/balanceOfAction.ts:generic-api-key:59
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Release History - plugin-memeooorr

## v0.1.7 (2025-02-20)

* Initial Release
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# plugin-memeooorr
Eliza plugin for memeoor Agent developed on autonolas framework.
Eliza plugin for memeooor Agent developed on autonolas framework.

> :warning: **Warning** <br />
> The code within this repository is provided without any warranties. It is important to note that the code has not been audited for potential security vulnerabilities.
> Using this code could potentially lead to loss of funds, compromised data, or asset risk.
> Exercise caution and use this code at your own risk. Please refer to the [LICENSE](./LICENSE) file for details about the terms and conditions.
> The plugin for now is specifically designed to be used with [agents-fun-eliza](https://github.com/valory-xyz/agents-fun-eliza).

# Eliza Twitter Plugin

## Overview
Expand All @@ -24,7 +31,7 @@ This plugin provides:
- Incorporates Twitter engagement metrics for holistic decision-making.

### Services
The **TwitterService** integrates with the ElizaOS `client-twitter` module to:
The **TwitterService** integrates with the ElizaOS `agent-twitter-client` module to:

- Post tweets.
- Reply to tweets with conversational threads.
Expand Down Expand Up @@ -72,10 +79,10 @@ const result = await runtime.invokeAction('decideTokenAction', {

#### Reply to a Tweet

Use the `TwitterService` to reply to a specific tweet:
Use the `TwitterScraper` to reply to a specific tweet:

```typescript
await twitterService.buildConversationThread(tweet, maxReplies);
await twitterService.replyToTweet(id, message);
```


Expand All @@ -87,13 +94,6 @@ await twitterService.buildConversationThread(tweet, maxReplies);
- **constants/**: Stores shared constants and configurations.
- **types/**: Defines TypeScript interfaces and types.

### Running Tests
Use the following command to run the test suite:

```bash
pnpm test
```

## Contributing

Contributions are welcome! Please follow these steps:
Expand All @@ -116,4 +116,4 @@ Contributions are welcome! Please follow these steps:

### Contact

For support or inquiries, reach out to (mailto:[email protected]).
For support or inquiries, reach out to (mailto:[email protected]).
34 changes: 34 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Security Policy

This document outlines security procedures and general policies for the `plugin-memeooorr` project.

## Supported Versions

The following table shows which versions of `plugin-memeooorr` are currently being supported with security updates.

| Version | Supported |
|---------|--------------------|
| `n/a` | :white_check_mark: |
| `n/a` | :x: |

## Reporting a Vulnerability

The `plugin-memeooorr` team and community take all security bugs in `plugin-memeooorr` seriously. Thank you for improving the security of `plugin-memeooorr`. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.

Report security bugs by emailing `[email protected]`.

The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavour to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.

Report security bugs in third-party modules to the person or team maintaining the module.

## Disclosure Policy

When the security team receives a security bug report, they will assign it to a primary handler. This person will coordinate the fix and release process, involving the following steps:

- Confirm the problem and determine the affected versions.
- Audit code to find any potential similar problems.
- Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible to PyPI.

## Comments on this Policy

If you have suggestions on how this process could be improved please submit a pull request.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"@elizaos/core": "0.1.7",
"safe-client": "workspace:*",
"agent-twitter-client": "^0.0.18",
"@safe-global/api-kit": "2.5.9",
"@safe-global/protocol-kit": "5.2.2",
"@safe-global/types-kit": "1.0.2",
"@safe-global/sdk-starter-kit": "1.1.5",
Expand Down
4 changes: 3 additions & 1 deletion src/actions/decideTwitterInteraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export const decideTwitterInteractionAction = (
currentState = await runtime.updateRecentMessageState(state);
}

elizaLogger.log("Fetching Twitter metadata");
elizaLogger.assert(
"Fetching Twitter metadata to decide on interaction",
);

const metadata: TwitterInteractionResponse | false =
await tweetProvider.get(runtime, message);
Expand Down
5 changes: 0 additions & 5 deletions src/actions/tokenDecisionAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ export const decideTokenAction = (
_params,
callback,
) => {
// if (message.content.action !== "TOKEN_ACTION") {
// elizaLogger.error("No runtime provided");
// return false;
// }

try {
if (!state) {
state = await runtime.composeState(message);
Expand Down
54 changes: 0 additions & 54 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,8 @@
export const PROVIDER_CONFIG = {
BIRDEYE_API: "https://public-api.birdeye.so",
TOKEN_SECURITY_ENDPOINT: "/defi/token_security?address=",
TOKEN_METADATA_ENDPOINT: "/defi/v3/token/meta-data/single?address=",
MARKET_SEARCH_ENDPOINT: "/defi/v3/token/trade-data/single?address=",
TOKEN_PRICE_CHANGE_ENDPOINT:
"/defi/v3/search?chain=solana&target=token&sort_by=price_change_24h_percent&sort_type=desc&verify_token=true&markets=Raydium&limit=20",
TOKEN_VOLUME_24_CHANGE_ENDPOINT:
"/defi/v3/search?chain=solana&target=token&sort_by=volume_24h_change_percent&sort_type=desc&verify_token=true&markets=Raydium&limit=20",
TOKEN_BUY_24_CHANGE_ENDPOINT:
"/defi/v3/search?chain=solana&target=token&sort_by=buy_24h_change_percent&sort_type=desc&verify_token=true&markets=Raydium&offset=0&limit=20",

TOKEN_SECURITY_ENDPOINT_BASE: "/defi/token_security?address=",
TOKEN_METADATA_ENDPOINT_BASE: "/defi/v3/token/meta-data/single?address=",
MARKET_SEARCH_ENDPOINT_BASE: "/defi/v3/token/trade-data/single?address=",
TOKEN_PRICE_CHANGE_ENDPOINT_BASE:
"/defi/v3/search?chain=base&target=token&sort_by=price_change_24h_percent&sort_type=desc&offset=0&limit=20",
TOKEN_VOLUME_24_ENDPOINT_BASE:
"/defi/v3/search?chain=base&target=token&sort_by=volume_24h_usd&sort_type=desc&offset=2&limit=20",
TOKEN_BUY_24_ENDPOINT_BASE:
"/defi/v3/search?chain=base&target=token&sort_by=buy_24h&sort_type=desc&offset=2&limit=20",

MAX_RETRIES: 3,
RETRY_DELAY: 2000,
};

// Add configuration for enabled chains
export const CHAIN_CONFIG = {
SOLANA_ENABLED: false, // Can be controlled via settings
BASE_ENABLED: true, // Can be controlled via settings
};

// Add Base chain configuration near other export constants
export const BASE_CONFIG = {
RPC_URL: process.env.EVM_PROVIDER_URL || "https://mainnet.base.org",
ROUTER_ADDRESS: "0x327Df1E6de05895d2ab08513aaDD9313Fe505d86", // Base Uniswap V2 Router
WETH_ADDRESS: "0x4200000000000000000000000000000000000006", // Base WETH
CHAIN_ID: 8453,
// Add Aerodrome-specific addresses
AERODROME: {
WETH: "0x4200000000000000000000000000000000000006",
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
},
};

export const CELO_CONFIG = {
RPC_URL: process.env.CELO_RPC_URL || "https://forno.celo.org",
CHAIN_ID: 42220,
ROUTER_ADDRESS: "0x1f98431c8ad98523631ae4a59f267346ea31f984",
WETH_ADDRESS: "0x471EcE3750Da237f93B8E339c536989b8978a438",
AERODROME: {
WETH: "0x471EcE3750Da237f93B8E339c536989b8978a438",
USDC: "0xceba9300f2b948710d2653dd7b07f33a8b32118c",
},
};

export const ACTIONS = {
START: "START",
TWITTER_INTERACTION: "TWITTER_INTERACTION",
Expand All @@ -64,9 +13,6 @@ export const ACTIONS = {

export default {
ACTIONS,
BASE_CONFIG,
CELO_CONFIG,
PROVIDER_CONFIG,
CHAIN_CONFIG,
};

Expand Down
21 changes: 0 additions & 21 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
export const SAFETY_LIMITS = {
MINIMUM_TRADE: 0.01, // Minimum 0.01 SOL per trade
MAX_POSITION_SIZE: 0.1, // Maximum 10% of token liquidity
MAX_SLIPPAGE: 0.05, // Maximum 5% slippage allowed
MIN_LIQUIDITY: 1000, // Minimum $1000 liquidity required
MIN_VOLUME: 2000, // Minimum $2000 24h volume required
MIN_TRUST_SCORE: 0.4, // Minimum trust score to trade
STOP_LOSS: 0.2, // 20% stop loss trigger
CHECK_INTERVAL: 5 * 60 * 1000, // Check every 5 minutes
TAKE_PROFIT: 0.12, // Take profit at 12% gain
TRAILING_STOP: 0.2, // 20% trailing stop from highest
PARTIAL_TAKE: 0.06, // Take 50% profit at 6% gain
REENTRY_DELAY: 60 * 60 * 1000, // Wait 1 hour before re-entering
MAX_ACTIVE_POSITIONS: 5, // Maximum concurrent positions
MIN_WALLET_BALANCE: 0.05, // Keep minimum 0.05 SOL in wallet
};

export const ANALYSIS_HISTORY_EXPIRY = 24 * 60 * 60 * 1000; // 24 hours in milliseconds

export const MAX_TWEETS_PER_HOUR = {
trade: 10,
market_search: 5,
};

export const MARKET_SEARCH_INTERVAL = 60 * 60 * 1000; // 1 hour in milliseconds

export const TOKENS_QUERY = `
query Tokens {
memeTokens {
Expand Down
40 changes: 0 additions & 40 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,9 @@ export * as actions from "./actions/index";
export * as providers from "./providers/index";
export * as types from "./types/index";

// // Consider exposing these settings as environment variables to allow users to provide custom configuration values.
// const config = {
// caching: {
// enabled: true,
// ttl: 3600000, // 1 hour
// maxSize: 1000,
// },
// security: {
// rateLimit: {
// enabled: true,
// maxRequests: 100,
// windowMs: 60000,
// },
// },
// maxConcurrent: 5, // Maximum concurrent requests
// maxRetries: 3, // Maximum retry attempts
// batchSize: 20, // Batch size for collection requests
// };

// function createMemeoorPlugin(): Plugin {
// // Initialize reusable CacheManager if caching is enabled

// return {
// name: "memeooorr",
// description: "Provides NFT collection information and market intelligence",
// providers: [
// tweetProvider,
// tokenProvider,
// tokenProvider,
// safeWalletProvider,
// ],
// actions: [
// decideTwitterInteractionAction(tweetProvider, twitterProvider),
// decideTokenAction(tokenProvider, safeWalletProvider),
// ],
// evaluators: [],
// };
// }
//
export const memeoorPlugin: Plugin = {
name: "memeooorr",
description: "Provides NFT collection information and market intelligence",
// providers: [tweetProvider, twitterProvider, tokenProvider, safeWalletProvider],
providers: [],
actions: [
decideTwitterInteractionAction(tweetProvider, twitterProvider),
Expand Down
13 changes: 4 additions & 9 deletions src/providers/safeaccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,16 @@ const MAX_HEART_VALUE = 20000000000000n;

let protocolKitInstance: Safe | null = null;

/**
*
* @param protocolKit
*/
export const getProtocolKit = async (protocolKit: Safe) => {
if (!protocolKitInstance) {
protocolKitInstance = protocolKit;
}
};

// export const protocolKit = Safe;

/**
* A Safe-based transaction provider.
*
Expand Down Expand Up @@ -399,13 +401,6 @@ export const safeAccountProvider: Provider = {

let summoned_token_nonce = undefined;

// if (decision.action === "summon") {
// summoned_token_nonce = await getTokenNonce(
// receipt.transactionHash,
// rpcUrl,
// );
// }

const actionSuccessMemory: Memory = {
id: stringToUuid(Date.now().toString()),
content: {
Expand Down
8 changes: 4 additions & 4 deletions src/providers/tokenProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ const tokenProvider: Provider = {

const scraper = new TwitterScraper(ts);

elizaLogger.log("Fetching latest tweets for user");
elizaLogger.assert("Fetching latest tweets for user");
const tweet = await scraper.getUserLatestTweet(username);
if (!tweet) {
elizaLogger.error("Failed to fetch latest tweet");
return false;
}

elizaLogger.log("Fetch current memecoins");
elizaLogger.assert("Fetch current memecoins");
const memeCoins: MemeCoin[] = await scraper.getTokens(
subUrl,
rpcUrl,
Expand All @@ -56,7 +56,7 @@ const tokenProvider: Provider = {
return false;
}

elizaLogger.log("Fetch replies to tweets");
elizaLogger.assert("Fetch replies to tweets");
const replies = await scraper.getTweetReplies(username, tweet);

// fetch available balance
Expand All @@ -72,7 +72,7 @@ const tokenProvider: Provider = {
replies: replies,
balance: balance.toString(),
};
elizaLogger.debug("Tweet retrieved successfully");
elizaLogger.success("Token interaction payload retrieved successfully");
return result;
} catch (error) {
elizaLogger.error("Failed to fetch tweet:", error);
Expand Down
Loading