Skip to content

Commit

Permalink
wallet mfers
Browse files Browse the repository at this point in the history
  • Loading branch information
lalalune committed Oct 23, 2024
1 parent 8cf7157 commit 93cde1a
Show file tree
Hide file tree
Showing 11 changed files with 909 additions and 581 deletions.
26 changes: 26 additions & 0 deletions src/clients/discord/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,32 @@ export class DiscordClient extends EventEmitter {
`${reaction.message.id}-${user.id}-${emoji}`,
);

// ensure the user id and room id are valid
if (!userIdUUID || !roomId) {
console.error("Invalid user id or room id");
return;
}
const agentId = this.runtime.agentId;
const userName = reaction.message.author.username;
const name = reaction.message.author.displayName;
await Promise.all([

this.runtime.ensureUserExists(
agentId,
this.client.user.username,
this.runtime.character.name,
"discord",
),
this.runtime.ensureUserExists(userIdUUID, userName, name, "discord"),
this.runtime.ensureRoomExists(roomId),
]);

await Promise.all([
this.runtime.ensureParticipantInRoom(userIdUUID, roomId),
this.runtime.ensureParticipantInRoom(agentId, roomId),
]);


// Save the reaction as a message
await this.runtime.messageManager.createMemory({
id: reactionUUID, // This is the ID of the reaction message
Expand Down
4 changes: 2 additions & 2 deletions src/clients/discord/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,9 +641,9 @@ export class MessageManager {
serverUrl: this.runtime.getSetting("X_SERVER_URL") ?? this.runtime.serverUrl,
token: this.runtime.getSetting("XAI_API_KEY") ?? this.runtime.token,
model: this.runtime.getSetting("XAI_MODEL") ? this.runtime.getSetting("XAI_MODEL") : "gpt-4o-mini",
temperature: 1.2,
temperature: 0.7,
frequency_penalty: 1.5,
presence_penalty: 0.8,
presence_penalty: 1.5,
});

if (!response) {
Expand Down
12 changes: 8 additions & 4 deletions src/clients/discord/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ About {{agentName}}:
# INSTRUCTIONS: Determine if {{agentName}} should respond to the message and participate in the conversation. Do not comment. Just respond with "RESPOND" or "IGNORE" or "STOP".
# RESPONSE EXAMPLES
<user 1>: I just saw a really great movie
<user 2>: Oh? Which movie?
Result: [IGNORE]
{{agentName}}: Oh, this is my favorite scene
<user 1>: sick
<user 2>: wait, why is it your favorite scene
Expand Down Expand Up @@ -120,10 +124,10 @@ Unless directly responding to a user, respond with [IGNORE] to messages that are
If a user asks {{agentName}} to be quiet, respond with [STOP]
If {{agentName}} concludes a conversation and isn't part of the conversation anymore, respond with [STOP]
{{recentMessages}}
IMPORTANT: {{agentName}} is particularly sensitive about being annoying, so if there is any doubt, it is better to respond with [IGNORE].
If {{agentName}} is conversing with a user and they have not asked to stop, it is better to respond with [RESPOND].
If {{agentName}} is interactived with or challenged they should respond with [RESPOND].
# INSTRUCTIONS: Choose the option that best describes {{agentName}}'s response to the last message.
{{recentMessages}}
# INSTRUCTIONS: Choose the option that best describes {{agentName}}'s response to the last message. Ignore messages if they are addressed to someone else.
` + shouldRespondFooter;
4 changes: 2 additions & 2 deletions src/clients/discord/voice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,9 @@ export class VoiceManager extends EventEmitter {
serverUrl: this.runtime.getSetting("X_SERVER_URL") ?? this.runtime.serverUrl,
token: this.runtime.getSetting("XAI_API_KEY") ?? this.runtime.token,
model: this.runtime.getSetting("XAI_MODEL") ? this.runtime.getSetting("XAI_MODEL") : "gpt-4o-mini",
temperature: 1.2,
temperature: 0.7,
frequency_penalty: 1.5,
presence_penalty: 0.8,
presence_penalty: 1.5,
});

response.source = "discord";
Expand Down
4 changes: 2 additions & 2 deletions src/clients/twitter/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class ClientBase extends EventEmitter {
lastCheckedTweetId: number | null = null;
tweetCacheFilePath = "tweetcache/latest_checked_tweet_id.txt";
imageDescriptionService: ImageDescriptionService;
temperature: number = 1.3;
temperature: number = 0.5;
dryRun: boolean = false;

private tweetCache: Map<string, Tweet> = new Map();
Expand Down Expand Up @@ -240,7 +240,7 @@ export class ClientBase extends EventEmitter {
const userId = await this.requestQueue.add(
async () => {
// wait 3 seconds before getting the user id
await new Promise((resolve) => setTimeout(resolve, 3000));
await new Promise((resolve) => setTimeout(resolve, 10000));
try{

return await this.twitterClient.getUserIdByScreenName(
Expand Down
1,224 changes: 661 additions & 563 deletions src/core/defaultCharacter.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/core/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,10 @@ export class AgentRuntime implements IAgentRuntime {
// if the model includes llama, set reptition_penalty to frequency_penalty
if (model.includes("llama")) {
(requestOptions.body as any).repetition_penalty = frequency_penalty;
} else {
(requestOptions.body as any).frequency_penalty = frequency_penalty;
(requestOptions.body as any).presence_penalty = presence_penalty;
// (requestOptions.body as any).logit_bias = logit_bias;
}

// stringify the body
Expand Down
102 changes: 102 additions & 0 deletions src/providers/balances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// TokenBalanceProvider.ts
import { Connection, PublicKey } from "@solana/web3.js";
import { getTokenBalances, getTokenPriceInSol } from "../services/tokenUtils";
import fetch from "cross-fetch";

interface Item {
name: string;
symbol: string;
decimals: number;
balance: string;
uiAmount: string;
priceUSD: string;
valueUSD: string;
}
interface walletPortfolio {
totalUsd: string;
items: Array<Item>;
}
interface price {
usd: string;
}
interface Prices {
solana: price;
bitcoin: price;
ethereum: price;

}
const API_Key = ""
export default class WalletProvider {
private connection: Connection;
private walletPublicKey: PublicKey;

constructor(connection: Connection, walletPublicKey: PublicKey) {
this.connection = connection;
this.walletPublicKey = walletPublicKey;
}

async getFormattedTokenBalances(): Promise<string> {
const tokenBalances = await getTokenBalances(this.connection, this.walletPublicKey);

let formattedBalances = "Token Balances:\n";
let totalValueInSol = 0;

for (const [tokenName, balance] of Object.entries(tokenBalances)) {
const tokenPrice = await getTokenPriceInSol(tokenName);
const totalValue = balance * tokenPrice;
totalValueInSol += totalValue;

formattedBalances += `${tokenName}: ${balance} (${totalValue} SOL)\n`;
}

formattedBalances += `\nTotal Value: ${totalValueInSol} SOL`;

return formattedBalances;
}

async fetchPortfolioValue(walletPublicKey:string): Promise<walletPortfolio> {
try {
const options = {
method: 'GET',
headers: {
accept: 'application/json',
'x-chain': 'solana',
'X-API-KEY': API_Key
}
};
const walletPortfolio = await fetch(`https://public-api.birdeye.so/v1/wallet/token_list?wallet=${walletPublicKey}`,
options
);
const walletPortfolioJson = await walletPortfolio.json();
const data = walletPortfolioJson.data;
const totalUsd = data.totalUsd;
const items = data.items;
const walletPortfolioFormatted = {
totalUsd,
items
};
return walletPortfolioFormatted;
} catch (error) {
console.log(error);
}
}

