mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-14 07:26:46 +00:00
init
This commit is contained in:
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
dist
|
||||
node_modules
|
||||
.env
|
||||
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
.DS_Store
|
||||
131
README.md
Normal file
131
README.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Solana Agent Kit
|
||||
|
||||
A powerful toolkit for interacting with the Solana blockchain, providing easy-to-use functions for token operations, NFT management, and trading.
|
||||
|
||||
## Features
|
||||
|
||||
- 🪙 Token Operations
|
||||
- Deploy new SPL tokens
|
||||
- Transfer SOL and SPL tokens
|
||||
- Check token balances
|
||||
|
||||
- 🖼️ 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
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install solana-agent-kit
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```typescript
|
||||
import { SolanaAgentKit } 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'
|
||||
);
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Deploy a New Token
|
||||
|
||||
```typescript
|
||||
import { deploy_token } from 'solana-agent-kit';
|
||||
|
||||
const result = await deploy_token(
|
||||
agent,
|
||||
9, // decimals
|
||||
1000000 // initial supply
|
||||
);
|
||||
|
||||
console.log('Token Mint Address:', result.mint.toString());
|
||||
```
|
||||
|
||||
### Create NFT Collection
|
||||
|
||||
```typescript
|
||||
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
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
### Swap Tokens
|
||||
|
||||
```typescript
|
||||
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
|
||||
);
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
## Dependencies
|
||||
|
||||
The toolkit relies on several key Solana and Metaplex libraries:
|
||||
|
||||
- @solana/web3.js
|
||||
- @solana/spl-token
|
||||
- @metaplex-foundation/js
|
||||
- @metaplex-foundation/mpl-token-metadata
|
||||
- @metaplex-foundation/umi
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
## License
|
||||
|
||||
ISC License
|
||||
|
||||
## Security
|
||||
|
||||
This toolkit handles private keys and transactions. Always ensure you're using it in a secure environment and never share your private keys.
|
||||
28
package.json
Normal file
28
package.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "solana-agent-kit",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@bonfida/spl-name-service": "^3.0.7",
|
||||
"@metaplex-foundation/js": "^0.20.1",
|
||||
"@metaplex-foundation/mpl-core": "^1.1.1",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^3.3.0",
|
||||
"@metaplex-foundation/umi": "^0.9.2",
|
||||
"@metaplex-foundation/umi-bundle-defaults": "^0.9.2",
|
||||
"@metaplex-foundation/umi-web3js-adapters": "^0.9.2",
|
||||
"@solana/spl-token": "^0.4.9",
|
||||
"@solana/web3.js": "^1.95.4",
|
||||
"bs58": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.9.0"
|
||||
}
|
||||
}
|
||||
3164
pnpm-lock.yaml
generated
Normal file
3164
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
src/constants/index.ts
Normal file
18
src/constants/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Common token addresses used across the toolkit
|
||||
*/
|
||||
export const TOKENS = {
|
||||
USDC: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Default configuration options
|
||||
* @property {number} SLIPPAGE_BPS - Default slippage tolerance in basis points (300 = 3%)
|
||||
* @property {number} TOKEN_DECIMALS - Default number of decimals for new tokens
|
||||
*/
|
||||
export const DEFAULT_OPTIONS = {
|
||||
SLIPPAGE_BPS: 300,
|
||||
TOKEN_DECIMALS: 9,
|
||||
} as const;
|
||||
78
src/index.ts
Normal file
78
src/index.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import bs58 from "bs58";
|
||||
import {
|
||||
request_faucet_funds,
|
||||
deploy_token,
|
||||
deploy_collection,
|
||||
get_balance,
|
||||
mintCollectionNFT,
|
||||
transfer,
|
||||
trade,
|
||||
} from "./tools";
|
||||
import { CollectionOptions } from "./types";
|
||||
import { DEFAULT_OPTIONS } from "./constants";
|
||||
|
||||
/**
|
||||
* Main class for interacting with Solana blockchain
|
||||
* Provides a unified interface for token operations, NFT management, and trading
|
||||
*
|
||||
* @class SolanaAgentKit
|
||||
* @property {Connection} connection - Solana RPC connection
|
||||
* @property {Keypair} wallet - Wallet keypair for signing transactions
|
||||
* @property {PublicKey} wallet_address - Public key of the wallet
|
||||
*/
|
||||
export class SolanaAgentKit {
|
||||
public connection: Connection;
|
||||
public wallet: Keypair;
|
||||
public wallet_address: PublicKey;
|
||||
|
||||
constructor(
|
||||
private_key: string,
|
||||
rpc_url = "https://api.mainnet-beta.solana.com"
|
||||
) {
|
||||
this.connection = new Connection(rpc_url);
|
||||
this.wallet = Keypair.fromSecretKey(bs58.decode(private_key));
|
||||
this.wallet_address = this.wallet.publicKey;
|
||||
}
|
||||
|
||||
// Tool methods
|
||||
async requestFaucetFunds() {
|
||||
return request_faucet_funds(this);
|
||||
}
|
||||
|
||||
async deployToken(
|
||||
decimals: number = DEFAULT_OPTIONS.TOKEN_DECIMALS,
|
||||
initialSupply?: number
|
||||
) {
|
||||
return deploy_token(this, decimals, initialSupply);
|
||||
}
|
||||
|
||||
async deployCollection(options: CollectionOptions) {
|
||||
return deploy_collection(this, options);
|
||||
}
|
||||
|
||||
async getBalance(token_address?: PublicKey) {
|
||||
return get_balance(this, token_address);
|
||||
}
|
||||
|
||||
async mintNFT(
|
||||
collectionMint: PublicKey,
|
||||
metadata: Parameters<typeof mintCollectionNFT>[2],
|
||||
recipient?: PublicKey
|
||||
) {
|
||||
return mintCollectionNFT(this, collectionMint, metadata, recipient);
|
||||
}
|
||||
|
||||
async transfer(to: PublicKey, amount: number, mint?: PublicKey) {
|
||||
return transfer(this, to, amount, mint);
|
||||
}
|
||||
|
||||
async trade(
|
||||
outputMint: PublicKey,
|
||||
inputAmount: number,
|
||||
inputMint?: PublicKey,
|
||||
slippageBps: number = DEFAULT_OPTIONS.SLIPPAGE_BPS
|
||||
) {
|
||||
return trade(this, outputMint, inputAmount, inputMint, slippageBps);
|
||||
}
|
||||
}
|
||||
60
src/tools/deploy_collection.ts
Normal file
60
src/tools/deploy_collection.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
createUmi,
|
||||
generateSigner,
|
||||
publicKey,
|
||||
} from '@metaplex-foundation/umi';
|
||||
import { createCollection, ruleSet } from '@metaplex-foundation/mpl-core';
|
||||
import { mplTokenMetadata } from '@metaplex-foundation/mpl-token-metadata';
|
||||
import { CollectionOptions, CollectionDeployment } from '../types';
|
||||
import { toWeb3JsPublicKey } from '@metaplex-foundation/umi-web3js-adapters';
|
||||
/**
|
||||
* Deploy a new NFT collection
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param options Collection options including name, URI, royalties, and creators
|
||||
* @returns Object containing collection address and metadata
|
||||
*/
|
||||
export async function deploy_collection(
|
||||
agent: SolanaAgentKit,
|
||||
options: CollectionOptions
|
||||
): Promise<CollectionDeployment> {
|
||||
try {
|
||||
// Initialize Umi
|
||||
const umi = createUmi()
|
||||
.use(mplTokenMetadata());
|
||||
|
||||
// Generate collection signer
|
||||
const collectionSigner = generateSigner(umi);
|
||||
|
||||
// Format creators if provided
|
||||
const formattedCreators = options.creators?.map(creator => ({
|
||||
address: publicKey(creator.address),
|
||||
percentage: creator.percentage,
|
||||
})) || [{
|
||||
address: publicKey(agent.wallet_address.toString()),
|
||||
percentage: 100,
|
||||
}];
|
||||
|
||||
// Create collection
|
||||
const tx = await createCollection(umi, {
|
||||
collection: collectionSigner,
|
||||
name: options.name,
|
||||
uri: options.uri,
|
||||
plugins: [
|
||||
{
|
||||
type: 'Royalties',
|
||||
basisPoints: options.royaltyBasisPoints || 500, // Default 5%
|
||||
creators: formattedCreators,
|
||||
ruleSet: ruleSet('None'), // Compatibility rule set
|
||||
},
|
||||
],
|
||||
}).sendAndConfirm(umi);
|
||||
|
||||
return {
|
||||
collectionAddress: toWeb3JsPublicKey(collectionSigner.publicKey),
|
||||
signature: tx.signature
|
||||
};
|
||||
} catch (error: any) {
|
||||
throw new Error(`Collection deployment failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
64
src/tools/deploy_token.ts
Normal file
64
src/tools/deploy_token.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
createMint,
|
||||
getOrCreateAssociatedTokenAccount,
|
||||
mintTo,
|
||||
TOKEN_PROGRAM_ID,
|
||||
Account
|
||||
} from "@solana/spl-token";
|
||||
|
||||
/**
|
||||
* Deploy a new SPL token
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param decimals Number of decimals for the token (default: 9)
|
||||
* @param initialSupply Initial supply to mint (optional)
|
||||
* @returns Object containing token mint address and initial account (if supply was minted)
|
||||
*/
|
||||
export async function deploy_token(
|
||||
agent: SolanaAgentKit,
|
||||
decimals: number = 9,
|
||||
initialSupply?: number
|
||||
) {
|
||||
try {
|
||||
// Create new token mint
|
||||
const mint = await createMint(
|
||||
agent.connection,
|
||||
agent.wallet, // Payer
|
||||
agent.wallet_address, // Mint authority
|
||||
agent.wallet_address, // Freeze authority (optional)
|
||||
decimals,
|
||||
undefined, // Optional keypair
|
||||
undefined, // Confirmation options
|
||||
TOKEN_PROGRAM_ID
|
||||
);
|
||||
|
||||
// If initial supply is specified, mint tokens
|
||||
let tokenAccount: Account | undefined = undefined;
|
||||
if (initialSupply) {
|
||||
// Create associated token account for the wallet
|
||||
tokenAccount = await getOrCreateAssociatedTokenAccount(
|
||||
agent.connection,
|
||||
agent.wallet,
|
||||
mint,
|
||||
agent.wallet_address
|
||||
);
|
||||
|
||||
// Mint the initial supply
|
||||
await mintTo(
|
||||
agent.connection,
|
||||
agent.wallet,
|
||||
mint,
|
||||
tokenAccount.address,
|
||||
agent.wallet_address,
|
||||
initialSupply * Math.pow(10, decimals)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
mint: mint,
|
||||
tokenAccount: tokenAccount?.address
|
||||
};
|
||||
} catch (error: any) {
|
||||
throw new Error(`Token deployment failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
19
src/tools/get_balance.ts
Normal file
19
src/tools/get_balance.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
|
||||
/**
|
||||
* Get the balance of SOL or an SPL token for the agent's wallet
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @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
|
||||
*/
|
||||
export async function get_balance(
|
||||
agent: SolanaAgentKit,
|
||||
token_address?: PublicKey
|
||||
) {
|
||||
if (!token_address)
|
||||
return await agent.connection.getBalance(agent.wallet_address);
|
||||
|
||||
const token_account = await agent.connection.getTokenAccountBalance(token_address);
|
||||
return token_account.value.uiAmount;
|
||||
}
|
||||
8
src/tools/index.ts
Normal file
8
src/tools/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './request_faucet_funds';
|
||||
export * from './deploy_token';
|
||||
export * from './deploy_collection';
|
||||
export * from './get_balance';
|
||||
export * from './mint_nft';
|
||||
export * from './transfer';
|
||||
export * from './trade';
|
||||
export * from './register_domain';
|
||||
63
src/tools/mint_nft.ts
Normal file
63
src/tools/mint_nft.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { generateSigner } from '@metaplex-foundation/umi';
|
||||
import { create } from '@metaplex-foundation/mpl-core';
|
||||
import { fetchCollection } from '@metaplex-foundation/mpl-core';
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { 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
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param collectionMint Address of the collection's master NFT
|
||||
* @param metadata NFT metadata object
|
||||
* @param recipient Optional recipient address (defaults to wallet address)
|
||||
* @returns Object containing NFT mint address and token account
|
||||
*/
|
||||
export async function mintCollectionNFT(
|
||||
agent: SolanaAgentKit,
|
||||
collectionMint: PublicKey,
|
||||
metadata: {
|
||||
name: string;
|
||||
symbol: string;
|
||||
uri: string;
|
||||
sellerFeeBasisPoints?: number;
|
||||
creators?: Array<{
|
||||
address: string;
|
||||
share: number;
|
||||
}>;
|
||||
},
|
||||
recipient?: PublicKey
|
||||
): Promise<MintCollectionNFTResponse> {
|
||||
try {
|
||||
// Create UMI instance from agent
|
||||
const umi = createUmi(agent.connection)
|
||||
|
||||
// Convert collection mint to UMI format
|
||||
const umiCollectionMint = fromWeb3JsPublicKey(collectionMint);
|
||||
|
||||
// Fetch the existing collection
|
||||
const collection = await fetchCollection(umi, umiCollectionMint);
|
||||
|
||||
// Generate a new signer for the NFT
|
||||
const assetSigner = generateSigner(umi);
|
||||
|
||||
// Create the NFT in the collection
|
||||
await create(umi, {
|
||||
asset: assetSigner,
|
||||
collection: collection,
|
||||
name: metadata.name,
|
||||
uri: metadata.uri,
|
||||
owner: fromWeb3JsPublicKey(recipient!)
|
||||
}).sendAndConfirm(umi);
|
||||
|
||||
return {
|
||||
mint: toWeb3JsPublicKey(assetSigner.publicKey),
|
||||
// Note: Token account is now handled automatically by the create instruction
|
||||
metadata: toWeb3JsPublicKey(assetSigner.publicKey)
|
||||
};
|
||||
} catch (error: any) {
|
||||
throw new Error(`Collection NFT minting failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
57
src/tools/register_domain.ts
Normal file
57
src/tools/register_domain.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { registerDomainNameV2 } from "@bonfida/spl-name-service";
|
||||
import { Transaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
||||
import { TOKENS } from "../constants";
|
||||
/**
|
||||
* Register a .sol domain name using Bonfida Name Service
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param name Domain name to register (without .sol)
|
||||
* @param spaceKB Space allocation in KB (max 10KB)
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function registerDomain(
|
||||
agent: SolanaAgentKit,
|
||||
name: string,
|
||||
spaceKB: number = 1
|
||||
): Promise<string> {
|
||||
try {
|
||||
// Validate space size
|
||||
if (spaceKB > 10) {
|
||||
throw new Error("Maximum domain size is 10KB");
|
||||
}
|
||||
|
||||
// Convert KB to bytes
|
||||
const space = spaceKB * 1_000;
|
||||
|
||||
const buyerTokenAccount = await getAssociatedTokenAddressSync(
|
||||
agent.wallet_address,
|
||||
TOKENS.USDC
|
||||
);
|
||||
|
||||
// Create registration instruction
|
||||
const instruction = await registerDomainNameV2(
|
||||
agent.connection,
|
||||
name,
|
||||
space,
|
||||
agent.wallet_address,
|
||||
buyerTokenAccount
|
||||
);
|
||||
|
||||
// Create and sign transaction
|
||||
const transaction = new Transaction().add(...instruction);
|
||||
transaction.recentBlockhash = (
|
||||
await agent.connection.getLatestBlockhash()
|
||||
).blockhash;
|
||||
transaction.feePayer = agent.wallet_address;
|
||||
|
||||
// Sign and send transaction
|
||||
const signature = await agent.connection.sendTransaction(transaction, [
|
||||
agent.wallet,
|
||||
]);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Domain registration failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
16
src/tools/request_faucet_funds.ts
Normal file
16
src/tools/request_faucet_funds.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Request SOL from the Solana faucet (devnet/testnet only)
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @returns Promise that resolves when the airdrop is confirmed
|
||||
* @throws Error if the request fails or times out
|
||||
*/
|
||||
export async function request_faucet_funds(agent: SolanaAgentKit) {
|
||||
const tx = await agent.connection.requestAirdrop(
|
||||
agent.wallet_address,
|
||||
5 * LAMPORTS_PER_SOL
|
||||
);
|
||||
await agent.connection.confirmTransaction(tx);
|
||||
}
|
||||
66
src/tools/trade.ts
Normal file
66
src/tools/trade.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import {
|
||||
VersionedTransaction,
|
||||
PublicKey,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { TOKENS, DEFAULT_OPTIONS } from "../constants";
|
||||
/**
|
||||
* Swap tokens using Jupiter Exchange
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param outputMint Target token mint address
|
||||
* @param inputAmount Amount to swap (in token decimals)
|
||||
* @param inputMint Source token mint address (defaults to USDC)
|
||||
* @param slippageBps Slippage tolerance in basis points (default: 300 = 3%)
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function trade(
|
||||
agent: SolanaAgentKit,
|
||||
outputMint: PublicKey,
|
||||
inputAmount: number,
|
||||
inputMint: PublicKey = TOKENS.USDC,
|
||||
slippageBps: number = DEFAULT_OPTIONS.SLIPPAGE_BPS
|
||||
): Promise<string> {
|
||||
try {
|
||||
// Get quote for the swap
|
||||
const quoteResponse = await (
|
||||
await fetch(
|
||||
`https://quote-api.jup.ag/v6/quote?` +
|
||||
`inputMint=${inputMint.toString()}` +
|
||||
`&outputMint=${outputMint.toString()}` +
|
||||
`&amount=${inputAmount}` +
|
||||
`&slippageBps=${slippageBps}` +
|
||||
`&onlyDirectRoutes=true` +
|
||||
`&maxAccounts=20`
|
||||
)
|
||||
).json();
|
||||
|
||||
// Get serialized transaction
|
||||
const { swapTransaction } = await (
|
||||
await fetch("https://quote-api.jup.ag/v6/swap", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
quoteResponse,
|
||||
userPublicKey: agent.wallet_address.toString(),
|
||||
wrapAndUnwrapSol: true,
|
||||
dynamicComputeUnitLimit: true,
|
||||
prioritizationFeeLamports: "auto",
|
||||
}),
|
||||
})
|
||||
).json();
|
||||
|
||||
// Deserialize transaction
|
||||
const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
|
||||
const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
|
||||
|
||||
// Sign and send transaction
|
||||
transaction.sign([agent.wallet]);
|
||||
const signature = await agent.connection.sendTransaction(transaction);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Swap failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
73
src/tools/transfer.ts
Normal file
73
src/tools/transfer.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
Transaction
|
||||
} from "@solana/web3.js";
|
||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||
import {
|
||||
getAssociatedTokenAddress,
|
||||
createTransferInstruction,
|
||||
getMint
|
||||
} from "@solana/spl-token";
|
||||
|
||||
/**
|
||||
* Transfer SOL or SPL tokens to a recipient
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param to Recipient's public key
|
||||
* @param amount Amount to transfer
|
||||
* @param mint Optional mint address for SPL tokens
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function transfer(
|
||||
agent: SolanaAgentKit,
|
||||
to: PublicKey,
|
||||
amount: number,
|
||||
mint?: PublicKey
|
||||
): Promise<string> {
|
||||
try {
|
||||
let tx: string;
|
||||
|
||||
if (!mint) {
|
||||
// Transfer native SOL
|
||||
const transaction = new Transaction().add(
|
||||
SystemProgram.transfer({
|
||||
fromPubkey: agent.wallet_address,
|
||||
toPubkey: to,
|
||||
lamports: amount * LAMPORTS_PER_SOL
|
||||
})
|
||||
);
|
||||
|
||||
tx = await agent.connection.sendTransaction(
|
||||
transaction,
|
||||
[agent.wallet]
|
||||
);
|
||||
} else {
|
||||
// Transfer SPL token
|
||||
const fromAta = await getAssociatedTokenAddress(mint, agent.wallet_address);
|
||||
const toAta = await getAssociatedTokenAddress(mint, to);
|
||||
|
||||
// Get mint info to determine decimals
|
||||
const mintInfo = await getMint(agent.connection, mint);
|
||||
const adjustedAmount = amount * Math.pow(10, mintInfo.decimals);
|
||||
|
||||
const transaction = new Transaction().add(
|
||||
createTransferInstruction(
|
||||
fromAta,
|
||||
toAta,
|
||||
agent.wallet_address,
|
||||
adjustedAmount
|
||||
)
|
||||
);
|
||||
|
||||
tx = await agent.connection.sendTransaction(
|
||||
transaction,
|
||||
[agent.wallet]
|
||||
);
|
||||
}
|
||||
|
||||
return tx;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Transfer failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
24
src/types/index.ts
Normal file
24
src/types/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
export interface Creator {
|
||||
address: string;
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export interface CollectionOptions {
|
||||
name: string;
|
||||
uri: string;
|
||||
royaltyBasisPoints?: number;
|
||||
creators?: Creator[];
|
||||
}
|
||||
|
||||
// Add return type interface
|
||||
export interface CollectionDeployment {
|
||||
collectionAddress: PublicKey;
|
||||
signature: Uint8Array;
|
||||
}
|
||||
|
||||
export interface MintCollectionNFTResponse {
|
||||
mint: PublicKey;
|
||||
metadata: PublicKey;
|
||||
}
|
||||
35
tsconfig.json
Normal file
35
tsconfig.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"module": "commonjs",
|
||||
"lib": ["es2020", "dom"],
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitThis": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"alwaysStrict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user