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.
- See all plugins
- Installation
- Usage
- Examples
- How to create a plugin
- How to add a chain
- How to add a wallet provider
- Packages
- Install the core package
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
- Configure your wallet
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);
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.
Use the create-plugin
command to generate all the necessary files and configuration for a new plugin
# Create a plugin with default type (any)
pnpm create-plugin -n your-plugin-name
# Create a plugin for a specific chain type
pnpm create-plugin -n your-plugin-name -t evm # For EVM chains
pnpm create-plugin -n your-plugin-name -t solana # For 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
-
1. Define your plugin extending the PluginBase class.
import { PluginBase, WalletClientBase } from "@goat-sdk/core";
// For a chain-agnostic plugin we use the WalletClientBase interface, for a chain-specific plugin we use the EVMWalletClient, SolanaWalletClient, or corresponding interfaces
export class MyPlugin extends PluginBase<WalletClientBase> {
constructor() {
// We define the name of the plugin
super("myPlugin", []);
}
// We define the chain support for the plugin, in this case we support all chains
supportsChain = (chain: Chain) => true;
}
// We export a factory function to create a new instance of the plugin
export const myPlugin = () => new MyPlugin();
There are two ways to add tools to the plugin:
- Using the
@Tool
decorator on our own class - Using the
getTools
andcreateTool
functions to create tools dynamically
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() {
// We define the name of the plugin
super("myPlugin", [new MyTools()]);
}
// We define the chain support for the plugin, in this case we support all chains
supportsChain = (chain: Chain) => true;
}
// We export a factory function to create a new instance of the plugin
export const myPlugin = () => new MyPlugin();
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";
// Since we are creating a chain-agnostic plugin, we can use the WalletClientBase interface
export class MyPlugin extends PluginBase<WalletClientBase> {
constructor() {
// We define the name of the plugin
super("myPlugin", []);
}
// We define the chain support for the plugin, in this case we support all chains
supportsChain = (chain: Chain) => true;
getTools(walletClient: WalletClientBase) {
return [
// Create tool requires two arguments:
// 1. The tool metadata (name, description, parameters)
// 2. The tool method (the function that will be executed when the tool is used)
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;
},
),
];
}
}
// We export a factory function to create a new instance of the plugin
export const myPlugin = () => new MyPlugin();
import { getOnChainTools } from '@goat-sdk/adapter-vercel-ai';
import { myPlugin } from './your-plugin-path/signMessagePlugin'; // Path to your plugin
const wallet = /* Initialize your wallet client */;
const tools = getOnChainTools({
wallet: viem(wallet), // or smartwallet(wallet), solana(wallet), etc.
plugins: [
myPlugin(),
// ...other plugins
],
});
// Prompt: Sign the message "Sign the message 'Go out and eat grass 🐐'"
- Share your plugin with others!
- Open a PR to add it to the plugins registry in the GOAT SDK.
Add your chain to the Chain.ts
file in the core package.
/**
* @param type - "evm" or "solana", extend this union as needed (e.g., "sui")
* @param id - Chain ID, optional for EVM
*/
export type Chain = EvmChain | SolanaChain | AptosChain | ChromiaChain | FuelChain | MyAwesomeChain;
export type MyAwesomeChain = {
type: "my-awesome-chain";
};
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 {
// Add your chain's methods here
abstract getChain(): MyAwesomeChain;
sendTransaction: (transaction: AwesomeChainTransaction) => Promise<Transaction>;
read: (query: AwesomeChainQuery) => Promise<AwesomeChainResponse>;
}
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, // Define the parameters schema
},
// Implement the method
(parameters: z.infer<typeof sendAWESOMETOKENParametersSchema>) => sendAWESOMETOKENMethod(walletClient, parameters),
);
return [sendTool];
}
}
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 {
// Implement the methods here
}
// Export the wallet client with a factory function
export const myAwesomeChain = () => new MyAwesomeChainKeyPairWalletClient();
Submit a PR to add your wallet provider to the wallets directory.
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:
- EVMWalletClient for all EVM chains
- EVMSmartWalletClient for EVM smart wallets
- SolanaWalletClient for Solana
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.
NPM package | |
---|---|
Core | @goat-sdk/core |
Wallet | NPM package |
---|---|
EVM | @goat-sdk/wallet-evm |
Viem | @goat-sdk/wallet-evm-viem |
Solana | @goat-sdk/wallet-solana |
Crossmint (smart and custodial wallets) | @goat-sdk/wallet-crossmint |
Aptos | @goat-sdk/wallet-aptos |
Chromia | @goat-sdk/wallet-chromia |
Cosmos | @goat-sdk/wallet-cosmos |
Fuel | @goat-sdk/wallet-fuel |
Sui | @goat-sdk/wallet-sui |
Starknet | @goat-sdk/wallet-starknet |
Zilliqa | @goat-sdk/wallet-zilliqa |
Adapter | NPM package |
---|---|
AI SDK | @goat-sdk/adapter-ai-sdk |
Langchain | @goat-sdk/adapter-langchain |
ElevenLabs | @goat-sdk/adapter-elevenlabs |
LlamaIndex | @goat-sdk/adapter-llamaindex |
Model Context Protocol | @goat-sdk/adapter-model-context-protocol |
*Eliza, ZerePy and GAME have direct integrations on their respective repos.
Plugin | Tools | NPM package |
---|---|---|
0x | Get quotes and swap on 0x | @goat-sdk/plugin-0x |
1inch | Get the balances of a wallet using 1inch API | @goat-sdk/plugin-1inch |
Allora | Get price predictions using Allora API | @goat-sdk/plugin-allora |
Avnu | Swap tokens on Starknet | @goat-sdk/plugin-avnu |
Balancer | Swap tokens and provide liquidity on Balancer | @goat-sdk/plugin-balancer |
Balmy | Swap tokens on Balmy | @goat-sdk/plugin-balmy |
BirdEye | Get token insights using BirdEye API | @goat-sdk/plugin-birdeye |
CoinGecko | Get coin information using CoinGecko API | @goat-sdk/plugin-coingecko |
Coinmarketcap | Get coin information using Coinmarketcap API | @goat-sdk/plugin-coinmarketcap |
Cosmosbank | Interact with Cosmos tokens | @goat-sdk/plugin-cosmosbank |
Crossmint Headless Checkout | Purchase any NFT on any chain using Crossmint | @goat-sdk/plugin-crossmint-headless-checkout |
Crossmint Mint, Faucet, Wallets | Create a wallet, mint tokens and get test tokens on any chain using Crossmint | @goat-sdk/plugin-crossmint-mint-faucet-wallets |
DeBridge | Bridge tokens on DeBridge | @goat-sdk/plugin-debridge |
Dexscreener | Get token information using Dexscreener API | @goat-sdk/plugin-dexscreener |
ERC20 | Interact with any ERC20 token | @goat-sdk/plugin-erc20 |
ERC721 | Interact with any ERC721 token | @goat-sdk/plugin-erc721 |
Etherscan | Get transaction information using Etherscan API | @goat-sdk/plugin-etherscan |
Farcaster | Read and post casts on Farcaster | @goat-sdk/plugin-farcaster |
Ionic | Borrow and lend on Ionic | @goat-sdk/plugin-ionic |
Ironclad | Create positions on Ironclad | @goat-sdk/plugin-ironclad |
JSON RPC | Call any JSON RPC endpoint | @goat-sdk/plugin-json-rpc |
Jupiter | Swap tokens on Jupiter | @goat-sdk/plugin-jupiter |
KIM | Swap tokens on KIM | @goat-sdk/plugin-kim |
Lulo | Deposit USDC on Lulo | @goat-sdk/plugin-lulo |
Meteora | Create liquidity pools on Meteora | @goat-sdk/plugin-meteora |
Mode Governance | Create a governance proposal on Mode | @goat-sdk/plugin-mode-governance |
Mode Voting | Vote on a governance proposal on Mode | @goat-sdk/plugin-mode-voting |
Mode Spray | Spray tokens on Mode | @goat-sdk/plugin-mode-spray |
Nansen | Get Nansen information using Nansen API | @goat-sdk/plugin-nansen |
OpenSea | Get nft and sales information using OpenSea API | @goat-sdk/plugin-opensea |
Orca | Create positions on Orca | @goat-sdk/plugin-orca |
Polymarket | Bet on Polymarket | @goat-sdk/plugin-polymarket |
Pump.fun | Launch a token on Pump.fun | @goat-sdk/plugin-pump-fun |
Renzo | Create a position on Renzo | @goat-sdk/plugin-renzo |
Rugcheck | Check SPL token validity on Rugcheck | @goat-sdk/plugin-rugcheck |
SNS | Interact with SNS | @goat-sdk/plugin-sns |
Solana Magic Eden | Purchase NFTs on Magic Eden | @goat-sdk/plugin-solana-magiceden |
Solana NFTs | Get NFT information using Solana NFTs API | @goat-sdk/plugin-solana-nfts |
SPL Tokens | Interact with SPL tokens | @goat-sdk/plugin-spl-tokens |
Starknet Token | Interact with Starknet tokens | @goat-sdk/plugin-starknet-token |
Superfluid | Create streams with Superfluid | @goat-sdk/plugin-superfluid |
Tensor | Purchase tokens on Tensor | @goat-sdk/plugin-tensor |
Uniswap | Swap tokens on Uniswap | @goat-sdk/plugin-uniswap |
Velodrome | Create a position on Velodrome | @goat-sdk/plugin-velodrome |
Worldstore | Purchase physical assets on Worldstore | @goat-sdk/plugin-worldstore |
ZeroDev Global Address | Create a global address on ZeroDev | @goat-sdk/plugin-zero-dev-global-address |
Zilliqa | Interact with Zilliqa | @goat-sdk/plugin-zilliqa |