GOAT 🐐 (Typescript)

GOAT (Great Onchain Agent Toolkit) is a library that adds more than +200 onchain tools to your AI agent.
- +200 tools: DeFi (Uniswap, Jupiter, KIM, Orca, etc.), minting (OpenSea, MagicEden, etc.), betting (Polymarket, etc.), analytics (CoinGecko, BirdEye, Allora, etc.) and more
- Chains: EVM (Base, Polygon, Mode, Sei, etc.), Solana, Aptos, Chromia, Fuel, Sui, Starknet and Zilliqa
- Wallets: keypair, smart wallets (Crossmint, etc.), LIT, MPC (Coinbase, etc.)
- Agent Frameworks: AI SDK, Langchain, Eliza, ZerePy, GAME, ElevenLabs, etc.
Table of Contens
Installation
npm install @goat-sdk/core
- Depending on the type of wallet you want to use, install the corresponding wallet (see all wallets here):
npm install @goat-sdk/wallet-solana
- Install the plugins for the protocols you need (see all available plugins here)
npm install @goat-sdk/plugin-jupiter @goat-sdk/plugin-spl-tokens
- Install the adapter for the agent framework you want to use (see all available adapters here)
npm install @goat-sdk/adapter-ai-sdk
Usage
import { Connection, Keypair } from "@solana/web3.js";
const connection = new Connection(process.env.SOLANA_RPC_URL as string);
const keypair = Keypair.fromSecretKey(base58.decode(process.env.SOLANA_PRIVATE_KEY as string));
- Configure your tools for the framework you want to use
import { getOnChainTools } from "@goat-sdk/adapter-ai-sdk";
import { solana, sendSOL } from "@goat-sdk/wallet-solana";
import { jupiter } from "@goat-sdk/plugin-jupiter";
import { splToken } from "@goat-sdk/plugin-spl-token";
const tools = await getOnChainTools({
wallet: solana({
keypair,
connection,
}),
plugins: [
sendSOL(),
jupiter(),
splToken(),
],
});
- Plug into your agent framework
const result = await generateText({
model: openai("gpt-4o-mini"),
tools: tools,
maxSteps: 10,
prompt: "Swap 10 USDC for JLP",
});
console.log(result);
How to create a plugin
GOAT plugins enable your agent to interact with various blockchain protocols.
Plugins can be chain-specific (EVM, Solana, etc.) or chain-agnostic. If a plugin is chain-specific it will fail to compile when being used with a wallet of a different chain.
You can see all available plugins here.
Using the Plugin Generator
Use the create-plugin command to generate all the necessary files and configuration for a new plugin
pnpm create-plugin -n your-plugin-name
pnpm create-plugin -n your-plugin-name -t evm
pnpm create-plugin -n your-plugin-name -t solana
The command will generate:
- A
package.json with standard metadata and dependencies
- TypeScript configuration files (
tsconfig.json, tsup.config.ts)
- A basic plugin structure in the
src directory:
parameters.ts - Example parameters using Zod schema
your-plugin-name.service.ts - Service class with an example tool
your-plugin-name.plugin.ts - Plugin class extending PluginBase
index.ts - Exports for your plugin
Manual Creation
1. Define your plugin extending the PluginBase class.
import { PluginBase, WalletClientBase } from "@goat-sdk/core";
export class MyPlugin extends PluginBase<WalletClientBase> {
constructor() {
super("myPlugin", []);
}
supportsChain = (chain: Chain) => true;
}
export const myPlugin = () => new MyPlugin();
2. Add tools to the plugin
There are two ways to add tools to the plugin:
- Using the
@Tool decorator on our own class
- Using the
getTools and createTool functions to create tools dynamically
Option 1: Using the @Tool decorator
The @Tool decorator is a way to create tools in a more declarative way.
You can create a class and decorate its methods with the @Tool decorator to create tools.
The tool methods will receive the wallet client as the first argument and the parameters as the second argument.
import { Tool } from "@goat-sdk/core";
import { createToolParameters } from "@goat-sdk/core";
import { z } from "zod";
export class SignMessageParameters extends createToolParameters(
z.object({
message: z.string(),
}),
) {}
class MyTools {
@Tool({
name: "sign_message",
description: "Sign a message",
})
async signMessage(walletClient: WalletClientBase, parameters: SignMessageParameters) {
const signed = await walletClient.signMessage(parameters.message);
return signed.signedMessage;
}
}
Once we have our class we now need to import it in our plugin class.
export class MyPlugin extends PluginBase<WalletClientBase> {
constructor() {
super("myPlugin", [new MyTools()]);
}
supportsChain = (chain: Chain) => true;
}
export const myPlugin = () => new MyPlugin();
Option 2: Using the getTools and createTool functions
We will implement the getTools method in our plugin class.
Inside the method, we will return an array of tools created using the createTool function.
import { PluginBase, WalletClientBase, createTool } from "@goat-sdk/core";
export class MyPlugin extends PluginBase<WalletClientBase> {
constructor() {
super("myPlugin", []);
}
supportsChain = (chain: Chain) => true;
getTools(walletClient: WalletClientBase) {
return [
createTool(
{
name: "sign_message",
description: "Sign a message",
parameters: z.object({
message: z.string(),
}),
},
async (parameters) => {
const signed = await walletClient.signMessage(parameters.message);
return signed.signedMessage;
},
),
];
}
}
export const myPlugin = () => new MyPlugin();
3. Add the plugin to the agent
import { getOnChainTools } from '@goat-sdk/adapter-vercel-ai';
import { myPlugin } from './your-plugin-path/signMessagePlugin';
const wallet = ;
const tools = getOnChainTools({
wallet: viem(wallet),
plugins: [
myPlugin(),
],
});
Next steps
How to add a chain
1. Add the chain to the Chain.ts file
Add your chain to the Chain.ts file in the core package.
export type Chain = EvmChain | SolanaChain | AptosChain | ChromiaChain | FuelChain | MyAwesomeChain;
export type MyAwesomeChain = {
type: "my-awesome-chain";
};
2. Create a new wallet provider package
Create a new package in the wallets directory with the name of your chain (e.g. my-awesome-chain) or copy an existing one (e.g. evm).
In this package you will define the abstract class for your chain's wallet client which will extend the WalletClientBase class defined in the core package.
WalletClientBase only includes the methods that are supported by all chains such as:
getAddress
getChain
signMessage
balanceOf
As well as includes the getCoreTools method which returns the core tools for the chain.
export abstract class MyAwesomeChainWalletClient extends WalletClientBase {
abstract getChain(): MyAwesomeChain;
sendTransaction: (transaction: AwesomeChainTransaction) => Promise<Transaction>;
read: (query: AwesomeChainQuery) => Promise<AwesomeChainResponse>;
}
3. Create a plugin to allow sending your native token to a wallet
Create a plugin to allow sending your native token to a wallet. Create a file in the same package as your wallet client and create a new file like send<native-token>.plugin.ts.
Implement the core plugin.
export class SendAWESOMETOKENPlugin extends PluginBase<MyAwesomeChainWalletClient> {
constructor() {
super("sendAWESOMETOKEN", []);
}
supportsChain = (chain: Chain) => chain.type === "my-awesome-chain";
getTools(walletClient: MyAwesomeChainWalletClient) {
const sendTool = createTool(
{
name: `send_myawesometoken`,
description: `Send MYAWESOMETOKEN to an address.`,
parameters: sendAWESOMETOKENParametersSchema,
},
(parameters: z.infer<typeof sendAWESOMETOKENParametersSchema>) => sendAWESOMETOKENMethod(walletClient, parameters),
);
return [sendTool];
}
}
4. Implement the wallet client
Extend your abstract class with the methods you need to implement and create your first wallet client! (e.g MyAwesomeChainKeyPairWalletClient)
export class MyAwesomeChainKeyPairWalletClient extends MyAwesomeChainWalletClient {
}
export const myAwesomeChain = () => new MyAwesomeChainKeyPairWalletClient();
5. Submit a PR
Submit a PR to add your wallet provider to the wallets directory.
How to add a wallet provider
If you don't see your wallet provider supported, you can easily integrate it by implementing the specific WalletClient interface for the chain and type of wallet you want to support:
Checkout here how the viem client implementation.
If you would like to see your wallet provider supported, please open an issue or submit a PR.
Packages
Core
Wallets
Agent Framework Adapters
*Eliza, ZerePy and GAME have direct integrations on their respective repos.
Plugins