mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-13 23:16:55 +00:00
Merge branch 'main' into main
This commit is contained in:
56
README.md
56
README.md
@@ -35,7 +35,10 @@ Anyone - whether an SF-based AI researcher or a crypto-native builder - can brin
|
||||
- Balance checks
|
||||
- Stake SOL
|
||||
- Zk compressed Airdrop by Light Protocol and Helius
|
||||
|
||||
- **NFTs on 3.Land**
|
||||
- Create your own collection
|
||||
- NFT creation and automatic listing on 3.land
|
||||
- List your NFT for sale in any SPL token
|
||||
- **NFT Management via Metaplex**
|
||||
- Collection deployment
|
||||
- NFT minting
|
||||
@@ -127,6 +130,57 @@ const result = await agent.deployToken(
|
||||
|
||||
console.log("Token Mint Address:", result.mint.toString());
|
||||
```
|
||||
### Create NFT Collection on 3Land
|
||||
```typescript
|
||||
const optionsWithBase58: StoreInitOptions = {
|
||||
privateKey: "",
|
||||
isMainnet: true, // if false, collection will be created on devnet 3.land (dev.3.land)
|
||||
};
|
||||
|
||||
const collectionOpts: CreateCollectionOptions = {
|
||||
collectionName: "",
|
||||
collectionSymbol: "",
|
||||
collectionDescription: "",
|
||||
mainImageUrl: ""
|
||||
};
|
||||
|
||||
const result = await agent.create3LandCollection(
|
||||
optionsWithBase58,
|
||||
collectionOpts
|
||||
);
|
||||
```
|
||||
|
||||
### Create NFT on 3Land
|
||||
When creating an NFT using 3Land's tool, it automatically goes for sale on 3.land website
|
||||
```typescript
|
||||
const optionsWithBase58: StoreInitOptions = {
|
||||
privateKey: "",
|
||||
isMainnet: true, // if false, listing will be on devnet 3.land (dev.3.land)
|
||||
};
|
||||
const collectionAccount = ""; //hash for the collection
|
||||
const createItemOptions: CreateSingleOptions = {
|
||||
itemName: "",
|
||||
sellerFee: 500, //5%
|
||||
itemAmount: 100, //total items to be created
|
||||
itemSymbol: "",
|
||||
itemDescription: "",
|
||||
traits: [
|
||||
{ trait_type: "", value: "" },
|
||||
],
|
||||
price: 0, //100000000 == 0.1 sol, can be set to 0 for a free mint
|
||||
mainImageUrl: "",
|
||||
splHash: "", //present if listing is on a specific SPL token, if not present sale will be on $SOL
|
||||
};
|
||||
const isMainnet = true;
|
||||
const result = await agent.create3LandNft(
|
||||
optionsWithBase58,
|
||||
collectionAccount,
|
||||
createItemOptions,
|
||||
isMainnet
|
||||
);
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Create NFT Collection
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
|
||||
export const agentKit = new SolanaAgentKit(
|
||||
process.env.SOLANA_PRIVATE_KEY!,
|
||||
process.env.RPC_URL!,
|
||||
process.env.OPENAI_API_KEY!,
|
||||
{ OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
|
||||
);
|
||||
|
||||
export const solanaTools = createSolanaTools(agentKit);
|
||||
|
||||
3
examples/market-making-agent/.env.example
Normal file
3
examples/market-making-agent/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
OPENAI_API_KEY=
|
||||
RPC_URL=
|
||||
SOLANA_PRIVATE_KEY=
|
||||
50
examples/market-making-agent/README.md
Normal file
50
examples/market-making-agent/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# AI Guided Market Making Agent
|
||||
|
||||
This agent showcases an ai guided market maker on Manifest, Solana's CLOB DEX. The agent guides the user to setup basic two-sided quotes on Manifest markets.
|
||||
[Reference](https://github.com/CKS-Systems/manifest)
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Automated Quoting**: The agent automatically refreshes quotes on an interval.
|
||||
- **Reducing Complexity**: Designed to abstract away parameters for setting up market making.
|
||||
- **Random Model**: The market making introduces randomness to prevent front running or other negative botting behavoirs.
|
||||
|
||||
|
||||
## Example
|
||||
=== Market Maker Configuration ===
|
||||
|
||||
Enter the market ID: 2Uj8277fkaVBtTU6Wp2GPRbQC86SkSdgQ2mp1Q5N2LHc
|
||||
Enter the base token symbol (e.g., SEND): SEND
|
||||
Enter the quote token symbol (e.g., USDC): USDC
|
||||
|
||||
=== Quote Parameters (applies to both buy and sell sides) ===
|
||||
Enter number of quotes to place on each side: 4
|
||||
Enter minimum quote depth (% distance from mid price): 0.1
|
||||
Enter maximum quote depth (% distance from mid price): 2
|
||||
|
||||
=== Token Allowances ===
|
||||
Enter total SEND allowance: 2
|
||||
Enter total USDC allowance: 3
|
||||
|
||||
Enter update interval in seconds: 20
|
||||
|
||||
=== Configuration Summary ===
|
||||
{
|
||||
"marketId": "2Uj8277fkaVBtTU6Wp2GPRbQC86SkSdgQ2mp1Q5N2LHc",
|
||||
"baseToken": "SEND",
|
||||
"quoteToken": "USDC",
|
||||
"quoteParams": {
|
||||
"number": 4,
|
||||
"minDepth": 0.1,
|
||||
"maxDepth": 2
|
||||
},
|
||||
"allowance": {
|
||||
"base": 2,
|
||||
"quote": 3
|
||||
},
|
||||
"intervalSeconds": 20
|
||||
}
|
||||
|
||||
Is this configuration correct? (yes/no): yes
|
||||
|
||||
Starting market maker mode for SEND/USDC...
|
||||
389
examples/market-making-agent/index.ts
Normal file
389
examples/market-making-agent/index.ts
Normal file
@@ -0,0 +1,389 @@
|
||||
import { HumanMessage } from "@langchain/core/messages";
|
||||
import { MemorySaver } from "@langchain/langgraph";
|
||||
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import * as dotenv from "dotenv";
|
||||
import * as fs from "fs";
|
||||
import * as readline from "readline";
|
||||
import { createSolanaTools, SolanaAgentKit } from "../../src";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
function validateEnvironment(): void {
|
||||
const missingVars: string[] = [];
|
||||
const requiredVars = ["OPENAI_API_KEY", "RPC_URL", "SOLANA_PRIVATE_KEY"];
|
||||
|
||||
requiredVars.forEach((varName) => {
|
||||
if (!process.env[varName]) {
|
||||
missingVars.push(varName);
|
||||
}
|
||||
});
|
||||
|
||||
if (missingVars.length > 0) {
|
||||
console.error("Error: Required environment variables are not set");
|
||||
missingVars.forEach((varName) => {
|
||||
console.error(`${varName}=your_${varName.toLowerCase()}_here`);
|
||||
});
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
validateEnvironment();
|
||||
|
||||
const WALLET_DATA_FILE = "wallet_data.txt";
|
||||
|
||||
async function initializeAgent() {
|
||||
try {
|
||||
const llm = new ChatOpenAI({
|
||||
modelName: "gpt-4o-mini",
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
let walletDataStr: string | null = null;
|
||||
|
||||
if (fs.existsSync(WALLET_DATA_FILE)) {
|
||||
try {
|
||||
walletDataStr = fs.readFileSync(WALLET_DATA_FILE, "utf8");
|
||||
} catch (error) {
|
||||
console.error("Error reading wallet data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const solanaAgent = new SolanaAgentKit(
|
||||
process.env.SOLANA_PRIVATE_KEY!,
|
||||
process.env.RPC_URL!,
|
||||
{
|
||||
OPENAI_API_KEY: process.env.OPENAI_API_KEY!,
|
||||
},
|
||||
);
|
||||
|
||||
const tools = createSolanaTools(solanaAgent);
|
||||
|
||||
const memory = new MemorySaver();
|
||||
const config = { configurable: { thread_id: "Solana Agent Kit!" } };
|
||||
|
||||
const agent = createReactAgent({
|
||||
llm,
|
||||
tools,
|
||||
checkpointSaver: memory,
|
||||
messageModifier: `
|
||||
You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
|
||||
empowered to interact onchain using your tools. If you ever need funds, you can request them from the
|
||||
faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
|
||||
(internal) HTTP error code, ask the user to try again later. If someone asks you to do something you
|
||||
can't do with your currently available tools, you must say so, and encourage them to implement it
|
||||
themselves using the Solana Agent Kit, recommend they go to https://www.solanaagentkit.xyz for more information. Be
|
||||
concise and helpful with your responses. Refrain from restating your tools' descriptions unless it is explicitly requested.
|
||||
`,
|
||||
});
|
||||
|
||||
if (walletDataStr) {
|
||||
fs.writeFileSync(WALLET_DATA_FILE, walletDataStr);
|
||||
}
|
||||
|
||||
return { agent, config };
|
||||
} catch (error) {
|
||||
console.error("Failed to initialize agent:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function runAutonomousMode(agent: any, config: any, interval = 10) {
|
||||
console.log("Starting autonomous mode...");
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const thought =
|
||||
"Be creative and do something interesting on the blockchain. " +
|
||||
"Choose an action or set of actions and execute it that highlights your abilities.";
|
||||
|
||||
const stream = await agent.stream(
|
||||
{ messages: [new HumanMessage(thought)] },
|
||||
config,
|
||||
);
|
||||
|
||||
for await (const chunk of stream) {
|
||||
if ("agent" in chunk) {
|
||||
console.log(chunk.agent.messages[0].content);
|
||||
} else if ("tools" in chunk) {
|
||||
console.log(chunk.tools.messages[0].content);
|
||||
}
|
||||
console.log("-------------------");
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error("Error:", error.message);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function runChatMode(agent: any, config: any) {
|
||||
console.log("Starting chat mode... Type 'exit' to end.");
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const question = (prompt: string): Promise<string> =>
|
||||
new Promise((resolve) => rl.question(prompt, resolve));
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
const userInput = await question("\nPrompt: ");
|
||||
|
||||
if (userInput.toLowerCase() === "exit") {
|
||||
break;
|
||||
}
|
||||
|
||||
const stream = await agent.stream(
|
||||
{ messages: [new HumanMessage(userInput)] },
|
||||
config,
|
||||
);
|
||||
|
||||
for await (const chunk of stream) {
|
||||
if ("agent" in chunk) {
|
||||
console.log(chunk.agent.messages[0].content);
|
||||
} else if ("tools" in chunk) {
|
||||
console.log(chunk.tools.messages[0].content);
|
||||
}
|
||||
console.log("-------------------");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error("Error:", error.message);
|
||||
}
|
||||
process.exit(1);
|
||||
} finally {
|
||||
rl.close();
|
||||
}
|
||||
}
|
||||
|
||||
interface MarketMakerConfig {
|
||||
marketId: string;
|
||||
baseToken: string;
|
||||
quoteToken: string;
|
||||
quoteParams: {
|
||||
number: number; // Number of quotes on each side
|
||||
minDepth: number; // Minimum distance from mid (%)
|
||||
maxDepth: number; // Maximum distance from mid (%)
|
||||
};
|
||||
allowance: {
|
||||
base: number;
|
||||
quote: number;
|
||||
};
|
||||
intervalSeconds: number;
|
||||
}
|
||||
|
||||
function createReadlineInterface() {
|
||||
return readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
}
|
||||
|
||||
async function askQuestion(
|
||||
rl: readline.Interface,
|
||||
question: string,
|
||||
): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
rl.question(question, (answer) => {
|
||||
resolve(answer);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function configureMarketMaker(): Promise<MarketMakerConfig> {
|
||||
const rl = createReadlineInterface();
|
||||
|
||||
try {
|
||||
console.log("\n=== Market Maker Configuration ===\n");
|
||||
|
||||
// Basic market information
|
||||
const marketId = await askQuestion(rl, "Enter the market ID: ");
|
||||
const baseToken = await askQuestion(
|
||||
rl,
|
||||
"Enter the base token symbol (e.g., SEND): ",
|
||||
);
|
||||
const quoteToken = await askQuestion(
|
||||
rl,
|
||||
"Enter the quote token symbol (e.g., USDC): ",
|
||||
);
|
||||
|
||||
// Quote parameters
|
||||
console.log(
|
||||
"\n=== Quote Parameters (applies to both buy and sell sides) ===",
|
||||
);
|
||||
const quoteNumber = parseInt(
|
||||
await askQuestion(rl, "Enter number of quotes to place on each side: "),
|
||||
);
|
||||
const minDepth = parseFloat(
|
||||
await askQuestion(
|
||||
rl,
|
||||
"Enter minimum quote depth (% distance from mid price): ",
|
||||
),
|
||||
);
|
||||
const maxDepth = parseFloat(
|
||||
await askQuestion(
|
||||
rl,
|
||||
"Enter maximum quote depth (% distance from mid price): ",
|
||||
),
|
||||
);
|
||||
|
||||
// Token allowances
|
||||
console.log("\n=== Token Allowances ===");
|
||||
const baseAllowance = parseFloat(
|
||||
await askQuestion(rl, `Enter total ${baseToken} allowance: `),
|
||||
);
|
||||
const quoteAllowance = parseFloat(
|
||||
await askQuestion(rl, `Enter total ${quoteToken} allowance: `),
|
||||
);
|
||||
|
||||
// Update interval
|
||||
const interval = parseInt(
|
||||
await askQuestion(rl, "\nEnter update interval in seconds: "),
|
||||
);
|
||||
|
||||
const config: MarketMakerConfig = {
|
||||
marketId,
|
||||
baseToken,
|
||||
quoteToken,
|
||||
quoteParams: {
|
||||
number: quoteNumber,
|
||||
minDepth: minDepth,
|
||||
maxDepth: maxDepth,
|
||||
},
|
||||
allowance: {
|
||||
base: baseAllowance,
|
||||
quote: quoteAllowance,
|
||||
},
|
||||
intervalSeconds: interval,
|
||||
};
|
||||
|
||||
// Display summary
|
||||
console.log("\n=== Configuration Summary ===");
|
||||
console.log(JSON.stringify(config, null, 2));
|
||||
|
||||
const confirm = await askQuestion(
|
||||
rl,
|
||||
"\nIs this configuration correct? (yes/no): ",
|
||||
);
|
||||
if (confirm.toLowerCase() !== "yes") {
|
||||
throw new Error("Configuration cancelled by user");
|
||||
}
|
||||
|
||||
return config;
|
||||
} finally {
|
||||
rl.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function runMarketMakerMode(agent: any, config: any) {
|
||||
try {
|
||||
const marketMakerConfig = await configureMarketMaker();
|
||||
console.log(
|
||||
`\nStarting market maker mode for ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken}...`,
|
||||
);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const thought = `You are an on-chain Solana market maker for the ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken} Manifest market, ${marketMakerConfig.marketId}.
|
||||
Find the ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken} live price by checking Jupiter.
|
||||
Use solana_batch_order to provide ${marketMakerConfig.quoteParams.number} buys at different prices between -${marketMakerConfig.quoteParams.minDepth}% to -${marketMakerConfig.quoteParams.maxDepth}% and ${marketMakerConfig.quoteParams.number} sells at different prices between +${marketMakerConfig.quoteParams.minDepth}% to +${marketMakerConfig.quoteParams.maxDepth}% with increasing quantities further from the live price.
|
||||
You have an allowance of ${marketMakerConfig.allowance.base} ${marketMakerConfig.baseToken} and ${marketMakerConfig.allowance.quote} ${marketMakerConfig.quoteToken}.
|
||||
Important! Only send 1 transaction, buy and sells can be combined into a single solana_batch_order.`;
|
||||
|
||||
const stream = await agent.stream(
|
||||
{ messages: [new HumanMessage(thought)] },
|
||||
config,
|
||||
);
|
||||
|
||||
for await (const chunk of stream) {
|
||||
if ("agent" in chunk) {
|
||||
console.log(chunk.agent.messages[0].content);
|
||||
} else if ("tools" in chunk) {
|
||||
console.log(chunk.tools.messages[0].content);
|
||||
}
|
||||
console.log("-------------------");
|
||||
}
|
||||
|
||||
await new Promise((resolve) =>
|
||||
setTimeout(resolve, marketMakerConfig.intervalSeconds * 1000),
|
||||
);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Configuration error:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function chooseMode(): Promise<"chat" | "auto" | "mm"> {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const question = (prompt: string): Promise<string> =>
|
||||
new Promise((resolve) => rl.question(prompt, resolve));
|
||||
|
||||
while (true) {
|
||||
console.log("\nAvailable modes:");
|
||||
console.log("1. chat - Interactive chat mode");
|
||||
console.log("2. auto - Autonomous action mode");
|
||||
console.log("3. mm - AI guided market making");
|
||||
|
||||
const choice = (await question("\nChoose a mode (enter number or name): "))
|
||||
.toLowerCase()
|
||||
.trim();
|
||||
|
||||
rl.close();
|
||||
|
||||
if (choice === "1" || choice === "chat") {
|
||||
return "chat";
|
||||
} else if (choice === "2" || choice === "auto") {
|
||||
return "auto";
|
||||
} else if (choice === "3" || choice === "mm") {
|
||||
return "mm";
|
||||
}
|
||||
console.log("Invalid choice. Please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
console.log("Starting Agent...");
|
||||
const { agent, config } = await initializeAgent();
|
||||
const mode = await chooseMode();
|
||||
|
||||
if (mode === "chat") {
|
||||
await runChatMode(agent, config);
|
||||
} else if (mode === "auto") {
|
||||
await runAutonomousMode(agent, config);
|
||||
} else {
|
||||
await runMarketMakerMode(agent, config);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.error("Error:", error.message);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch((error) => {
|
||||
console.error("Fatal error:", error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
16
examples/market-making-agent/package.json
Normal file
16
examples/market-making-agent/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "market-making-agent",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"main": "ts-node index.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@langchain/langgraph-checkpoint-postgres": "^0.0.2",
|
||||
"solana-agent-kit": "^1.3.6"
|
||||
}
|
||||
}
|
||||
6000
examples/market-making-agent/pnpm-lock.yaml
generated
Normal file
6000
examples/market-making-agent/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
||||
"author": "sendaifun",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@3land/listings-sdk": "^0.0.4",
|
||||
"@ai-sdk/openai": "^1.0.11",
|
||||
"@bonfida/spl-name-service": "^3.0.7",
|
||||
"@cks-systems/manifest-sdk": "0.1.59",
|
||||
|
||||
2734
pnpm-lock.yaml
generated
2734
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,15 @@ import {
|
||||
FlashTradeParams,
|
||||
FlashCloseTradeParams,
|
||||
} from "../types";
|
||||
import {
|
||||
createCollection,
|
||||
createSingle,
|
||||
} from "../tools/create_3land_collectible";
|
||||
import {
|
||||
CreateCollectionOptions,
|
||||
CreateSingleOptions,
|
||||
StoreInitOptions,
|
||||
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
|
||||
|
||||
/**
|
||||
* Main class for interacting with Solana blockchain
|
||||
@@ -563,4 +572,27 @@ export class SolanaAgentKit {
|
||||
async flashCloseTrade(params: FlashCloseTradeParams): Promise<string> {
|
||||
return flashCloseTrade(this, params);
|
||||
}
|
||||
|
||||
async create3LandCollection(
|
||||
optionsWithBase58: StoreInitOptions,
|
||||
collectionOpts: CreateCollectionOptions,
|
||||
): Promise<string> {
|
||||
const tx = await createCollection(optionsWithBase58, collectionOpts);
|
||||
return `Transaction: ${tx}`;
|
||||
}
|
||||
|
||||
async create3LandNft(
|
||||
optionsWithBase58: StoreInitOptions,
|
||||
collectionAccount: string,
|
||||
createItemOptions: CreateSingleOptions,
|
||||
isMainnet: boolean,
|
||||
): Promise<string> {
|
||||
const tx = await createSingle(
|
||||
optionsWithBase58,
|
||||
collectionAccount,
|
||||
createItemOptions,
|
||||
isMainnet,
|
||||
);
|
||||
return `Transaction: ${tx}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ import {
|
||||
} from "../index";
|
||||
import { create_image, FEE_TIERS, generateOrdersfromPattern } from "../tools";
|
||||
import { marketTokenMap } from "../utils/flashUtils";
|
||||
import {
|
||||
CreateCollectionOptions,
|
||||
CreateSingleOptions,
|
||||
StoreInitOptions,
|
||||
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
|
||||
|
||||
export class SolanaBalanceTool extends Tool {
|
||||
name = "solana_balance";
|
||||
@@ -2255,6 +2260,153 @@ export class SolanaFetchTokenDetailedReportTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class Solana3LandCreateSingle extends Tool {
|
||||
name = "3land_minting_tool";
|
||||
description = `Creates an NFT and lists it on 3.land's website
|
||||
|
||||
Inputs:
|
||||
privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
|
||||
collectionAccount (optional): represents the account for the nft collection
|
||||
itemName (required): the name of the NFT
|
||||
sellerFee (required): the fee of the seller
|
||||
itemAmount (required): the amount of the NFTs that can be minted
|
||||
itemDescription (required): the description of the NFT
|
||||
traits (required): the traits of the NFT [{trait_type: string, value: string}]
|
||||
price (required): the price of the item, if is 0 the listing will be free
|
||||
mainImageUrl (required): the main image of the NFT
|
||||
coverImageUrl (optional): the cover image of the NFT
|
||||
splHash (optional): the hash of the spl token, if not provided listing will be in $SOL
|
||||
isMainnet (required): defines is the tx takes places in mainnet
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const inputFormat = JSON.parse(input);
|
||||
const privateKey = inputFormat.privateKey;
|
||||
const isMainnet = inputFormat.isMainnet;
|
||||
|
||||
const optionsWithBase58: StoreInitOptions = {
|
||||
...(privateKey && { privateKey }),
|
||||
...(isMainnet && { isMainnet }),
|
||||
};
|
||||
|
||||
let collectionAccount = inputFormat.collectionAccount;
|
||||
|
||||
const itemName = inputFormat?.itemName;
|
||||
const sellerFee = inputFormat?.sellerFee;
|
||||
const itemAmount = inputFormat?.itemAmount;
|
||||
const itemSymbol = inputFormat?.itemSymbol;
|
||||
const itemDescription = inputFormat?.itemDescription;
|
||||
const traits = inputFormat?.traits;
|
||||
const price = inputFormat?.price;
|
||||
const mainImageUrl = inputFormat?.mainImageUrl;
|
||||
const coverImageUrl = inputFormat?.coverImageUrl;
|
||||
const splHash = inputFormat?.splHash;
|
||||
|
||||
const createItemOptions: CreateSingleOptions = {
|
||||
...(itemName && { itemName }),
|
||||
...(sellerFee && { sellerFee }),
|
||||
...(itemAmount && { itemAmount }),
|
||||
...(itemSymbol && { itemSymbol }),
|
||||
...(itemDescription && { itemDescription }),
|
||||
...(traits && { traits }),
|
||||
...(price && { price }),
|
||||
...(mainImageUrl && { mainImageUrl }),
|
||||
...(coverImageUrl && { coverImageUrl }),
|
||||
...(splHash && { splHash }),
|
||||
};
|
||||
|
||||
if (!collectionAccount) {
|
||||
throw new Error("Collection account is required");
|
||||
}
|
||||
|
||||
const tx = await this.solanaKit.create3LandNft(
|
||||
optionsWithBase58,
|
||||
collectionAccount,
|
||||
createItemOptions,
|
||||
isMainnet,
|
||||
);
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: `Created listing successfully ${tx}`,
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Solana3LandCreateCollection extends Tool {
|
||||
name = "3land_minting_tool";
|
||||
description = `Creates an NFT Collection that you can visit on 3.land's website (3.land/collection/{collectionAccount})
|
||||
|
||||
Inputs:
|
||||
privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
|
||||
isMainnet (required): defines is the tx takes places in mainnet
|
||||
collectionSymbol (required): the symbol of the collection
|
||||
collectionName (required): the name of the collection
|
||||
collectionDescription (required): the description of the collection
|
||||
mainImageUrl (required): the image of the collection
|
||||
coverImageUrl (optional): the cover image of the collection
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const inputFormat = JSON.parse(input);
|
||||
const privateKey = inputFormat.privateKey;
|
||||
const isMainnet = inputFormat.isMainnet;
|
||||
|
||||
const optionsWithBase58: StoreInitOptions = {
|
||||
...(privateKey && { privateKey }),
|
||||
...(isMainnet && { isMainnet }),
|
||||
};
|
||||
|
||||
const collectionSymbol = inputFormat?.collectionSymbol;
|
||||
const collectionName = inputFormat?.collectionName;
|
||||
const collectionDescription = inputFormat?.collectionDescription;
|
||||
const mainImageUrl = inputFormat?.mainImageUrl;
|
||||
const coverImageUrl = inputFormat?.coverImageUrl;
|
||||
|
||||
const collectionOpts: CreateCollectionOptions = {
|
||||
...(collectionSymbol && { collectionSymbol }),
|
||||
...(collectionName && { collectionName }),
|
||||
...(collectionDescription && { collectionDescription }),
|
||||
...(mainImageUrl && { mainImageUrl }),
|
||||
...(coverImageUrl && { coverImageUrl }),
|
||||
};
|
||||
|
||||
const tx = await this.solanaKit.create3LandCollection(
|
||||
optionsWithBase58,
|
||||
collectionOpts,
|
||||
);
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: `Created Collection successfully ${tx}`,
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
return [
|
||||
new SolanaBalanceTool(solanaKit),
|
||||
@@ -2307,9 +2459,12 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaCancelNFTListingTool(solanaKit),
|
||||
new SolanaFetchTokenReportSummaryTool(solanaKit),
|
||||
new SolanaFetchTokenDetailedReportTool(solanaKit),
|
||||
new Solana3LandCreateSingle(solanaKit),
|
||||
new Solana3LandCreateCollection(solanaKit),
|
||||
new SolanaPerpOpenTradeTool(solanaKit),
|
||||
new SolanaPerpCloseTradeTool(solanaKit),
|
||||
new SolanaFlashOpenTrade(solanaKit),
|
||||
new SolanaFlashCloseTrade(solanaKit),
|
||||
new Solana3LandCreateSingle(solanaKit),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
|
||||
/**
|
||||
* Cancels all orders from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function cancelAllOrders(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const cancelAllOrdersIx = await mfxClient.cancelAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(cancelAllOrdersIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Cancel all orders failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
69
src/tools/create_3land_collectible.ts
Normal file
69
src/tools/create_3land_collectible.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { createCollectionImp, createSingleImp } from "@3land/listings-sdk";
|
||||
import {
|
||||
StoreInitOptions,
|
||||
CreateCollectionOptions,
|
||||
CreateSingleOptions,
|
||||
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
|
||||
|
||||
/**
|
||||
* Create a collection on 3Land
|
||||
* @param optionsWithBase58 represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
|
||||
* @param collectionOpts represents the options for the collection creation
|
||||
* @returns
|
||||
*/
|
||||
export async function createCollection(
|
||||
optionsWithBase58: StoreInitOptions,
|
||||
collectionOpts: CreateCollectionOptions,
|
||||
) {
|
||||
try {
|
||||
const collection = await createCollectionImp(
|
||||
optionsWithBase58,
|
||||
collectionOpts,
|
||||
);
|
||||
return collection;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Collection creation failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single edition on 3Land
|
||||
* @param optionsWithBase58 represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
|
||||
* @param collectionAccount represents the account for the nft collection
|
||||
* @param createItemOptions the options for the creation of the single NFT listing
|
||||
* @returns
|
||||
*/
|
||||
export async function createSingle(
|
||||
optionsWithBase58: StoreInitOptions,
|
||||
collectionAccount: string,
|
||||
createItemOptions: CreateSingleOptions,
|
||||
isMainnet: boolean,
|
||||
) {
|
||||
try {
|
||||
const landStore = isMainnet
|
||||
? "AmQNs2kgw4LvS9sm6yE9JJ4Hs3JpVu65eyx9pxMG2xA"
|
||||
: "GyPCu89S63P9NcCQAtuSJesiefhhgpGWrNVJs4bF2cSK";
|
||||
|
||||
const singleEditionTx = await createSingleImp(
|
||||
optionsWithBase58,
|
||||
landStore,
|
||||
collectionAccount,
|
||||
createItemOptions,
|
||||
);
|
||||
return singleEditionTx;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Single edition creation failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy a single edition on 3Land
|
||||
* @param
|
||||
* @returns
|
||||
*/
|
||||
// export async function buySingle() {
|
||||
// try {
|
||||
// } catch (error: any) {
|
||||
// throw new Error(`Buying single edition failed: ${error.message}`);
|
||||
// }
|
||||
// }
|
||||
@@ -1,6 +1,4 @@
|
||||
export * from "./adrena_perp_trading";
|
||||
export * from "./batch_order";
|
||||
export * from "./cancel_all_orders";
|
||||
export * from "./create_gibwork_task";
|
||||
export * from "./create_image";
|
||||
export * from "./create_tiplinks";
|
||||
@@ -20,8 +18,7 @@ export * from "./get_tps";
|
||||
export * from "./get_wallet_address";
|
||||
export * from "./launch_pumpfun_token";
|
||||
export * from "./lend";
|
||||
export * from "./limit_order";
|
||||
export * from "./manifest_create_market";
|
||||
export * from "./manifest_trade";
|
||||
export * from "./mint_nft";
|
||||
export * from "./openbook_create_market";
|
||||
export * from "./orca_close_position";
|
||||
@@ -46,7 +43,7 @@ export * from "./stake_with_solayer";
|
||||
export * from "./tensor_trade";
|
||||
export * from "./trade";
|
||||
export * from "./transfer";
|
||||
export * from "./withdraw_all";
|
||||
|
||||
export * from "./flash_open_trade";
|
||||
export * from "./flash_close_trade";
|
||||
|
||||
export * from "./create_3land_collectible";
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
import {
|
||||
PublicKey,
|
||||
Transaction,
|
||||
sendAndConfirmTransaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
ManifestClient,
|
||||
WrapperPlaceOrderParamsExternal,
|
||||
OrderType,
|
||||
} from "@cks-systems/manifest-sdk";
|
||||
|
||||
/**
|
||||
* Place limit orders using Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @param quantity Amount to trade in tokens
|
||||
* @param side Buy or Sell
|
||||
* @param price Price in tokens ie. SOL/USDC
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function limitOrder(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
quantity: number,
|
||||
side: string,
|
||||
price: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const orderParams: WrapperPlaceOrderParamsExternal = {
|
||||
numBaseTokens: quantity,
|
||||
tokenPrice: price,
|
||||
isBid: side === "Buy",
|
||||
lastValidSlot: 0,
|
||||
orderType: OrderType.Limit,
|
||||
clientOrderId: Number(Math.random() * 1000),
|
||||
};
|
||||
|
||||
const depositPlaceOrderIx: TransactionInstruction[] =
|
||||
await mfxClient.placeOrderWithRequiredDepositIx(
|
||||
agent.wallet.publicKey,
|
||||
orderParams,
|
||||
);
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...depositPlaceOrderIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Limit Order failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
|
||||
export async function manifestCreateMarket(
|
||||
agent: SolanaAgentKit,
|
||||
baseMint: PublicKey,
|
||||
quoteMint: PublicKey,
|
||||
): Promise<string[]> {
|
||||
const marketKeypair: Keypair = Keypair.generate();
|
||||
const FIXED_MANIFEST_HEADER_SIZE: number = 256;
|
||||
const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
|
||||
fromPubkey: agent.wallet.publicKey,
|
||||
newAccountPubkey: marketKeypair.publicKey,
|
||||
space: FIXED_MANIFEST_HEADER_SIZE,
|
||||
lamports: await agent.connection.getMinimumBalanceForRentExemption(
|
||||
FIXED_MANIFEST_HEADER_SIZE,
|
||||
),
|
||||
programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
|
||||
});
|
||||
const createMarketIx = ManifestClient["createMarketIx"](
|
||||
agent.wallet.publicKey,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
marketKeypair.publicKey,
|
||||
);
|
||||
|
||||
const tx: Transaction = new Transaction();
|
||||
tx.add(createAccountIx);
|
||||
tx.add(createMarketIx);
|
||||
const signature = await sendAndConfirmTransaction(agent.connection, tx, [
|
||||
agent.wallet,
|
||||
marketKeypair,
|
||||
]);
|
||||
return [signature, marketKeypair.publicKey.toBase58()];
|
||||
}
|
||||
@@ -1,16 +1,159 @@
|
||||
import {
|
||||
PublicKey,
|
||||
Transaction,
|
||||
sendAndConfirmTransaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import {
|
||||
ManifestClient,
|
||||
WrapperPlaceOrderParamsExternal,
|
||||
OrderType,
|
||||
WrapperPlaceOrderParamsExternal,
|
||||
} from "@cks-systems/manifest-sdk";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { BatchOrderPattern, OrderParams } from "../types";
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { BatchOrderPattern, OrderParams, SolanaAgentKit } from "../index";
|
||||
|
||||
export async function manifestCreateMarket(
|
||||
agent: SolanaAgentKit,
|
||||
baseMint: PublicKey,
|
||||
quoteMint: PublicKey,
|
||||
): Promise<string[]> {
|
||||
const marketKeypair: Keypair = Keypair.generate();
|
||||
const FIXED_MANIFEST_HEADER_SIZE: number = 256;
|
||||
const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
|
||||
fromPubkey: agent.wallet.publicKey,
|
||||
newAccountPubkey: marketKeypair.publicKey,
|
||||
space: FIXED_MANIFEST_HEADER_SIZE,
|
||||
lamports: await agent.connection.getMinimumBalanceForRentExemption(
|
||||
FIXED_MANIFEST_HEADER_SIZE,
|
||||
),
|
||||
programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
|
||||
});
|
||||
const createMarketIx = ManifestClient["createMarketIx"](
|
||||
agent.wallet.publicKey,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
marketKeypair.publicKey,
|
||||
);
|
||||
|
||||
const tx: Transaction = new Transaction();
|
||||
tx.add(createAccountIx);
|
||||
tx.add(createMarketIx);
|
||||
const signature = await sendAndConfirmTransaction(agent.connection, tx, [
|
||||
agent.wallet,
|
||||
marketKeypair,
|
||||
]);
|
||||
return [signature, marketKeypair.publicKey.toBase58()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Place limit orders using Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @param quantity Amount to trade in tokens
|
||||
* @param side Buy or Sell
|
||||
* @param price Price in tokens ie. SOL/USDC
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function limitOrder(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
quantity: number,
|
||||
side: string,
|
||||
price: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const orderParams: WrapperPlaceOrderParamsExternal = {
|
||||
numBaseTokens: quantity,
|
||||
tokenPrice: price,
|
||||
isBid: side === "Buy",
|
||||
lastValidSlot: 0,
|
||||
orderType: OrderType.Limit,
|
||||
clientOrderId: Number(Math.random() * 1000),
|
||||
};
|
||||
|
||||
const depositPlaceOrderIx: TransactionInstruction[] =
|
||||
await mfxClient.placeOrderWithRequiredDepositIx(
|
||||
agent.wallet.publicKey,
|
||||
orderParams,
|
||||
);
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...depositPlaceOrderIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Limit Order failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all orders from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function cancelAllOrders(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const cancelAllOrdersIx = await mfxClient.cancelAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(cancelAllOrdersIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Cancel all orders failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraws all funds from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function withdrawAll(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const withdrawAllIx = await mfxClient.withdrawAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...withdrawAllIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Withdraw all failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of orders based on the specified pattern
|
||||
@@ -1,37 +0,0 @@
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
|
||||
/**
|
||||
* Withdraws all funds from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function withdrawAll(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const withdrawAllIx = await mfxClient.withdrawAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...withdrawAllIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Withdraw all failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
63
test/tools/3land.ts
Normal file
63
test/tools/3land.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import {
|
||||
CreateCollectionOptions,
|
||||
CreateSingleOptions,
|
||||
StoreInitOptions,
|
||||
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
|
||||
|
||||
import "dotenv/config";
|
||||
import { SolanaAgentKit, createSolanaTools } from "../../src";
|
||||
|
||||
const agent = new SolanaAgentKit(
|
||||
process.env.SOLANA_PRIVATE_KEY!,
|
||||
process.env.RPC_URL!,
|
||||
{ OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
|
||||
);
|
||||
|
||||
const optionsWithBase58: StoreInitOptions = {
|
||||
privateKey: process.env.SOLANA_PRIVATE_KEY!,
|
||||
isMainnet: false,
|
||||
};
|
||||
|
||||
/****************************** CREATING COLLECTION ******************************** */
|
||||
|
||||
const collectionOpts: CreateCollectionOptions = {
|
||||
collectionName: "",
|
||||
collectionSymbol: "",
|
||||
collectionDescription: "",
|
||||
mainImageUrl: "",
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const collection = await agent.create3LandCollection(
|
||||
optionsWithBase58,
|
||||
collectionOpts,
|
||||
);
|
||||
|
||||
console.log("collection: ", collection);
|
||||
})();
|
||||
|
||||
/****************************** CREATING NFT ******************************** */
|
||||
const collectionAccount = "";
|
||||
const createItemOptions: CreateSingleOptions = {
|
||||
itemName: "",
|
||||
sellerFee: 500, //5%
|
||||
itemAmount: 100,
|
||||
itemSymbol: "",
|
||||
itemDescription: "",
|
||||
traits: [{ trait_type: "", value: "" }],
|
||||
price: 0, //100000000 == 0.1 sol
|
||||
mainImageUrl: "",
|
||||
};
|
||||
|
||||
const isMainnet = false;
|
||||
(async () => {
|
||||
const result = agent.create3LandNft(
|
||||
optionsWithBase58,
|
||||
collectionAccount,
|
||||
createItemOptions,
|
||||
isMainnet,
|
||||
);
|
||||
console.log("result: ", result);
|
||||
})();
|
||||
|
||||
export { SolanaAgentKit, createSolanaTools };
|
||||
@@ -22,7 +22,6 @@
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||
|
||||
Reference in New Issue
Block a user