mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-06-06 15:11:43 +00:00
fixes and renames
This commit is contained in:
@@ -78,10 +78,10 @@ npm install solana-agent-kit
|
|||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
|
import { SolanaAgent, createSolanaTools } from "solana-agent-kit";
|
||||||
|
|
||||||
// Initialize with private key and optional RPC URL
|
// Initialize with private key and optional RPC URL
|
||||||
const agent = new SolanaAgentKit(
|
const agent = new SolanaAgent(
|
||||||
"your-wallet-private-key-as-base58",
|
"your-wallet-private-key-as-base58",
|
||||||
"https://api.mainnet-beta.solana.com",
|
"https://api.mainnet-beta.solana.com",
|
||||||
"your-openai-api-key"
|
"your-openai-api-key"
|
||||||
|
|||||||
@@ -21,19 +21,19 @@ Create a new TypeScript file in the `src/tools/` directory for your tool (e.g.,
|
|||||||
|
|
||||||
```typescript:src/tools/custom_tool.ts
|
```typescript:src/tools/custom_tool.ts
|
||||||
import { Tool } from "langchain/tools";
|
import { Tool } from "langchain/tools";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../agent";
|
||||||
|
|
||||||
export class CustomTool extends Tool {
|
export class CustomTool extends Tool {
|
||||||
name = "custom_tool";
|
name = "custom_tool";
|
||||||
description = "Description of what the custom tool does.";
|
description = "Description of what the custom tool does.";
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const result = await this.solanaKit.customFunction(input);
|
const result = await this.solanaAgent.customFunction(input);
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
message: "Custom tool executed successfully",
|
message: "Custom tool executed successfully",
|
||||||
@@ -53,7 +53,7 @@ export class CustomTool extends Tool {
|
|||||||
### 3. Add Supporting Functions to SolanaAgentKit
|
### 3. Add Supporting Functions to SolanaAgentKit
|
||||||
|
|
||||||
```typescript:src/agent/index.ts
|
```typescript:src/agent/index.ts
|
||||||
export class SolanaAgentKit {
|
export class SolanaAgent {
|
||||||
// ... existing code ...
|
// ... existing code ...
|
||||||
|
|
||||||
async customFunction(input: string): Promise<string> {
|
async customFunction(input: string): Promise<string> {
|
||||||
@@ -87,9 +87,9 @@ export function createSolanaTools(agent: SolanaAgentKit) {
|
|||||||
### 6. Usage Example
|
### 6. Usage Example
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
|
import { SolanaAgent, createSolanaTools } from "solana-agent-kit";
|
||||||
|
|
||||||
const agent = new SolanaAgentKit(
|
const agent = new SolanaAgent(
|
||||||
"your-wallet-private-key-as-base58",
|
"your-wallet-private-key-as-base58",
|
||||||
"https://api.mainnet-beta.solana.com",
|
"https://api.mainnet-beta.solana.com",
|
||||||
"your-openai-api-key"
|
"your-openai-api-key"
|
||||||
@@ -118,19 +118,19 @@ Here's a complete example of implementing a tool to fetch token prices:
|
|||||||
|
|
||||||
```typescript:src/tools/fetch_token_price.ts
|
```typescript:src/tools/fetch_token_price.ts
|
||||||
import { Tool } from "langchain/tools";
|
import { Tool } from "langchain/tools";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../agent";
|
||||||
|
|
||||||
export class FetchTokenPriceTool extends Tool {
|
export class FetchTokenPriceTool extends Tool {
|
||||||
name = "fetch_token_price";
|
name = "fetch_token_price";
|
||||||
description = "Fetches the current price of a specified token.";
|
description = "Fetches the current price of a specified token.";
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(tokenSymbol: string): Promise<string> {
|
protected async _call(tokenSymbol: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const price = await this.solanaKit.getTokenPrice(tokenSymbol);
|
const price = await this.solanaAgent.getTokenPrice(tokenSymbol);
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
message: `Price fetched successfully for ${tokenSymbol}.`,
|
message: `Price fetched successfully for ${tokenSymbol}.`,
|
||||||
@@ -176,4 +176,4 @@ If you encounter any issues while implementing your custom tool:
|
|||||||
- Contact the maintainer
|
- Contact the maintainer
|
||||||
- Check existing tools for implementation examples
|
- Check existing tools for implementation examples
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
"pnpm": ">=8.0.0"
|
"pnpm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "sendaifun",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@raydium-io/raydium-sdk-v2": "0.1.95-alpha",
|
|
||||||
"@bonfida/spl-name-service": "^3.0.7",
|
"@bonfida/spl-name-service": "^3.0.7",
|
||||||
"@coral-xyz/anchor": "0.29",
|
"@coral-xyz/anchor": "0.29",
|
||||||
"@langchain/core": "^0.3.18",
|
"@langchain/core": "^0.3.18",
|
||||||
@@ -34,11 +33,12 @@
|
|||||||
"@metaplex-foundation/umi-web3js-adapters": "^0.9.2",
|
"@metaplex-foundation/umi-web3js-adapters": "^0.9.2",
|
||||||
"@orca-so/common-sdk": "0.6.4",
|
"@orca-so/common-sdk": "0.6.4",
|
||||||
"@orca-so/whirlpools-sdk": "^0.13.12",
|
"@orca-so/whirlpools-sdk": "^0.13.12",
|
||||||
|
"@raydium-io/raydium-sdk-v2": "0.1.95-alpha",
|
||||||
"@solana/spl-token": "^0.4.9",
|
"@solana/spl-token": "^0.4.9",
|
||||||
"@solana/web3.js": "^1.95.4",
|
"@solana/web3.js": "^1.95.4",
|
||||||
|
"bn.js": "^5.2.1",
|
||||||
"bs58": "^6.0.0",
|
"bs58": "^6.0.0",
|
||||||
"decimal.js": "^10.4.3",
|
"decimal.js": "^10.4.3",
|
||||||
"bn.js": "^5.2.1",
|
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
"form-data": "^4.0.1",
|
"form-data": "^4.0.1",
|
||||||
"langchain": "^0.3.6",
|
"langchain": "^0.3.6",
|
||||||
@@ -51,4 +51,4 @@
|
|||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
sendCompressedAirdrop,
|
sendCompressedAirdrop,
|
||||||
createOrcaSingleSidedWhirlpool,
|
createOrcaSingleSidedWhirlpool,
|
||||||
FEE_TIERS,
|
FEE_TIERS,
|
||||||
|
fetchPrice,
|
||||||
} from "../tools";
|
} from "../tools";
|
||||||
import {
|
import {
|
||||||
CollectionDeployment,
|
CollectionDeployment,
|
||||||
@@ -39,14 +40,14 @@ import { BN } from "@coral-xyz/anchor";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for interacting with Solana blockchain
|
* Main class for interacting with Solana blockchain
|
||||||
* Provides a unified interface for token operations, NFT management, and trading
|
* Provides a unified interface for token operations, NFT management, trading and more
|
||||||
*
|
*
|
||||||
* @class SolanaAgentKit
|
* @class SolanaAgent
|
||||||
* @property {Connection} connection - Solana RPC connection
|
* @property {Connection} connection - Solana RPC connection
|
||||||
* @property {Keypair} wallet - Wallet keypair for signing transactions
|
* @property {Keypair} wallet - Wallet keypair for signing transactions
|
||||||
* @property {PublicKey} wallet_address - Public key of the wallet
|
* @property {PublicKey} wallet_address - Public key of the wallet
|
||||||
*/
|
*/
|
||||||
export class SolanaAgentKit {
|
export class SolanaAgent {
|
||||||
public connection: Connection;
|
public connection: Connection;
|
||||||
public wallet: Keypair;
|
public wallet: Keypair;
|
||||||
public wallet_address: PublicKey;
|
public wallet_address: PublicKey;
|
||||||
@@ -145,6 +146,10 @@ export class SolanaAgentKit {
|
|||||||
return getTokenDataByTicker(ticker);
|
return getTokenDataByTicker(ticker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fetchTokenPrice(mint: string) {
|
||||||
|
return fetchPrice(new PublicKey(mint));
|
||||||
|
}
|
||||||
|
|
||||||
async launchPumpFunToken(
|
async launchPumpFunToken(
|
||||||
tokenName: string,
|
tokenName: string,
|
||||||
tokenTicker: string,
|
tokenTicker: string,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SolanaAgentKit } from './agent'; // Move the SolanaAgentKit class to src/agent.ts
|
import { SolanaAgent } from "./agent";
|
||||||
import { createSolanaTools } from './langchain';
|
import { createSolanaTools } from "./langchain";
|
||||||
|
|
||||||
export { SolanaAgentKit, createSolanaTools };
|
export { SolanaAgent, createSolanaTools };
|
||||||
|
|
||||||
// Optional: Export types that users might need
|
// Optional: Export types that users might need
|
||||||
export * from './types';
|
export * from "./types";
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import Decimal from "decimal.js";
|
import Decimal from "decimal.js";
|
||||||
import { Tool } from "langchain/tools";
|
import { Tool } from "langchain/tools";
|
||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { create_image } from "../tools/create_image";
|
import { create_image } from "../tools/create_image";
|
||||||
import { fetchPrice } from "../tools/fetch_price";
|
|
||||||
import { BN } from "@coral-xyz/anchor";
|
import { BN } from "@coral-xyz/anchor";
|
||||||
import { FEE_TIERS } from "../tools";
|
import { FEE_TIERS } from "../tools";
|
||||||
import { toJSON } from "../utils/toJSON";
|
import { toJSON } from "../utils/toJSON";
|
||||||
@@ -18,14 +17,14 @@ export class SolanaBalanceTool extends Tool {
|
|||||||
Inputs:
|
Inputs:
|
||||||
tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`;
|
tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const tokenAddress = input ? new PublicKey(input) : undefined;
|
const tokenAddress = input ? new PublicKey(input) : undefined;
|
||||||
const balance = await this.solanaKit.getBalance(tokenAddress);
|
const balance = await this.solanaAgent.getBalance(tokenAddress);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -51,7 +50,7 @@ export class SolanaTransferTool extends Tool {
|
|||||||
amount: number, eg 1 (required)
|
amount: number, eg 1 (required)
|
||||||
mint?: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`;
|
mint?: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,10 +63,10 @@ export class SolanaTransferTool extends Tool {
|
|||||||
? new PublicKey(parsedInput.mint)
|
? new PublicKey(parsedInput.mint)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const tx = await this.solanaKit.transfer(
|
const tx = await this.solanaAgent.transfer(
|
||||||
recipient,
|
recipient,
|
||||||
parsedInput.amount,
|
parsedInput.amount,
|
||||||
mintAddress
|
mintAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -94,12 +93,12 @@ export class SolanaDeployTokenTool extends Tool {
|
|||||||
|
|
||||||
Inputs (input is a JSON string):
|
Inputs (input is a JSON string):
|
||||||
name: string, eg "My Token" (required)
|
name: string, eg "My Token" (required)
|
||||||
uri: string, eg "https://example.com/token.json" (required)
|
uri: string, eg "https://example.com/token.json" (required)
|
||||||
symbol: string, eg "MTK" (required)
|
symbol: string, eg "MTK" (required)
|
||||||
decimals?: number, eg 9 (optional, defaults to 9)
|
decimals?: number, eg 9 (optional, defaults to 9)
|
||||||
initialSupply?: number, eg 1000000 (optional)`;
|
initialSupply?: number, eg 1000000 (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,12 +106,12 @@ export class SolanaDeployTokenTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input);
|
const parsedInput = JSON.parse(input);
|
||||||
|
|
||||||
const result = await this.solanaKit.deployToken(
|
const result = await this.solanaAgent.deployToken(
|
||||||
parsedInput.name,
|
parsedInput.name,
|
||||||
parsedInput.uri,
|
parsedInput.uri,
|
||||||
parsedInput.symbol,
|
parsedInput.symbol,
|
||||||
parsedInput.decimals,
|
parsedInput.decimals,
|
||||||
parsedInput.initialSupply
|
parsedInput.initialSupply,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -140,7 +139,7 @@ export class SolanaDeployCollectionTool extends Tool {
|
|||||||
uri: string, eg "https://example.com/collection.json" (required)
|
uri: string, eg "https://example.com/collection.json" (required)
|
||||||
royaltyBasisPoints?: number, eg 500 for 5% (optional)`;
|
royaltyBasisPoints?: number, eg 500 for 5% (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +147,7 @@ export class SolanaDeployCollectionTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input);
|
const parsedInput = JSON.parse(input);
|
||||||
|
|
||||||
const result = await this.solanaKit.deployCollection(parsedInput);
|
const result = await this.solanaAgent.deployCollection(parsedInput);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -174,9 +173,9 @@ export class SolanaMintNFTTool extends Tool {
|
|||||||
collectionMint: string, eg "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" (required) - The address of the collection to mint into
|
collectionMint: string, eg "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" (required) - The address of the collection to mint into
|
||||||
name: string, eg "My NFT" (required)
|
name: string, eg "My NFT" (required)
|
||||||
uri: string, eg "https://example.com/nft.json" (required)
|
uri: string, eg "https://example.com/nft.json" (required)
|
||||||
recipient?: string, eg "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u" (optional) - The wallet to receive the NFT, defaults to agent's wallet which is ${this.solanaKit.wallet_address.toString()}`;
|
recipient?: string, eg "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u" (optional) - The wallet to receive the NFT, defaults to agent's wallet which is ${this.solanaAgent.wallet_address.toString()}`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +183,7 @@ export class SolanaMintNFTTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input);
|
const parsedInput = JSON.parse(input);
|
||||||
|
|
||||||
const result = await this.solanaKit.mintNFT(
|
const result = await this.solanaAgent.mintNFT(
|
||||||
new PublicKey(parsedInput.collectionMint),
|
new PublicKey(parsedInput.collectionMint),
|
||||||
{
|
{
|
||||||
name: parsedInput.name,
|
name: parsedInput.name,
|
||||||
@@ -192,7 +191,7 @@ export class SolanaMintNFTTool extends Tool {
|
|||||||
},
|
},
|
||||||
parsedInput.recipient
|
parsedInput.recipient
|
||||||
? new PublicKey(parsedInput.recipient)
|
? new PublicKey(parsedInput.recipient)
|
||||||
: this.solanaKit.wallet_address
|
: this.solanaAgent.wallet_address,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -226,7 +225,7 @@ export class SolanaTradeTool extends Tool {
|
|||||||
inputMint?: string, eg "So11111111111111111111111111111111111111112" (optional)
|
inputMint?: string, eg "So11111111111111111111111111111111111111112" (optional)
|
||||||
slippageBps?: number, eg 100 (optional)`;
|
slippageBps?: number, eg 100 (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,13 +233,13 @@ export class SolanaTradeTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input);
|
const parsedInput = JSON.parse(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.trade(
|
const tx = await this.solanaAgent.trade(
|
||||||
new PublicKey(parsedInput.outputMint),
|
new PublicKey(parsedInput.outputMint),
|
||||||
parsedInput.inputAmount,
|
parsedInput.inputAmount,
|
||||||
parsedInput.inputMint
|
parsedInput.inputMint
|
||||||
? new PublicKey(parsedInput.inputMint)
|
? new PublicKey(parsedInput.inputMint)
|
||||||
: new PublicKey("So11111111111111111111111111111111111111112"),
|
: new PublicKey("So11111111111111111111111111111111111111112"),
|
||||||
parsedInput.slippageBps
|
parsedInput.slippageBps,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -265,18 +264,18 @@ export class SolanaRequestFundsTool extends Tool {
|
|||||||
name = "solana_request_funds";
|
name = "solana_request_funds";
|
||||||
description = "Request SOL from Solana faucet (devnet/testnet only)";
|
description = "Request SOL from Solana faucet (devnet/testnet only)";
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(_input: string): Promise<string> {
|
protected async _call(_input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
await this.solanaKit.requestFaucetFunds();
|
await this.solanaAgent.requestFaucetFunds();
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
message: "Successfully requested faucet funds",
|
message: "Successfully requested faucet funds",
|
||||||
network: this.solanaKit.connection.rpcEndpoint.split("/")[2],
|
network: this.solanaAgent.connection.rpcEndpoint.split("/")[2],
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -297,7 +296,7 @@ export class SolanaRegisterDomainTool extends Tool {
|
|||||||
spaceKB: number, eg 1 (optional, default is 1)
|
spaceKB: number, eg 1 (optional, default is 1)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,9 +317,9 @@ export class SolanaRegisterDomainTool extends Tool {
|
|||||||
const parsedInput = toJSON(input);
|
const parsedInput = toJSON(input);
|
||||||
this.validateInput(parsedInput);
|
this.validateInput(parsedInput);
|
||||||
|
|
||||||
const tx = await this.solanaKit.registerDomain(
|
const tx = await this.solanaAgent.registerDomain(
|
||||||
parsedInput.name,
|
parsedInput.name,
|
||||||
parsedInput.spaceKB || 1
|
parsedInput.spaceKB || 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -348,14 +347,14 @@ export class SolanaResolveDomainTool extends Tool {
|
|||||||
domain: string, eg "pumpfun.sol" or "pumpfun"(required)
|
domain: string, eg "pumpfun.sol" or "pumpfun"(required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const domain = input.trim();
|
const domain = input.trim();
|
||||||
const publicKey = await this.solanaKit.resolveSolDomain(domain);
|
const publicKey = await this.solanaAgent.resolveSolDomain(domain);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -380,14 +379,14 @@ export class SolanaGetDomainTool extends Tool {
|
|||||||
account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)
|
account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const account = new PublicKey(input.trim());
|
const account = new PublicKey(input.trim());
|
||||||
const domain = await this.solanaKit.getPrimaryDomain(account);
|
const domain = await this.solanaAgent.getPrimaryDomain(account);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -408,12 +407,12 @@ export class SolanaGetWalletAddressTool extends Tool {
|
|||||||
name = "solana_get_wallet_address";
|
name = "solana_get_wallet_address";
|
||||||
description = `Get the wallet address of the agent`;
|
description = `Get the wallet address of the agent`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(_input: string): Promise<string> {
|
async _call(_input: string): Promise<string> {
|
||||||
return this.solanaKit.wallet_address.toString();
|
return this.solanaAgent.wallet_address.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +430,7 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
|||||||
description: string, eg "PumpFun Token is a token on the Solana blockchain",
|
description: string, eg "PumpFun Token is a token on the Solana blockchain",
|
||||||
imageUrl: string, eg "https://i.imgur.com/UFm07Np_d.png`;
|
imageUrl: string, eg "https://i.imgur.com/UFm07Np_d.png`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,7 +464,7 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
|||||||
this.validateInput(parsedInput);
|
this.validateInput(parsedInput);
|
||||||
|
|
||||||
// Launch token with validated input
|
// Launch token with validated input
|
||||||
await this.solanaKit.launchPumpFunToken(
|
await this.solanaAgent.launchPumpFunToken(
|
||||||
parsedInput.tokenName,
|
parsedInput.tokenName,
|
||||||
parsedInput.tokenTicker,
|
parsedInput.tokenTicker,
|
||||||
parsedInput.description,
|
parsedInput.description,
|
||||||
@@ -475,7 +474,7 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
|||||||
telegram: parsedInput.telegram,
|
telegram: parsedInput.telegram,
|
||||||
website: parsedInput.website,
|
website: parsedInput.website,
|
||||||
initialLiquiditySOL: parsedInput.initialLiquiditySOL,
|
initialLiquiditySOL: parsedInput.initialLiquiditySOL,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -499,7 +498,7 @@ export class SolanaCreateImageTool extends Tool {
|
|||||||
description =
|
description =
|
||||||
"Create an image using OpenAI's DALL-E. Input should be a string prompt for the image.";
|
"Create an image using OpenAI's DALL-E. Input should be a string prompt for the image.";
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +511,7 @@ export class SolanaCreateImageTool extends Tool {
|
|||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
this.validateInput(input);
|
this.validateInput(input);
|
||||||
const result = await create_image(this.solanaKit, input.trim());
|
const result = await create_image(this.solanaAgent, input.trim());
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -536,7 +535,7 @@ export class SolanaLendAssetTool extends Tool {
|
|||||||
Inputs (input is a json string):
|
Inputs (input is a json string):
|
||||||
amount: number, eg 1, 0.01 (required)`;
|
amount: number, eg 1, 0.01 (required)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -544,7 +543,7 @@ export class SolanaLendAssetTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
let amount = JSON.parse(input).amount || input;
|
let amount = JSON.parse(input).amount || input;
|
||||||
|
|
||||||
const tx = await this.solanaKit.lendAssets(amount);
|
const tx = await this.solanaAgent.lendAssets(amount);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -566,13 +565,13 @@ export class SolanaTPSCalculatorTool extends Tool {
|
|||||||
name = "solana_get_tps";
|
name = "solana_get_tps";
|
||||||
description = "Get the current TPS of the Solana network";
|
description = "Get the current TPS of the Solana network";
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(_input: string): Promise<string> {
|
async _call(_input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const tps = await this.solanaKit.getTPS();
|
const tps = await this.solanaAgent.getTPS();
|
||||||
return `Solana (mainnet-beta) current transactions per second: ${tps}`;
|
return `Solana (mainnet-beta) current transactions per second: ${tps}`;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return `Error fetching TPS: ${error.message}`;
|
return `Error fetching TPS: ${error.message}`;
|
||||||
@@ -587,7 +586,7 @@ export class SolanaStakeTool extends Tool {
|
|||||||
Inputs ( input is a JSON string ):
|
Inputs ( input is a JSON string ):
|
||||||
amount: number, eg 1 or 0.01 (required)`;
|
amount: number, eg 1 or 0.01 (required)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,7 +594,7 @@ export class SolanaStakeTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input) || Number(input);
|
const parsedInput = JSON.parse(input) || Number(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.stake(parsedInput.amount);
|
const tx = await this.solanaAgent.stake(parsedInput.amount);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -619,17 +618,17 @@ export class SolanaStakeTool extends Tool {
|
|||||||
export class SolanaFetchPriceTool extends Tool {
|
export class SolanaFetchPriceTool extends Tool {
|
||||||
name = "solana_fetch_price";
|
name = "solana_fetch_price";
|
||||||
description = `Fetch the price of a given token in USDC.
|
description = `Fetch the price of a given token in USDC.
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- tokenId: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"`;
|
- tokenId: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(input: string): Promise<string> {
|
async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const price = await fetchPrice(this.solanaKit, input.trim());
|
const price = await this.solanaAgent.fetchTokenPrice(input.trim());
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
tokenId: input.trim(),
|
tokenId: input.trim(),
|
||||||
@@ -652,7 +651,7 @@ export class SolanaTokenDataTool extends Tool {
|
|||||||
Inputs: mintAddress is required.
|
Inputs: mintAddress is required.
|
||||||
mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`;
|
mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,7 +659,8 @@ export class SolanaTokenDataTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = input.trim();
|
const parsedInput = input.trim();
|
||||||
|
|
||||||
const tokenData = await this.solanaKit.getTokenDataByAddress(parsedInput);
|
const tokenData =
|
||||||
|
await this.solanaAgent.getTokenDataByAddress(parsedInput);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
@@ -683,14 +683,14 @@ export class SolanaTokenDataByTickerTool extends Tool {
|
|||||||
Inputs: ticker is required.
|
Inputs: ticker is required.
|
||||||
ticker: string, eg "USDC" (required)`;
|
ticker: string, eg "USDC" (required)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async _call(input: string): Promise<string> {
|
protected async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const ticker = input.trim();
|
const ticker = input.trim();
|
||||||
const tokenData = await this.solanaKit.getTokenDataByTicker(ticker);
|
const tokenData = await this.solanaAgent.getTokenDataByTicker(ticker);
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
status: "success",
|
status: "success",
|
||||||
tokenData: tokenData,
|
tokenData: tokenData,
|
||||||
@@ -708,7 +708,7 @@ export class SolanaTokenDataByTickerTool extends Tool {
|
|||||||
export class SolanaCompressedAirdropTool extends Tool {
|
export class SolanaCompressedAirdropTool extends Tool {
|
||||||
name = "solana_compressed_airdrop";
|
name = "solana_compressed_airdrop";
|
||||||
description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens)
|
description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens)
|
||||||
|
|
||||||
Inputs (input is a JSON string):
|
Inputs (input is a JSON string):
|
||||||
mintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required)
|
mintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required)
|
||||||
amount: number, the amount of tokens to airdrop per recipient, e.g., 42 (required)
|
amount: number, the amount of tokens to airdrop per recipient, e.g., 42 (required)
|
||||||
@@ -717,7 +717,7 @@ export class SolanaCompressedAirdropTool extends Tool {
|
|||||||
priorityFeeInLamports: number, the priority fee in lamports. Default is 30_000. (optional)
|
priorityFeeInLamports: number, the priority fee in lamports. Default is 30_000. (optional)
|
||||||
shouldLog: boolean, whether to log progress to stdout. Default is false. (optional)`;
|
shouldLog: boolean, whether to log progress to stdout. Default is false. (optional)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,13 +725,13 @@ export class SolanaCompressedAirdropTool extends Tool {
|
|||||||
try {
|
try {
|
||||||
const parsedInput = JSON.parse(input);
|
const parsedInput = JSON.parse(input);
|
||||||
|
|
||||||
const txs = await this.solanaKit.sendCompressedAirdrop(
|
const txs = await this.solanaAgent.sendCompressedAirdrop(
|
||||||
parsedInput.mintAddress,
|
parsedInput.mintAddress,
|
||||||
parsedInput.amount,
|
parsedInput.amount,
|
||||||
parsedInput.decimals,
|
parsedInput.decimals,
|
||||||
parsedInput.recipients,
|
parsedInput.recipients,
|
||||||
parsedInput.priorityFeeInLamports || 30_000,
|
parsedInput.priorityFeeInLamports || 30_000,
|
||||||
parsedInput.shouldLog || false
|
parsedInput.shouldLog || false,
|
||||||
);
|
);
|
||||||
|
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
@@ -761,7 +761,7 @@ export class SolanaCreateSingleSidedWhirlpoolTool extends Tool {
|
|||||||
- maxPrice: number, eg: 5.0 (required, maximum price at which liquidity is added)
|
- maxPrice: number, eg: 5.0 (required, maximum price at which liquidity is added)
|
||||||
- feeTier: number, eg: 0.30 (required, fee tier for the pool)`;
|
- feeTier: number, eg: 0.30 (required, fee tier for the pool)`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,10 +776,12 @@ export class SolanaCreateSingleSidedWhirlpoolTool extends Tool {
|
|||||||
const feeTier = inputFormat.feeTier;
|
const feeTier = inputFormat.feeTier;
|
||||||
|
|
||||||
if (!feeTier || !(feeTier in FEE_TIERS)) {
|
if (!feeTier || !(feeTier in FEE_TIERS)) {
|
||||||
throw new Error(`Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join(", ")}`);
|
throw new Error(
|
||||||
|
`Invalid feeTier. Available options: ${Object.keys(FEE_TIERS).join(", ")}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txId = await this.solanaKit.createOrcaSingleSidedWhirlpool(
|
const txId = await this.solanaAgent.createOrcaSingleSidedWhirlpool(
|
||||||
depositTokenAmount,
|
depositTokenAmount,
|
||||||
depositTokenMint,
|
depositTokenMint,
|
||||||
otherTokenMint,
|
otherTokenMint,
|
||||||
@@ -803,7 +805,6 @@ export class SolanaCreateSingleSidedWhirlpoolTool extends Tool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class SolanaRaydiumCreateAmmV4 extends Tool {
|
export class SolanaRaydiumCreateAmmV4 extends Tool {
|
||||||
name = "raydium_create_ammV4";
|
name = "raydium_create_ammV4";
|
||||||
description = `Raydium's Legacy AMM that requiers an OpenBook marketID
|
description = `Raydium's Legacy AMM that requiers an OpenBook marketID
|
||||||
@@ -815,15 +816,15 @@ export class SolanaRaydiumCreateAmmV4 extends Tool {
|
|||||||
startTime: number(seconds), eg: now number or zero (required)
|
startTime: number(seconds), eg: now number or zero (required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(input: string): Promise<string> {
|
async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
let inputFormat = JSON.parse(input)
|
let inputFormat = JSON.parse(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.raydiumCreateAmmV4(
|
const tx = await this.solanaAgent.raydiumCreateAmmV4(
|
||||||
new PublicKey(inputFormat.marketId),
|
new PublicKey(inputFormat.marketId),
|
||||||
new BN(inputFormat.baseAmount),
|
new BN(inputFormat.baseAmount),
|
||||||
new BN(inputFormat.quoteAmount),
|
new BN(inputFormat.quoteAmount),
|
||||||
@@ -857,15 +858,15 @@ export class SolanaRaydiumCreateClmm extends Tool {
|
|||||||
startTime: number(seconds), eg: now number or zero (required)
|
startTime: number(seconds), eg: now number or zero (required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(input: string): Promise<string> {
|
async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
let inputFormat = JSON.parse(input)
|
let inputFormat = JSON.parse(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.raydiumCreateClmm(
|
const tx = await this.solanaAgent.raydiumCreateClmm(
|
||||||
new PublicKey(inputFormat.mint1),
|
new PublicKey(inputFormat.mint1),
|
||||||
new PublicKey(inputFormat.mint2),
|
new PublicKey(inputFormat.mint2),
|
||||||
|
|
||||||
@@ -892,7 +893,7 @@ export class SolanaRaydiumCreateClmm extends Tool {
|
|||||||
|
|
||||||
export class SolanaRaydiumCreateCpmm extends Tool {
|
export class SolanaRaydiumCreateCpmm extends Tool {
|
||||||
name = "raydium_create_cpmm";
|
name = "raydium_create_cpmm";
|
||||||
description = `Raydium's newest CPMM, does not require marketID, supports Token 2022 standard
|
description = `Raydium's newest CPMM, does not require marketID, supports Token 2022 standard
|
||||||
|
|
||||||
Inputs (input is a json string):
|
Inputs (input is a json string):
|
||||||
mint1: string (required)
|
mint1: string (required)
|
||||||
@@ -903,15 +904,15 @@ export class SolanaRaydiumCreateCpmm extends Tool {
|
|||||||
startTime: number(seconds), eg: now number or zero (required)
|
startTime: number(seconds), eg: now number or zero (required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(input: string): Promise<string> {
|
async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
let inputFormat = JSON.parse(input)
|
let inputFormat = JSON.parse(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.raydiumCreateCpmm(
|
const tx = await this.solanaAgent.raydiumCreateCpmm(
|
||||||
new PublicKey(inputFormat.mint1),
|
new PublicKey(inputFormat.mint1),
|
||||||
new PublicKey(inputFormat.mint2),
|
new PublicKey(inputFormat.mint2),
|
||||||
|
|
||||||
@@ -940,7 +941,7 @@ export class SolanaRaydiumCreateCpmm extends Tool {
|
|||||||
|
|
||||||
export class SolanaOpenbookCreateMarket extends Tool {
|
export class SolanaOpenbookCreateMarket extends Tool {
|
||||||
name = "solana_openbook_create_market";
|
name = "solana_openbook_create_market";
|
||||||
description = `Openbook marketId, required for ammv4
|
description = `Openbook marketId, required for ammv4
|
||||||
|
|
||||||
Inputs (input is a json string):
|
Inputs (input is a json string):
|
||||||
baseMint: string (required)
|
baseMint: string (required)
|
||||||
@@ -949,15 +950,15 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
|||||||
tickSize: number (required)
|
tickSize: number (required)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
constructor(private solanaKit: SolanaAgentKit) {
|
constructor(private solanaAgent: SolanaAgent) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _call(input: string): Promise<string> {
|
async _call(input: string): Promise<string> {
|
||||||
try {
|
try {
|
||||||
let inputFormat = JSON.parse(input)
|
let inputFormat = JSON.parse(input);
|
||||||
|
|
||||||
const tx = await this.solanaKit.openbookCreateMarket(
|
const tx = await this.solanaAgent.openbookCreateMarket(
|
||||||
new PublicKey(inputFormat.baseMint),
|
new PublicKey(inputFormat.baseMint),
|
||||||
new PublicKey(inputFormat.quoteMint),
|
new PublicKey(inputFormat.quoteMint),
|
||||||
|
|
||||||
@@ -980,32 +981,32 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
export function createSolanaTools(solanaAgent: SolanaAgent) {
|
||||||
return [
|
return [
|
||||||
new SolanaBalanceTool(solanaKit),
|
new SolanaBalanceTool(solanaAgent),
|
||||||
new SolanaTransferTool(solanaKit),
|
new SolanaTransferTool(solanaAgent),
|
||||||
new SolanaDeployTokenTool(solanaKit),
|
new SolanaDeployTokenTool(solanaAgent),
|
||||||
new SolanaDeployCollectionTool(solanaKit),
|
new SolanaDeployCollectionTool(solanaAgent),
|
||||||
new SolanaMintNFTTool(solanaKit),
|
new SolanaMintNFTTool(solanaAgent),
|
||||||
new SolanaTradeTool(solanaKit),
|
new SolanaTradeTool(solanaAgent),
|
||||||
new SolanaRequestFundsTool(solanaKit),
|
new SolanaRequestFundsTool(solanaAgent),
|
||||||
new SolanaRegisterDomainTool(solanaKit),
|
new SolanaRegisterDomainTool(solanaAgent),
|
||||||
new SolanaGetWalletAddressTool(solanaKit),
|
new SolanaGetWalletAddressTool(solanaAgent),
|
||||||
new SolanaPumpfunTokenLaunchTool(solanaKit),
|
new SolanaPumpfunTokenLaunchTool(solanaAgent),
|
||||||
new SolanaCreateImageTool(solanaKit),
|
new SolanaCreateImageTool(solanaAgent),
|
||||||
new SolanaLendAssetTool(solanaKit),
|
new SolanaLendAssetTool(solanaAgent),
|
||||||
new SolanaTPSCalculatorTool(solanaKit),
|
new SolanaTPSCalculatorTool(solanaAgent),
|
||||||
new SolanaStakeTool(solanaKit),
|
new SolanaStakeTool(solanaAgent),
|
||||||
new SolanaFetchPriceTool(solanaKit),
|
new SolanaFetchPriceTool(solanaAgent),
|
||||||
new SolanaResolveDomainTool(solanaKit),
|
new SolanaResolveDomainTool(solanaAgent),
|
||||||
new SolanaGetDomainTool(solanaKit),
|
new SolanaGetDomainTool(solanaAgent),
|
||||||
new SolanaTokenDataTool(solanaKit),
|
new SolanaTokenDataTool(solanaAgent),
|
||||||
new SolanaTokenDataByTickerTool(solanaKit),
|
new SolanaTokenDataByTickerTool(solanaAgent),
|
||||||
new SolanaCompressedAirdropTool(solanaKit),
|
new SolanaCompressedAirdropTool(solanaAgent),
|
||||||
new SolanaRaydiumCreateAmmV4(solanaKit),
|
new SolanaRaydiumCreateAmmV4(solanaAgent),
|
||||||
new SolanaRaydiumCreateClmm(solanaKit),
|
new SolanaRaydiumCreateClmm(solanaAgent),
|
||||||
new SolanaRaydiumCreateCpmm(solanaKit),
|
new SolanaRaydiumCreateCpmm(solanaAgent),
|
||||||
new SolanaOpenbookCreateMarket(solanaKit),
|
new SolanaOpenbookCreateMarket(solanaAgent),
|
||||||
new SolanaCreateSingleSidedWhirlpoolTool(solanaKit),
|
new SolanaCreateSingleSidedWhirlpoolTool(solanaAgent),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import OpenAI from "openai";
|
import OpenAI from "openai";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an image using OpenAI's DALL-E
|
* Generate an image using OpenAI's DALL-E
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param prompt Text description of the image to generate
|
* @param prompt Text description of the image to generate
|
||||||
* @param size Image size ('256x256', '512x512', or '1024x1024') (default: '1024x1024')
|
* @param size Image size ('256x256', '512x512', or '1024x1024') (default: '1024x1024')
|
||||||
* @param n Number of images to generate (default: 1)
|
* @param n Number of images to generate (default: 1)
|
||||||
* @returns Object containing the generated image URLs
|
* @returns Object containing the generated image URLs
|
||||||
*/
|
*/
|
||||||
export async function create_image(
|
export async function create_image(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
prompt: string,
|
prompt: string,
|
||||||
size: "256x256" | "512x512" | "1024x1024" = "1024x1024",
|
size: "256x256" | "512x512" | "1024x1024" = "1024x1024",
|
||||||
n: number = 1,
|
n: number = 1,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../index";
|
||||||
import { BN, Wallet } from "@coral-xyz/anchor";
|
import { BN, Wallet } from "@coral-xyz/anchor";
|
||||||
import { Decimal } from "decimal.js";
|
import { Decimal } from "decimal.js";
|
||||||
import {
|
import {
|
||||||
@@ -40,7 +40,7 @@ import { sendTx } from "../utils/send_tx";
|
|||||||
* @remarks
|
* @remarks
|
||||||
* Fee tiers determine the percentage of fees collected on swaps, while tick spacing affects
|
* Fee tiers determine the percentage of fees collected on swaps, while tick spacing affects
|
||||||
* the granularity of price ranges for liquidity positions.
|
* the granularity of price ranges for liquidity positions.
|
||||||
*
|
*
|
||||||
* For more details, refer to:
|
* For more details, refer to:
|
||||||
* - [Whirlpool Fees](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Fees)
|
* - [Whirlpool Fees](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Fees)
|
||||||
* - [Whirlpool Parameters](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Parameters)
|
* - [Whirlpool Parameters](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Parameters)
|
||||||
@@ -54,17 +54,17 @@ export const FEE_TIERS = {
|
|||||||
0.04: 4,
|
0.04: 4,
|
||||||
0.05: 8,
|
0.05: 8,
|
||||||
0.16: 16,
|
0.16: 16,
|
||||||
0.30: 64,
|
0.3: 64,
|
||||||
0.65: 96,
|
0.65: 96,
|
||||||
1.00: 128,
|
1.0: 128,
|
||||||
2.00: 256,
|
2.0: 256,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* # Creates a single-sided Whirlpool.
|
* # Creates a single-sided Whirlpool.
|
||||||
*
|
*
|
||||||
* This function initializes a new Whirlpool (liquidity pool) on Orca and seeds it with liquidity from a single token.
|
* This function initializes a new Whirlpool (liquidity pool) on Orca and seeds it with liquidity from a single token.
|
||||||
*
|
*
|
||||||
* ## Example Usage:
|
* ## Example Usage:
|
||||||
* You created a new token called SHARK, and you want to set the initial price to 0.001 USDC.
|
* You created a new token called SHARK, and you want to set the initial price to 0.001 USDC.
|
||||||
* You set `depositTokenMint` to SHARK's mint address and `otherTokenMint` to USDC's mint address.
|
* You set `depositTokenMint` to SHARK's mint address and `otherTokenMint` to USDC's mint address.
|
||||||
@@ -72,7 +72,7 @@ export const FEE_TIERS = {
|
|||||||
* 1. Increase the amount of tokens you deposit
|
* 1. Increase the amount of tokens you deposit
|
||||||
* 2. Set the initial price very low
|
* 2. Set the initial price very low
|
||||||
* 3. Set the maximum price closer to the initial price
|
* 3. Set the maximum price closer to the initial price
|
||||||
*
|
*
|
||||||
* ### Note for experts:
|
* ### Note for experts:
|
||||||
* The Wrhirlpool program initializes the Whirlpool with the in a specific order. This might not be
|
* The Wrhirlpool program initializes the Whirlpool with the in a specific order. This might not be
|
||||||
* the order you expect, so the function checks the order and adjusts the inverts the prices. This means that
|
* the order you expect, so the function checks the order and adjusts the inverts the prices. This means that
|
||||||
@@ -86,13 +86,13 @@ export const FEE_TIERS = {
|
|||||||
* @param initialPrice - The initial price of the deposit token in terms of the other token.
|
* @param initialPrice - The initial price of the deposit token in terms of the other token.
|
||||||
* @param maxPrice - The maximum price at which liquidity is added.
|
* @param maxPrice - The maximum price at which liquidity is added.
|
||||||
* @param feeTier - The fee tier percentage for the pool, determining tick spacing and fee collection rates.
|
* @param feeTier - The fee tier percentage for the pool, determining tick spacing and fee collection rates.
|
||||||
*
|
*
|
||||||
* @returns A promise that resolves to a transaction ID (`string`) of the transaction creating the pool.
|
* @returns A promise that resolves to a transaction ID (`string`) of the transaction creating the pool.
|
||||||
*
|
*
|
||||||
* @throws Will throw an error if:
|
* @throws Will throw an error if:
|
||||||
* - Mint accounts for the tokens cannot be fetched.
|
* - Mint accounts for the tokens cannot be fetched.
|
||||||
* - Prices are out of bounds.
|
* - Prices are out of bounds.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This function is designed for single-sided deposits where users only contribute one type of token,
|
* This function is designed for single-sided deposits where users only contribute one type of token,
|
||||||
* and the function manages mint order and necessary calculations.
|
* and the function manages mint order and necessary calculations.
|
||||||
@@ -103,7 +103,7 @@ export const FEE_TIERS = {
|
|||||||
* import { PublicKey } from "@solana/web3.js";
|
* import { PublicKey } from "@solana/web3.js";
|
||||||
* import { BN } from "@coral-xyz/anchor";
|
* import { BN } from "@coral-xyz/anchor";
|
||||||
* import Decimal from "decimal.js";
|
* import Decimal from "decimal.js";
|
||||||
*
|
*
|
||||||
* const agent = new SolanaAgentKit(wallet, connection);
|
* const agent = new SolanaAgentKit(wallet, connection);
|
||||||
* const depositAmount = new BN(1_000_000_000_000); // 1 million SHARK if SHARK has 6 decimals
|
* const depositAmount = new BN(1_000_000_000_000); // 1 million SHARK if SHARK has 6 decimals
|
||||||
* const depositTokenMint = new PublicKey("DEPOSTI_TOKEN_ADDRESS");
|
* const depositTokenMint = new PublicKey("DEPOSTI_TOKEN_ADDRESS");
|
||||||
@@ -111,7 +111,7 @@ export const FEE_TIERS = {
|
|||||||
* const initialPrice = new Decimal(0.001);
|
* const initialPrice = new Decimal(0.001);
|
||||||
* const maxPrice = new Decimal(5.0);
|
* const maxPrice = new Decimal(5.0);
|
||||||
* const feeTier = 0.30;
|
* const feeTier = 0.30;
|
||||||
*
|
*
|
||||||
* const txId = await createOrcaSingleSidedWhirlpool(
|
* const txId = await createOrcaSingleSidedWhirlpool(
|
||||||
* agent,
|
* agent,
|
||||||
* depositAmount,
|
* depositAmount,
|
||||||
@@ -125,7 +125,7 @@ export const FEE_TIERS = {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export async function createOrcaSingleSidedWhirlpool(
|
export async function createOrcaSingleSidedWhirlpool(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
depositTokenAmount: BN,
|
depositTokenAmount: BN,
|
||||||
depositTokenMint: PublicKey,
|
depositTokenMint: PublicKey,
|
||||||
otherTokenMint: PublicKey,
|
otherTokenMint: PublicKey,
|
||||||
@@ -134,13 +134,19 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
feeTier: keyof typeof FEE_TIERS,
|
feeTier: keyof typeof FEE_TIERS,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const wallet = new Wallet(agent.wallet);
|
const wallet = new Wallet(agent.wallet);
|
||||||
const ctx = WhirlpoolContext.from(agent.connection, wallet, ORCA_WHIRLPOOL_PROGRAM_ID);
|
const ctx = WhirlpoolContext.from(
|
||||||
|
agent.connection,
|
||||||
|
wallet,
|
||||||
|
ORCA_WHIRLPOOL_PROGRAM_ID,
|
||||||
|
);
|
||||||
const fetcher = ctx.fetcher;
|
const fetcher = ctx.fetcher;
|
||||||
|
|
||||||
const correctTokenOrder = PoolUtil.orderMints(otherTokenMint, depositTokenMint).map(
|
const correctTokenOrder = PoolUtil.orderMints(
|
||||||
(addr) => addr.toString(),
|
otherTokenMint,
|
||||||
);
|
depositTokenMint,
|
||||||
const isCorrectMintOrder = correctTokenOrder[0] === depositTokenMint.toString();
|
).map((addr) => addr.toString());
|
||||||
|
const isCorrectMintOrder =
|
||||||
|
correctTokenOrder[0] === depositTokenMint.toString();
|
||||||
let mintA, mintB;
|
let mintA, mintB;
|
||||||
if (isCorrectMintOrder) {
|
if (isCorrectMintOrder) {
|
||||||
[mintA, mintB] = [depositTokenMint, otherTokenMint];
|
[mintA, mintB] = [depositTokenMint, otherTokenMint];
|
||||||
@@ -151,10 +157,18 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
}
|
}
|
||||||
const mintAAccount = await fetcher.getMintInfo(mintA);
|
const mintAAccount = await fetcher.getMintInfo(mintA);
|
||||||
const mintBAccount = await fetcher.getMintInfo(mintB);
|
const mintBAccount = await fetcher.getMintInfo(mintB);
|
||||||
if (mintAAccount === null || mintBAccount === null) throw Error('Mint account not found');
|
if (mintAAccount === null || mintBAccount === null)
|
||||||
|
throw Error("Mint account not found");
|
||||||
const tickSpacing = FEE_TIERS[feeTier];
|
const tickSpacing = FEE_TIERS[feeTier];
|
||||||
const tickIndex = PriceMath.priceToTickIndex(initialPrice, mintAAccount.decimals, mintBAccount.decimals);
|
const tickIndex = PriceMath.priceToTickIndex(
|
||||||
const initialTick = TickUtil.getInitializableTickIndex(tickIndex, tickSpacing);
|
initialPrice,
|
||||||
|
mintAAccount.decimals,
|
||||||
|
mintBAccount.decimals,
|
||||||
|
);
|
||||||
|
const initialTick = TickUtil.getInitializableTickIndex(
|
||||||
|
tickIndex,
|
||||||
|
tickSpacing,
|
||||||
|
);
|
||||||
|
|
||||||
const tokenExtensionCtx: TokenExtensionContextForPool = {
|
const tokenExtensionCtx: TokenExtensionContextForPool = {
|
||||||
...NO_TOKEN_EXTENSION_CONTEXT,
|
...NO_TOKEN_EXTENSION_CONTEXT,
|
||||||
@@ -196,17 +210,17 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
tokenVaultBKeypair,
|
tokenVaultBKeypair,
|
||||||
feeTierKey,
|
feeTierKey,
|
||||||
tickSpacing: tickSpacing,
|
tickSpacing: tickSpacing,
|
||||||
funder: wallet.publicKey
|
funder: wallet.publicKey,
|
||||||
};
|
};
|
||||||
const initPoolIx = !TokenExtensionUtil.isV2IxRequiredPool(tokenExtensionCtx)
|
const initPoolIx = !TokenExtensionUtil.isV2IxRequiredPool(tokenExtensionCtx)
|
||||||
? WhirlpoolIx.initializePoolIx(ctx.program, baseParamsPool)
|
? WhirlpoolIx.initializePoolIx(ctx.program, baseParamsPool)
|
||||||
: WhirlpoolIx.initializePoolV2Ix(ctx.program, {
|
: WhirlpoolIx.initializePoolV2Ix(ctx.program, {
|
||||||
...baseParamsPool,
|
...baseParamsPool,
|
||||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||||
tokenBadgeA,
|
tokenBadgeA,
|
||||||
tokenBadgeB,
|
tokenBadgeB,
|
||||||
});
|
});
|
||||||
const initialTickArrayStartTick = TickUtil.getStartTickIndex(
|
const initialTickArrayStartTick = TickUtil.getStartTickIndex(
|
||||||
initialTick,
|
initialTick,
|
||||||
tickSpacing,
|
tickSpacing,
|
||||||
@@ -235,14 +249,32 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
let tickLowerIndex, tickUpperIndex;
|
let tickLowerIndex, tickUpperIndex;
|
||||||
if (isCorrectMintOrder) {
|
if (isCorrectMintOrder) {
|
||||||
tickLowerIndex = initialTick;
|
tickLowerIndex = initialTick;
|
||||||
tickUpperIndex = PriceMath.priceToTickIndex(maxPrice, mintAAccount.decimals, mintBAccount.decimals);
|
tickUpperIndex = PriceMath.priceToTickIndex(
|
||||||
|
maxPrice,
|
||||||
|
mintAAccount.decimals,
|
||||||
|
mintBAccount.decimals,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
tickLowerIndex = PriceMath.priceToTickIndex(maxPrice, mintAAccount.decimals, mintBAccount.decimals);
|
tickLowerIndex = PriceMath.priceToTickIndex(
|
||||||
|
maxPrice,
|
||||||
|
mintAAccount.decimals,
|
||||||
|
mintBAccount.decimals,
|
||||||
|
);
|
||||||
tickUpperIndex = initialTick;
|
tickUpperIndex = initialTick;
|
||||||
}
|
}
|
||||||
const tickLowerInitializableIndex = TickUtil.getInitializableTickIndex(tickLowerIndex, tickSpacing);
|
const tickLowerInitializableIndex = TickUtil.getInitializableTickIndex(
|
||||||
const tickUpperInitializableIndex = TickUtil.getInitializableTickIndex(tickUpperIndex, tickSpacing);
|
tickLowerIndex,
|
||||||
if (!TickUtil.checkTickInBounds(tickLowerInitializableIndex) || !TickUtil.checkTickInBounds(tickUpperInitializableIndex)) throw Error('Prices out of bounds');
|
tickSpacing,
|
||||||
|
);
|
||||||
|
const tickUpperInitializableIndex = TickUtil.getInitializableTickIndex(
|
||||||
|
tickUpperIndex,
|
||||||
|
tickSpacing,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
!TickUtil.checkTickInBounds(tickLowerInitializableIndex) ||
|
||||||
|
!TickUtil.checkTickInBounds(tickUpperInitializableIndex)
|
||||||
|
)
|
||||||
|
throw Error("Prices out of bounds");
|
||||||
const increasLiquidityQuoteParam: IncreaseLiquidityQuoteParam = {
|
const increasLiquidityQuoteParam: IncreaseLiquidityQuoteParam = {
|
||||||
inputTokenAmount: new BN(depositTokenAmount),
|
inputTokenAmount: new BN(depositTokenAmount),
|
||||||
inputTokenMint: depositTokenMint,
|
inputTokenMint: depositTokenMint,
|
||||||
@@ -253,11 +285,11 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
tickLowerIndex: tickLowerInitializableIndex,
|
tickLowerIndex: tickLowerInitializableIndex,
|
||||||
tickUpperIndex: tickUpperInitializableIndex,
|
tickUpperIndex: tickUpperInitializableIndex,
|
||||||
tokenExtensionCtx: tokenExtensionCtx,
|
tokenExtensionCtx: tokenExtensionCtx,
|
||||||
slippageTolerance: Percentage.fromFraction(0, 100)
|
slippageTolerance: Percentage.fromFraction(0, 100),
|
||||||
}
|
};
|
||||||
const liquidityInput = increaseLiquidityQuoteByInputTokenWithParams(
|
const liquidityInput = increaseLiquidityQuoteByInputTokenWithParams(
|
||||||
increasLiquidityQuoteParam
|
increasLiquidityQuoteParam,
|
||||||
)
|
);
|
||||||
const { liquidityAmount: liquidity, tokenMaxA, tokenMaxB } = liquidityInput;
|
const { liquidityAmount: liquidity, tokenMaxA, tokenMaxB } = liquidityInput;
|
||||||
|
|
||||||
const positionMintKeypair = Keypair.generate();
|
const positionMintKeypair = Keypair.generate();
|
||||||
@@ -285,7 +317,7 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
...params,
|
...params,
|
||||||
positionMint: positionMintPubkey,
|
positionMint: positionMintPubkey,
|
||||||
withTokenMetadataExtension: true,
|
withTokenMetadataExtension: true,
|
||||||
})
|
});
|
||||||
|
|
||||||
txBuilder.addInstruction(positionIx);
|
txBuilder.addInstruction(positionIx);
|
||||||
txBuilder.addSigner(positionMintKeypair);
|
txBuilder.addSigner(positionMintKeypair);
|
||||||
@@ -365,35 +397,33 @@ export async function createOrcaSingleSidedWhirlpool(
|
|||||||
tickArrayUpper: tickArrayUpperPda.publicKey,
|
tickArrayUpper: tickArrayUpperPda.publicKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
const liquidityIx = !TokenExtensionUtil.isV2IxRequiredPool(
|
const liquidityIx = !TokenExtensionUtil.isV2IxRequiredPool(tokenExtensionCtx)
|
||||||
tokenExtensionCtx,
|
|
||||||
)
|
|
||||||
? increaseLiquidityIx(ctx.program, baseParamsLiquidity)
|
? increaseLiquidityIx(ctx.program, baseParamsLiquidity)
|
||||||
: increaseLiquidityV2Ix(ctx.program, {
|
: increaseLiquidityV2Ix(ctx.program, {
|
||||||
...baseParamsLiquidity,
|
...baseParamsLiquidity,
|
||||||
tokenMintA: mintA,
|
tokenMintA: mintA,
|
||||||
tokenMintB: mintB,
|
tokenMintB: mintB,
|
||||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||||
});
|
});
|
||||||
txBuilder.addInstruction(liquidityIx);
|
txBuilder.addInstruction(liquidityIx);
|
||||||
|
|
||||||
const txPayload = await txBuilder.build({
|
const txPayload = await txBuilder.build({
|
||||||
maxSupportedTransactionVersion: "legacy"
|
maxSupportedTransactionVersion: "legacy",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (txPayload.transaction instanceof Transaction) {
|
if (txPayload.transaction instanceof Transaction) {
|
||||||
try {
|
try {
|
||||||
const txId = await sendTx(
|
const txId = await sendTx(agent, txPayload.transaction, [
|
||||||
agent,
|
positionMintKeypair,
|
||||||
txPayload.transaction,
|
tokenVaultAKeypair,
|
||||||
[positionMintKeypair, tokenVaultAKeypair, tokenVaultBKeypair],
|
tokenVaultBKeypair,
|
||||||
);
|
]);
|
||||||
return txId;
|
return txId;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Failed to create pool: ${JSON.stringify(error)}`);
|
throw new Error(`Failed to create pool: ${JSON.stringify(error)}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to create pool: Transaction not created');
|
throw new Error("Failed to create pool: Transaction not created");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { generateSigner, keypairIdentity, publicKey } from "@metaplex-foundation/umi";
|
import {
|
||||||
import { createCollection, mplCore, ruleSet } from "@metaplex-foundation/mpl-core";
|
generateSigner,
|
||||||
|
keypairIdentity,
|
||||||
|
publicKey,
|
||||||
|
} from "@metaplex-foundation/umi";
|
||||||
|
import {
|
||||||
|
createCollection,
|
||||||
|
mplCore,
|
||||||
|
ruleSet,
|
||||||
|
} from "@metaplex-foundation/mpl-core";
|
||||||
import { CollectionOptions, CollectionDeployment } from "../types";
|
import { CollectionOptions, CollectionDeployment } from "../types";
|
||||||
import { fromWeb3JsKeypair, toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
import {
|
||||||
|
fromWeb3JsKeypair,
|
||||||
|
toWeb3JsPublicKey,
|
||||||
|
} from "@metaplex-foundation/umi-web3js-adapters";
|
||||||
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deploy a new NFT collection
|
* Deploy a new NFT collection
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param options Collection options including name, URI, royalties, and creators
|
* @param options Collection options including name, URI, royalties, and creators
|
||||||
* @returns Object containing collection address and metadata
|
* @returns Object containing collection address and metadata
|
||||||
*/
|
*/
|
||||||
export async function deploy_collection(
|
export async function deploy_collection(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
options: CollectionOptions,
|
options: CollectionOptions,
|
||||||
): Promise<CollectionDeployment> {
|
): Promise<CollectionDeployment> {
|
||||||
try {
|
try {
|
||||||
@@ -28,11 +39,11 @@ export async function deploy_collection(
|
|||||||
address: publicKey(creator.address),
|
address: publicKey(creator.address),
|
||||||
percentage: creator.percentage,
|
percentage: creator.percentage,
|
||||||
})) || [
|
})) || [
|
||||||
{
|
{
|
||||||
address: publicKey(agent.wallet_address.toString()),
|
address: publicKey(agent.wallet_address.toString()),
|
||||||
percentage: 100,
|
percentage: 100,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Create collection
|
// Create collection
|
||||||
const tx = await createCollection(umi, {
|
const tx = await createCollection(umi, {
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
||||||
import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi";
|
import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi";
|
||||||
import { createFungible, mintV1, TokenStandard } from "@metaplex-foundation/mpl-token-metadata";
|
import {
|
||||||
import { fromWeb3JsKeypair, fromWeb3JsPublicKey, toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
createFungible,
|
||||||
|
mintV1,
|
||||||
|
TokenStandard,
|
||||||
|
} from "@metaplex-foundation/mpl-token-metadata";
|
||||||
|
import {
|
||||||
|
fromWeb3JsKeypair,
|
||||||
|
fromWeb3JsPublicKey,
|
||||||
|
toWeb3JsPublicKey,
|
||||||
|
} from "@metaplex-foundation/umi-web3js-adapters";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deploy a new SPL token
|
* Deploy a new SPL token
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param name Name of the token
|
* @param name Name of the token
|
||||||
* @param uri URI for the token metadata
|
* @param uri URI for the token metadata
|
||||||
* @param symbol Symbol of the token
|
* @param symbol Symbol of the token
|
||||||
@@ -16,16 +24,16 @@ import { fromWeb3JsKeypair, fromWeb3JsPublicKey, toWeb3JsPublicKey } from "@meta
|
|||||||
* @returns Object containing token mint address and initial account (if supply was minted)
|
* @returns Object containing token mint address and initial account (if supply was minted)
|
||||||
*/
|
*/
|
||||||
export async function deploy_token(
|
export async function deploy_token(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
name: string,
|
name: string,
|
||||||
uri: string,
|
uri: string,
|
||||||
symbol: string,
|
symbol: string,
|
||||||
decimals: number = 9,
|
decimals: number = 9,
|
||||||
initialSupply?: number
|
initialSupply?: number,
|
||||||
): Promise<{ mint: PublicKey }> {
|
): Promise<{ mint: PublicKey }> {
|
||||||
try {
|
try {
|
||||||
// Create UMI instance from agent
|
// Create UMI instance from agent
|
||||||
const umi = createUmi(agent.connection.rpcEndpoint)
|
const umi = createUmi(agent.connection.rpcEndpoint);
|
||||||
umi.use(keypairIdentity(fromWeb3JsKeypair(agent.wallet)));
|
umi.use(keypairIdentity(fromWeb3JsKeypair(agent.wallet)));
|
||||||
|
|
||||||
// Create new token mint
|
// Create new token mint
|
||||||
@@ -51,11 +59,11 @@ export async function deploy_token(
|
|||||||
tokenStandard: TokenStandard.Fungible,
|
tokenStandard: TokenStandard.Fungible,
|
||||||
tokenOwner: fromWeb3JsPublicKey(agent.wallet_address),
|
tokenOwner: fromWeb3JsPublicKey(agent.wallet_address),
|
||||||
amount: initialSupply,
|
amount: initialSupply,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.sendAndConfirm(umi, { confirm: { commitment: 'finalized' } });
|
builder.sendAndConfirm(umi, { confirm: { commitment: "finalized" } });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mint: toWeb3JsPublicKey(mint.publicKey),
|
mint: toWeb3JsPublicKey(mint.publicKey),
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { Tool } from "langchain/tools";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the price of a given token in USDC using Jupiter API
|
* Fetch the price of a given token quoted in USDC using Jupiter API
|
||||||
* @param agent SolanaAgentKit instance
|
|
||||||
* @param tokenId The token mint address
|
* @param tokenId The token mint address
|
||||||
* @returns The price of the token in USDC
|
* @returns The price of the token quoted in USDC
|
||||||
*/
|
*/
|
||||||
export async function fetchPrice(
|
export async function fetchPrice(tokenId: PublicKey): Promise<string> {
|
||||||
agent: SolanaAgentKit,
|
|
||||||
tokenId: string
|
|
||||||
): Promise<string> {
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(`https://api.jup.ag/price/v2?ids=${tokenId}`);
|
||||||
`https://api.jup.ag/price/v2?ids=${tokenId}`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to fetch price: ${response.statusText}`);
|
throw new Error(`Failed to fetch price: ${response.statusText}`);
|
||||||
@@ -22,7 +15,7 @@ export async function fetchPrice(
|
|||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
const price = data.data[tokenId]?.price;
|
const price = data.data[tokenId.toBase58()]?.price;
|
||||||
|
|
||||||
if (!price) {
|
if (!price) {
|
||||||
throw new Error("Price data not available for the given token.");
|
throw new Error("Price data not available for the given token.");
|
||||||
@@ -32,4 +25,4 @@ export async function fetchPrice(
|
|||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(`Price fetch failed: ${error.message}`);
|
throw new Error(`Price fetch failed: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
|
import { LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the balance of SOL or an SPL token for the agent's wallet
|
* Get the balance of SOL or an SPL token for the agent's wallet
|
||||||
* @param agent - SolanaAgentKit instance
|
* @param agent - SolanaAgent instance
|
||||||
* @param token_address - Optional SPL token mint address. If not provided, returns SOL balance
|
* @param token_address - Optional SPL token mint address. If not provided, returns SOL balance
|
||||||
* @returns Promise resolving to the balance as a number (in UI units) or null if account doesn't exist
|
* @returns Promise resolving to the balance as a number (in UI units) or null if account doesn't exist
|
||||||
*/
|
*/
|
||||||
export async function get_balance(
|
export async function get_balance(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
token_address?: PublicKey,
|
token_address?: PublicKey,
|
||||||
): Promise<number | null> {
|
): Promise<number | null> {
|
||||||
if (!token_address)
|
if (!token_address)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service";
|
import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the primary .sol domain associated with a given Solana public key.
|
* Retrieves the primary .sol domain associated with a given Solana public key.
|
||||||
@@ -9,29 +9,29 @@ import { SolanaAgentKit } from "../index";
|
|||||||
* a specified Solana public key. If the primary domain is stale or an error occurs during
|
* a specified Solana public key. If the primary domain is stale or an error occurs during
|
||||||
* the resolution, it throws an error.
|
* the resolution, it throws an error.
|
||||||
*
|
*
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param account The Solana public key for which to retrieve the primary domain
|
* @param account The Solana public key for which to retrieve the primary domain
|
||||||
* @returns A promise that resolves to the primary .sol domain as a string
|
* @returns A promise that resolves to the primary .sol domain as a string
|
||||||
* @throws Error if the domain is stale or if the domain resolution fails
|
* @throws Error if the domain is stale or if the domain resolution fails
|
||||||
*/
|
*/
|
||||||
export async function getPrimaryDomain(
|
export async function getPrimaryDomain(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
account: PublicKey
|
account: PublicKey,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const { reverse, stale } = await _getPrimaryDomain(
|
const { reverse, stale } = await _getPrimaryDomain(
|
||||||
agent.connection,
|
agent.connection,
|
||||||
account
|
account,
|
||||||
);
|
);
|
||||||
if (stale) {
|
if (stale) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Primary domain is stale for account: ${account.toBase58()}`
|
`Primary domain is stale for account: ${account.toBase58()}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return reverse;
|
return reverse;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed to get primary domain for account: ${account.toBase58()}`
|
`Failed to get primary domain for account: ${account.toBase58()}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
export async function getTPS(agent: SolanaAgentKit): Promise<number> {
|
export async function getTPS(agent: SolanaAgentKit): Promise<number> {
|
||||||
const perfSamples = await agent.connection.getRecentPerformanceSamples();
|
const perfSamples = await agent.connection.getRecentPerformanceSamples();
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ export * from "./get_token_data";
|
|||||||
export * from "./stake_with_jup";
|
export * from "./stake_with_jup";
|
||||||
export * from "./fetch_price";
|
export * from "./fetch_price";
|
||||||
export * from "./send_compressed_airdrop";
|
export * from "./send_compressed_airdrop";
|
||||||
|
export * from "./create_orca_single_sided_whirlpool";
|
||||||
export * from "./create_orca_single_sided_whirlpool";export * from "./raydium_create_ammV4";
|
export * from "./raydium_create_ammV4";
|
||||||
export * from "./raydium_create_clmm";
|
export * from "./raydium_create_clmm";
|
||||||
export * from "./raydium_create_cpmm";
|
export * from "./raydium_create_cpmm";
|
||||||
export * from "./openbook_create_market";
|
export * from "./openbook_create_market";
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ async function uploadMetadata(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createTokenTransaction(
|
async function createTokenTransaction(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
mintKeypair: Keypair,
|
mintKeypair: Keypair,
|
||||||
metadataResponse: any,
|
metadataResponse: any,
|
||||||
options?: PumpFunTokenOptions,
|
options?: PumpFunTokenOptions,
|
||||||
@@ -140,7 +140,7 @@ async function signAndSendTransaction(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch a token on Pump.fun
|
* Launch a token on Pump.fun
|
||||||
* @param agent - SolanaAgentKit instance
|
* @param agent - SolanaAgent instance
|
||||||
* @param tokenName - Name of the token
|
* @param tokenName - Name of the token
|
||||||
* @param tokenTicker - Ticker of the token
|
* @param tokenTicker - Ticker of the token
|
||||||
* @param description - Description of the token
|
* @param description - Description of the token
|
||||||
@@ -149,7 +149,7 @@ async function signAndSendTransaction(
|
|||||||
* @returns - Signature of the transaction, mint address and metadata URI, if successful, else error
|
* @returns - Signature of the transaction, mint address and metadata URI, if successful, else error
|
||||||
*/
|
*/
|
||||||
export async function launchPumpFunToken(
|
export async function launchPumpFunToken(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
tokenName: string,
|
tokenName: string,
|
||||||
tokenTicker: string,
|
tokenTicker: string,
|
||||||
description: string,
|
description: string,
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
import { VersionedTransaction } from "@solana/web3.js";
|
import { VersionedTransaction } from "@solana/web3.js";
|
||||||
import { LuloAccountDetailsResponse } from "../types";
|
import { SolanaAgent } from "../index";
|
||||||
import { SolanaAgentKit } from "../agent";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lend tokens for yields using Lulo
|
* Lend tokens for yields using Lulo
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param amount Amount of USDC to lend
|
* @param amount Amount of USDC to lend
|
||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
*/
|
*/
|
||||||
export async function lendAsset(
|
export async function lendAsset(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
amount: number
|
amount: number,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
@@ -23,14 +22,14 @@ export async function lendAsset(
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
account: agent.wallet.publicKey.toBase58(),
|
account: agent.wallet.publicKey.toBase58(),
|
||||||
}),
|
}),
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
// Deserialize the transaction
|
// Deserialize the transaction
|
||||||
const luloTxn = VersionedTransaction.deserialize(
|
const luloTxn = VersionedTransaction.deserialize(
|
||||||
Buffer.from(data.transaction, "base64")
|
Buffer.from(data.transaction, "base64"),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get a recent blockhash and set it
|
// Get a recent blockhash and set it
|
||||||
|
|||||||
@@ -1,22 +1,26 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { generateSigner, keypairIdentity } from '@metaplex-foundation/umi';
|
import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi";
|
||||||
import { create, mplCore } from '@metaplex-foundation/mpl-core';
|
import { create, mplCore } from "@metaplex-foundation/mpl-core";
|
||||||
import { fetchCollection } from '@metaplex-foundation/mpl-core';
|
import { fetchCollection } from "@metaplex-foundation/mpl-core";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { fromWeb3JsKeypair, fromWeb3JsPublicKey, toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
import {
|
||||||
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
|
fromWeb3JsKeypair,
|
||||||
import { MintCollectionNFTResponse } from '../types';
|
fromWeb3JsPublicKey,
|
||||||
|
toWeb3JsPublicKey,
|
||||||
|
} from "@metaplex-foundation/umi-web3js-adapters";
|
||||||
|
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
||||||
|
import { MintCollectionNFTResponse } from "../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mint a new NFT as part of an existing collection
|
* Mint a new NFT as part of an existing collection
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param collectionMint Address of the collection's master NFT
|
* @param collectionMint Address of the collection's master NFT
|
||||||
* @param metadata NFT metadata object
|
* @param metadata NFT metadata object
|
||||||
* @param recipient Optional recipient address (defaults to wallet address)
|
* @param recipient Optional recipient address (defaults to wallet address)
|
||||||
* @returns Object containing NFT mint address and token account
|
* @returns Object containing NFT mint address and token account
|
||||||
*/
|
*/
|
||||||
export async function mintCollectionNFT(
|
export async function mintCollectionNFT(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
collectionMint: PublicKey,
|
collectionMint: PublicKey,
|
||||||
metadata: {
|
metadata: {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -27,7 +31,7 @@ export async function mintCollectionNFT(
|
|||||||
share: number;
|
share: number;
|
||||||
}>;
|
}>;
|
||||||
},
|
},
|
||||||
recipient?: PublicKey
|
recipient?: PublicKey,
|
||||||
): Promise<MintCollectionNFTResponse> {
|
): Promise<MintCollectionNFTResponse> {
|
||||||
try {
|
try {
|
||||||
// Create UMI instance from agent
|
// Create UMI instance from agent
|
||||||
@@ -49,15 +53,15 @@ export async function mintCollectionNFT(
|
|||||||
collection: collection,
|
collection: collection,
|
||||||
name: metadata.name,
|
name: metadata.name,
|
||||||
uri: metadata.uri,
|
uri: metadata.uri,
|
||||||
owner: fromWeb3JsPublicKey(recipient ?? agent.wallet.publicKey)
|
owner: fromWeb3JsPublicKey(recipient ?? agent.wallet.publicKey),
|
||||||
}).sendAndConfirm(umi);
|
}).sendAndConfirm(umi);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
mint: toWeb3JsPublicKey(assetSigner.publicKey),
|
mint: toWeb3JsPublicKey(assetSigner.publicKey),
|
||||||
// Note: Token account is now handled automatically by the create instruction
|
// Note: Token account is now handled automatically by the create instruction
|
||||||
metadata: toWeb3JsPublicKey(assetSigner.publicKey)
|
metadata: toWeb3JsPublicKey(assetSigner.publicKey),
|
||||||
};
|
};
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(`Collection NFT minting failed: ${error.message}`);
|
throw new Error(`Collection NFT minting failed: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
import { OPEN_BOOK_PROGRAM, Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
|
import {
|
||||||
|
OPEN_BOOK_PROGRAM,
|
||||||
|
Raydium,
|
||||||
|
TxVersion,
|
||||||
|
} from "@raydium-io/raydium-sdk-v2";
|
||||||
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
export async function openbookCreateMarket(
|
export async function openbookCreateMarket(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
|
|
||||||
baseMint: PublicKey,
|
baseMint: PublicKey,
|
||||||
quoteMint: PublicKey,
|
quoteMint: PublicKey,
|
||||||
|
|
||||||
lotSize: number = 1,
|
lotSize: number = 1,
|
||||||
tickSize: number = 0.01,
|
tickSize: number = 0.01,
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
|
|
||||||
const raydium = await Raydium.load({
|
const raydium = await Raydium.load({
|
||||||
owner: agent.wallet,
|
owner: agent.wallet,
|
||||||
connection: agent.connection,
|
connection: agent.connection,
|
||||||
})
|
});
|
||||||
|
|
||||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint)
|
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint)
|
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||||
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'openbook market only support TOKEN_PROGRAM_ID mints, if you want to create pool with token-2022, please create raydium cpmm pool instead'
|
"openbook market only support TOKEN_PROGRAM_ID mints, if you want to create pool with token-2022, please create raydium cpmm pool instead",
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { execute } = await raydium.marketV2.create({
|
const { execute } = await raydium.marketV2.create({
|
||||||
@@ -44,9 +45,9 @@ export async function openbookCreateMarket(
|
|||||||
dexProgramId: OPEN_BOOK_PROGRAM,
|
dexProgramId: OPEN_BOOK_PROGRAM,
|
||||||
|
|
||||||
txVersion: TxVersion.V0,
|
txVersion: TxVersion.V0,
|
||||||
})
|
});
|
||||||
|
|
||||||
const { txIds } = await execute({ sequentially: true, })
|
const { txIds } = await execute({ sequentially: true });
|
||||||
|
|
||||||
return txIds
|
return txIds;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,59 @@
|
|||||||
import { AMM_V4, FEE_DESTINATION_ID, MARKET_STATE_LAYOUT_V3, OPEN_BOOK_PROGRAM, Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
|
import {
|
||||||
|
AMM_V4,
|
||||||
|
FEE_DESTINATION_ID,
|
||||||
|
MARKET_STATE_LAYOUT_V3,
|
||||||
|
OPEN_BOOK_PROGRAM,
|
||||||
|
Raydium,
|
||||||
|
TxVersion,
|
||||||
|
} from "@raydium-io/raydium-sdk-v2";
|
||||||
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import BN from 'bn.js';
|
import BN from "bn.js";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
export async function raydiumCreateAmmV4(
|
export async function raydiumCreateAmmV4(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
|
|
||||||
marketId: PublicKey,
|
marketId: PublicKey,
|
||||||
|
|
||||||
baseAmount: BN,
|
baseAmount: BN,
|
||||||
quoteAmount: BN,
|
quoteAmount: BN,
|
||||||
|
|
||||||
startTime: BN,
|
startTime: BN,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
|
||||||
const raydium = await Raydium.load({
|
const raydium = await Raydium.load({
|
||||||
owner: agent.wallet,
|
owner: agent.wallet,
|
||||||
connection: agent.connection,
|
connection: agent.connection,
|
||||||
})
|
});
|
||||||
|
|
||||||
const marketBufferInfo = await agent.connection.getAccountInfo(new PublicKey(marketId))
|
const marketBufferInfo = await agent.connection.getAccountInfo(
|
||||||
const { baseMint, quoteMint } = MARKET_STATE_LAYOUT_V3.decode(marketBufferInfo!.data)
|
new PublicKey(marketId),
|
||||||
|
);
|
||||||
|
const { baseMint, quoteMint } = MARKET_STATE_LAYOUT_V3.decode(
|
||||||
|
marketBufferInfo!.data,
|
||||||
|
);
|
||||||
|
|
||||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint)
|
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint)
|
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||||
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'amm pools with openbook market only support TOKEN_PROGRAM_ID mints, if you want to create pool with token-2022, please create cpmm pool instead'
|
"amm pools with openbook market only support TOKEN_PROGRAM_ID mints, if you want to create pool with token-2022, please create cpmm pool instead",
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseAmount.mul(quoteAmount).lte(new BN(1).mul(new BN(10 ** MintLayout.decode(baseMintInfo.data).decimals)).pow(new BN(2)))) {
|
if (
|
||||||
throw new Error('initial liquidity too low, try adding more baseAmount/quoteAmount')
|
baseAmount
|
||||||
|
.mul(quoteAmount)
|
||||||
|
.lte(
|
||||||
|
new BN(1)
|
||||||
|
.mul(new BN(10 ** MintLayout.decode(baseMintInfo.data).decimals))
|
||||||
|
.pow(new BN(2)),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"initial liquidity too low, try adding more baseAmount/quoteAmount",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { execute } = await raydium.liquidity.createPoolV4({
|
const { execute } = await raydium.liquidity.createPoolV4({
|
||||||
@@ -63,9 +80,9 @@ export async function raydiumCreateAmmV4(
|
|||||||
associatedOnly: false,
|
associatedOnly: false,
|
||||||
txVersion: TxVersion.V0,
|
txVersion: TxVersion.V0,
|
||||||
feeDestinationId: FEE_DESTINATION_ID,
|
feeDestinationId: FEE_DESTINATION_ID,
|
||||||
})
|
});
|
||||||
|
|
||||||
const { txId } = await execute({ sendAndConfirm: true })
|
const { txId } = await execute({ sendAndConfirm: true });
|
||||||
|
|
||||||
return txId
|
return txId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,58 @@
|
|||||||
import { CLMM_PROGRAM_ID, Raydium, TxVersion } from '@raydium-io/raydium-sdk-v2'
|
import {
|
||||||
import { MintLayout } from '@solana/spl-token'
|
CLMM_PROGRAM_ID,
|
||||||
import { PublicKey } from '@solana/web3.js'
|
Raydium,
|
||||||
import BN from 'bn.js'
|
TxVersion,
|
||||||
import Decimal from 'decimal.js'
|
} from "@raydium-io/raydium-sdk-v2";
|
||||||
import { SolanaAgentKit } from '../agent'
|
import { MintLayout } from "@solana/spl-token";
|
||||||
|
import { PublicKey } from "@solana/web3.js";
|
||||||
|
import BN from "bn.js";
|
||||||
|
import Decimal from "decimal.js";
|
||||||
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
export async function raydiumCreateClmm(
|
export async function raydiumCreateClmm(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
|
|
||||||
mint1: PublicKey,
|
mint1: PublicKey,
|
||||||
mint2: PublicKey,
|
mint2: PublicKey,
|
||||||
|
|
||||||
configId: PublicKey,
|
configId: PublicKey,
|
||||||
|
|
||||||
initialPrice: Decimal,
|
initialPrice: Decimal,
|
||||||
startTime: BN,
|
startTime: BN,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
|
||||||
const raydium = await Raydium.load({
|
const raydium = await Raydium.load({
|
||||||
owner: agent.wallet,
|
owner: agent.wallet,
|
||||||
connection: agent.connection,
|
connection: agent.connection,
|
||||||
})
|
});
|
||||||
|
|
||||||
const [mintInfo1, mintInfo2] = await agent.connection.getMultipleAccountsInfo([mint1, mint2])
|
const [mintInfo1, mintInfo2] = await agent.connection.getMultipleAccountsInfo(
|
||||||
if (mintInfo1 === null || mintInfo2 === null) throw Error('fetch mint info error')
|
[mint1, mint2],
|
||||||
|
);
|
||||||
|
if (mintInfo1 === null || mintInfo2 === null)
|
||||||
|
throw Error("fetch mint info error");
|
||||||
|
|
||||||
const mintDecodeInfo1 = MintLayout.decode(mintInfo1.data)
|
const mintDecodeInfo1 = MintLayout.decode(mintInfo1.data);
|
||||||
const mintDecodeInfo2 = MintLayout.decode(mintInfo2.data)
|
const mintDecodeInfo2 = MintLayout.decode(mintInfo2.data);
|
||||||
|
|
||||||
const mintFormatInfo1 = {
|
const mintFormatInfo1 = {
|
||||||
chainId: 101,
|
chainId: 101,
|
||||||
address: mint1.toString(),
|
address: mint1.toString(),
|
||||||
programId: mintInfo1.owner.toString(),
|
programId: mintInfo1.owner.toString(),
|
||||||
logoURI: '',
|
logoURI: "",
|
||||||
symbol: '',
|
symbol: "",
|
||||||
name: '',
|
name: "",
|
||||||
decimals: mintDecodeInfo1.decimals,
|
decimals: mintDecodeInfo1.decimals,
|
||||||
tags: [],
|
tags: [],
|
||||||
extensions: {}
|
extensions: {},
|
||||||
}
|
};
|
||||||
const mintFormatInfo2 = {
|
const mintFormatInfo2 = {
|
||||||
chainId: 101,
|
chainId: 101,
|
||||||
address: mint2.toString(),
|
address: mint2.toString(),
|
||||||
programId: mintInfo2.owner.toString(),
|
programId: mintInfo2.owner.toString(),
|
||||||
logoURI: '',
|
logoURI: "",
|
||||||
symbol: '',
|
symbol: "",
|
||||||
name: '',
|
name: "",
|
||||||
decimals: mintDecodeInfo2.decimals,
|
decimals: mintDecodeInfo2.decimals,
|
||||||
tags: [],
|
tags: [],
|
||||||
extensions: {}
|
extensions: {},
|
||||||
}
|
};
|
||||||
|
|
||||||
const { execute } = await raydium.clmm.createPool({
|
const { execute } = await raydium.clmm.createPool({
|
||||||
programId: CLMM_PROGRAM_ID,
|
programId: CLMM_PROGRAM_ID,
|
||||||
@@ -65,9 +68,9 @@ export async function raydiumCreateClmm(
|
|||||||
// units: 600000,
|
// units: 600000,
|
||||||
// microLamports: 46591500,
|
// microLamports: 46591500,
|
||||||
// },
|
// },
|
||||||
})
|
});
|
||||||
|
|
||||||
const { txId } = await execute({ sendAndConfirm: true })
|
const { txId } = await execute({ sendAndConfirm: true });
|
||||||
|
|
||||||
return txId
|
return txId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,60 +2,58 @@ import {
|
|||||||
CREATE_CPMM_POOL_FEE_ACC,
|
CREATE_CPMM_POOL_FEE_ACC,
|
||||||
CREATE_CPMM_POOL_PROGRAM,
|
CREATE_CPMM_POOL_PROGRAM,
|
||||||
Raydium,
|
Raydium,
|
||||||
TxVersion
|
TxVersion,
|
||||||
} from '@raydium-io/raydium-sdk-v2'
|
} from "@raydium-io/raydium-sdk-v2";
|
||||||
import { MintLayout } from '@solana/spl-token'
|
import { MintLayout } from "@solana/spl-token";
|
||||||
import { PublicKey } from '@solana/web3.js'
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import BN from 'bn.js'
|
import BN from "bn.js";
|
||||||
import { SolanaAgentKit } from '../agent'
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
export async function raydiumCreateCpmm(
|
export async function raydiumCreateCpmm(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
|
|
||||||
mintA: PublicKey,
|
mintA: PublicKey,
|
||||||
mintB: PublicKey,
|
mintB: PublicKey,
|
||||||
|
|
||||||
configId: PublicKey,
|
configId: PublicKey,
|
||||||
|
|
||||||
mintAAmount: BN,
|
mintAAmount: BN,
|
||||||
mintBAmount: BN,
|
mintBAmount: BN,
|
||||||
|
|
||||||
startTime: BN,
|
startTime: BN,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
|
||||||
const raydium = await Raydium.load({
|
const raydium = await Raydium.load({
|
||||||
owner: agent.wallet,
|
owner: agent.wallet,
|
||||||
connection: agent.connection,
|
connection: agent.connection,
|
||||||
})
|
});
|
||||||
|
|
||||||
const [mintInfoA, mintInfoB] = await agent.connection.getMultipleAccountsInfo([mintA, mintB])
|
const [mintInfoA, mintInfoB] = await agent.connection.getMultipleAccountsInfo(
|
||||||
if (mintInfoA === null || mintInfoB === null) throw Error('fetch mint info error')
|
[mintA, mintB],
|
||||||
|
);
|
||||||
|
if (mintInfoA === null || mintInfoB === null)
|
||||||
|
throw Error("fetch mint info error");
|
||||||
|
|
||||||
const mintDecodeInfoA = MintLayout.decode(mintInfoA.data)
|
const mintDecodeInfoA = MintLayout.decode(mintInfoA.data);
|
||||||
const mintDecodeInfoB = MintLayout.decode(mintInfoB.data)
|
const mintDecodeInfoB = MintLayout.decode(mintInfoB.data);
|
||||||
|
|
||||||
const mintFormatInfoA = {
|
const mintFormatInfoA = {
|
||||||
chainId: 101,
|
chainId: 101,
|
||||||
address: mintA.toString(),
|
address: mintA.toString(),
|
||||||
programId: mintInfoA.owner.toString(),
|
programId: mintInfoA.owner.toString(),
|
||||||
logoURI: '',
|
logoURI: "",
|
||||||
symbol: '',
|
symbol: "",
|
||||||
name: '',
|
name: "",
|
||||||
decimals: mintDecodeInfoA.decimals,
|
decimals: mintDecodeInfoA.decimals,
|
||||||
tags: [],
|
tags: [],
|
||||||
extensions: {}
|
extensions: {},
|
||||||
}
|
};
|
||||||
const mintFormatInfoB = {
|
const mintFormatInfoB = {
|
||||||
chainId: 101,
|
chainId: 101,
|
||||||
address: mintB.toString(),
|
address: mintB.toString(),
|
||||||
programId: mintInfoB.owner.toString(),
|
programId: mintInfoB.owner.toString(),
|
||||||
logoURI: '',
|
logoURI: "",
|
||||||
symbol: '',
|
symbol: "",
|
||||||
name: '',
|
name: "",
|
||||||
decimals: mintDecodeInfoB.decimals,
|
decimals: mintDecodeInfoB.decimals,
|
||||||
tags: [],
|
tags: [],
|
||||||
extensions: {}
|
extensions: {},
|
||||||
}
|
};
|
||||||
|
|
||||||
const { execute, extInfo } = await raydium.cpmm.createPool({
|
const { execute, extInfo } = await raydium.cpmm.createPool({
|
||||||
programId: CREATE_CPMM_POOL_PROGRAM,
|
programId: CREATE_CPMM_POOL_PROGRAM,
|
||||||
@@ -76,9 +74,9 @@ export async function raydiumCreateCpmm(
|
|||||||
// units: 600000,
|
// units: 600000,
|
||||||
// microLamports: 46591500,
|
// microLamports: 46591500,
|
||||||
// },
|
// },
|
||||||
})
|
});
|
||||||
|
|
||||||
const { txId } = await execute({ sendAndConfirm: true })
|
const { txId } = await execute({ sendAndConfirm: true });
|
||||||
|
|
||||||
return txId
|
return txId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
import { registerDomainNameV2 } from "@bonfida/spl-name-service";
|
import { registerDomainNameV2 } from "@bonfida/spl-name-service";
|
||||||
import { Transaction } from "@solana/web3.js";
|
import { Transaction } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
||||||
import { TOKENS } from "../constants";
|
import { TOKENS } from "../constants";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a .sol domain name using Bonfida Name Service
|
* Register a .sol domain name using Bonfida Name Service
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param name Domain name to register (without .sol)
|
* @param name Domain name to register (without .sol)
|
||||||
* @param spaceKB Space allocation in KB (max 10KB)
|
* @param spaceKB Space allocation in KB (max 10KB)
|
||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
*/
|
*/
|
||||||
export async function registerDomain(
|
export async function registerDomain(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
name: string,
|
name: string,
|
||||||
spaceKB: number = 1,
|
spaceKB: number = 1,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request SOL from the Solana faucet (devnet/testnet only)
|
* Request SOL from the Solana faucet (devnet/testnet only)
|
||||||
* @param agent - SolanaAgentKit instance
|
* @param agent - SolanaAgent instance
|
||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
* @throws Error if the request fails or times out
|
* @throws Error if the request fails or times out
|
||||||
*/
|
*/
|
||||||
export async function request_faucet_funds(
|
export async function request_faucet_funds(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const tx = await agent.connection.requestAirdrop(
|
const tx = await agent.connection.requestAirdrop(
|
||||||
agent.wallet_address,
|
agent.wallet_address,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { resolve } from "@bonfida/spl-name-service";
|
import { resolve } from "@bonfida/spl-name-service";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a .sol domain to a Solana PublicKey.
|
* Resolves a .sol domain to a Solana PublicKey.
|
||||||
@@ -9,14 +9,14 @@ import { SolanaAgentKit } from "../index";
|
|||||||
* to the corresponding Solana PublicKey. The domain can be provided with or without
|
* to the corresponding Solana PublicKey. The domain can be provided with or without
|
||||||
* the .sol suffix.
|
* the .sol suffix.
|
||||||
*
|
*
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param domain The .sol domain to resolve. This can be provided with or without the .sol TLD suffix
|
* @param domain The .sol domain to resolve. This can be provided with or without the .sol TLD suffix
|
||||||
* @returns A promise that resolves to the corresponding Solana PublicKey
|
* @returns A promise that resolves to the corresponding Solana PublicKey
|
||||||
* @throws Error if the domain resolution fails
|
* @throws Error if the domain resolution fails
|
||||||
*/
|
*/
|
||||||
export async function resolveSolDomain(
|
export async function resolveSolDomain(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
domain: string
|
domain: string,
|
||||||
): Promise<PublicKey> {
|
): Promise<PublicKey> {
|
||||||
if (!domain || typeof domain !== "string") {
|
if (!domain || typeof domain !== "string") {
|
||||||
throw new Error("Invalid domain. Expected a non-empty string.");
|
throw new Error("Invalid domain. Expected a non-empty string.");
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
AddressLookupTableAccount,
|
AddressLookupTableAccount,
|
||||||
ComputeBudgetProgram,
|
ComputeBudgetProgram,
|
||||||
Connection,
|
|
||||||
Keypair,
|
Keypair,
|
||||||
PublicKey,
|
PublicKey,
|
||||||
TransactionInstruction,
|
TransactionInstruction,
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../agent/index.js";
|
import { SolanaAgent } from "../index";
|
||||||
import {
|
import {
|
||||||
buildAndSignTx,
|
buildAndSignTx,
|
||||||
calculateComputeUnitPrice,
|
calculateComputeUnitPrice,
|
||||||
@@ -33,7 +32,7 @@ const MAX_CONCURRENT_TXS = 30;
|
|||||||
*/
|
*/
|
||||||
export const getAirdropCostEstimate = (
|
export const getAirdropCostEstimate = (
|
||||||
numberOfRecipients: number,
|
numberOfRecipients: number,
|
||||||
priorityFeeInLamports: number
|
priorityFeeInLamports: number,
|
||||||
) => {
|
) => {
|
||||||
const baseFee = 5000;
|
const baseFee = 5000;
|
||||||
const perRecipientCompressedStateFee = 300;
|
const perRecipientCompressedStateFee = 300;
|
||||||
@@ -57,28 +56,27 @@ export const getAirdropCostEstimate = (
|
|||||||
* @param shouldLog Whether to log progress to stdout. Defaults to false.
|
* @param shouldLog Whether to log progress to stdout. Defaults to false.
|
||||||
*/
|
*/
|
||||||
export async function sendCompressedAirdrop(
|
export async function sendCompressedAirdrop(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
mintAddress: PublicKey,
|
mintAddress: PublicKey,
|
||||||
amount: number,
|
amount: number,
|
||||||
decimals: number,
|
decimals: number,
|
||||||
recipients: PublicKey[],
|
recipients: PublicKey[],
|
||||||
priorityFeeInLamports: number,
|
priorityFeeInLamports: number,
|
||||||
shouldLog: boolean = false
|
shouldLog: boolean = false,
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
if (recipients.length > MAX_AIRDROP_RECIPIENTS) {
|
if (recipients.length > MAX_AIRDROP_RECIPIENTS) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Max airdrop can be ${MAX_AIRDROP_RECIPIENTS} recipients at a time. For more scale, use open source ZK Compression airdrop tools such as https://github.com/helius-labs/airship.`
|
`Max airdrop can be ${MAX_AIRDROP_RECIPIENTS} recipients at a time. For more scale, use open source ZK Compression airdrop tools such as https://github.com/helius-labs/airship.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const url = agent.connection.rpcEndpoint;
|
const url = agent.connection.rpcEndpoint;
|
||||||
if (url.includes("devnet")) {
|
if (url.includes("devnet")) {
|
||||||
throw new Error("Devnet is not supported for airdrop. Please use mainnet.");
|
throw new Error("Devnet is not supported for airdrop. Please use mainnet.");
|
||||||
}
|
}
|
||||||
if (!url.includes("helius")) {
|
if (!url.includes("helius")) {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Warning: Must use RPC with ZK Compression support. Double check with your RPC provider if in doubt."
|
"Warning: Must use RPC with ZK Compression support. Double check with your RPC provider if in doubt.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,11 +86,11 @@ export async function sendCompressedAirdrop(
|
|||||||
agent.connection,
|
agent.connection,
|
||||||
agent.wallet,
|
agent.wallet,
|
||||||
mintAddress,
|
mintAddress,
|
||||||
agent.wallet.publicKey
|
agent.wallet.publicKey,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Source token account not found and failed to create it. Please add funds to your wallet and try again."
|
"Source token account not found and failed to create it. Please add funds to your wallet and try again.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +98,7 @@ export async function sendCompressedAirdrop(
|
|||||||
await createTokenPool(
|
await createTokenPool(
|
||||||
agent.connection as unknown as Rpc,
|
agent.connection as unknown as Rpc,
|
||||||
agent.wallet,
|
agent.wallet,
|
||||||
mintAddress
|
mintAddress,
|
||||||
);
|
);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
if (error.message.includes("already in use")) {
|
if (error.message.includes("already in use")) {
|
||||||
@@ -116,17 +114,17 @@ export async function sendCompressedAirdrop(
|
|||||||
mintAddress,
|
mintAddress,
|
||||||
recipients,
|
recipients,
|
||||||
priorityFeeInLamports,
|
priorityFeeInLamports,
|
||||||
shouldLog
|
shouldLog,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processAll(
|
async function processAll(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
amount: number,
|
amount: number,
|
||||||
mint: PublicKey,
|
mint: PublicKey,
|
||||||
recipients: PublicKey[],
|
recipients: PublicKey[],
|
||||||
priorityFeeInLamports: number,
|
priorityFeeInLamports: number,
|
||||||
shouldLog: boolean
|
shouldLog: boolean,
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
const mintAddress = mint;
|
const mintAddress = mint;
|
||||||
const payer = agent.wallet;
|
const payer = agent.wallet;
|
||||||
@@ -135,13 +133,13 @@ async function processAll(
|
|||||||
agent.connection,
|
agent.connection,
|
||||||
agent.wallet,
|
agent.wallet,
|
||||||
mintAddress,
|
mintAddress,
|
||||||
agent.wallet.publicKey
|
agent.wallet.publicKey,
|
||||||
);
|
);
|
||||||
|
|
||||||
const maxRecipientsPerInstruction = 5;
|
const maxRecipientsPerInstruction = 5;
|
||||||
const maxIxs = 3; // empirically determined (as of 12/15/2024)
|
const maxIxs = 3; // empirically determined (as of 12/15/2024)
|
||||||
const lookupTableAddress = new PublicKey(
|
const lookupTableAddress = new PublicKey(
|
||||||
"9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ"
|
"9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ",
|
||||||
);
|
);
|
||||||
|
|
||||||
const lookupTableAccount = (
|
const lookupTableAccount = (
|
||||||
@@ -164,7 +162,7 @@ async function processAll(
|
|||||||
ComputeBudgetProgram.setComputeUnitPrice({
|
ComputeBudgetProgram.setComputeUnitPrice({
|
||||||
microLamports: calculateComputeUnitPrice(
|
microLamports: calculateComputeUnitPrice(
|
||||||
priorityFeeInLamports,
|
priorityFeeInLamports,
|
||||||
500_000
|
500_000,
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
@@ -184,13 +182,13 @@ async function processAll(
|
|||||||
toAddress: batch,
|
toAddress: batch,
|
||||||
amount: batch.map(() => amount),
|
amount: batch.map(() => amount),
|
||||||
mint: mintAddress,
|
mint: mintAddress,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const compressIxs = await Promise.all(compressIxPromises);
|
const compressIxs = await Promise.all(compressIxPromises);
|
||||||
return [...instructions, ...compressIxs];
|
return [...instructions, ...compressIxs];
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const url = agent.connection.rpcEndpoint;
|
const url = agent.connection.rpcEndpoint;
|
||||||
@@ -225,12 +223,12 @@ async function processAll(
|
|||||||
instructions,
|
instructions,
|
||||||
payer,
|
payer,
|
||||||
lookupTableAccount,
|
lookupTableAccount,
|
||||||
i + idx
|
i + idx,
|
||||||
).then((signature) => {
|
).then((signature) => {
|
||||||
confirmedCount++;
|
confirmedCount++;
|
||||||
log("\r" + renderProgressBar(confirmedCount, totalBatches));
|
log("\r" + renderProgressBar(confirmedCount, totalBatches));
|
||||||
return signature;
|
return signature;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const batchResults = await Promise.allSettled(batchPromises);
|
const batchResults = await Promise.allSettled(batchPromises);
|
||||||
@@ -250,7 +248,7 @@ async function processAll(
|
|||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed to process ${failures.length} batches: ${failures
|
`Failed to process ${failures.length} batches: ${failures
|
||||||
.map((f) => f.error)
|
.map((f) => f.error)
|
||||||
.join(", ")}`
|
.join(", ")}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,7 +260,7 @@ async function sendTransactionWithRetry(
|
|||||||
instructions: TransactionInstruction[],
|
instructions: TransactionInstruction[],
|
||||||
payer: Keypair,
|
payer: Keypair,
|
||||||
lookupTableAccount: AddressLookupTableAccount,
|
lookupTableAccount: AddressLookupTableAccount,
|
||||||
batchIndex: number
|
batchIndex: number,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const MAX_RETRIES = 3;
|
const MAX_RETRIES = 3;
|
||||||
const INITIAL_BACKOFF = 500; // ms
|
const INITIAL_BACKOFF = 500; // ms
|
||||||
@@ -275,7 +273,7 @@ async function sendTransactionWithRetry(
|
|||||||
payer,
|
payer,
|
||||||
blockhash,
|
blockhash,
|
||||||
[],
|
[],
|
||||||
[lookupTableAccount]
|
[lookupTableAccount],
|
||||||
);
|
);
|
||||||
|
|
||||||
const signature = await sendAndConfirmTx(connection, tx);
|
const signature = await sendAndConfirmTx(connection, tx);
|
||||||
@@ -292,7 +290,7 @@ async function sendTransactionWithRetry(
|
|||||||
throw new Error(
|
throw new Error(
|
||||||
`Batch ${batchIndex} failed after ${attempt + 1} attempts: ${
|
`Batch ${batchIndex} failed after ${attempt + 1} attempts: ${
|
||||||
error.message
|
error.message
|
||||||
}`
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { VersionedTransaction } from "@solana/web3.js";
|
import { VersionedTransaction } from "@solana/web3.js";
|
||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../index";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stake SOL with Jup validator
|
* Stake SOL with Jup validator
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param amount Amount of SOL to stake
|
* @param amount Amount of SOL to stake
|
||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
*/
|
*/
|
||||||
export async function stakeWithJup(
|
export async function stakeWithJup(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
amount: number,
|
amount: number,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { VersionedTransaction, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
|
import {
|
||||||
import { SolanaAgentKit } from "../index";
|
VersionedTransaction,
|
||||||
|
PublicKey,
|
||||||
|
LAMPORTS_PER_SOL,
|
||||||
|
} from "@solana/web3.js";
|
||||||
|
import { SolanaAgent } from "../index";
|
||||||
import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swap tokens using Jupiter Exchange
|
* Swap tokens using Jupiter Exchange
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param outputMint Target token mint address
|
* @param outputMint Target token mint address
|
||||||
* @param inputAmount Amount to swap (in token decimals)
|
* @param inputAmount Amount to swap (in token decimals)
|
||||||
* @param inputMint Source token mint address (defaults to USDC)
|
* @param inputMint Source token mint address (defaults to USDC)
|
||||||
@@ -12,7 +16,7 @@ import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
|||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
*/
|
*/
|
||||||
export async function trade(
|
export async function trade(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
outputMint: PublicKey,
|
outputMint: PublicKey,
|
||||||
inputAmount: number,
|
inputAmount: number,
|
||||||
inputMint: PublicKey = TOKENS.USDC,
|
inputMint: PublicKey = TOKENS.USDC,
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
import { SolanaAgentKit } from "../index";
|
import { SolanaAgent } from "../index";
|
||||||
import {
|
import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js";
|
||||||
PublicKey,
|
|
||||||
SystemProgram,
|
|
||||||
Transaction
|
|
||||||
} from "@solana/web3.js";
|
|
||||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||||
import {
|
import {
|
||||||
getAssociatedTokenAddress,
|
getAssociatedTokenAddress,
|
||||||
createTransferInstruction,
|
createTransferInstruction,
|
||||||
getMint
|
getMint,
|
||||||
} from "@solana/spl-token";
|
} from "@solana/spl-token";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer SOL or SPL tokens to a recipient
|
* Transfer SOL or SPL tokens to a recipient
|
||||||
* @param agent SolanaAgentKit instance
|
* @param agent SolanaAgent instance
|
||||||
* @param to Recipient's public key
|
* @param to Recipient's public key
|
||||||
* @param amount Amount to transfer
|
* @param amount Amount to transfer
|
||||||
* @param mint Optional mint address for SPL tokens
|
* @param mint Optional mint address for SPL tokens
|
||||||
* @returns Transaction signature
|
* @returns Transaction signature
|
||||||
*/
|
*/
|
||||||
export async function transfer(
|
export async function transfer(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
to: PublicKey,
|
to: PublicKey,
|
||||||
amount: number,
|
amount: number,
|
||||||
mint?: PublicKey
|
mint?: PublicKey,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try {
|
try {
|
||||||
let tx: string;
|
let tx: string;
|
||||||
@@ -34,19 +30,19 @@ export async function transfer(
|
|||||||
SystemProgram.transfer({
|
SystemProgram.transfer({
|
||||||
fromPubkey: agent.wallet_address,
|
fromPubkey: agent.wallet_address,
|
||||||
toPubkey: to,
|
toPubkey: to,
|
||||||
lamports: amount * LAMPORTS_PER_SOL
|
lamports: amount * LAMPORTS_PER_SOL,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
tx = await agent.connection.sendTransaction(
|
tx = await agent.connection.sendTransaction(transaction, [agent.wallet]);
|
||||||
transaction,
|
|
||||||
[agent.wallet]
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// Transfer SPL token
|
// Transfer SPL token
|
||||||
const fromAta = await getAssociatedTokenAddress(mint, agent.wallet_address);
|
const fromAta = await getAssociatedTokenAddress(
|
||||||
|
mint,
|
||||||
|
agent.wallet_address,
|
||||||
|
);
|
||||||
const toAta = await getAssociatedTokenAddress(mint, to);
|
const toAta = await getAssociatedTokenAddress(mint, to);
|
||||||
|
|
||||||
// Get mint info to determine decimals
|
// Get mint info to determine decimals
|
||||||
const mintInfo = await getMint(agent.connection, mint);
|
const mintInfo = await getMint(agent.connection, mint);
|
||||||
const adjustedAmount = amount * Math.pow(10, mintInfo.decimals);
|
const adjustedAmount = amount * Math.pow(10, mintInfo.decimals);
|
||||||
@@ -56,18 +52,15 @@ export async function transfer(
|
|||||||
fromAta,
|
fromAta,
|
||||||
toAta,
|
toAta,
|
||||||
agent.wallet_address,
|
agent.wallet_address,
|
||||||
adjustedAmount
|
adjustedAmount,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
tx = await agent.connection.sendTransaction(
|
tx = await agent.connection.sendTransaction(transaction, [agent.wallet]);
|
||||||
transaction,
|
|
||||||
[agent.wallet]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(`Transfer failed: ${error.message}`);
|
throw new Error(`Transfer failed: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SolanaAgentKit } from "../agent";
|
import { SolanaAgent } from "../agent";
|
||||||
import { Transaction, Keypair, TransactionInstruction } from "@solana/web3.js";
|
import { Transaction, Keypair, TransactionInstruction } from "@solana/web3.js";
|
||||||
import { Connection, ComputeBudgetProgram } from "@solana/web3.js";
|
import { Connection, ComputeBudgetProgram } from "@solana/web3.js";
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ export async function getPriorityFees(connection: Connection): Promise<{
|
|||||||
const median =
|
const median =
|
||||||
sortedFees.length % 2 === 0
|
sortedFees.length % 2 === 0
|
||||||
? ((sortedFees[mid - 1] ?? 0) + (sortedFees[mid] ?? 0)) / 2
|
? ((sortedFees[mid - 1] ?? 0) + (sortedFees[mid] ?? 0)) / 2
|
||||||
: sortedFees[mid] ?? 0;
|
: (sortedFees[mid] ?? 0);
|
||||||
|
|
||||||
// Helper to create priority fee IX based on chosen strategy
|
// Helper to create priority fee IX based on chosen strategy
|
||||||
const createPriorityFeeIx = (fee: number) => {
|
const createPriorityFeeIx = (fee: number) => {
|
||||||
@@ -69,14 +69,14 @@ export async function getPriorityFees(connection: Connection): Promise<{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a transaction with priority fees
|
* Send a transaction with priority fees
|
||||||
* @param agent - SolanaAgentKit instance
|
* @param agent - SolanaAgent instance
|
||||||
* @param tx - Transaction to send
|
* @param tx - Transaction to send
|
||||||
* @returns Transaction ID
|
* @returns Transaction ID
|
||||||
*/
|
*/
|
||||||
export async function sendTx(
|
export async function sendTx(
|
||||||
agent: SolanaAgentKit,
|
agent: SolanaAgent,
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
otherKeypairs?: Keypair[]
|
otherKeypairs?: Keypair[],
|
||||||
) {
|
) {
|
||||||
tx.recentBlockhash = (await agent.connection.getLatestBlockhash()).blockhash;
|
tx.recentBlockhash = (await agent.connection.getLatestBlockhash()).blockhash;
|
||||||
tx.feePayer = agent.wallet_address;
|
tx.feePayer = agent.wallet_address;
|
||||||
@@ -90,9 +90,8 @@ export async function sendTx(
|
|||||||
await agent.connection.confirmTransaction({
|
await agent.connection.confirmTransaction({
|
||||||
signature: txid,
|
signature: txid,
|
||||||
blockhash: (await agent.connection.getLatestBlockhash()).blockhash,
|
blockhash: (await agent.connection.getLatestBlockhash()).blockhash,
|
||||||
lastValidBlockHeight: (
|
lastValidBlockHeight: (await agent.connection.getLatestBlockhash())
|
||||||
await agent.connection.getLatestBlockhash()
|
.lastValidBlockHeight,
|
||||||
).lastValidBlockHeight,
|
|
||||||
});
|
});
|
||||||
return txid;
|
return txid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SolanaAgentKit } from "../src";
|
import { SolanaAgent } from "../src";
|
||||||
import { createSolanaTools } from "../src/langchain";
|
import { createSolanaTools } from "../src/langchain";
|
||||||
import { HumanMessage } from "@langchain/core/messages";
|
import { HumanMessage } from "@langchain/core/messages";
|
||||||
import { MemorySaver } from "@langchain/langgraph";
|
import { MemorySaver } from "@langchain/langgraph";
|
||||||
@@ -14,7 +14,7 @@ function validateEnvironment(): void {
|
|||||||
const missingVars: string[] = [];
|
const missingVars: string[] = [];
|
||||||
const requiredVars = ["OPENAI_API_KEY", "RPC_URL", "SOLANA_PRIVATE_KEY"];
|
const requiredVars = ["OPENAI_API_KEY", "RPC_URL", "SOLANA_PRIVATE_KEY"];
|
||||||
|
|
||||||
requiredVars.forEach(varName => {
|
requiredVars.forEach((varName) => {
|
||||||
if (!process.env[varName]) {
|
if (!process.env[varName]) {
|
||||||
missingVars.push(varName);
|
missingVars.push(varName);
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ function validateEnvironment(): void {
|
|||||||
|
|
||||||
if (missingVars.length > 0) {
|
if (missingVars.length > 0) {
|
||||||
console.error("Error: Required environment variables are not set");
|
console.error("Error: Required environment variables are not set");
|
||||||
missingVars.forEach(varName => {
|
missingVars.forEach((varName) => {
|
||||||
console.error(`${varName}=your_${varName.toLowerCase()}_here`);
|
console.error(`${varName}=your_${varName.toLowerCase()}_here`);
|
||||||
});
|
});
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@@ -50,13 +50,13 @@ async function initializeAgent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const solanaKit = new SolanaAgentKit(
|
const solanaAgent = new SolanaAgent(
|
||||||
process.env.SOLANA_PRIVATE_KEY!,
|
process.env.SOLANA_PRIVATE_KEY!,
|
||||||
process.env.RPC_URL,
|
process.env.RPC_URL,
|
||||||
process.env.OPENAI_API_KEY!
|
process.env.OPENAI_API_KEY!,
|
||||||
);
|
);
|
||||||
|
|
||||||
const tools = createSolanaTools(solanaKit);
|
const tools = createSolanaTools(solanaAgent);
|
||||||
const memory = new MemorySaver();
|
const memory = new MemorySaver();
|
||||||
const config = { configurable: { thread_id: "Solana Agent Kit!" } };
|
const config = { configurable: { thread_id: "Solana Agent Kit!" } };
|
||||||
|
|
||||||
@@ -65,13 +65,13 @@ async function initializeAgent() {
|
|||||||
tools,
|
tools,
|
||||||
checkpointSaver: memory,
|
checkpointSaver: memory,
|
||||||
messageModifier: `
|
messageModifier: `
|
||||||
You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
|
You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
|
||||||
empowered to interact onchain using your tools. If you ever need funds, you can request them from the
|
empowered to interact onchain using your tools. If you ever need funds, you can request them from the
|
||||||
faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
|
faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
|
||||||
(internal) HTTP error code, ask the user to try again later. If someone asks you to do something you
|
(internal) HTTP error code, ask the user to try again later. If someone asks you to do something you
|
||||||
can't do with your currently available tools, you must say so, and encourage them to implement it
|
can't do with your currently available tools, you must say so, and encourage them to implement it
|
||||||
themselves using the Solana Agent Kit, recommend they go to https://sendai.fun/kit for more information. Be
|
themselves using the Solana Agent Kit, recommend they go to https://sendai.fun/kit for more information. Be
|
||||||
concise and helpful with your responses. Refrain from restating your tools' descriptions unless it is
|
concise and helpful with your responses. Refrain from restating your tools' descriptions unless it is
|
||||||
explicitly requested.
|
explicitly requested.
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
@@ -96,7 +96,10 @@ async function runAutonomousMode(agent: any, config: any, interval = 10) {
|
|||||||
"Be creative and do something interesting on the blockchain. " +
|
"Be creative and do something interesting on the blockchain. " +
|
||||||
"Choose an action or set of actions and execute it that highlights your abilities.";
|
"Choose an action or set of actions and execute it that highlights your abilities.";
|
||||||
|
|
||||||
const stream = await agent.stream({ messages: [new HumanMessage(thought)] }, config);
|
const stream = await agent.stream(
|
||||||
|
{ messages: [new HumanMessage(thought)] },
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
|
||||||
for await (const chunk of stream) {
|
for await (const chunk of stream) {
|
||||||
if ("agent" in chunk) {
|
if ("agent" in chunk) {
|
||||||
@@ -107,7 +110,7 @@ async function runAutonomousMode(agent: any, config: any, interval = 10) {
|
|||||||
console.log("-------------------");
|
console.log("-------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, interval * 1000));
|
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
console.error("Error:", error.message);
|
console.error("Error:", error.message);
|
||||||
@@ -126,7 +129,7 @@ async function runChatMode(agent: any, config: any) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const question = (prompt: string): Promise<string> =>
|
const question = (prompt: string): Promise<string> =>
|
||||||
new Promise(resolve => rl.question(prompt, resolve));
|
new Promise((resolve) => rl.question(prompt, resolve));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -136,7 +139,10 @@ async function runChatMode(agent: any, config: any) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stream = await agent.stream({ messages: [new HumanMessage(userInput)] }, config);
|
const stream = await agent.stream(
|
||||||
|
{ messages: [new HumanMessage(userInput)] },
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
|
||||||
for await (const chunk of stream) {
|
for await (const chunk of stream) {
|
||||||
if ("agent" in chunk) {
|
if ("agent" in chunk) {
|
||||||
@@ -164,7 +170,7 @@ async function chooseMode(): Promise<"chat" | "auto"> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const question = (prompt: string): Promise<string> =>
|
const question = (prompt: string): Promise<string> =>
|
||||||
new Promise(resolve => rl.question(prompt, resolve));
|
new Promise((resolve) => rl.question(prompt, resolve));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
console.log("\nAvailable modes:");
|
console.log("\nAvailable modes:");
|
||||||
@@ -206,7 +212,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main().catch(error => {
|
main().catch((error) => {
|
||||||
console.error("Fatal error:", error);
|
console.error("Fatal error:", error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user