fix: pump launch

This commit is contained in:
aryan
2024-12-08 01:54:41 +05:30
parent d057645db3
commit b40f65d5c0
3 changed files with 150 additions and 57 deletions

View File

@@ -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
View File

@@ -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:

View File

@@ -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",
});
}
}