async fetchPrices(): Promise<Prices> {
const apiUrl = 'https://api.coingecko.com/api/v3/simple/price';
const ids = 'solana,bitcoin,ethereum';
const vsCurrencies = 'usd';

try {
const response = await fetch(`${apiUrl}?ids=${ids}&vs_currencies=${vsCurrencies}`);

if (!response.ok) {
throw new Error('Failed to fetch prices');
}

const data = await response.json();
return data;
} catch (error) {
console.log('Error fetching prices:', error);
}
}
}
6 changes: 4 additions & 2 deletions src/providers/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { IAgentRuntime, Memory, Provider, State } from "../core/types.ts";

const time: Provider = {
get: async (_runtime: IAgentRuntime, _message: Memory, _state?: State) => {
const currentTime = new Date().toLocaleTimeString("en-US");
return "The current time is: " + currentTime;
const currentDate = new Date();
const currentTime = currentDate.toLocaleTimeString("en-US");
const currentYear = currentDate.getFullYear();
return `The current time is: ${currentTime}, ${currentYear}`;
},
};

Expand Down
99 changes: 96 additions & 3 deletions src/providers/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,66 @@
// TokenBalanceProvider.ts
import { getAccount, getAssociatedTokenAddress } from "@solana/spl-token";
import { Connection, PublicKey } from "@solana/web3.js";
import { getTokenBalances, getTokenPriceInSol } from "./tokenUtils";
import fetch from "cross-fetch";
import { IAgentRuntime, Memory, Provider, State } from "../core/types.ts";

