Skip to content

Commit

Permalink
feat: add fetch balances action
Browse files Browse the repository at this point in the history
  • Loading branch information
KacperKoza343 committed Jan 10, 2025
1 parent 82607be commit 8c70138
Show file tree
Hide file tree
Showing 7 changed files with 1,578 additions and 1,176 deletions.
181 changes: 181 additions & 0 deletions packages/plugin-cosmos/src/actions/fetch-balance/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { HandlerCallback, IAgentRuntime, Memory, State } from "@elizaos/core";
import { initWalletChainsData } from "../../providers/wallet/utils";
import { cosmosTransferTemplate } from "../../templates";
import type {
ICosmosPluginOptions,
ICosmosWalletChains,
} from "../../shared/interfaces";
import { FetchBalancesActionService } from "./services/fetch-balance";

export const fetchBalancesAction = (pluginOptions: ICosmosPluginOptions) => ({
name: "FETCH_BALANCES",
description: "Fetch balances for all connected chains",
handler: async (
_runtime: IAgentRuntime,
_message: Memory,
state: State,
_options: { [key: string]: unknown },
_callback?: HandlerCallback
) => {
try {
const walletProvider: ICosmosWalletChains =
await initWalletChainsData(_runtime);

const action = new FetchBalancesActionService(walletProvider);

const transferResp = await action.execute(
pluginOptions?.customChainData
);

console.log(transferResp);

if (_callback) {
await _callback({
text: `Successfully fetched balances`,
content: {
success: true,
},
});

const newMemory: Memory = {
userId: _message.agentId,
agentId: _message.agentId,
roomId: _message.roomId,
content: {
text: `Successfully fetched balances`,
},
};

await _runtime.messageManager.createMemory(newMemory);
}
return true;
} catch (error) {
console.error("Error during token transfer:", error);

if (_callback) {
await _callback({
text: `Error while fetching balance: ${error.message}`,
content: { error: error.message },
});
}

const newMemory: Memory = {
userId: _message.agentId,
agentId: _message.agentId,
roomId: _message.roomId,
content: {
text: `Balance fetch failed`,
},
};

await _runtime.messageManager.createMemory(newMemory);

return false;
}
},
template: cosmosTransferTemplate,
validate: async (runtime: IAgentRuntime) => {
const mnemonic = runtime.getSetting("COSMOS_RECOVERY_PHRASE");
const availableChains = runtime.getSetting("COSMOS_AVAILABLE_CHAINS");
const availableChainsArray = availableChains?.split(",");

return !(mnemonic && availableChains && availableChainsArray.length);
},
examples: [
[
{
user: "{{user1}}",
content: {
text: "Fetch balances",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "Do you confirm the transfer action?",
action: "FETCH_BALANCES",
},
},
{
user: "{{user1}}",
content: {
text: "Yes",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "",
action: "FETCH_BALANCES",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "Display my wallet balances",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "Do you confirm the transfer action?",
action: "FETCH_BALANCES",
},
},
{
user: "{{user1}}",
content: {
text: "Yes",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "",
action: "FETCH_BALANCES",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "Show me my wallet balances",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "Do you confirm the transfer action?",
action: "FETCH_BALANCES",
},
},
{
user: "{{user1}}",
content: {
text: "Yes",
action: "FETCH_BALANCES",
},
},
{
user: "{{user2}}",
content: {
text: "",
action: "FETCH_BALANCES",
},
},
],
],
similes: [
"COSMOS_FETCH_ACCOUNT_BALANCE",
"COSMOS_GET_BALANCE",
"COSMOS_GET_WALLET_BALANCE",
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { getChainByChainName } from "@chain-registry/utils";
import type {
ICosmosActionService,
ICosmosPluginCustomChainData,
ICosmosWalletChains,
} from "../../../shared/interfaces.ts";
import { assets, chains } from "chain-registry";
import { balanceFetcher } from "../../../shared/services/balance-fetcher.ts";
import { Coin } from "@cosmjs/proto-signing";

export class FetchBalancesActionService implements ICosmosActionService {
constructor(private cosmosWalletChains: ICosmosWalletChains) {
this.cosmosWalletChains = cosmosWalletChains;
}

async execute(
customChains?: ICosmosPluginCustomChainData[]
): Promise<{ chainName: string; balances: Coin[] }[]> {
const chainRegisteryChainsWithCustomChains = [...chains];
const chainRegisteryAssetsWithCustomAssets = [...assets];

if (customChains) {
chainRegisteryChainsWithCustomChains.push(
...customChains.map(({ chainData }) => chainData)
);
chainRegisteryAssetsWithCustomAssets.push(
...customChains.map(({ assets }) => assets)
);
}

const chainsDetails = Object.keys(
this.cosmosWalletChains.walletChainsData
)
.map((chainName) => getChainByChainName(chains, chainName))
.filter(Boolean);

return Promise.all(
chainsDetails.map(async (chainDetails) => {
const addressForGivenChain =
await this.cosmosWalletChains.getWalletAddress(
chainDetails.chain_name
);

const balanceForGivenChain = await balanceFetcher(
chainDetails.apis.rpc[0].address,
addressForGivenChain
);

return {
chainName: chainDetails.chain_name,
balances: balanceForGivenChain,
};
})
);
}
}
6 changes: 5 additions & 1 deletion packages/plugin-cosmos/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Plugin } from "@elizaos/core";
import { createTransferAction } from "./actions/transfer";
import { createCosmosWalletProvider } from "./providers/wallet";
import { ICosmosPluginOptions } from "./shared/interfaces";
import { fetchBalancesAction } from "./actions/fetch-balance";

export const createCosmosPlugin = (
pluginOptions?: ICosmosPluginOptions
Expand All @@ -11,7 +12,10 @@ export const createCosmosPlugin = (
providers: [createCosmosWalletProvider(pluginOptions)],
evaluators: [],
services: [],
actions: [createTransferAction(pluginOptions)],
actions: [
createTransferAction(pluginOptions),
fetchBalancesAction(pluginOptions),
],
});

export default createCosmosPlugin;
6 changes: 6 additions & 0 deletions packages/plugin-cosmos/src/shared/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,9 @@ export interface ICosmosWalletChains {
export interface ICosmosWalletChainsData {
[chainName: string]: ICosmosChainWallet;
}

export interface Coin {
denom: string;
amount: string;
exp?: number;
};
14 changes: 14 additions & 0 deletions packages/plugin-cosmos/src/shared/services/balance-fetcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { cosmos } from "interchain";
import type { Coin } from "@cosmjs/proto-signing";

export const balanceFetcher = async (rpcEndpoint: string, address: string) => {
const client = await cosmos.ClientFactory.createRPCQueryClient({
rpcEndpoint,
});

const allBalances = await client.cosmos.bank.v1beta1.allBalances({
address,
});

return allBalances.balances as Coin[];
};
23 changes: 23 additions & 0 deletions packages/plugin-cosmos/src/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,26 @@ Example reponse for the input: "Make transfer 0.0001 OM to mantra1pcnw46km8m5amv
Now respond with a JSON markdown block containing only the extracted values.
`;

export const cosmosFetchBalancesTemplate = `Given the recent messages and cosmos wallet information below:
{{recentMessages}}
{{walletInfo}}
Extract the following information about the requested transfer:
1. **Chain name**:
- Identify the chain mentioned in the instruction where the transfer will take place (e.g., carbon, axelar, cosmoshub).
- Provide this as a string.
Respond with a JSON markdown block containing only the extracted values. All fields except 'token' are required:
\`\`\`json
{
"chainName": string // The chain name.
\`\`\`
Example reponse for the input: "Fetch my balance on axelar chain", the response should be:
\`\`\`json
{
"chainName": "axelar"
\`\`\`
Now respond with a JSON markdown block containing only the extracted values.
`;
Loading

0 comments on commit 8c70138

Please sign in to comment.