mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-14 07:26:46 +00:00
fixes and renames
This commit is contained in:
@@ -26,6 +26,7 @@ import {
|
||||
sendCompressedAirdrop,
|
||||
createOrcaSingleSidedWhirlpool,
|
||||
FEE_TIERS,
|
||||
fetchPrice,
|
||||
} from "../tools";
|
||||
import {
|
||||
CollectionDeployment,
|
||||
@@ -39,14 +40,14 @@ import { BN } from "@coral-xyz/anchor";
|
||||
|
||||
/**
|
||||
* 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 {Keypair} wallet - Wallet keypair for signing transactions
|
||||
* @property {PublicKey} wallet_address - Public key of the wallet
|
||||
*/
|
||||
export class SolanaAgentKit {
|
||||
export class SolanaAgent {
|
||||
public connection: Connection;
|
||||
public wallet: Keypair;
|
||||
public wallet_address: PublicKey;
|
||||
@@ -145,6 +146,10 @@ export class SolanaAgentKit {
|
||||
return getTokenDataByTicker(ticker);
|
||||
}
|
||||
|
||||
async fetchTokenPrice(mint: string) {
|
||||
return fetchPrice(new PublicKey(mint));
|
||||
}
|
||||
|
||||
async launchPumpFunToken(
|
||||
tokenName: string,
|
||||
tokenTicker: string,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SolanaAgentKit } from './agent'; // Move the SolanaAgentKit class to src/agent.ts
|
||||
import { createSolanaTools } from './langchain';
|
||||
import { SolanaAgent } from "./agent";
|
||||
import { createSolanaTools } from "./langchain";
|
||||
|
||||
export { SolanaAgentKit, createSolanaTools };
|
||||
export { SolanaAgent, createSolanaTools };
|
||||
|
||||
// Optional: Export types that users might need
|
||||
export * from './types';
|
||||
export * from "./types";
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import Decimal from "decimal.js";
|
||||
import { Tool } from "langchain/tools";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { create_image } from "../tools/create_image";
|
||||
import { fetchPrice } from "../tools/fetch_price";
|
||||
import { BN } from "@coral-xyz/anchor";
|
||||
import { FEE_TIERS } from "../tools";
|
||||
import { toJSON } from "../utils/toJSON";
|
||||
@@ -18,14 +17,14 @@ export class SolanaBalanceTool extends Tool {
|
||||
Inputs:
|
||||
tokenAddress: string, eg "So11111111111111111111111111111111111111112" (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const tokenAddress = input ? new PublicKey(input) : undefined;
|
||||
const balance = await this.solanaKit.getBalance(tokenAddress);
|
||||
const balance = await this.solanaAgent.getBalance(tokenAddress);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -51,7 +50,7 @@ export class SolanaTransferTool extends Tool {
|
||||
amount: number, eg 1 (required)
|
||||
mint?: string, eg "So11111111111111111111111111111111111111112" or "SENDdRQtYMWaQrBroBrJ2Q53fgVuq95CV9UPGEvpCxa" (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -64,10 +63,10 @@ export class SolanaTransferTool extends Tool {
|
||||
? new PublicKey(parsedInput.mint)
|
||||
: undefined;
|
||||
|
||||
const tx = await this.solanaKit.transfer(
|
||||
const tx = await this.solanaAgent.transfer(
|
||||
recipient,
|
||||
parsedInput.amount,
|
||||
mintAddress
|
||||
mintAddress,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -94,12 +93,12 @@ export class SolanaDeployTokenTool extends Tool {
|
||||
|
||||
Inputs (input is a JSON string):
|
||||
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)
|
||||
decimals?: number, eg 9 (optional, defaults to 9)
|
||||
initialSupply?: number, eg 1000000 (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -107,12 +106,12 @@ export class SolanaDeployTokenTool extends Tool {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const result = await this.solanaKit.deployToken(
|
||||
const result = await this.solanaAgent.deployToken(
|
||||
parsedInput.name,
|
||||
parsedInput.uri,
|
||||
parsedInput.symbol,
|
||||
parsedInput.decimals,
|
||||
parsedInput.initialSupply
|
||||
parsedInput.initialSupply,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -140,7 +139,7 @@ export class SolanaDeployCollectionTool extends Tool {
|
||||
uri: string, eg "https://example.com/collection.json" (required)
|
||||
royaltyBasisPoints?: number, eg 500 for 5% (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -148,7 +147,7 @@ export class SolanaDeployCollectionTool extends Tool {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const result = await this.solanaKit.deployCollection(parsedInput);
|
||||
const result = await this.solanaAgent.deployCollection(parsedInput);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -174,9 +173,9 @@ export class SolanaMintNFTTool extends Tool {
|
||||
collectionMint: string, eg "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w" (required) - The address of the collection to mint into
|
||||
name: string, eg "My NFT" (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();
|
||||
}
|
||||
|
||||
@@ -184,7 +183,7 @@ export class SolanaMintNFTTool extends Tool {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const result = await this.solanaKit.mintNFT(
|
||||
const result = await this.solanaAgent.mintNFT(
|
||||
new PublicKey(parsedInput.collectionMint),
|
||||
{
|
||||
name: parsedInput.name,
|
||||
@@ -192,7 +191,7 @@ export class SolanaMintNFTTool extends Tool {
|
||||
},
|
||||
parsedInput.recipient
|
||||
? new PublicKey(parsedInput.recipient)
|
||||
: this.solanaKit.wallet_address
|
||||
: this.solanaAgent.wallet_address,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -226,7 +225,7 @@ export class SolanaTradeTool extends Tool {
|
||||
inputMint?: string, eg "So11111111111111111111111111111111111111112" (optional)
|
||||
slippageBps?: number, eg 100 (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -234,13 +233,13 @@ export class SolanaTradeTool extends Tool {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const tx = await this.solanaKit.trade(
|
||||
const tx = await this.solanaAgent.trade(
|
||||
new PublicKey(parsedInput.outputMint),
|
||||
parsedInput.inputAmount,
|
||||
parsedInput.inputMint
|
||||
? new PublicKey(parsedInput.inputMint)
|
||||
: new PublicKey("So11111111111111111111111111111111111111112"),
|
||||
parsedInput.slippageBps
|
||||
parsedInput.slippageBps,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -265,18 +264,18 @@ export class SolanaRequestFundsTool extends Tool {
|
||||
name = "solana_request_funds";
|
||||
description = "Request SOL from Solana faucet (devnet/testnet only)";
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(_input: string): Promise<string> {
|
||||
try {
|
||||
await this.solanaKit.requestFaucetFunds();
|
||||
await this.solanaAgent.requestFaucetFunds();
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Successfully requested faucet funds",
|
||||
network: this.solanaKit.connection.rpcEndpoint.split("/")[2],
|
||||
network: this.solanaAgent.connection.rpcEndpoint.split("/")[2],
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
@@ -297,7 +296,7 @@ export class SolanaRegisterDomainTool extends Tool {
|
||||
spaceKB: number, eg 1 (optional, default is 1)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -318,9 +317,9 @@ export class SolanaRegisterDomainTool extends Tool {
|
||||
const parsedInput = toJSON(input);
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
const tx = await this.solanaKit.registerDomain(
|
||||
const tx = await this.solanaAgent.registerDomain(
|
||||
parsedInput.name,
|
||||
parsedInput.spaceKB || 1
|
||||
parsedInput.spaceKB || 1,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -348,14 +347,14 @@ export class SolanaResolveDomainTool extends Tool {
|
||||
domain: string, eg "pumpfun.sol" or "pumpfun"(required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const domain = input.trim();
|
||||
const publicKey = await this.solanaKit.resolveSolDomain(domain);
|
||||
const publicKey = await this.solanaAgent.resolveSolDomain(domain);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -380,14 +379,14 @@ export class SolanaGetDomainTool extends Tool {
|
||||
account: string, eg "4Be9CvxqHW6BYiRAxW9Q3xu1ycTMWaL5z8NX4HR3ha7t" (required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const account = new PublicKey(input.trim());
|
||||
const domain = await this.solanaKit.getPrimaryDomain(account);
|
||||
const domain = await this.solanaAgent.getPrimaryDomain(account);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -408,12 +407,12 @@ export class SolanaGetWalletAddressTool extends Tool {
|
||||
name = "solana_get_wallet_address";
|
||||
description = `Get the wallet address of the agent`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
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",
|
||||
imageUrl: string, eg "https://i.imgur.com/UFm07Np_d.png`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -465,7 +464,7 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
||||
this.validateInput(parsedInput);
|
||||
|
||||
// Launch token with validated input
|
||||
await this.solanaKit.launchPumpFunToken(
|
||||
await this.solanaAgent.launchPumpFunToken(
|
||||
parsedInput.tokenName,
|
||||
parsedInput.tokenTicker,
|
||||
parsedInput.description,
|
||||
@@ -475,7 +474,7 @@ export class SolanaPumpfunTokenLaunchTool extends Tool {
|
||||
telegram: parsedInput.telegram,
|
||||
website: parsedInput.website,
|
||||
initialLiquiditySOL: parsedInput.initialLiquiditySOL,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
@@ -499,7 +498,7 @@ export class SolanaCreateImageTool extends Tool {
|
||||
description =
|
||||
"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();
|
||||
}
|
||||
|
||||
@@ -512,7 +511,7 @@ export class SolanaCreateImageTool extends Tool {
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
this.validateInput(input);
|
||||
const result = await create_image(this.solanaKit, input.trim());
|
||||
const result = await create_image(this.solanaAgent, input.trim());
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -536,7 +535,7 @@ export class SolanaLendAssetTool extends Tool {
|
||||
Inputs (input is a json string):
|
||||
amount: number, eg 1, 0.01 (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -544,7 +543,7 @@ export class SolanaLendAssetTool extends Tool {
|
||||
try {
|
||||
let amount = JSON.parse(input).amount || input;
|
||||
|
||||
const tx = await this.solanaKit.lendAssets(amount);
|
||||
const tx = await this.solanaAgent.lendAssets(amount);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -566,13 +565,13 @@ export class SolanaTPSCalculatorTool extends Tool {
|
||||
name = "solana_get_tps";
|
||||
description = "Get the current TPS of the Solana network";
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(_input: string): Promise<string> {
|
||||
try {
|
||||
const tps = await this.solanaKit.getTPS();
|
||||
const tps = await this.solanaAgent.getTPS();
|
||||
return `Solana (mainnet-beta) current transactions per second: ${tps}`;
|
||||
} catch (error: any) {
|
||||
return `Error fetching TPS: ${error.message}`;
|
||||
@@ -587,7 +586,7 @@ export class SolanaStakeTool extends Tool {
|
||||
Inputs ( input is a JSON string ):
|
||||
amount: number, eg 1 or 0.01 (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -595,7 +594,7 @@ export class SolanaStakeTool extends Tool {
|
||||
try {
|
||||
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({
|
||||
status: "success",
|
||||
@@ -619,17 +618,17 @@ export class SolanaStakeTool extends Tool {
|
||||
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) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const price = await fetchPrice(this.solanaKit, input.trim());
|
||||
const price = await this.solanaAgent.fetchTokenPrice(input.trim());
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
tokenId: input.trim(),
|
||||
@@ -652,7 +651,7 @@ export class SolanaTokenDataTool extends Tool {
|
||||
Inputs: mintAddress is required.
|
||||
mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -660,7 +659,8 @@ export class SolanaTokenDataTool extends Tool {
|
||||
try {
|
||||
const parsedInput = input.trim();
|
||||
|
||||
const tokenData = await this.solanaKit.getTokenDataByAddress(parsedInput);
|
||||
const tokenData =
|
||||
await this.solanaAgent.getTokenDataByAddress(parsedInput);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
@@ -683,14 +683,14 @@ export class SolanaTokenDataByTickerTool extends Tool {
|
||||
Inputs: ticker is required.
|
||||
ticker: string, eg "USDC" (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const ticker = input.trim();
|
||||
const tokenData = await this.solanaKit.getTokenDataByTicker(ticker);
|
||||
const tokenData = await this.solanaAgent.getTokenDataByTicker(ticker);
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
tokenData: tokenData,
|
||||
@@ -708,7 +708,7 @@ export class SolanaTokenDataByTickerTool extends Tool {
|
||||
export class SolanaCompressedAirdropTool extends Tool {
|
||||
name = "solana_compressed_airdrop";
|
||||
description = `Airdrop SPL tokens with ZK Compression (also called as airdropping tokens)
|
||||
|
||||
|
||||
Inputs (input is a JSON string):
|
||||
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)
|
||||
@@ -717,7 +717,7 @@ export class SolanaCompressedAirdropTool extends Tool {
|
||||
priorityFeeInLamports: number, the priority fee in lamports. Default is 30_000. (optional)
|
||||
shouldLog: boolean, whether to log progress to stdout. Default is false. (optional)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -725,13 +725,13 @@ export class SolanaCompressedAirdropTool extends Tool {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const txs = await this.solanaKit.sendCompressedAirdrop(
|
||||
const txs = await this.solanaAgent.sendCompressedAirdrop(
|
||||
parsedInput.mintAddress,
|
||||
parsedInput.amount,
|
||||
parsedInput.decimals,
|
||||
parsedInput.recipients,
|
||||
parsedInput.priorityFeeInLamports || 30_000,
|
||||
parsedInput.shouldLog || false
|
||||
parsedInput.shouldLog || false,
|
||||
);
|
||||
|
||||
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)
|
||||
- feeTier: number, eg: 0.30 (required, fee tier for the pool)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -776,10 +776,12 @@ export class SolanaCreateSingleSidedWhirlpoolTool extends Tool {
|
||||
const feeTier = inputFormat.feeTier;
|
||||
|
||||
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,
|
||||
depositTokenMint,
|
||||
otherTokenMint,
|
||||
@@ -803,7 +805,6 @@ export class SolanaCreateSingleSidedWhirlpoolTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SolanaRaydiumCreateAmmV4 extends Tool {
|
||||
name = "raydium_create_ammV4";
|
||||
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)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
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 BN(inputFormat.baseAmount),
|
||||
new BN(inputFormat.quoteAmount),
|
||||
@@ -857,15 +858,15 @@ export class SolanaRaydiumCreateClmm extends Tool {
|
||||
startTime: number(seconds), eg: now number or zero (required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
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.mint2),
|
||||
|
||||
@@ -892,7 +893,7 @@ export class SolanaRaydiumCreateClmm extends Tool {
|
||||
|
||||
export class SolanaRaydiumCreateCpmm extends Tool {
|
||||
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):
|
||||
mint1: string (required)
|
||||
@@ -903,15 +904,15 @@ export class SolanaRaydiumCreateCpmm extends Tool {
|
||||
startTime: number(seconds), eg: now number or zero (required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
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.mint2),
|
||||
|
||||
@@ -940,7 +941,7 @@ export class SolanaRaydiumCreateCpmm extends Tool {
|
||||
|
||||
export class SolanaOpenbookCreateMarket extends Tool {
|
||||
name = "solana_openbook_create_market";
|
||||
description = `Openbook marketId, required for ammv4
|
||||
description = `Openbook marketId, required for ammv4
|
||||
|
||||
Inputs (input is a json string):
|
||||
baseMint: string (required)
|
||||
@@ -949,15 +950,15 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
||||
tickSize: number (required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
constructor(private solanaAgent: SolanaAgent) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
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.quoteMint),
|
||||
|
||||
@@ -980,32 +981,32 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
export function createSolanaTools(solanaAgent: SolanaAgent) {
|
||||
return [
|
||||
new SolanaBalanceTool(solanaKit),
|
||||
new SolanaTransferTool(solanaKit),
|
||||
new SolanaDeployTokenTool(solanaKit),
|
||||
new SolanaDeployCollectionTool(solanaKit),
|
||||
new SolanaMintNFTTool(solanaKit),
|
||||
new SolanaTradeTool(solanaKit),
|
||||
new SolanaRequestFundsTool(solanaKit),
|
||||
new SolanaRegisterDomainTool(solanaKit),
|
||||
new SolanaGetWalletAddressTool(solanaKit),
|
||||
new SolanaPumpfunTokenLaunchTool(solanaKit),
|
||||
new SolanaCreateImageTool(solanaKit),
|
||||
new SolanaLendAssetTool(solanaKit),
|
||||
new SolanaTPSCalculatorTool(solanaKit),
|
||||
new SolanaStakeTool(solanaKit),
|
||||
new SolanaFetchPriceTool(solanaKit),
|
||||
new SolanaResolveDomainTool(solanaKit),
|
||||
new SolanaGetDomainTool(solanaKit),
|
||||
new SolanaTokenDataTool(solanaKit),
|
||||
new SolanaTokenDataByTickerTool(solanaKit),
|
||||
new SolanaCompressedAirdropTool(solanaKit),
|
||||
new SolanaRaydiumCreateAmmV4(solanaKit),
|
||||
new SolanaRaydiumCreateClmm(solanaKit),
|
||||
new SolanaRaydiumCreateCpmm(solanaKit),
|
||||
new SolanaOpenbookCreateMarket(solanaKit),
|
||||
new SolanaCreateSingleSidedWhirlpoolTool(solanaKit),
|
||||
new SolanaBalanceTool(solanaAgent),
|
||||
new SolanaTransferTool(solanaAgent),
|
||||
new SolanaDeployTokenTool(solanaAgent),
|
||||
new SolanaDeployCollectionTool(solanaAgent),
|
||||
new SolanaMintNFTTool(solanaAgent),
|
||||
new SolanaTradeTool(solanaAgent),
|
||||
new SolanaRequestFundsTool(solanaAgent),
|
||||
new SolanaRegisterDomainTool(solanaAgent),
|
||||
new SolanaGetWalletAddressTool(solanaAgent),
|
||||
new SolanaPumpfunTokenLaunchTool(solanaAgent),
|
||||
new SolanaCreateImageTool(solanaAgent),
|
||||
new SolanaLendAssetTool(solanaAgent),
|
||||
new SolanaTPSCalculatorTool(solanaAgent),
|
||||
new SolanaStakeTool(solanaAgent),
|
||||
new SolanaFetchPriceTool(solanaAgent),
|
||||
new SolanaResolveDomainTool(solanaAgent),
|
||||
new SolanaGetDomainTool(solanaAgent),
|
||||
new SolanaTokenDataTool(solanaAgent),
|
||||
new SolanaTokenDataByTickerTool(solanaAgent),
|
||||
new SolanaCompressedAirdropTool(solanaAgent),
|
||||
new SolanaRaydiumCreateAmmV4(solanaAgent),
|
||||
new SolanaRaydiumCreateClmm(solanaAgent),
|
||||
new SolanaRaydiumCreateCpmm(solanaAgent),
|
||||
new SolanaOpenbookCreateMarket(solanaAgent),
|
||||
new SolanaCreateSingleSidedWhirlpoolTool(solanaAgent),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } from "../index";
|
||||
import OpenAI from "openai";
|
||||
|
||||
/**
|
||||
* 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 size Image size ('256x256', '512x512', or '1024x1024') (default: '1024x1024')
|
||||
* @param n Number of images to generate (default: 1)
|
||||
* @returns Object containing the generated image URLs
|
||||
*/
|
||||
export async function create_image(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
prompt: string,
|
||||
size: "256x256" | "512x512" | "1024x1024" = "1024x1024",
|
||||
n: number = 1,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { BN, Wallet } from "@coral-xyz/anchor";
|
||||
import { Decimal } from "decimal.js";
|
||||
import {
|
||||
@@ -40,7 +40,7 @@ import { sendTx } from "../utils/send_tx";
|
||||
* @remarks
|
||||
* Fee tiers determine the percentage of fees collected on swaps, while tick spacing affects
|
||||
* the granularity of price ranges for liquidity positions.
|
||||
*
|
||||
*
|
||||
* For more details, refer to:
|
||||
* - [Whirlpool Fees](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Fees)
|
||||
* - [Whirlpool Parameters](https://orca-so.github.io/whirlpools/Architecture%20Overview/Whirlpool%20Parameters)
|
||||
@@ -54,17 +54,17 @@ export const FEE_TIERS = {
|
||||
0.04: 4,
|
||||
0.05: 8,
|
||||
0.16: 16,
|
||||
0.30: 64,
|
||||
0.3: 64,
|
||||
0.65: 96,
|
||||
1.00: 128,
|
||||
2.00: 256,
|
||||
1.0: 128,
|
||||
2.0: 256,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* # Creates a single-sided Whirlpool.
|
||||
*
|
||||
* This function initializes a new Whirlpool (liquidity pool) on Orca and seeds it with liquidity from a single token.
|
||||
*
|
||||
*
|
||||
* ## Example Usage:
|
||||
* 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.
|
||||
@@ -72,7 +72,7 @@ export const FEE_TIERS = {
|
||||
* 1. Increase the amount of tokens you deposit
|
||||
* 2. Set the initial price very low
|
||||
* 3. Set the maximum price closer to the initial price
|
||||
*
|
||||
*
|
||||
* ### Note for experts:
|
||||
* 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
|
||||
@@ -86,13 +86,13 @@ export const FEE_TIERS = {
|
||||
* @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 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.
|
||||
*
|
||||
*
|
||||
* @throws Will throw an error if:
|
||||
* - Mint accounts for the tokens cannot be fetched.
|
||||
* - Prices are out of bounds.
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* 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.
|
||||
@@ -103,7 +103,7 @@ export const FEE_TIERS = {
|
||||
* import { PublicKey } from "@solana/web3.js";
|
||||
* import { BN } from "@coral-xyz/anchor";
|
||||
* import Decimal from "decimal.js";
|
||||
*
|
||||
*
|
||||
* const agent = new SolanaAgentKit(wallet, connection);
|
||||
* const depositAmount = new BN(1_000_000_000_000); // 1 million SHARK if SHARK has 6 decimals
|
||||
* const depositTokenMint = new PublicKey("DEPOSTI_TOKEN_ADDRESS");
|
||||
@@ -111,7 +111,7 @@ export const FEE_TIERS = {
|
||||
* const initialPrice = new Decimal(0.001);
|
||||
* const maxPrice = new Decimal(5.0);
|
||||
* const feeTier = 0.30;
|
||||
*
|
||||
*
|
||||
* const txId = await createOrcaSingleSidedWhirlpool(
|
||||
* agent,
|
||||
* depositAmount,
|
||||
@@ -125,7 +125,7 @@ export const FEE_TIERS = {
|
||||
* ```
|
||||
*/
|
||||
export async function createOrcaSingleSidedWhirlpool(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
depositTokenAmount: BN,
|
||||
depositTokenMint: PublicKey,
|
||||
otherTokenMint: PublicKey,
|
||||
@@ -134,13 +134,19 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
feeTier: keyof typeof FEE_TIERS,
|
||||
): Promise<string> {
|
||||
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 correctTokenOrder = PoolUtil.orderMints(otherTokenMint, depositTokenMint).map(
|
||||
(addr) => addr.toString(),
|
||||
);
|
||||
const isCorrectMintOrder = correctTokenOrder[0] === depositTokenMint.toString();
|
||||
const correctTokenOrder = PoolUtil.orderMints(
|
||||
otherTokenMint,
|
||||
depositTokenMint,
|
||||
).map((addr) => addr.toString());
|
||||
const isCorrectMintOrder =
|
||||
correctTokenOrder[0] === depositTokenMint.toString();
|
||||
let mintA, mintB;
|
||||
if (isCorrectMintOrder) {
|
||||
[mintA, mintB] = [depositTokenMint, otherTokenMint];
|
||||
@@ -151,10 +157,18 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
}
|
||||
const mintAAccount = await fetcher.getMintInfo(mintA);
|
||||
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 tickIndex = PriceMath.priceToTickIndex(initialPrice, mintAAccount.decimals, mintBAccount.decimals);
|
||||
const initialTick = TickUtil.getInitializableTickIndex(tickIndex, tickSpacing);
|
||||
const tickIndex = PriceMath.priceToTickIndex(
|
||||
initialPrice,
|
||||
mintAAccount.decimals,
|
||||
mintBAccount.decimals,
|
||||
);
|
||||
const initialTick = TickUtil.getInitializableTickIndex(
|
||||
tickIndex,
|
||||
tickSpacing,
|
||||
);
|
||||
|
||||
const tokenExtensionCtx: TokenExtensionContextForPool = {
|
||||
...NO_TOKEN_EXTENSION_CONTEXT,
|
||||
@@ -196,17 +210,17 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
tokenVaultBKeypair,
|
||||
feeTierKey,
|
||||
tickSpacing: tickSpacing,
|
||||
funder: wallet.publicKey
|
||||
funder: wallet.publicKey,
|
||||
};
|
||||
const initPoolIx = !TokenExtensionUtil.isV2IxRequiredPool(tokenExtensionCtx)
|
||||
? WhirlpoolIx.initializePoolIx(ctx.program, baseParamsPool)
|
||||
: WhirlpoolIx.initializePoolV2Ix(ctx.program, {
|
||||
...baseParamsPool,
|
||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||
tokenBadgeA,
|
||||
tokenBadgeB,
|
||||
});
|
||||
...baseParamsPool,
|
||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||
tokenBadgeA,
|
||||
tokenBadgeB,
|
||||
});
|
||||
const initialTickArrayStartTick = TickUtil.getStartTickIndex(
|
||||
initialTick,
|
||||
tickSpacing,
|
||||
@@ -235,14 +249,32 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
let tickLowerIndex, tickUpperIndex;
|
||||
if (isCorrectMintOrder) {
|
||||
tickLowerIndex = initialTick;
|
||||
tickUpperIndex = PriceMath.priceToTickIndex(maxPrice, mintAAccount.decimals, mintBAccount.decimals);
|
||||
tickUpperIndex = PriceMath.priceToTickIndex(
|
||||
maxPrice,
|
||||
mintAAccount.decimals,
|
||||
mintBAccount.decimals,
|
||||
);
|
||||
} else {
|
||||
tickLowerIndex = PriceMath.priceToTickIndex(maxPrice, mintAAccount.decimals, mintBAccount.decimals);
|
||||
tickLowerIndex = PriceMath.priceToTickIndex(
|
||||
maxPrice,
|
||||
mintAAccount.decimals,
|
||||
mintBAccount.decimals,
|
||||
);
|
||||
tickUpperIndex = initialTick;
|
||||
}
|
||||
const tickLowerInitializableIndex = TickUtil.getInitializableTickIndex(tickLowerIndex, tickSpacing);
|
||||
const tickUpperInitializableIndex = TickUtil.getInitializableTickIndex(tickUpperIndex, tickSpacing);
|
||||
if (!TickUtil.checkTickInBounds(tickLowerInitializableIndex) || !TickUtil.checkTickInBounds(tickUpperInitializableIndex)) throw Error('Prices out of bounds');
|
||||
const tickLowerInitializableIndex = TickUtil.getInitializableTickIndex(
|
||||
tickLowerIndex,
|
||||
tickSpacing,
|
||||
);
|
||||
const tickUpperInitializableIndex = TickUtil.getInitializableTickIndex(
|
||||
tickUpperIndex,
|
||||
tickSpacing,
|
||||
);
|
||||
if (
|
||||
!TickUtil.checkTickInBounds(tickLowerInitializableIndex) ||
|
||||
!TickUtil.checkTickInBounds(tickUpperInitializableIndex)
|
||||
)
|
||||
throw Error("Prices out of bounds");
|
||||
const increasLiquidityQuoteParam: IncreaseLiquidityQuoteParam = {
|
||||
inputTokenAmount: new BN(depositTokenAmount),
|
||||
inputTokenMint: depositTokenMint,
|
||||
@@ -253,11 +285,11 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
tickLowerIndex: tickLowerInitializableIndex,
|
||||
tickUpperIndex: tickUpperInitializableIndex,
|
||||
tokenExtensionCtx: tokenExtensionCtx,
|
||||
slippageTolerance: Percentage.fromFraction(0, 100)
|
||||
}
|
||||
slippageTolerance: Percentage.fromFraction(0, 100),
|
||||
};
|
||||
const liquidityInput = increaseLiquidityQuoteByInputTokenWithParams(
|
||||
increasLiquidityQuoteParam
|
||||
)
|
||||
increasLiquidityQuoteParam,
|
||||
);
|
||||
const { liquidityAmount: liquidity, tokenMaxA, tokenMaxB } = liquidityInput;
|
||||
|
||||
const positionMintKeypair = Keypair.generate();
|
||||
@@ -285,7 +317,7 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
...params,
|
||||
positionMint: positionMintPubkey,
|
||||
withTokenMetadataExtension: true,
|
||||
})
|
||||
});
|
||||
|
||||
txBuilder.addInstruction(positionIx);
|
||||
txBuilder.addSigner(positionMintKeypair);
|
||||
@@ -365,35 +397,33 @@ export async function createOrcaSingleSidedWhirlpool(
|
||||
tickArrayUpper: tickArrayUpperPda.publicKey,
|
||||
};
|
||||
|
||||
const liquidityIx = !TokenExtensionUtil.isV2IxRequiredPool(
|
||||
tokenExtensionCtx,
|
||||
)
|
||||
const liquidityIx = !TokenExtensionUtil.isV2IxRequiredPool(tokenExtensionCtx)
|
||||
? increaseLiquidityIx(ctx.program, baseParamsLiquidity)
|
||||
: increaseLiquidityV2Ix(ctx.program, {
|
||||
...baseParamsLiquidity,
|
||||
tokenMintA: mintA,
|
||||
tokenMintB: mintB,
|
||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||
});
|
||||
...baseParamsLiquidity,
|
||||
tokenMintA: mintA,
|
||||
tokenMintB: mintB,
|
||||
tokenProgramA: tokenExtensionCtx.tokenMintWithProgramA.tokenProgram,
|
||||
tokenProgramB: tokenExtensionCtx.tokenMintWithProgramB.tokenProgram,
|
||||
});
|
||||
txBuilder.addInstruction(liquidityIx);
|
||||
|
||||
const txPayload = await txBuilder.build({
|
||||
maxSupportedTransactionVersion: "legacy"
|
||||
maxSupportedTransactionVersion: "legacy",
|
||||
});
|
||||
|
||||
if (txPayload.transaction instanceof Transaction) {
|
||||
try {
|
||||
const txId = await sendTx(
|
||||
agent,
|
||||
txPayload.transaction,
|
||||
[positionMintKeypair, tokenVaultAKeypair, tokenVaultBKeypair],
|
||||
);
|
||||
const txId = await sendTx(agent, txPayload.transaction, [
|
||||
positionMintKeypair,
|
||||
tokenVaultAKeypair,
|
||||
tokenVaultBKeypair,
|
||||
]);
|
||||
return txId;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create pool: ${JSON.stringify(error)}`);
|
||||
throw new Error(`Failed to create pool: ${JSON.stringify(error)}`);
|
||||
}
|
||||
} 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 { generateSigner, keypairIdentity, publicKey } from "@metaplex-foundation/umi";
|
||||
import { createCollection, mplCore, ruleSet } from "@metaplex-foundation/mpl-core";
|
||||
import { SolanaAgent } from "../index";
|
||||
import {
|
||||
generateSigner,
|
||||
keypairIdentity,
|
||||
publicKey,
|
||||
} from "@metaplex-foundation/umi";
|
||||
import {
|
||||
createCollection,
|
||||
mplCore,
|
||||
ruleSet,
|
||||
} from "@metaplex-foundation/mpl-core";
|
||||
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";
|
||||
|
||||
/**
|
||||
* Deploy a new NFT collection
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent 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,
|
||||
agent: SolanaAgent,
|
||||
options: CollectionOptions,
|
||||
): Promise<CollectionDeployment> {
|
||||
try {
|
||||
@@ -28,11 +39,11 @@ export async function deploy_collection(
|
||||
address: publicKey(creator.address),
|
||||
percentage: creator.percentage,
|
||||
})) || [
|
||||
{
|
||||
address: publicKey(agent.wallet_address.toString()),
|
||||
percentage: 100,
|
||||
},
|
||||
];
|
||||
{
|
||||
address: publicKey(agent.wallet_address.toString()),
|
||||
percentage: 100,
|
||||
},
|
||||
];
|
||||
|
||||
// Create collection
|
||||
const tx = await createCollection(umi, {
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
|
||||
import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi";
|
||||
import { createFungible, mintV1, TokenStandard } from "@metaplex-foundation/mpl-token-metadata";
|
||||
import { fromWeb3JsKeypair, fromWeb3JsPublicKey, toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
||||
import {
|
||||
createFungible,
|
||||
mintV1,
|
||||
TokenStandard,
|
||||
} from "@metaplex-foundation/mpl-token-metadata";
|
||||
import {
|
||||
fromWeb3JsKeypair,
|
||||
fromWeb3JsPublicKey,
|
||||
toWeb3JsPublicKey,
|
||||
} from "@metaplex-foundation/umi-web3js-adapters";
|
||||
|
||||
/**
|
||||
* Deploy a new SPL token
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent instance
|
||||
* @param name Name of the token
|
||||
* @param uri URI for the token metadata
|
||||
* @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)
|
||||
*/
|
||||
export async function deploy_token(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
name: string,
|
||||
uri: string,
|
||||
symbol: string,
|
||||
decimals: number = 9,
|
||||
initialSupply?: number
|
||||
initialSupply?: number,
|
||||
): Promise<{ mint: PublicKey }> {
|
||||
try {
|
||||
// Create UMI instance from agent
|
||||
const umi = createUmi(agent.connection.rpcEndpoint)
|
||||
const umi = createUmi(agent.connection.rpcEndpoint);
|
||||
umi.use(keypairIdentity(fromWeb3JsKeypair(agent.wallet)));
|
||||
|
||||
// Create new token mint
|
||||
@@ -51,11 +59,11 @@ export async function deploy_token(
|
||||
tokenStandard: TokenStandard.Fungible,
|
||||
tokenOwner: fromWeb3JsPublicKey(agent.wallet_address),
|
||||
amount: initialSupply,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
builder.sendAndConfirm(umi, { confirm: { commitment: 'finalized' } });
|
||||
builder.sendAndConfirm(umi, { confirm: { commitment: "finalized" } });
|
||||
|
||||
return {
|
||||
mint: toWeb3JsPublicKey(mint.publicKey),
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { Tool } from "langchain/tools";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Fetch the price of a given token in USDC using Jupiter API
|
||||
* @param agent SolanaAgentKit instance
|
||||
* Fetch the price of a given token quoted in USDC using Jupiter API
|
||||
* @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(
|
||||
agent: SolanaAgentKit,
|
||||
tokenId: string
|
||||
): Promise<string> {
|
||||
export async function fetchPrice(tokenId: PublicKey): Promise<string> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`https://api.jup.ag/price/v2?ids=${tokenId}`
|
||||
);
|
||||
const response = await fetch(`https://api.jup.ag/price/v2?ids=${tokenId}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch price: ${response.statusText}`);
|
||||
@@ -22,7 +15,7 @@ export async function fetchPrice(
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const price = data.data[tokenId]?.price;
|
||||
const price = data.data[tokenId.toBase58()]?.price;
|
||||
|
||||
if (!price) {
|
||||
throw new Error("Price data not available for the given token.");
|
||||
@@ -32,4 +25,4 @@ export async function fetchPrice(
|
||||
} catch (error: any) {
|
||||
throw new Error(`Price fetch failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
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
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @param agent - SolanaAgent 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,
|
||||
agent: SolanaAgent,
|
||||
token_address?: PublicKey,
|
||||
): Promise<number | null> {
|
||||
if (!token_address)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service";
|
||||
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.
|
||||
@@ -9,29 +9,29 @@ import { SolanaAgentKit } from "../index";
|
||||
* a specified Solana public key. If the primary domain is stale or an error occurs during
|
||||
* 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
|
||||
* @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
|
||||
*/
|
||||
export async function getPrimaryDomain(
|
||||
agent: SolanaAgentKit,
|
||||
account: PublicKey
|
||||
agent: SolanaAgent,
|
||||
account: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const { reverse, stale } = await _getPrimaryDomain(
|
||||
agent.connection,
|
||||
account
|
||||
account,
|
||||
);
|
||||
if (stale) {
|
||||
throw new Error(
|
||||
`Primary domain is stale for account: ${account.toBase58()}`
|
||||
`Primary domain is stale for account: ${account.toBase58()}`,
|
||||
);
|
||||
}
|
||||
return reverse;
|
||||
} catch (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> {
|
||||
const perfSamples = await agent.connection.getRecentPerformanceSamples();
|
||||
|
||||
@@ -15,8 +15,8 @@ export * from "./get_token_data";
|
||||
export * from "./stake_with_jup";
|
||||
export * from "./fetch_price";
|
||||
export * from "./send_compressed_airdrop";
|
||||
|
||||
export * from "./create_orca_single_sided_whirlpool";export * from "./raydium_create_ammV4";
|
||||
export * from "./create_orca_single_sided_whirlpool";
|
||||
export * from "./raydium_create_ammV4";
|
||||
export * from "./raydium_create_clmm";
|
||||
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(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
mintKeypair: Keypair,
|
||||
metadataResponse: any,
|
||||
options?: PumpFunTokenOptions,
|
||||
@@ -140,7 +140,7 @@ async function signAndSendTransaction(
|
||||
|
||||
/**
|
||||
* Launch a token on Pump.fun
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @param agent - SolanaAgent instance
|
||||
* @param tokenName - Name of the token
|
||||
* @param tokenTicker - Ticker 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
|
||||
*/
|
||||
export async function launchPumpFunToken(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
tokenName: string,
|
||||
tokenTicker: string,
|
||||
description: string,
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { VersionedTransaction } from "@solana/web3.js";
|
||||
import { LuloAccountDetailsResponse } from "../types";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
/**
|
||||
* Lend tokens for yields using Lulo
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent instance
|
||||
* @param amount Amount of USDC to lend
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function lendAsset(
|
||||
agent: SolanaAgentKit,
|
||||
amount: number
|
||||
agent: SolanaAgent,
|
||||
amount: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
@@ -23,14 +22,14 @@ export async function lendAsset(
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Deserialize the transaction
|
||||
const luloTxn = VersionedTransaction.deserialize(
|
||||
Buffer.from(data.transaction, "base64")
|
||||
Buffer.from(data.transaction, "base64"),
|
||||
);
|
||||
|
||||
// Get a recent blockhash and set it
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { generateSigner, keypairIdentity } from '@metaplex-foundation/umi';
|
||||
import { create, mplCore } from '@metaplex-foundation/mpl-core';
|
||||
import { fetchCollection } from '@metaplex-foundation/mpl-core';
|
||||
import { SolanaAgent } from "../index";
|
||||
import { generateSigner, keypairIdentity } from "@metaplex-foundation/umi";
|
||||
import { create, mplCore } from "@metaplex-foundation/mpl-core";
|
||||
import { fetchCollection } from "@metaplex-foundation/mpl-core";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { fromWeb3JsKeypair, fromWeb3JsPublicKey, toWeb3JsPublicKey } from "@metaplex-foundation/umi-web3js-adapters";
|
||||
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
|
||||
import { MintCollectionNFTResponse } from '../types';
|
||||
import {
|
||||
fromWeb3JsKeypair,
|
||||
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 agent SolanaAgent 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,
|
||||
agent: SolanaAgent,
|
||||
collectionMint: PublicKey,
|
||||
metadata: {
|
||||
name: string;
|
||||
@@ -27,7 +31,7 @@ export async function mintCollectionNFT(
|
||||
share: number;
|
||||
}>;
|
||||
},
|
||||
recipient?: PublicKey
|
||||
recipient?: PublicKey,
|
||||
): Promise<MintCollectionNFTResponse> {
|
||||
try {
|
||||
// Create UMI instance from agent
|
||||
@@ -49,15 +53,15 @@ export async function mintCollectionNFT(
|
||||
collection: collection,
|
||||
name: metadata.name,
|
||||
uri: metadata.uri,
|
||||
owner: fromWeb3JsPublicKey(recipient ?? agent.wallet.publicKey)
|
||||
owner: fromWeb3JsPublicKey(recipient ?? agent.wallet.publicKey),
|
||||
}).sendAndConfirm(umi);
|
||||
|
||||
return {
|
||||
mint: toWeb3JsPublicKey(assetSigner.publicKey),
|
||||
// Note: Token account is now handled automatically by the create instruction
|
||||
metadata: toWeb3JsPublicKey(assetSigner.publicKey)
|
||||
metadata: toWeb3JsPublicKey(assetSigner.publicKey),
|
||||
};
|
||||
} catch (error: any) {
|
||||
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 { PublicKey } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
export async function openbookCreateMarket(
|
||||
agent: SolanaAgentKit,
|
||||
|
||||
agent: SolanaAgent,
|
||||
baseMint: PublicKey,
|
||||
quoteMint: PublicKey,
|
||||
|
||||
lotSize: number = 1,
|
||||
tickSize: number = 0.01,
|
||||
): Promise<string[]> {
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
})
|
||||
});
|
||||
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint)
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint)
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||
|
||||
if (
|
||||
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||
) {
|
||||
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({
|
||||
@@ -44,9 +45,9 @@ export async function openbookCreateMarket(
|
||||
dexProgramId: OPEN_BOOK_PROGRAM,
|
||||
|
||||
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 { PublicKey } from "@solana/web3.js";
|
||||
import BN from 'bn.js';
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import BN from "bn.js";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
export async function raydiumCreateAmmV4(
|
||||
agent: SolanaAgentKit,
|
||||
|
||||
agent: SolanaAgent,
|
||||
marketId: PublicKey,
|
||||
|
||||
baseAmount: BN,
|
||||
quoteAmount: BN,
|
||||
|
||||
startTime: BN,
|
||||
): Promise<string> {
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
})
|
||||
});
|
||||
|
||||
const marketBufferInfo = await agent.connection.getAccountInfo(new PublicKey(marketId))
|
||||
const { baseMint, quoteMint } = MARKET_STATE_LAYOUT_V3.decode(marketBufferInfo!.data)
|
||||
const marketBufferInfo = await agent.connection.getAccountInfo(
|
||||
new PublicKey(marketId),
|
||||
);
|
||||
const { baseMint, quoteMint } = MARKET_STATE_LAYOUT_V3.decode(
|
||||
marketBufferInfo!.data,
|
||||
);
|
||||
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint)
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint)
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||
|
||||
if (
|
||||
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||
) {
|
||||
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)))) {
|
||||
throw new Error('initial liquidity too low, try adding more baseAmount/quoteAmount')
|
||||
if (
|
||||
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({
|
||||
@@ -63,9 +80,9 @@ export async function raydiumCreateAmmV4(
|
||||
associatedOnly: false,
|
||||
txVersion: TxVersion.V0,
|
||||
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 { MintLayout } from '@solana/spl-token'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import BN from 'bn.js'
|
||||
import Decimal from 'decimal.js'
|
||||
import { SolanaAgentKit } from '../agent'
|
||||
import {
|
||||
CLMM_PROGRAM_ID,
|
||||
Raydium,
|
||||
TxVersion,
|
||||
} from "@raydium-io/raydium-sdk-v2";
|
||||
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(
|
||||
agent: SolanaAgentKit,
|
||||
|
||||
agent: SolanaAgent,
|
||||
mint1: PublicKey,
|
||||
mint2: PublicKey,
|
||||
|
||||
configId: PublicKey,
|
||||
|
||||
initialPrice: Decimal,
|
||||
startTime: BN,
|
||||
): Promise<string> {
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
})
|
||||
});
|
||||
|
||||
const [mintInfo1, mintInfo2] = await agent.connection.getMultipleAccountsInfo([mint1, mint2])
|
||||
if (mintInfo1 === null || mintInfo2 === null) throw Error('fetch mint info error')
|
||||
const [mintInfo1, mintInfo2] = await agent.connection.getMultipleAccountsInfo(
|
||||
[mint1, mint2],
|
||||
);
|
||||
if (mintInfo1 === null || mintInfo2 === null)
|
||||
throw Error("fetch mint info error");
|
||||
|
||||
const mintDecodeInfo1 = MintLayout.decode(mintInfo1.data)
|
||||
const mintDecodeInfo2 = MintLayout.decode(mintInfo2.data)
|
||||
const mintDecodeInfo1 = MintLayout.decode(mintInfo1.data);
|
||||
const mintDecodeInfo2 = MintLayout.decode(mintInfo2.data);
|
||||
|
||||
const mintFormatInfo1 = {
|
||||
chainId: 101,
|
||||
address: mint1.toString(),
|
||||
programId: mintInfo1.owner.toString(),
|
||||
logoURI: '',
|
||||
symbol: '',
|
||||
name: '',
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfo1.decimals,
|
||||
tags: [],
|
||||
extensions: {}
|
||||
}
|
||||
extensions: {},
|
||||
};
|
||||
const mintFormatInfo2 = {
|
||||
chainId: 101,
|
||||
address: mint2.toString(),
|
||||
programId: mintInfo2.owner.toString(),
|
||||
logoURI: '',
|
||||
symbol: '',
|
||||
name: '',
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfo2.decimals,
|
||||
tags: [],
|
||||
extensions: {}
|
||||
}
|
||||
extensions: {},
|
||||
};
|
||||
|
||||
const { execute } = await raydium.clmm.createPool({
|
||||
programId: CLMM_PROGRAM_ID,
|
||||
@@ -65,9 +68,9 @@ export async function raydiumCreateClmm(
|
||||
// units: 600000,
|
||||
// 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_PROGRAM,
|
||||
Raydium,
|
||||
TxVersion
|
||||
} from '@raydium-io/raydium-sdk-v2'
|
||||
import { MintLayout } from '@solana/spl-token'
|
||||
import { PublicKey } from '@solana/web3.js'
|
||||
import BN from 'bn.js'
|
||||
import { SolanaAgentKit } from '../agent'
|
||||
TxVersion,
|
||||
} from "@raydium-io/raydium-sdk-v2";
|
||||
import { MintLayout } from "@solana/spl-token";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
export async function raydiumCreateCpmm(
|
||||
agent: SolanaAgentKit,
|
||||
|
||||
agent: SolanaAgent,
|
||||
mintA: PublicKey,
|
||||
mintB: PublicKey,
|
||||
|
||||
configId: PublicKey,
|
||||
|
||||
mintAAmount: BN,
|
||||
mintBAmount: BN,
|
||||
|
||||
startTime: BN,
|
||||
): Promise<string> {
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
})
|
||||
});
|
||||
|
||||
const [mintInfoA, mintInfoB] = await agent.connection.getMultipleAccountsInfo([mintA, mintB])
|
||||
if (mintInfoA === null || mintInfoB === null) throw Error('fetch mint info error')
|
||||
const [mintInfoA, mintInfoB] = await agent.connection.getMultipleAccountsInfo(
|
||||
[mintA, mintB],
|
||||
);
|
||||
if (mintInfoA === null || mintInfoB === null)
|
||||
throw Error("fetch mint info error");
|
||||
|
||||
const mintDecodeInfoA = MintLayout.decode(mintInfoA.data)
|
||||
const mintDecodeInfoB = MintLayout.decode(mintInfoB.data)
|
||||
const mintDecodeInfoA = MintLayout.decode(mintInfoA.data);
|
||||
const mintDecodeInfoB = MintLayout.decode(mintInfoB.data);
|
||||
|
||||
const mintFormatInfoA = {
|
||||
chainId: 101,
|
||||
address: mintA.toString(),
|
||||
programId: mintInfoA.owner.toString(),
|
||||
logoURI: '',
|
||||
symbol: '',
|
||||
name: '',
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfoA.decimals,
|
||||
tags: [],
|
||||
extensions: {}
|
||||
}
|
||||
extensions: {},
|
||||
};
|
||||
const mintFormatInfoB = {
|
||||
chainId: 101,
|
||||
address: mintB.toString(),
|
||||
programId: mintInfoB.owner.toString(),
|
||||
logoURI: '',
|
||||
symbol: '',
|
||||
name: '',
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfoB.decimals,
|
||||
tags: [],
|
||||
extensions: {}
|
||||
}
|
||||
extensions: {},
|
||||
};
|
||||
|
||||
const { execute, extInfo } = await raydium.cpmm.createPool({
|
||||
programId: CREATE_CPMM_POOL_PROGRAM,
|
||||
@@ -76,9 +74,9 @@ export async function raydiumCreateCpmm(
|
||||
// units: 600000,
|
||||
// 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 { Transaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } 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 agent SolanaAgent 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,
|
||||
agent: SolanaAgent,
|
||||
name: string,
|
||||
spaceKB: number = 1,
|
||||
): Promise<string> {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Request SOL from the Solana faucet (devnet/testnet only)
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @param agent - SolanaAgent instance
|
||||
* @returns Transaction signature
|
||||
* @throws Error if the request fails or times out
|
||||
*/
|
||||
export async function request_faucet_funds(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
): Promise<string> {
|
||||
const tx = await agent.connection.requestAirdrop(
|
||||
agent.wallet_address,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { resolve } from "@bonfida/spl-name-service";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* @returns A promise that resolves to the corresponding Solana PublicKey
|
||||
* @throws Error if the domain resolution fails
|
||||
*/
|
||||
export async function resolveSolDomain(
|
||||
agent: SolanaAgentKit,
|
||||
domain: string
|
||||
agent: SolanaAgent,
|
||||
domain: string,
|
||||
): Promise<PublicKey> {
|
||||
if (!domain || typeof domain !== "string") {
|
||||
throw new Error("Invalid domain. Expected a non-empty string.");
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import {
|
||||
AddressLookupTableAccount,
|
||||
ComputeBudgetProgram,
|
||||
Connection,
|
||||
Keypair,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent/index.js";
|
||||
import { SolanaAgent } from "../index";
|
||||
import {
|
||||
buildAndSignTx,
|
||||
calculateComputeUnitPrice,
|
||||
@@ -33,7 +32,7 @@ const MAX_CONCURRENT_TXS = 30;
|
||||
*/
|
||||
export const getAirdropCostEstimate = (
|
||||
numberOfRecipients: number,
|
||||
priorityFeeInLamports: number
|
||||
priorityFeeInLamports: number,
|
||||
) => {
|
||||
const baseFee = 5000;
|
||||
const perRecipientCompressedStateFee = 300;
|
||||
@@ -57,28 +56,27 @@ export const getAirdropCostEstimate = (
|
||||
* @param shouldLog Whether to log progress to stdout. Defaults to false.
|
||||
*/
|
||||
export async function sendCompressedAirdrop(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
mintAddress: PublicKey,
|
||||
amount: number,
|
||||
decimals: number,
|
||||
recipients: PublicKey[],
|
||||
priorityFeeInLamports: number,
|
||||
shouldLog: boolean = false
|
||||
shouldLog: boolean = false,
|
||||
): Promise<string[]> {
|
||||
if (recipients.length > MAX_AIRDROP_RECIPIENTS) {
|
||||
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;
|
||||
if (url.includes("devnet")) {
|
||||
throw new Error("Devnet is not supported for airdrop. Please use mainnet.");
|
||||
}
|
||||
if (!url.includes("helius")) {
|
||||
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.wallet,
|
||||
mintAddress,
|
||||
agent.wallet.publicKey
|
||||
agent.wallet.publicKey,
|
||||
);
|
||||
} catch (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(
|
||||
agent.connection as unknown as Rpc,
|
||||
agent.wallet,
|
||||
mintAddress
|
||||
mintAddress,
|
||||
);
|
||||
} catch (error: any) {
|
||||
if (error.message.includes("already in use")) {
|
||||
@@ -116,17 +114,17 @@ export async function sendCompressedAirdrop(
|
||||
mintAddress,
|
||||
recipients,
|
||||
priorityFeeInLamports,
|
||||
shouldLog
|
||||
shouldLog,
|
||||
);
|
||||
}
|
||||
|
||||
async function processAll(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
amount: number,
|
||||
mint: PublicKey,
|
||||
recipients: PublicKey[],
|
||||
priorityFeeInLamports: number,
|
||||
shouldLog: boolean
|
||||
shouldLog: boolean,
|
||||
): Promise<string[]> {
|
||||
const mintAddress = mint;
|
||||
const payer = agent.wallet;
|
||||
@@ -135,13 +133,13 @@ async function processAll(
|
||||
agent.connection,
|
||||
agent.wallet,
|
||||
mintAddress,
|
||||
agent.wallet.publicKey
|
||||
agent.wallet.publicKey,
|
||||
);
|
||||
|
||||
const maxRecipientsPerInstruction = 5;
|
||||
const maxIxs = 3; // empirically determined (as of 12/15/2024)
|
||||
const lookupTableAddress = new PublicKey(
|
||||
"9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ"
|
||||
"9NYFyEqPkyXUhkerbGHXUXkvb4qpzeEdHuGpgbgpH1NJ",
|
||||
);
|
||||
|
||||
const lookupTableAccount = (
|
||||
@@ -164,7 +162,7 @@ async function processAll(
|
||||
ComputeBudgetProgram.setComputeUnitPrice({
|
||||
microLamports: calculateComputeUnitPrice(
|
||||
priorityFeeInLamports,
|
||||
500_000
|
||||
500_000,
|
||||
),
|
||||
}),
|
||||
];
|
||||
@@ -184,13 +182,13 @@ async function processAll(
|
||||
toAddress: batch,
|
||||
amount: batch.map(() => amount),
|
||||
mint: mintAddress,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const compressIxs = await Promise.all(compressIxPromises);
|
||||
return [...instructions, ...compressIxs];
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const url = agent.connection.rpcEndpoint;
|
||||
@@ -225,12 +223,12 @@ async function processAll(
|
||||
instructions,
|
||||
payer,
|
||||
lookupTableAccount,
|
||||
i + idx
|
||||
i + idx,
|
||||
).then((signature) => {
|
||||
confirmedCount++;
|
||||
log("\r" + renderProgressBar(confirmedCount, totalBatches));
|
||||
return signature;
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const batchResults = await Promise.allSettled(batchPromises);
|
||||
@@ -250,7 +248,7 @@ async function processAll(
|
||||
throw new Error(
|
||||
`Failed to process ${failures.length} batches: ${failures
|
||||
.map((f) => f.error)
|
||||
.join(", ")}`
|
||||
.join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -262,7 +260,7 @@ async function sendTransactionWithRetry(
|
||||
instructions: TransactionInstruction[],
|
||||
payer: Keypair,
|
||||
lookupTableAccount: AddressLookupTableAccount,
|
||||
batchIndex: number
|
||||
batchIndex: number,
|
||||
): Promise<string> {
|
||||
const MAX_RETRIES = 3;
|
||||
const INITIAL_BACKOFF = 500; // ms
|
||||
@@ -275,7 +273,7 @@ async function sendTransactionWithRetry(
|
||||
payer,
|
||||
blockhash,
|
||||
[],
|
||||
[lookupTableAccount]
|
||||
[lookupTableAccount],
|
||||
);
|
||||
|
||||
const signature = await sendAndConfirmTx(connection, tx);
|
||||
@@ -292,7 +290,7 @@ async function sendTransactionWithRetry(
|
||||
throw new Error(
|
||||
`Batch ${batchIndex} failed after ${attempt + 1} attempts: ${
|
||||
error.message
|
||||
}`
|
||||
}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { VersionedTransaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { SolanaAgent } from "../index";
|
||||
|
||||
/**
|
||||
* Stake SOL with Jup validator
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent instance
|
||||
* @param amount Amount of SOL to stake
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function stakeWithJup(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
amount: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import { VersionedTransaction, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
VersionedTransaction,
|
||||
PublicKey,
|
||||
LAMPORTS_PER_SOL,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
||||
|
||||
/**
|
||||
* Swap tokens using Jupiter Exchange
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent instance
|
||||
* @param outputMint Target token mint address
|
||||
* @param inputAmount Amount to swap (in token decimals)
|
||||
* @param inputMint Source token mint address (defaults to USDC)
|
||||
@@ -12,7 +16,7 @@ import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function trade(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
outputMint: PublicKey,
|
||||
inputAmount: number,
|
||||
inputMint: PublicKey = TOKENS.USDC,
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
Transaction
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgent } from "../index";
|
||||
import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js";
|
||||
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
|
||||
import {
|
||||
getAssociatedTokenAddress,
|
||||
import {
|
||||
getAssociatedTokenAddress,
|
||||
createTransferInstruction,
|
||||
getMint
|
||||
getMint,
|
||||
} from "@solana/spl-token";
|
||||
|
||||
/**
|
||||
* Transfer SOL or SPL tokens to a recipient
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param agent SolanaAgent 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,
|
||||
agent: SolanaAgent,
|
||||
to: PublicKey,
|
||||
amount: number,
|
||||
mint?: PublicKey
|
||||
mint?: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
let tx: string;
|
||||
@@ -34,19 +30,19 @@ export async function transfer(
|
||||
SystemProgram.transfer({
|
||||
fromPubkey: agent.wallet_address,
|
||||
toPubkey: to,
|
||||
lamports: amount * LAMPORTS_PER_SOL
|
||||
})
|
||||
lamports: amount * LAMPORTS_PER_SOL,
|
||||
}),
|
||||
);
|
||||
|
||||
tx = await agent.connection.sendTransaction(
|
||||
transaction,
|
||||
[agent.wallet]
|
||||
);
|
||||
tx = await agent.connection.sendTransaction(transaction, [agent.wallet]);
|
||||
} else {
|
||||
// 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);
|
||||
|
||||
|
||||
// Get mint info to determine decimals
|
||||
const mintInfo = await getMint(agent.connection, mint);
|
||||
const adjustedAmount = amount * Math.pow(10, mintInfo.decimals);
|
||||
@@ -56,18 +52,15 @@ export async function transfer(
|
||||
fromAta,
|
||||
toAta,
|
||||
agent.wallet_address,
|
||||
adjustedAmount
|
||||
)
|
||||
adjustedAmount,
|
||||
),
|
||||
);
|
||||
|
||||
tx = await agent.connection.sendTransaction(
|
||||
transaction,
|
||||
[agent.wallet]
|
||||
);
|
||||
tx = await agent.connection.sendTransaction(transaction, [agent.wallet]);
|
||||
}
|
||||
|
||||
return tx;
|
||||
} catch (error: any) {
|
||||
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 { Connection, ComputeBudgetProgram } from "@solana/web3.js";
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function getPriorityFees(connection: Connection): Promise<{
|
||||
const median =
|
||||
sortedFees.length % 2 === 0
|
||||
? ((sortedFees[mid - 1] ?? 0) + (sortedFees[mid] ?? 0)) / 2
|
||||
: sortedFees[mid] ?? 0;
|
||||
: (sortedFees[mid] ?? 0);
|
||||
|
||||
// Helper to create priority fee IX based on chosen strategy
|
||||
const createPriorityFeeIx = (fee: number) => {
|
||||
@@ -69,14 +69,14 @@ export async function getPriorityFees(connection: Connection): Promise<{
|
||||
|
||||
/**
|
||||
* Send a transaction with priority fees
|
||||
* @param agent - SolanaAgentKit instance
|
||||
* @param agent - SolanaAgent instance
|
||||
* @param tx - Transaction to send
|
||||
* @returns Transaction ID
|
||||
*/
|
||||
export async function sendTx(
|
||||
agent: SolanaAgentKit,
|
||||
agent: SolanaAgent,
|
||||
tx: Transaction,
|
||||
otherKeypairs?: Keypair[]
|
||||
otherKeypairs?: Keypair[],
|
||||
) {
|
||||
tx.recentBlockhash = (await agent.connection.getLatestBlockhash()).blockhash;
|
||||
tx.feePayer = agent.wallet_address;
|
||||
@@ -90,9 +90,8 @@ export async function sendTx(
|
||||
await agent.connection.confirmTransaction({
|
||||
signature: txid,
|
||||
blockhash: (await agent.connection.getLatestBlockhash()).blockhash,
|
||||
lastValidBlockHeight: (
|
||||
await agent.connection.getLatestBlockhash()
|
||||
).lastValidBlockHeight,
|
||||
lastValidBlockHeight: (await agent.connection.getLatestBlockhash())
|
||||
.lastValidBlockHeight,
|
||||
});
|
||||
return txid;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user