Merge branch 'main' into jup-list

This commit is contained in:
aryan
2024-12-19 05:45:01 +05:30
30 changed files with 3384 additions and 89 deletions

3
.env.example Normal file
View File

@@ -0,0 +1,3 @@
OPENAI_API_KEY=
HELIUS_API_KEY=
SOLANA_PRIVATE_KEY=

154
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,154 @@
# Contributing to Solana Agent Kit
First off, thank you for considering contributing to Solana Agent Kit! 🎉 Your contributions are **greatly appreciated**.
## Table of Contents
- [Contributing to Solana Agent Kit](#contributing-to-solana-agent-kit)
- [Table of Contents](#table-of-contents)
- [Code of Conduct](#code-of-conduct)
- [How Can I Contribute?](#how-can-i-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Pull Requests](#pull-requests)
- [Style Guides](#style-guides)
- [Code Style](#code-style)
- [Commit Messages](#commit-messages)
- [Naming Conventions](#naming-conventions)
- [Development Setup](#development-setup)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Building the Project](#building-the-project)
- [Running Tests](#running-tests)
- [Generating Documentation](#generating-documentation)
- [Security](#security)
- [License](#license)
## Code of Conduct
This project adheres to the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/0/code_of_conduct/). By participating, you are expected to uphold this code. Please report unacceptable behavior to [aryan@sendai.fun](mailto:aryan@sendai.fun).
## How Can I Contribute?
### Reporting Bugs
**Great**! Opening an issue is the best way to help us improve. Here's how you can report a bug:
1. **Search** the [existing issues](https://github.com/sendaifun/solana-agent-kit/issues) to make sure it hasn't been reported.
2. **Open a new issue** and fill out the template with as much information as possible.
3. **Provide reproduction steps** if applicable.
### Suggesting Enhancements
We welcome your ideas for improving Solana Agent Kit! To suggest an enhancement:
1. **Search** the [existing issues](https://github.com/sendaifun/solana-agent-kit/issues) to see if it's already been suggested.
2. **Open a new issue** and describe your idea in detail.
### Your First Code Contribution
Unsure where to start? You can help out by:
- Fixing simple bugs.
- Improving documentation.
- Adding tests.
Check out the [Good First Issues](https://github.com/sendaifun/solana-agent-kit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) to get started!
### Pull Requests
1. **Fork** the repository.
2. **Create** a new branch for your feature or bugfix.
```bash
git checkout -b feature/your-feature-name
```
3. **Commit** your changes with clear and descriptive messages.
4. **Push** to your fork.
```bash
git push origin feature/your-feature-name
```
5. **Open a Pull Request** against the `main` branch of this repository.
## Style Guides
### Code Style
- **Language**: TypeScript
- **Formatting**: Follow the existing codebase formatting. Consider using [Prettier](https://prettier.io/) for consistent code formatting.
- **Linting**: Adhere to the linting rules defined in `.eslintrc`. Ensure all linting checks pass before submitting a PR.
### Commit Messages
Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) for your commit messages. Examples:
- `feat: add ability to deploy new SPL token`
- `fix: handle edge case when deploying collection`
- `docs: update README with new usage examples`
### Naming Conventions
- **Variables and Functions**: `camelCase`
- **Classes and Types**: `PascalCase`
- **Constants**: `UPPER_SNAKE_CASE`
## Development Setup
### Prerequisites
- **Node.js**: v23.x or higher
- **npm**: v10.x or higher
- **Git**: Installed and configured
### Installation
1. **Clone** the repository:
```bash
git clone https://github.com/yourusername/solana-agent-kit.git
```
2. **Navigate** to the project directory:
```bash
cd solana-agent-kit
```
3. **Install** dependencies:
```bash
pnpm install
```
### Building the Project
To compile the TypeScript code:
```bash
pnpm run build
```
### Running Tests
To execute the test suite:
```bash
pnpm run test
```
### Generating Documentation
To generate the project documentation using TypeDoc:
```bash
npm run docs
```
The documentation will be available in the `docs/` directory.
## Security
This toolkit handles sensitive information such as private keys and API keys. **Ensure you never commit `.env` files or any sensitive data**. Review the `.gitignore` to confirm that sensitive files are excluded.
For security vulnerabilities, please follow the [responsible disclosure](mailto:aryan@sendai.fun) process.
## License
This project is licensed under the [ISC License](LICENSE).
---

21
LICENSE.md Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 SendAI
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -5,21 +5,26 @@ A powerful toolkit for interacting with the Solana blockchain, providing easy-to
## Features
- 🪙 Token Operations
- Deploy new SPL tokens
- Transfer SOL and SPL tokens
- Check token balances
- Stake SOL
- 🖼️ NFT Management
- Deploy NFT collections
- Mint NFTs to collections
- Manage metadata and royalties
- 💱 Trading
- Integrated Jupiter Exchange support
- Token swaps with customizable slippage
- Direct routing options
- 🏦 Yield Farming
- Lend idle assets to earn interest with Lulo
- 🔗 LangChain Integration
@@ -35,12 +40,13 @@ npm install solana-agent-kit
## Quick Start
```typescript
import { SolanaAgentKit, createSolanaTools } from 'solana-agent-kit';
import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
// Initialize with private key and optional RPC URL
const agent = new SolanaAgentKit(
'your-private-key',
'https://api.mainnet-beta.solana.com'
"your-wallet-private-key-as-base58",
"https://api.mainnet-beta.solana.com",
"your-openai-api-key"
);
// Create LangChain tools
@@ -52,87 +58,122 @@ const tools = createSolanaTools(agent);
### Deploy a New Token
```typescript
import { deploy_token } from 'solana-agent-kit';
import { deploy_token } from "solana-agent-kit";
const result = await deploy_token(
agent,
9, // decimals
1000000 // initial supply
agent,
9, // decimals
1000000 // initial supply
);
console.log('Token Mint Address:', result.mint.toString());
console.log("Token Mint Address:", result.mint.toString());
```
### Create NFT Collection
```typescript
import { deploy_collection } from 'solana-agent-kit';
import { deploy_collection } from "solana-agent-kit";
const collection = await deploy_collection(agent, {
name: "My NFT Collection",
uri: "https://arweave.net/metadata.json",
royaltyBasisPoints: 500, // 5%
creators: [
{
address: "creator-wallet-address",
percentage: 100
}
]
name: "My NFT Collection",
uri: "https://arweave.net/metadata.json",
royaltyBasisPoints: 500, // 5%
creators: [
{
address: "creator-wallet-address",
percentage: 100,
},
],
});
```
### Swap Tokens
```typescript
import { trade } from 'solana-agent-kit';
import { PublicKey } from '@solana/web3.js';
import { trade } from "solana-agent-kit";
import { PublicKey } from "@solana/web3.js";
const signature = await trade(
agent,
new PublicKey('target-token-mint'),
100, // amount
new PublicKey('source-token-mint'),
300 // 3% slippage
agent,
new PublicKey("target-token-mint"),
100, // amount
new PublicKey("source-token-mint"),
300 // 3% slippage
);
```
### Lend Tokens
```typescript
import { lendAsset } from 'solana-agent-kit';
import { PublicKey } from '@solana/web3.js';
import { lendAsset } from "solana-agent-kit";
import { PublicKey } from "@solana/web3.js";
const signature = await lendAsset(
agent,
100, // amount
agent,
100 // amount
);
```
### Stake SOL
```typescript
import { stakeWithJup } from "solana-agent-kit";
const signature = await stakeWithJup(
agent,
1 // amount in SOL
);
```
### Fetch Token Price
```typescript
import { fetchPrice } from "solana-agent-kit";
const price = await fetchPrice(
agent,
"JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" // Token mint address
);
console.log("Price in USDC:", price);
```
## API Reference
### Core Functions
#### `deploy_token(agent, decimals?, initialSupply?)`
Deploy a new SPL token with optional initial supply.
#### `deploy_collection(agent, options)`
Create a new NFT collection with customizable metadata and royalties.
#### `mintCollectionNFT(agent, collectionMint, metadata, recipient?)`
Mint a new NFT as part of an existing collection.
#### `transfer(agent, to, amount, mint?)`
Transfer SOL or SPL tokens to a recipient.
#### `trade(agent, outputMint, inputAmount, inputMint?, slippageBps?)`
Swap tokens using Jupiter Exchange integration.
#### `get_balance(agent, token_address)`
Check SOL or token balance for the agent's wallet.
#### `lendAsset(agent, assetMint, amount, apiKey)`
Lend idle assets to earn interest with Lulo.
#### `stakeWithJup(agent, amount)`
Stake SOL with Jupiter to earn rewards.
## Dependencies
The toolkit relies on several key Solana and Metaplex libraries:

View File

@@ -1 +1 @@
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE4XSTUsDQQwG4P+S8+Ji0SJ7K5ZerB/o3sTDMGbdodlk2GRAkf53qRXt4nR6mUveeUJInj/B8N2ggSchx27xhmw3waCC6KyHBjw5VdR6Wj/rbSCoYBP4FZrz2dW2+pWuhQi9BeElRpKPAfnAC2w4ds6j1rngFJ5dzrPwfdy9ekL9SRXJEZ3JmIf2tdL3dSJZeC+JbYnmAukjahRWzIrH46Umt4Htb6i7VVvscTRdavGQhtglXrvEvi/y2eQpepW4lQ0W15bJlVi/Ww7uj7IVoQO0S/w9u9b/QlNxfrF9+QJeMbLbAQMAAA=="
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE4XTQUvDMBTA8e+Sc7E4dEhvw9KDzm1ob+IhxNc1LH0vJC+gyL67bBNdXfZ26SX//l4T0tcvxfDBqlIv5DTq2RqQHy2rQnnNvaqUcTpGiOV4/arnwalCbSy+q+p6crctfqV7cg4MW8IavKPPAfDIs8gQOm0glrlwDE9up1l46XfPeEH9qUQygGYKeeiwJr3eAJt+FayBZ4ieMEJWOs0k9CF5yxBa2gDWmnWW/B9J4Dw5mhlDCbkG1tZF8WvP59KQJ4v8d/SLphVnnK2lEas0+C7hXCc0vchny0t0k3B/nNLlynQSa3ZXCA6/TkvkjtAu4X7vsTyJxuL0Zvv2DYU9ByOnAwAA"

View File

@@ -1 +1 @@
window.searchData = "data:application/octet-stream;base64,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";
window.searchData = "data:application/octet-stream;base64,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";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,6 +2,8 @@
</div></section><section class="tsd-index-section"><h3 class="tsd-index-heading">Interfaces</h3><div class="tsd-index-list"><a href="interfaces/CollectionDeployment.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Collection<wbr/>Deployment</span></a>
<a href="interfaces/CollectionOptions.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Collection<wbr/>Options</span></a>
<a href="interfaces/Creator.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Creator</span></a>
<a href="interfaces/FetchPriceResponse.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Fetch<wbr/>Price<wbr/>Response</span></a>
<a href="interfaces/JupiterTokenData.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Jupiter<wbr/>Token<wbr/>Data</span></a>
<a href="interfaces/LuloAccountDetailsResponse.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Lulo<wbr/>Account<wbr/>Details<wbr/>Response</span></a>
<a href="interfaces/MintCollectionNFTResponse.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Mint<wbr/>CollectionNFTResponse</span></a>
<a href="interfaces/PumpfunLaunchResponse.html" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-256"></use></svg><span>Pumpfun<wbr/>Launch<wbr/>Response</span></a>

2900
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "solana-agent-kit",
"version": "1.1.0",
"version": "1.1.1",
"description": "A toolkit for interacting with the Solana blockchain using LangChain",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -14,6 +14,7 @@ import {
getTPS,
getTokenDataByAddress,
getTokenDataByTicker,
stakeWithJup,
} from "../tools";
import { CollectionOptions, PumpFunTokenOptions } from "../types";
import { DEFAULT_OPTIONS } from "../constants";
@@ -121,4 +122,10 @@ export class SolanaAgentKit {
options
);
}
async stake(
amount: number,
) {
return stakeWithJup(this, amount);
}
}

View File

@@ -3,6 +3,7 @@ import { SolanaAgentKit } from "../index";
import { PublicKey } from "@solana/web3.js";
import { toJSON } from "../utils/toJSON";
import { create_image } from "../tools/create_image";
import { fetchPrice } from "../tools/fetch_price";
export class SolanaBalanceTool extends Tool {
name = "solana_balance";
@@ -567,6 +568,71 @@ export class SolanaTPSCalculatorTool extends Tool {
}
}
export class SolanaStakeTool extends Tool {
name = "solana_stake";
description = `This tool can be used to stake your SOL (Solana), also called as SOL staking or liquid staking.
Inputs ( input is a JSON string ):
amount: number, eg 1 or 0.01 (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input) || Number(input);
const tx = await this.solanaKit.stake(parsedInput.amount);
return JSON.stringify({
status: "success",
message: "Staked successfully",
transaction: tx,
amount: parsedInput.amount,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
/**
* Tool to fetch the price of a token in USDC
*/
export class SolanaFetchPriceTool extends Tool {
name = "solana_fetch_price";
description = `Fetch the price of a given token in USDC.
Inputs:
- tokenId: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
const price = await fetchPrice(this.solanaKit, input.trim());
return JSON.stringify({
status: "success",
tokenId: input.trim(),
priceInUSDC: price,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
export class SolanaTokenDataTool extends Tool {
name = "solana_token_data";
description = `Get the token data for a given token mint address
@@ -644,6 +710,8 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaCreateImageTool(solanaKit),
new SolanaLendAssetTool(solanaKit),
new SolanaTPSCalculatorTool(solanaKit),
new SolanaStakeTool(solanaKit),
new SolanaFetchPriceTool(solanaKit),
new SolanaTokenDataTool(solanaKit),
new SolanaTokenDataByTickerTool(solanaKit),
];

View File

@@ -27,10 +27,6 @@ export async function deploy_token(
);
const mint = Keypair.generate();
console.log("Mint address: ", mint.publicKey.toString());
console.log("Agent address: ", agent.wallet_address.toString());
let account_create_ix = SystemProgram.createAccount({
fromPubkey: agent.wallet_address,
newAccountPubkey: mint.publicKey,
@@ -51,13 +47,6 @@ export async function deploy_token(
let hash = await sendTx(agent, tx, [mint]);
console.log("Transaction hash: ", hash);
console.log(
"Token deployed successfully. Mint address: ",
mint.publicKey.toString()
);
return {
mint: mint.publicKey,
};

35
src/tools/fetch_price.ts Normal file
View File

@@ -0,0 +1,35 @@
import { SolanaAgentKit } from "../index";
import { Tool } from "langchain/tools";
/**
* Fetch the price of a given token in USDC using Jupiter API
* @param agent SolanaAgentKit instance
* @param tokenId The token mint address
* @returns The price of the token in USDC
*/
export async function fetchPrice(
agent: SolanaAgentKit,
tokenId: string
): Promise<string> {
try {
const response = await fetch(
`https://api.jup.ag/price/v2?ids=${tokenId}`
);
if (!response.ok) {
throw new Error(`Failed to fetch price: ${response.statusText}`);
}
const data = await response.json();
const price = data.data[tokenId]?.price;
if (!price) {
throw new Error("Price data not available for the given token.");
}
return price;
} catch (error: any) {
throw new Error(`Price fetch failed: ${error.message}`);
}
}

View File

@@ -10,3 +10,5 @@ export * from "./launch_pumpfun_token";
export * from "./lend";
export * from "./get_tps";
export * from "./get_token_data";
export * from './stake_with_jup';
export * from "./fetch_price";

View File

@@ -38,7 +38,6 @@ async function uploadMetadata(
finalFormData.append('file', files.file);
}
console.log("Final form data:", finalFormData);
const metadataResponse = await fetch("https://pump.fun/api/ipfs", {
method: "POST",
@@ -46,7 +45,6 @@ async function uploadMetadata(
});
if (!metadataResponse.ok) {
console.log("Metadata response:", await metadataResponse.json());
throw new Error(`Metadata upload failed: ${metadataResponse.statusText}`);
}
@@ -152,30 +150,14 @@ export async function launchPumpFunToken(
options?: PumpFunTokenOptions
) {
try {
// TBD : Remove clgs after approval
console.log("Starting token launch process...");
// Generate mint keypair
const mintKeypair = Keypair.generate();
console.log("Mint public key:", mintKeypair.publicKey.toBase58());
// Upload metadata
console.log("Uploading metadata to IPFS...");
const metadataResponse = await uploadMetadata(tokenName, tokenTicker, description, imageUrl, options);
console.log("Metadata response:", metadataResponse);
// Create token transaction
console.log("Creating token transaction...");
const response = await createTokenTransaction(agent, mintKeypair, metadataResponse, options);
const transactionData = await response.arrayBuffer();
const tx = VersionedTransaction.deserialize(new Uint8Array(transactionData));
// Send transaction with proper blockhash handling
console.log("Sending transaction...");
const signature = await signAndSendTransaction(agent, tx, mintKeypair);
console.log("Token launch successful!");
return {
signature,
mint: mintKeypair.publicKey.toBase58(),

View File

@@ -0,0 +1,56 @@
import { VersionedTransaction } from "@solana/web3.js";
import { SolanaAgentKit } from "../agent";
/**
* Stake SOL with Jup validator
* @param agent SolanaAgentKit instance
* @param amount Amount of SOL to stake
* @returns Transaction signature
*/
export async function stakeWithJup(
agent: SolanaAgentKit,
amount: number,
): Promise<string> {
try {
const res = await fetch(
`https://worker.jup.ag/blinks/swap/So11111111111111111111111111111111111111112/jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v/${amount}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
account: agent.wallet.publicKey.toBase58(),
}),
},
);
const data = await res.json();
const txn = VersionedTransaction.deserialize(
Buffer.from(data.transaction, "base64"),
);
const { blockhash } = await agent.connection.getLatestBlockhash();
txn.message.recentBlockhash = blockhash;
// Sign and send transaction
txn.sign([agent.wallet]);
const signature = await agent.connection.sendTransaction(txn, {
preflightCommitment: "confirmed",
maxRetries: 3,
});
const latestBlockhash = await agent.connection.getLatestBlockhash();
await agent.connection.confirmTransaction({
signature,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
});
return signature;
} catch (error: any) {
console.error(error);
throw new Error(`jupSOL staking failed: ${error.message}`);
}
}

View File

@@ -19,8 +19,6 @@ export async function trade(
slippageBps: number = DEFAULT_OPTIONS.SLIPPAGE_BPS,
): Promise<string> {
try {
// Get quote for the swap
console.log(inputMint.toString(), outputMint.toString(), inputAmount, slippageBps);
const quoteResponse = await (
await fetch(
`${JUP_API}/quote?` +

View File

@@ -69,3 +69,11 @@ export interface JupiterTokenData {
coingeckoId?: string;
};
}
export interface FetchPriceResponse {
status: "success" | "error";
tokenId?: string;
priceInUSDC?: string;
message?: string;
code?: string;
}