export async function getTokenPriceInSol(tokenSymbol: string): Promise<number> {
const response = await fetch(`https://price.jup.ag/v6/price?ids=${tokenSymbol}`);
const data = await response.json();
return data.data[tokenSymbol].price;
}

async function getTokenBalance(
connection: Connection,
walletPublicKey: PublicKey,
tokenMintAddress: PublicKey
): Promise<number> {
const tokenAccountAddress = await getAssociatedTokenAddress(tokenMintAddress, walletPublicKey);

try {
const tokenAccount = await getAccount(connection, tokenAccountAddress);
const tokenAmount = tokenAccount.amount as unknown as number;
return tokenAmount;
} catch (error) {
console.error(`Error retrieving balance for token: ${tokenMintAddress.toBase58()}`, error);
return 0;
}
}

async function getTokenBalances(
connection: Connection,
walletPublicKey: PublicKey
): Promise<{ [tokenName: string]: number }> {
const tokenBalances: { [tokenName: string]: number } = {};

// Add the token mint addresses you want to retrieve balances for
const tokenMintAddresses = [
new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC
new PublicKey("So11111111111111111111111111111111111111112"), // SOL
// Add more token mint addresses as needed
];

for (const mintAddress of tokenMintAddresses) {
const tokenName = getTokenName(mintAddress);
const balance = await getTokenBalance(connection, walletPublicKey, mintAddress);
tokenBalances[tokenName] = balance;
}

return tokenBalances;
}

function getTokenName(mintAddress: PublicKey): string {
// Implement a mapping of mint addresses to token names
const tokenNameMap: { [mintAddress: string]: string } = {
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v": "USDC",
"So11111111111111111111111111111111111111112": "SOL",
// Add more token mint addresses and their corresponding names
};

return tokenNameMap[mintAddress.toBase58()] || "Unknown Token";
}

export { getTokenBalance, getTokenBalances };


interface Item {
name: string;
Expand Down Expand Up @@ -99,4 +158,38 @@ export class WalletProvider {
console.log('Error fetching prices:', error);
}
}
}
}


const walletProvider: Provider = {
get: async (runtime: IAgentRuntime, _message: Memory, _state?: State) => {
try {
const walletPublicKey = new PublicKey(runtime.getSetting("WALLET_PUBLIC_KEY"));
const connection = new Connection(runtime.getSetting("RPC_ENDPOINT"));

const provider = new WalletProvider(connection, walletPublicKey);
const portfolio = await provider.fetchPortfolioValue(walletPublicKey.toBase58());
const prices = await provider.fetchPrices();

let formattedBalances = `Wallet Address: ${walletPublicKey.toBase58()}\n\n`;
formattedBalances += `Total Portfolio Value: $${portfolio.totalUsd}\n\n`;
formattedBalances += "Token Balances:\n";

for (const item of portfolio.items) {
formattedBalances += `${item.name} (${item.symbol}): ${item.uiAmount} ($${item.valueUSD})\n`;
}

formattedBalances += "\nCurrent Prices:\n";
formattedBalances += `Solana: $${prices.solana.usd}\n`;
formattedBalances += `Bitcoin: $${prices.bitcoin.usd}\n`;
formattedBalances += `Ethereum: $${prices.ethereum.usd}\n`;

return formattedBalances;
} catch (error) {
console.error("Error fetching wallet information:", error);
return "Failed to fetch wallet information.";
}
},
};

export default walletProvider;
5 changes: 2 additions & 3 deletions src/services/tokenUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// tokenUtils.ts
import { Connection, PublicKey, ParsedAccountData, TokenAmount } from "@solana/web3.js";
import { getAccount, getAssociatedTokenAddress } from "@solana/spl-token";
import { Connection, PublicKey } from "@solana/web3.js";

export async function getTokenPriceInSol(tokenSymbol: string): Promise<number> {
const response = await fetch(`https://price.jup.ag/v6/price?ids=${tokenSymbol}`);
Expand Down Expand Up @@ -58,4 +57,4 @@ function getTokenName(mintAddress: PublicKey): string {
return tokenNameMap[mintAddress.toBase58()] || "Unknown Token";
}

export { getTokenBalance, getTokenBalances };
export { getTokenBalance, getTokenBalances };

0 comments on commit 93cde1a

Please sign in to comment.