diff --git a/src/agent/index.ts b/src/agent/index.ts index 175304a..56f66f4 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -34,10 +34,12 @@ import { getMainAllDomainsDomain, getOwnedAllDomains, resolveAllDomains, + create_gibwork_task, } from "../tools"; import { CollectionDeployment, CollectionOptions, + GibworkCreateTaskReponse, JupiterTokenData, MintCollectionNFTResponse, PumpfunLaunchResponse, @@ -314,4 +316,25 @@ export class SolanaAgentKit { async pythFetchPrice(priceFeedID: string): Promise { return pythFetchPrice(priceFeedID); } + + async createGibworkTask( + title: string, + content: string, + requirements: string, + tags: string[], + tokenMintAddress: string, + tokenAmount: number, + payer?: string, + ): Promise { + return create_gibwork_task( + this, + title, + content, + requirements, + tags, + new PublicKey(tokenMintAddress), + tokenAmount, + payer ? new PublicKey(payer) : undefined, + ); + } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 2d31173..f28b000 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -1,7 +1,11 @@ import { PublicKey } from "@solana/web3.js"; import Decimal from "decimal.js"; import { Tool } from "langchain/tools"; -import { PythFetchPriceResponse, SolanaAgentKit } from "../index"; +import { + GibworkCreateTaskReponse, + PythFetchPriceResponse, + SolanaAgentKit, +} from "../index"; import { create_image } from "../tools/create_image"; import { BN } from "@coral-xyz/anchor"; import { FEE_TIERS } from "../tools"; @@ -1176,6 +1180,55 @@ export class SolanaGetMainDomain extends Tool { } } +export class SolanaCreateGibworkTask extends Tool { + name = "create_gibwork_task"; + description = `Create a task on Gibwork. + + Inputs (input is a JSON string): + title: string, title of the task (required) + content: string, description of the task (required) + requirements: string, requirements to complete the task (required) + tags: string[], list of tags associated with the task (required) + payer: string, payer address (optional, defaults to agent wallet) + tokenMintAddress: string, the mint address of the token, e.g., "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN" (required) + amount: number, payment amount (required) + `; + + constructor(private solanaSdk: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const taskData = await this.solanaSdk.createGibworkTask( + parsedInput.title, + parsedInput.content, + parsedInput.requirements, + parsedInput.tags, + parsedInput.tokenMintAddress, + parsedInput.amount, + parsedInput.payer, + ); + + const response: GibworkCreateTaskReponse = { + status: "success", + taskId: taskData.taskId, + signature: taskData.signature, + }; + + return JSON.stringify(response); + } catch (err: any) { + return JSON.stringify({ + status: "error", + message: err.message, + code: err.code || "CREATE_TASK_ERROR", + }); + } + } +} + export function createSolanaTools(solanaKit: SolanaAgentKit) { return [ new SolanaBalanceTool(solanaKit), @@ -1209,5 +1262,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaGetAllTlds(solanaKit), new SolanaGetMainDomain(solanaKit), new SolanaResolveAllDomainsTool(solanaKit), + new SolanaCreateGibworkTask(solanaKit), ]; } diff --git a/src/tools/create_gibwork_task.ts b/src/tools/create_gibwork_task.ts new file mode 100644 index 0000000..40ff3c3 --- /dev/null +++ b/src/tools/create_gibwork_task.ts @@ -0,0 +1,81 @@ +import { VersionedTransaction } from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; +import { GibworkCreateTaskReponse, SolanaAgentKit } from "../index"; + +/** + * Create an new task on Gibwork + * @param agent SolanaAgentKit instance + * @param title Title of the task + * @param content Description of the task + * @param requirements Requirements to complete the task + * @param tags List of tags associated with the task + * @param payer Payer address for the task (default: agent wallet address) + * @param tokenMintAddress Token mint address for payment + * @param tokenAmount Payment amount for the task + * @returns Object containing task creation transaction and generated taskId + */ +export async function create_gibwork_task( + agent: SolanaAgentKit, + title: string, + content: string, + requirements: string, + tags: string[], + tokenMintAddress: PublicKey, + tokenAmount: number, + payer?: PublicKey, +): Promise { + try { + const apiResponse = await fetch( + "https://api2.gib.work/tasks/public/transaction", + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + title: title, + content: content, + requirements: requirements, + tags: tags, + payer: payer?.toBase58() || agent.wallet.publicKey.toBase58(), + token: { + mintAddress: tokenMintAddress.toBase58(), + amount: tokenAmount, + }, + }), + }, + ); + + const responseData = await apiResponse.json(); + if (!responseData.taskId && !responseData.serializedTransaction) { + throw new Error(`${responseData.message}`); + } + + const serializedTransaction = Buffer.from( + responseData.serializedTransaction, + "base64", + ); + const tx = VersionedTransaction.deserialize(serializedTransaction); + + tx.sign([agent.wallet]); + const signature = await agent.connection.sendTransaction(tx, { + preflightCommitment: "confirmed", + maxRetries: 3, + }); + + const latestBlockhash = await agent.connection.getLatestBlockhash(); + await agent.connection.confirmTransaction({ + signature, + blockhash: latestBlockhash.blockhash, + lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, + }); + + return { + status: "success", + taskId: responseData.taskId, + signature: signature, + }; + } catch (err: any) { + throw new Error(`${err.message}`); + } +} diff --git a/src/tools/index.ts b/src/tools/index.ts index 8729dd3..9a18cf4 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -35,3 +35,5 @@ export * from "./raydium_create_clmm"; export * from "./raydium_create_cpmm"; export * from "./openbook_create_market"; export * from "./pyth_fetch_price"; + +export * from "./create_gibwork_task"; diff --git a/src/types/index.ts b/src/types/index.ts index 6c9dc16..95d1fc5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -85,3 +85,9 @@ export interface PythFetchPriceResponse { message?: string; code?: string; } + +export interface GibworkCreateTaskReponse { + status: "success" | "error"; + taskId?: string | undefined; + signature?: string | undefined; +}