mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-13 23:16:55 +00:00
Added Rock paper scissors blink to the solana agent kit (#42)
This commit is contained in:
@@ -35,6 +35,7 @@ import {
|
||||
getOwnedAllDomains,
|
||||
resolveAllDomains,
|
||||
create_gibwork_task,
|
||||
rock_paper_scissor,
|
||||
} from "../tools";
|
||||
import {
|
||||
CollectionDeployment,
|
||||
@@ -337,4 +338,11 @@ export class SolanaAgentKit {
|
||||
payer ? new PublicKey(payer) : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
async rockPaperScissors(
|
||||
amount: number,
|
||||
choice: "rock" | "paper" | "scissors",
|
||||
) {
|
||||
return rock_paper_scissor(this, amount, choice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,6 +1229,56 @@ export class SolanaCreateGibworkTask extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaRockPaperScissorsTool extends Tool {
|
||||
name = "rock_paper_scissors";
|
||||
description = `Play rock paper scissors to win SEND coins.
|
||||
|
||||
Inputs (input is a JSON string):
|
||||
choice: string, either "rock", "paper", or "scissors" (required)
|
||||
amount: number, amount of SOL to play with - must be 0.1, 0.01, or 0.005 SOL (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
private validateInput(input: any): void {
|
||||
if (input.choice !== undefined) {
|
||||
throw new Error("choice is required.");
|
||||
}
|
||||
if (
|
||||
input.amount !== undefined &&
|
||||
(typeof input.spaceKB !== "number" || input.spaceKB <= 0)
|
||||
) {
|
||||
throw new Error("amount must be a positive number when provided");
|
||||
}
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const parsedInput = toJSON(input);
|
||||
this.validateInput(parsedInput);
|
||||
const result = await this.solanaKit.rockPaperScissors(
|
||||
Number(parsedInput['"amount"']),
|
||||
parsedInput['"choice"'].replace(/^"|"$/g, "") as
|
||||
| "rock"
|
||||
| "paper"
|
||||
| "scissors",
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: result,
|
||||
});
|
||||
} 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),
|
||||
@@ -1263,5 +1313,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaGetMainDomain(solanaKit),
|
||||
new SolanaResolveAllDomainsTool(solanaKit),
|
||||
new SolanaCreateGibworkTask(solanaKit),
|
||||
new SolanaRockPaperScissorsTool(solanaKit),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -37,3 +37,5 @@ export * from "./openbook_create_market";
|
||||
export * from "./pyth_fetch_price";
|
||||
|
||||
export * from "./create_gibwork_task";
|
||||
|
||||
export * from "./rock_paper_scissor";
|
||||
|
||||
132
src/tools/rock_paper_scissor.ts
Normal file
132
src/tools/rock_paper_scissor.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { sendAndConfirmTransaction, Transaction } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
|
||||
export async function rock_paper_scissor(
|
||||
agent: SolanaAgentKit,
|
||||
amount: number,
|
||||
choice: "rock" | "paper" | "scissors",
|
||||
) {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`https://rps.sendarcade.fun/api/actions/bot?amount=${amount}&choice=${choice}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data = await res.json();
|
||||
if (data.transaction) {
|
||||
const txn = Transaction.from(Buffer.from(data.transaction, "base64"));
|
||||
txn.sign(agent.wallet);
|
||||
txn.recentBlockhash = (
|
||||
await agent.connection.getLatestBlockhash()
|
||||
).blockhash;
|
||||
const sig = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
txn,
|
||||
[agent.wallet],
|
||||
{ commitment: "confirmed" },
|
||||
);
|
||||
const href = data.links?.next?.href;
|
||||
return await outcome(agent, sig, href);
|
||||
} else {
|
||||
return "failed";
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`RPS game failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
async function outcome(
|
||||
agent: SolanaAgentKit,
|
||||
sig: string,
|
||||
href: string,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const res = await fetch(
|
||||
"https://rps.sendarcade.fun" + href, // href = /api/actions/outcome?id=...
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
signature: sig,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data: any = await res.json();
|
||||
const title = data.title;
|
||||
if (title.startsWith("You lost")) {
|
||||
return title;
|
||||
}
|
||||
const next_href = data.links?.actions?.[0]?.href;
|
||||
return title + "\n" + (await won(agent, next_href));
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`RPS outcome failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
async function won(agent: SolanaAgentKit, href: string): Promise<string> {
|
||||
try {
|
||||
const res = await fetch(
|
||||
"https://rps.sendarcade.fun" + href, // href = /api/actions/won?id=...
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data: any = await res.json();
|
||||
if (data.transaction) {
|
||||
const txn = Transaction.from(Buffer.from(data.transaction, "base64"));
|
||||
txn.partialSign(agent.wallet);
|
||||
await agent.connection.sendRawTransaction(txn.serialize(), {
|
||||
preflightCommitment: "confirmed",
|
||||
});
|
||||
} else {
|
||||
return "Failed to claim prize.";
|
||||
}
|
||||
const next_href = data.links?.next?.href;
|
||||
return await postWin(agent, next_href);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`RPS outcome failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
async function postWin(agent: SolanaAgentKit, href: string): Promise<string> {
|
||||
try {
|
||||
const res = await fetch(
|
||||
"https://rps.sendarcade.fun" + href, // href = /api/actions/postwin?id=...
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data: any = await res.json();
|
||||
const title = data.title;
|
||||
return "Prize claimed Successfully" + "\n" + title;
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
throw new Error(`RPS outcome failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user