Skip to content

Commit

Permalink
better
Browse files Browse the repository at this point in the history
  • Loading branch information
mPaella committed Dec 9, 2024
1 parent e980ef8 commit d6ca2bb
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 48 deletions.
14 changes: 10 additions & 4 deletions typescript/packages/plugins/spl-token/src/methods/transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@ import type { SolanaWalletClient } from "@goat-sdk/core";
import {
createAssociatedTokenAccountInstruction,
createTransferCheckedInstruction,
createTransferInstruction,
getAssociatedTokenAddressSync,
} from "@solana/spl-token";
import { type Connection, PublicKey, type TransactionInstruction } from "@solana/web3.js";
import type { NetworkSpecificToken } from "../tokens";
import type { SolanaNetwork } from "../tokens";
import { doesAccountExist } from "../utils/doesAccountExist";
import { getTokenByMintAddress } from "../utils/getTokenByMintAddress";

export async function transfer(
connection: Connection,
network: SolanaNetwork,
walletClient: SolanaWalletClient,
to: string,
token: NetworkSpecificToken,
tokenMintAddress: string,
amount: string,
) {
const tokenMintPublicKey = new PublicKey(token.mintAddress);
const token = getTokenByMintAddress(tokenMintAddress, network);
if (!token) {
throw new Error(`Token with mint address ${tokenMintAddress} not found`);
}

const tokenMintPublicKey = new PublicKey(tokenMintAddress);
const fromPublicKey = new PublicKey(walletClient.getAddress());
const toPublicKey = new PublicKey(to);

Expand Down
17 changes: 10 additions & 7 deletions typescript/packages/plugins/spl-token/src/parameters.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { z } from "zod";
import { splTokenSymbolSchema } from "./tokens";

export const getBalanceParametersSchema = z.object({
wallet: z.string().describe("The address to get the balance of"),
export const getTokenMintAddressBySymbolParametersSchema = z.object({
symbol: splTokenSymbolSchema.describe("The symbol of the token to get the mint address of"),
});

export const transferParametersSchema = z.object({
to: z.string().describe("The address to transfer the token to"),
amount: z.string().describe("The amount of tokens to transfer"),
export const getTokenBalanceByMintAddressParametersSchema = z.object({
walletAddress: z.string().describe("The address to get the balance of"),
mintAddress: z.string().describe("The mint address of the token to get the balance of"),
});

export const getTokenBalanceByMintAddressParametersSchema = getBalanceParametersSchema.extend({
mintAddress: z.string().describe("The mint address of the token to get the balance of"),
export const transferTokenByMintAddressParametersSchema = z.object({
mintAddress: z.string().describe("The mint address of the token to transfer"),
to: z.string().describe("The address to transfer the token to"),
amount: z.string().describe("The amount of tokens to transfer"),
});
8 changes: 2 additions & 6 deletions typescript/packages/plugins/spl-token/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ import { getTokensForNetwork } from "./utils/getTokensForNetwork";
import { getTools } from "./utils/getTools";

export function splToken({
tokens,
connection,
network,
}: { tokens: Token[]; connection: Connection; network: SolanaNetwork }): Plugin<SolanaWalletClient> {
}: { connection: Connection; network: SolanaNetwork }): Plugin<SolanaWalletClient> {
return {
name: "splToken",
supportsSmartWallets: () => false,
supportsChain: (chain) => chain.type === "solana",
getTools: async () => {
const tokenList = getTokensForNetwork(network, tokens);
return getTools(tokenList, connection);
},
getTools: async () => getTools(connection, network),
};
}
11 changes: 9 additions & 2 deletions typescript/packages/plugins/spl-token/src/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { z } from "zod";

export type SolanaNetwork = "devnet" | "mainnet";

export const splTokenSymbolSchema = z.enum(["USDC"]);
export type SplTokenSymbol = z.infer<typeof splTokenSymbolSchema>;

export type Token = {
decimals: number;
symbol: string;
symbol: SplTokenSymbol;
name: string;
mintAddresses: Record<SolanaNetwork, string | null>;
};
Expand All @@ -14,10 +19,12 @@ export type NetworkSpecificToken = Omit<Token, "mintAddresses"> & {

export const USDC: Token = {
decimals: 6,
symbol: "USDC",
symbol: splTokenSymbolSchema.Enum.USDC,
name: "USDC",
mintAddresses: {
devnet: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
mainnet: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
},
};

export const SPL_TOKENS: Token[] = [USDC];
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SPL_TOKENS, type SolanaNetwork } from "../tokens";
import { getTokensForNetwork } from "./getTokensForNetwork";

export function getTokenByMintAddress(mintAddress: string, network: SolanaNetwork) {
const tokensForNetwork = getTokensForNetwork(network, SPL_TOKENS);
const token = tokensForNetwork.find((token) => token.mintAddress === mintAddress);
return token || null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { SPL_TOKENS, type SolanaNetwork, type SplTokenSymbol } from "../tokens";
import { getTokensForNetwork } from "./getTokensForNetwork";

export function getTokenMintAddressBySymbol(symbol: SplTokenSymbol, network: SolanaNetwork) {
const tokensForNetwork = getTokensForNetwork(network, SPL_TOKENS);
const token = tokensForNetwork.find((token) => [token.symbol, token.symbol.toLowerCase()].includes(symbol));
return token?.mintAddress || null;
}
58 changes: 29 additions & 29 deletions typescript/packages/plugins/spl-token/src/utils/getTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,46 @@ import type { z } from "zod";
import { balanceOf } from "../methods/balance";
import { transfer } from "../methods/transfer";
import {
getBalanceParametersSchema,
getTokenBalanceByMintAddressParametersSchema,
transferParametersSchema,
getTokenMintAddressBySymbolParametersSchema,
transferTokenByMintAddressParametersSchema,
} from "../parameters";
import type { NetworkSpecificToken } from "../tokens";
import type { SolanaNetwork } from "../tokens";
import { getTokenMintAddressBySymbol } from "./getTokenMintAddressBySymbol";

export function getTools(
tokenList: NetworkSpecificToken[],
connection: Connection,
): DeferredTool<SolanaWalletClient>[] {
export function getTools(connection: Connection, network: SolanaNetwork): DeferredTool<SolanaWalletClient>[] {
const tools: DeferredTool<SolanaWalletClient>[] = [];

for (const token of tokenList) {
const balanceTool: DeferredTool<SolanaWalletClient> = {
name: `get_solana_${token.symbol}_balance`,
description: `This {{tool}} gets the balance of ${token.symbol}`,
parameters: getBalanceParametersSchema,
method: async (walletClient: SolanaWalletClient, parameters: z.infer<typeof getBalanceParametersSchema>) =>
balanceOf(connection, parameters.wallet, token.mintAddress),
};

const transferTool: DeferredTool<SolanaWalletClient> = {
name: `transfer_solana_${token.symbol}`,
description: `This {{tool}} transfers ${token.symbol}`,
parameters: transferParametersSchema,
method: async (walletClient: SolanaWalletClient, parameters: z.infer<typeof transferParametersSchema>) =>
transfer(connection, walletClient, parameters.to, token, parameters.amount),
};

tools.push(balanceTool, transferTool);
}
tools.push({
name: "get_token_mint_address_by_symbol",
description: "This {{tool}} gets the mint address of an SPL token by its symbol",
parameters: getTokenMintAddressBySymbolParametersSchema,
method: async (
walletClient: SolanaWalletClient,
parameters: z.infer<typeof getTokenMintAddressBySymbolParametersSchema>,
) => getTokenMintAddressBySymbol(parameters.symbol, network),
});

tools.push({
name: "get_solana_token_balance_by_mint_address",
description: "This {{tool}} gets the balance of an SPL token by its mint address",
name: "get_token_balance_by_mint_address",
description:
"This {{tool}} gets the balance of an SPL token by its mint address. Use get_token_mint_address_by_symbol to get the mint address first.",
parameters: getTokenBalanceByMintAddressParametersSchema,
method: async (
walletClient: SolanaWalletClient,
parameters: z.infer<typeof getTokenBalanceByMintAddressParametersSchema>,
) => balanceOf(connection, parameters.wallet, parameters.mintAddress),
) => balanceOf(connection, parameters.walletAddress, parameters.mintAddress),
});

tools.push({
name: "transfer_token_by_mint_address",
description:
"This {{tool}} transfers an SPL token by its mint address. Use get_token_mint_address_by_symbol to get the mint address first.",
parameters: transferTokenByMintAddressParametersSchema,
method: async (
walletClient: SolanaWalletClient,
parameters: z.infer<typeof transferTokenByMintAddressParametersSchema>,
) => transfer(connection, network, walletClient, parameters.to, parameters.mintAddress, parameters.amount),
});

return tools;
Expand Down

0 comments on commit d6ca2bb

Please sign in to comment.