Implement searchAssets tool

This commit is contained in:
Damjan
2025-01-16 14:22:50 +01:00
parent a4774374b3
commit 4d213665d3
9 changed files with 212 additions and 1 deletions

View File

@@ -62,6 +62,7 @@ import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate";
import getAssetAction from "./metaplex/getAsset";
import getAssetsByAuthorityAction from "./metaplex/getAssetsByAuthority";
import getAssetsByCreatorAction from "./metaplex/getAssetsByCreator";
import searchAssetsAction from "./metaplex/searchAssets";
export const ACTIONS = {
WALLET_ADDRESS_ACTION: getWalletAddressAction,
@@ -129,6 +130,7 @@ export const ACTIONS = {
GET_ASSET_ACTION: getAssetAction,
GET_ASSETS_BY_AUTHORITY_ACTION: getAssetsByAuthorityAction,
GET_ASSETS_BY_CREATOR_ACTION: getAssetsByCreatorAction,
SEARCH_ASSETS_ACTION: searchAssetsAction,
};
export type { Action, ActionExample, Handler } from "../types/action";

View File

@@ -0,0 +1,113 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { search_assets } from "../../tools/metaplex";
import { publicKey } from "@metaplex-foundation/umi";
const searchAssetsAction: Action = {
name: "SEARCH_ASSETS",
similes: ["search assets", "find assets", "lookup assets", "query assets"],
description: `Search for assets using various criteria with the Metaplex DAS API.`,
examples: [
[
{
input: {
owner: publicKey("N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw"),
jsonUri:
"https://arweave.net/c9aGs5fOk7gD4wWnSvmzeqgtfxAGRgtI1jYzvl8-IVs/chiaki-violet-azure-common.json",
},
output: {
status: "success",
message: "Assets retrieved successfully",
result: {
total: 2,
limit: 10,
items: [
{
interface: "V1_NFT",
id: "ExampleAssetId1",
content: {
json_uri: "https://example.com/asset1.json",
metadata: {
name: "Example Asset 1",
symbol: "EXA1",
},
},
authorities: [],
compression: {},
grouping: [],
royalty: {},
creators: [],
ownership: {},
supply: {},
mutable: true,
burnt: false,
},
{
interface: "V1_NFT",
id: "ExampleAssetId2",
content: {
json_uri: "https://example.com/asset2.json",
metadata: {
name: "Example Asset 2",
symbol: "EXA2",
},
},
authorities: [],
compression: {},
grouping: [],
royalty: {},
creators: [],
ownership: {},
supply: {},
mutable: true,
burnt: false,
},
],
},
},
explanation: "Search for assets using various criteria",
},
],
],
schema: z.object({
negate: z.boolean().optional(),
conditionType: z.enum(["all", "any"]).optional(),
interface: z.string().optional(),
jsonUri: z.string().optional(),
owner: z.string().optional(),
ownerType: z.enum(["single", "token"]).optional(),
creator: z.string().optional(),
creatorVerified: z.boolean().optional(),
authority: z.string().optional(),
grouping: z.tuple([z.string(), z.string()]).optional(),
delegate: z.string().optional(),
frozen: z.boolean().optional(),
supply: z.number().optional(),
supplyMint: z.string().optional(),
compressed: z.boolean().optional(),
compressible: z.boolean().optional(),
royaltyModel: z.enum(["creators", "fanout", "single"]).optional(),
royaltyTarget: z.string().optional(),
royaltyAmount: z.number().optional(),
burnt: z.boolean().optional(),
limit: z.number().optional(),
page: z.number().optional(),
before: z.string().optional(),
after: z.string().optional(),
}),
handler: async (
agent: SolanaAgentKit,
input: z.infer<typeof searchAssetsAction.schema>,
) => {
const result = await search_assets(agent, input);
return {
status: "success",
message: "Assets retrieved successfully",
result,
};
},
};
export default searchAssetsAction;

View File

@@ -100,6 +100,8 @@ import {
get_token_balance,
get_asset,
get_assets_by_authority,
get_assets_by_creator,
search_assets,
} from "../tools";
import {
Config,
@@ -122,8 +124,8 @@ import {
DasApiAssetList,
GetAssetsByAuthorityRpcInput,
GetAssetsByCreatorRpcInput,
SearchAssetsRpcInput,
} from "@metaplex-foundation/digital-asset-standard-api";
import { get_assets_by_creator } from "../tools/metaplex/get_assets_by_creator";
/**
* Main class for interacting with Solana blockchain
@@ -844,4 +846,7 @@ export class SolanaAgentKit {
): Promise<DasApiAssetList> {
return get_assets_by_creator(this, params);
}
async searchAssets(params: SearchAssetsRpcInput): Promise<DasApiAssetList> {
return search_assets(this, params);
}
}

View File

@@ -4,3 +4,4 @@ export * from "./deploy_token";
export * from "./get_asset";
export * from "./get_assets_by_authority";
export * from "./get_assets_by_creator";
export * from "./search_assets";

View File

@@ -0,0 +1,57 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
export class SolanaSearchAssetsTool extends Tool {
name = "solana_search_assets";
description = `Search for assets using various criteria with the Metaplex DAS API.
Inputs (input is a JSON string):
negate: boolean (optional)
conditionType: "all" | "any" (optional)
interface: string (optional)
jsonUri: string (optional)
owner: string (optional)
ownerType: "single" | "token" (optional)
creator: string (optional)
creatorVerified: boolean (optional)
authority: string (optional)
grouping: [string, string] (optional)
delegate: string (optional)
frozen: boolean (optional)
supply: number (optional)
supplyMint: string (optional)
compressed: boolean (optional)
compressible: boolean (optional)
royaltyModel: "creators" | "fanout" | "single" (optional)
royaltyTarget: string (optional)
royaltyAmount: number (optional)
burnt: boolean (optional)
limit: number (optional)
page: number (optional)
before: string (optional)
after: string (optional)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const result = await this.solanaKit.searchAssets(parsedInput);
return JSON.stringify({
status: "success",
message: "Assets retrieved successfully",
result,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -5,6 +5,12 @@ import {
GetAssetsByAuthorityRpcInput,
} from "@metaplex-foundation/digital-asset-standard-api";
/**
* Fetch assets by authority using the Metaplex DAS API
* @param agent SolanaAgentKit instance
* @param params Parameters for fetching assets by authority
* @returns List of assets associated with the given authority
*/
export async function get_assets_by_authority(
agent: SolanaAgentKit,
params: GetAssetsByAuthorityRpcInput,

View File

@@ -5,6 +5,12 @@ import {
GetAssetsByCreatorRpcInput,
} from "@metaplex-foundation/digital-asset-standard-api";
/**
* Fetch assets by creator using the Metaplex DAS API
* @param agent SolanaAgentKit instance
* @param params Parameters for fetching assets by creator
* @returns List of assets created by the specified creator
*/
export async function get_assets_by_creator(
agent: SolanaAgentKit,
params: GetAssetsByCreatorRpcInput,

View File

@@ -4,3 +4,4 @@ export * from "./deploy_token";
export * from "./get_asset";
export * from "./get_assets_by_authority";
export * from "./get_assets_by_creator";
export * from "./search_assets";

View File

@@ -0,0 +1,20 @@
import { SolanaAgentKit } from "../../agent";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import {
dasApi,
SearchAssetsRpcInput,
} from "@metaplex-foundation/digital-asset-standard-api";
/**
* Search for assets using the Metaplex DAS API
* @param agent SolanaAgentKit instance
* @param params Parameters for searching assets
* @returns List of assets matching the search criteria
*/
export async function search_assets(
agent: SolanaAgentKit,
params: SearchAssetsRpcInput,
) {
const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi());
return await umi.rpc.searchAssets(params);
}