From bb629f287f8384cb0221a8c7d249d6d46595eb62 Mon Sep 17 00:00:00 2001 From: thatsmeadarsh Date: Wed, 25 Dec 2024 09:16:44 +0530 Subject: [PATCH 1/2] feat: Create tasks on Gibwork --- src/agent/index.ts | 25 ++++++++++- src/langchain/index.ts | 52 +++++++++++++++++++++- src/tools/create_gibwork_task.ts | 75 ++++++++++++++++++++++++++++++++ src/tools/index.ts | 2 + src/types/index.ts | 6 +++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/tools/create_gibwork_task.ts diff --git a/src/agent/index.ts b/src/agent/index.ts index f1833f7..ead4bfb 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, @@ -229,7 +231,7 @@ export class SolanaAgentKit { async getOwnedDomainsForTLD( tld: string - ):Promise { + ): Promise { return getOwnedDomainsForTLD(this, tld); } @@ -318,4 +320,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 51fc6b4..00f31e6 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -1,7 +1,7 @@ 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"; @@ -1181,6 +1181,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), @@ -1214,5 +1263,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..60d0dbc --- /dev/null +++ b/src/tools/create_gibwork_task.ts @@ -0,0 +1,75 @@ +import { SendTransactionError, Transaction, 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}`); + } +} \ No newline at end of file diff --git a/src/tools/index.ts b/src/tools/index.ts index 846c92b..92c6c1e 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -36,3 +36,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; +} From 8c1ce69743b4804dbda0f784efee523d6159ef50 Mon Sep 17 00:00:00 2001 From: aryan Date: Wed, 25 Dec 2024 17:20:17 +0530 Subject: [PATCH 2/2] fix: lint --- src/agent/index.ts | 4 +- src/langchain/index.ts | 6 +- src/tools/create_gibwork_task.ts | 118 ++++++++++++++++--------------- 3 files changed, 69 insertions(+), 59 deletions(-) diff --git a/src/agent/index.ts b/src/agent/index.ts index b217dee..56f66f4 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -324,7 +324,7 @@ export class SolanaAgentKit { tags: string[], tokenMintAddress: string, tokenAmount: number, - payer?: string + payer?: string, ): Promise { return create_gibwork_task( this, @@ -334,7 +334,7 @@ export class SolanaAgentKit { tags, new PublicKey(tokenMintAddress), tokenAmount, - payer ? new PublicKey(payer) : undefined + payer ? new PublicKey(payer) : undefined, ); } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 4095269..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 { GibworkCreateTaskReponse, 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"; diff --git a/src/tools/create_gibwork_task.ts b/src/tools/create_gibwork_task.ts index 60d0dbc..40ff3c3 100644 --- a/src/tools/create_gibwork_task.ts +++ b/src/tools/create_gibwork_task.ts @@ -1,4 +1,4 @@ -import { SendTransactionError, Transaction, VersionedTransaction } from "@solana/web3.js"; +import { VersionedTransaction } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js"; import { GibworkCreateTaskReponse, SolanaAgentKit } from "../index"; @@ -15,61 +15,67 @@ import { GibworkCreateTaskReponse, SolanaAgentKit } from "../index"; * @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, + 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 - } - }) - }); + 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}`); + const responseData = await apiResponse.json(); + if (!responseData.taskId && !responseData.serializedTransaction) { + throw new Error(`${responseData.message}`); } -} \ No newline at end of file + + 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}`); + } +}