mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-14 07:26:46 +00:00
fix: pump launch
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"docs": "typedoc src --out docs",
|
||||
"test": "ts-node test/index.ts"
|
||||
"test": "ts-node test/index.ts",
|
||||
"generate": "ts-node src/utils/keypair.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
@@ -16,6 +17,7 @@
|
||||
"@bonfida/spl-name-service": "^3.0.7",
|
||||
"@langchain/core": "^0.3.18",
|
||||
"@langchain/groq": "^0.1.2",
|
||||
"@langchain/langgraph": "^0.2.27",
|
||||
"@langchain/openai": "^0.3.13",
|
||||
"@metaplex-foundation/mpl-core": "^1.1.1",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^3.3.0",
|
||||
|
||||
49
pnpm-lock.yaml
generated
49
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ importers:
|
||||
'@langchain/groq':
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))
|
||||
'@langchain/langgraph':
|
||||
specifier: ^0.2.27
|
||||
version: 0.2.27(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))
|
||||
'@langchain/openai':
|
||||
specifier: ^0.3.13
|
||||
version: 0.3.13(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))
|
||||
@@ -107,6 +110,21 @@ packages:
|
||||
peerDependencies:
|
||||
'@langchain/core': '>=0.2.21 <0.4.0'
|
||||
|
||||
'@langchain/langgraph-checkpoint@0.0.13':
|
||||
resolution: {integrity: sha512-amdmBcNT8a9xP2VwcEWxqArng4gtRDcnVyVI4DsQIo1Aaz8e8+hH17zSwrUF3pt1pIYztngIfYnBOim31mtKMg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@langchain/core': '>=0.2.31 <0.4.0'
|
||||
|
||||
'@langchain/langgraph-sdk@0.0.31':
|
||||
resolution: {integrity: sha512-oYZWoC3x7vH9bAL1Y30XjtuWnic1j3knXD4BbldsY0chFLxwIT5i6/GMThNy3Oiwb4SB+c6gvaSuxBNDkp7dkw==}
|
||||
|
||||
'@langchain/langgraph@0.2.27':
|
||||
resolution: {integrity: sha512-7+PlVXlNpswzXzZp/k8O99YBN3zBkUdusfyxISkZ/gdXz1p5RySQEpKQ4EVIZnzBrZ98zZ3FArj4OWOgeF0EeA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
'@langchain/core': '>=0.2.36 <0.3.0 || >=0.3.9 < 0.4.0'
|
||||
|
||||
'@langchain/openai@0.3.13':
|
||||
resolution: {integrity: sha512-lfiauYttb1Vv1GVGDNZlse8475RUsKm9JJ7X9kMVtYoOQnK8xxzMVSrpW7HYLmJokrtVgF6STwRzNJI2gZ3uBw==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -368,6 +386,9 @@ packages:
|
||||
'@types/hast@3.0.4':
|
||||
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
|
||||
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
'@types/mdast@4.0.4':
|
||||
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
||||
|
||||
@@ -969,6 +990,10 @@ packages:
|
||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||
hasBin: true
|
||||
|
||||
uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
|
||||
v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
|
||||
@@ -1107,6 +1132,26 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
'@langchain/langgraph-checkpoint@0.0.13(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))':
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.18(openai@4.75.0(zod@3.23.8))
|
||||
uuid: 10.0.0
|
||||
|
||||
'@langchain/langgraph-sdk@0.0.31':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
p-queue: 6.6.2
|
||||
p-retry: 4.6.2
|
||||
uuid: 9.0.1
|
||||
|
||||
'@langchain/langgraph@0.2.27(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))':
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.18(openai@4.75.0(zod@3.23.8))
|
||||
'@langchain/langgraph-checkpoint': 0.0.13(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))
|
||||
'@langchain/langgraph-sdk': 0.0.31
|
||||
uuid: 10.0.0
|
||||
zod: 3.23.8
|
||||
|
||||
'@langchain/openai@0.3.13(@langchain/core@0.3.18(openai@4.75.0(zod@3.23.8)))':
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.18(openai@4.75.0(zod@3.23.8))
|
||||
@@ -1478,6 +1523,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/mdast@4.0.4':
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
@@ -2059,6 +2106,8 @@ snapshots:
|
||||
|
||||
uuid@8.3.2: {}
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
v8-compile-cache-lib@3.0.1: {}
|
||||
|
||||
vfile-message@4.0.2:
|
||||
|
||||
@@ -4,6 +4,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { PumpFunTokenOptions } from "../types";
|
||||
import { toJSON } from "../utils/toJSON";
|
||||
import { create_image } from "../tools/create_image";
|
||||
|
||||
export class SolanaBalanceTool extends Tool {
|
||||
name = "solana_balance";
|
||||
description =
|
||||
@@ -17,17 +18,17 @@ export class SolanaBalanceTool extends Tool {
|
||||
try {
|
||||
const tokenAddress = input ? new PublicKey(input) : undefined;
|
||||
const balance = await this.solanaKit.getBalance(tokenAddress);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
balance: balance,
|
||||
token: input || "SOL"
|
||||
token: input || "SOL",
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -60,22 +61,24 @@ export class SolanaTransferTool extends Tool {
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
const recipient = new PublicKey(parsedInput.to);
|
||||
const mintAddress = parsedInput.mint ? new PublicKey(parsedInput.mint) : undefined;
|
||||
const mintAddress = parsedInput.mint
|
||||
? new PublicKey(parsedInput.mint)
|
||||
: undefined;
|
||||
|
||||
await this.solanaKit.transfer(recipient, parsedInput.amount, mintAddress);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Transfer completed successfully",
|
||||
amount: parsedInput.amount,
|
||||
recipient: parsedInput.to,
|
||||
token: parsedInput.mint || "SOL"
|
||||
token: parsedInput.mint || "SOL",
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -91,12 +94,20 @@ export class SolanaDeployTokenTool extends Tool {
|
||||
}
|
||||
|
||||
private validateInput(input: any): void {
|
||||
if (input.decimals !== undefined &&
|
||||
(typeof input.decimals !== "number" || input.decimals < 0 || input.decimals > 9)) {
|
||||
throw new Error("decimals must be a number between 0 and 9 when provided");
|
||||
if (
|
||||
input.decimals !== undefined &&
|
||||
(typeof input.decimals !== "number" ||
|
||||
input.decimals < 0 ||
|
||||
input.decimals > 9)
|
||||
) {
|
||||
throw new Error(
|
||||
"decimals must be a number between 0 and 9 when provided"
|
||||
);
|
||||
}
|
||||
if (input.initialSupply !== undefined &&
|
||||
(typeof input.initialSupply !== "number" || input.initialSupply <= 0)) {
|
||||
if (
|
||||
input.initialSupply !== undefined &&
|
||||
(typeof input.initialSupply !== "number" || input.initialSupply <= 0)
|
||||
) {
|
||||
throw new Error("initialSupply must be a positive number when provided");
|
||||
}
|
||||
}
|
||||
@@ -107,18 +118,18 @@ export class SolanaDeployTokenTool extends Tool {
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
const result = await this.solanaKit.deployToken(parsedInput.decimals);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Token deployed successfully",
|
||||
mintAddress: result.mint.toString(),
|
||||
decimals: parsedInput.decimals || 9
|
||||
decimals: parsedInput.decimals || 9,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -140,11 +151,15 @@ export class SolanaDeployCollectionTool extends Tool {
|
||||
if (!input.uri || typeof input.uri !== "string") {
|
||||
throw new Error("uri is required and must be a string");
|
||||
}
|
||||
if (input.royaltyBasisPoints !== undefined &&
|
||||
(typeof input.royaltyBasisPoints !== "number" ||
|
||||
input.royaltyBasisPoints < 0 ||
|
||||
input.royaltyBasisPoints > 10000)) {
|
||||
throw new Error("royaltyBasisPoints must be a number between 0 and 10000 when provided");
|
||||
if (
|
||||
input.royaltyBasisPoints !== undefined &&
|
||||
(typeof input.royaltyBasisPoints !== "number" ||
|
||||
input.royaltyBasisPoints < 0 ||
|
||||
input.royaltyBasisPoints > 10000)
|
||||
) {
|
||||
throw new Error(
|
||||
"royaltyBasisPoints must be a number between 0 and 10000 when provided"
|
||||
);
|
||||
}
|
||||
if (input.creators) {
|
||||
if (!Array.isArray(input.creators)) {
|
||||
@@ -152,10 +167,18 @@ export class SolanaDeployCollectionTool extends Tool {
|
||||
}
|
||||
input.creators.forEach((creator: any, index: number) => {
|
||||
if (!creator.address || typeof creator.address !== "string") {
|
||||
throw new Error(`creator[${index}].address is required and must be a string`);
|
||||
throw new Error(
|
||||
`creator[${index}].address is required and must be a string`
|
||||
);
|
||||
}
|
||||
if (typeof creator.percentage !== "number" || creator.percentage < 0 || creator.percentage > 100) {
|
||||
throw new Error(`creator[${index}].percentage must be a number between 0 and 100`);
|
||||
if (
|
||||
typeof creator.percentage !== "number" ||
|
||||
creator.percentage < 0 ||
|
||||
creator.percentage > 100
|
||||
) {
|
||||
throw new Error(
|
||||
`creator[${index}].percentage must be a number between 0 and 100`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -167,18 +190,18 @@ export class SolanaDeployCollectionTool extends Tool {
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
const result = await this.solanaKit.deployCollection(parsedInput);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Collection deployed successfully",
|
||||
collectionAddress: result.collectionAddress.toString(),
|
||||
name: parsedInput.name
|
||||
name: parsedInput.name,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -224,19 +247,19 @@ export class SolanaMintNFTTool extends Tool {
|
||||
parsedInput.metadata,
|
||||
parsedInput.recipient ? new PublicKey(parsedInput.recipient) : undefined
|
||||
);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "NFT minted successfully",
|
||||
mintAddress: result.mint.toString(),
|
||||
name: parsedInput.metadata.name,
|
||||
recipient: parsedInput.recipient || result.mint.toString()
|
||||
recipient: parsedInput.recipient || result.mint.toString(),
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -261,11 +284,15 @@ export class SolanaTradeTool extends Tool {
|
||||
if (input.inputMint !== undefined && typeof input.inputMint !== "string") {
|
||||
throw new Error("inputMint must be a string when provided");
|
||||
}
|
||||
if (input.slippageBps !== undefined &&
|
||||
(typeof input.slippageBps !== "number" ||
|
||||
input.slippageBps < 0 ||
|
||||
input.slippageBps > 10000)) {
|
||||
throw new Error("slippageBps must be a number between 0 and 10000 when provided");
|
||||
if (
|
||||
input.slippageBps !== undefined &&
|
||||
(typeof input.slippageBps !== "number" ||
|
||||
input.slippageBps < 0 ||
|
||||
input.slippageBps > 10000)
|
||||
) {
|
||||
throw new Error(
|
||||
"slippageBps must be a number between 0 and 10000 when provided"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,23 +304,25 @@ export class SolanaTradeTool extends Tool {
|
||||
const tx = await this.solanaKit.trade(
|
||||
new PublicKey(parsedInput.outputMint),
|
||||
parsedInput.inputAmount,
|
||||
parsedInput.inputMint ? new PublicKey(parsedInput.inputMint) : undefined,
|
||||
parsedInput.inputMint
|
||||
? new PublicKey(parsedInput.inputMint)
|
||||
: undefined,
|
||||
parsedInput.slippageBps
|
||||
);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Trade executed successfully",
|
||||
transaction: tx,
|
||||
inputAmount: parsedInput.inputAmount,
|
||||
inputToken: parsedInput.inputMint || "SOL",
|
||||
outputToken: parsedInput.outputMint
|
||||
outputToken: parsedInput.outputMint,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -310,17 +339,17 @@ export class SolanaRequestFundsTool extends Tool {
|
||||
protected async _call(_input: string): Promise<string> {
|
||||
try {
|
||||
await this.solanaKit.requestFaucetFunds();
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Successfully requested faucet funds",
|
||||
network: this.solanaKit.connection.rpcEndpoint.split("/")[2]
|
||||
network: this.solanaKit.connection.rpcEndpoint.split("/")[2],
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -339,8 +368,10 @@ export class SolanaRegisterDomainTool extends Tool {
|
||||
if (!input.name || typeof input.name !== "string") {
|
||||
throw new Error("name is required and must be a string");
|
||||
}
|
||||
if (input.spaceKB !== undefined &&
|
||||
(typeof input.spaceKB !== "number" || input.spaceKB <= 0)) {
|
||||
if (
|
||||
input.spaceKB !== undefined &&
|
||||
(typeof input.spaceKB !== "number" || input.spaceKB <= 0)
|
||||
) {
|
||||
throw new Error("spaceKB must be a positive number when provided");
|
||||
}
|
||||
}
|
||||
@@ -351,22 +382,22 @@ export class SolanaRegisterDomainTool extends Tool {
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
const tx = await this.solanaKit.registerDomain(
|
||||
parsedInput.name,
|
||||
parsedInput.name,
|
||||
parsedInput.spaceKB || 1
|
||||
);
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Domain registered successfully",
|
||||
transaction: tx,
|
||||
domain: `${parsedInput.name}.sol`,
|
||||
spaceKB: parsedInput.spaceKB || 1
|
||||
spaceKB: parsedInput.spaceKB || 1,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -387,14 +418,26 @@ export class SolanaGetWalletAddressTool extends Tool {
|
||||
|
||||
export class SolanaPumpfunTokenLaunchTool extends Tool {
|
||||
name = "solana_launch_pumpfun_token";
|
||||
description =
|
||||
"Launch a new token on Pump.fun via Solana Agent Kit. Requires a JSON input with tokenName, tokenTicker, description, imageUrl, and optional fields for twitter, telegram, website, and initialLiquiditySOL.";
|
||||
// description =
|
||||
// "Launch a new token on Pump.fun via Solana Agent Kit. Requires a JSON input with tokenName, tokenTicker, description, imageUrl, and optional fields for twitter, telegram, website, and initialLiquiditySOL.";
|
||||
|
||||
description = `This tool can be used to launch a token on Pump.fun,
|
||||
do not use this tool for any other purpose, or for creating SPL tokens.
|
||||
If the user asks you to chose the parameters, you should generate valid values.
|
||||
For generating the image, you can use the solana_create_image tool.
|
||||
|
||||
Inputs:
|
||||
tokenName: string, eg "PumpFun Token",
|
||||
tokenTicker: string, eg "PUMP",
|
||||
description: string, eg "PumpFun Token is a token on the Solana blockchain",
|
||||
imageUrl: string, eg "https://i.imgur.com/UFm07Np_d.png`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
private validateInput(input: any): void {
|
||||
console.log(input);
|
||||
if (!input.tokenName || typeof input.tokenName !== "string") {
|
||||
throw new Error("tokenName is required and must be a string");
|
||||
}
|
||||
@@ -418,11 +461,10 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
// Parse and normalize input
|
||||
const parsedInput = toJSON(input);
|
||||
// Validate the input
|
||||
this.validateInput(parsedInput);
|
||||
input = input.trim();
|
||||
let parsedInput = JSON.parse(input);
|
||||
|
||||
console.log(parsedInput);
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
// Launch token with validated input
|
||||
await this.solanaKit.launchPumpFunToken(
|
||||
@@ -473,17 +515,17 @@ export class SolanaCreateImageTool extends Tool {
|
||||
try {
|
||||
this.validateInput(input);
|
||||
const result = await create_image(this.solanaKit, input.trim());
|
||||
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Image created successfully",
|
||||
...result
|
||||
...result,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR"
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user