← 返回 Skills 市场
vladthecto

CrewMind.xyz Arena Betting

作者 Vlad · GitHub ↗ · v1.0.0
cross-platform ⚠ suspicious
1615
总下载
1
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install crewmind-bets
功能描述
Place bets in CrewMind Arena on AI models competing in each round and claim rewards if your chosen model wins after finalization.
使用说明 (SKILL.md)

CrewMind Arena Betting Skill

TL;DR: Place bets on LLM models competing in CrewMind Arena. Bet on which AI wins each round, claim rewards if your model wins.

Quick Start

npm install @solana/web3.js @coral-xyz/anchor dotenv

Program Info

Parameter Value
Program ID F5eS61Nmt3iDw8RJvvK5DL4skdKUMA637MQtG5hbht3Z
Network Solana Mainnet
Website https://crewmind.xyz

Ship Index Mapping

Index Model
0 OpenAI
1 DeepSeek
2 Grok
3 Gemini

PDA Seeds

Account Seeds
Config ["config"]
Round ["round", config, round_id]
Bet ["bet", round, user]
Vault ["vault", round]

Instruction Discriminators

Instruction Discriminator (bytes)
place_bet [222, 62, 67, 220, 63, 166, 126, 33]
claim [62, 198, 214, 193, 213, 159, 108, 210]

Account Structures

Config Account (120 bytes)

Offset  Size  Field
─────────────────────────────────
0       8     discriminator
8       32    admin (Pubkey)
40      32    treasury (Pubkey)
72      8     next_round_id (u64)
80      32    active_round (Pubkey) ← use this!
112     8     active_round_id (u64)

Round Account (190 bytes)

Offset  Size  Field
─────────────────────────────────
0       8     discriminator
8       8     id (u64)
16      1     status (u8: 0=Open, 1=Finalized)
17      1     ship_count (u8)
18      1     winner_ship (u8, 255=unset)
19      1     swept (bool)
20      8     start_ts (i64)
28      8     end_ts (i64)
36      8     finalized_ts (i64)
44      8     min_bet (u64)
52      8     max_bet (u64)
60      2     participants (u16)
62      8     total_staked (u64)
70      32    totals_by_ship ([u64; 4])
102     64    weighted_by_ship ([u128; 4])
166     8     losing_pool (u64)
174     16    total_weighted_winners (u128)

Bet Account (96 bytes)

Offset  Size  Field
─────────────────────────────────
0       8     discriminator
8       1     initialized (bool)
9       32    round (Pubkey)
41      32    user (Pubkey)
73      1     ship (u8)
74      1     claimed (bool)
75      6     _pad
81      8     total_amount (u64)
89      16    total_weighted (u128)

Entrypoint: place_bet

Goal

Place a bet on a ship (AI model) in the active round.

Instruction

place_bet(ship: u8, amount: u64)

Accounts (in order)

# Account Signer Writable Description
0 user Your wallet
1 config PDA ["config"]
2 round Active round pubkey from config
3 bet PDA ["bet", round, user]
4 vault PDA ["vault", round]
5 system_program 11111111111111111111111111111111

Constraints

  • ship \x3C ship_count (usually 4)
  • min_bet \x3C= amount \x3C= max_bet
  • current_time \x3C end_ts
  • Round status must be Open (0)

Instruction Data Layout

Bytes 0-7:   discriminator [222, 62, 67, 220, 63, 166, 126, 33]
Byte 8:     ship (u8)
Bytes 9-16: amount (u64 LE)

Entrypoint: claim

Goal

Claim rewards after round finalization (if your ship won).

Instruction

claim() — no arguments

Accounts (in order)

# Account Signer Writable Description
0 user Your wallet
1 round The finalized round
2 bet PDA ["bet", round, user]
3 vault PDA ["vault", round]
4 system_program 11111111111111111111111111111111

Constraints

  • Round status must be Finalized (1)
  • Your bet's ship == winner_ship
  • claimed == false

Instruction Data Layout

Bytes 0-7: discriminator [62, 198, 214, 193, 213, 159, 108, 210]

Errors

Code Name Description
6004 InvalidShip Ship index >= ship_count
6005 RoundNotOpen Round is finalized
6006 RoundEnded Past end_ts
6008 RoundNotFinalized Can't claim yet
6009 TooLate Too late to bet
6011 InvalidBetAmount Amount out of bounds
6014 AlreadyClaimed Already claimed
6015 NotAWinner Your ship didn't win

Complete JavaScript Example

import { Connection, PublicKey, Keypair, Transaction, TransactionInstruction, SystemProgram } from '@solana/web3.js';

const PROGRAM_ID = new PublicKey('F5eS61Nmt3iDw8RJvvK5DL4skdKUMA637MQtG5hbht3Z');
const SHIPS = { openai: 0, deepseek: 1, grok: 2, gemini: 3 };

async function getActiveRound(connection) {
  const [configPda] = PublicKey.findProgramAddressSync([Buffer.from('config')], PROGRAM_ID);
  const configAccount = await connection.getAccountInfo(configPda);
  if (!configAccount) throw new Error('Config not found');

  const activeRound = new PublicKey(configAccount.data.slice(80, 112));
  if (activeRound.equals(PublicKey.default)) throw new Error('No active round');

  return { configPda, activeRound };
}

async function getRoundInfo(connection, roundPubkey) {
  const acc = await connection.getAccountInfo(roundPubkey);
  if (!acc) throw new Error('Round not found');
  const d = acc.data;

  return {
    id: d.readBigUInt64LE(8),
    status: d.readUInt8(16),           // 0=Open, 1=Finalized
    shipCount: d.readUInt8(17),
    winnerShip: d.readUInt8(18),       // 255 if not set
    startTs: d.readBigInt64LE(20),
    endTs: d.readBigInt64LE(28),
    minBet: d.readBigUInt64LE(44),
    maxBet: d.readBigUInt64LE(52),
  };
}

async function placeBet(connection, wallet, shipName, amountSol) {
  const ship = SHIPS[shipName.toLowerCase()];
  const amountLamports = BigInt(Math.floor(amountSol * 1e9));

  const { configPda, activeRound } = await getActiveRound(connection);
  const roundInfo = await getRoundInfo(connection, activeRound);

  // Validations
  if (roundInfo.status !== 0) throw new Error('Round not open');
  if (BigInt(Date.now() / 1000) >= roundInfo.endTs) throw new Error('Round ended');
  if (amountLamports \x3C roundInfo.minBet || amountLamports > roundInfo.maxBet) {
    throw new Error(`Amount must be between ${Number(roundInfo.minBet)/1e9} and ${Number(roundInfo.maxBet)/1e9} SOL`);
  }

  const [betPda] = PublicKey.findProgramAddressSync(
    [Buffer.from('bet'), activeRound.toBuffer(), wallet.publicKey.toBuffer()], PROGRAM_ID
  );
  const [vaultPda] = PublicKey.findProgramAddressSync(
    [Buffer.from('vault'), activeRound.toBuffer()], PROGRAM_ID
  );

  const data = Buffer.concat([
    Buffer.from([222, 62, 67, 220, 63, 166, 126, 33]), // discriminator
    Buffer.from([ship]),                                // ship u8
    (() => { const b = Buffer.alloc(8); b.writeBigUInt64LE(amountLamports); return b; })()
  ]);

  const ix = new TransactionInstruction({
    keys: [
      { pubkey: wallet.publicKey, isSigner: true, isWritable: true },
      { pubkey: configPda, isSigner: false, isWritable: false },
      { pubkey: activeRound, isSigner: false, isWritable: true },
      { pubkey: betPda, isSigner: false, isWritable: true },
      { pubkey: vaultPda, isSigner: false, isWritable: true },
      { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
    ],
    programId: PROGRAM_ID,
    data,
  });

  const tx = new Transaction().add(ix);
  tx.feePayer = wallet.publicKey;
  tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
  tx.sign(wallet);

  return await connection.sendRawTransaction(tx.serialize());
}

async function claim(connection, wallet, roundPubkey) {
  const roundInfo = await getRoundInfo(connection, roundPubkey);
  if (roundInfo.status !== 1) throw new Error('Round not finalized yet');

  const [betPda] = PublicKey.findProgramAddressSync(
    [Buffer.from('bet'), roundPubkey.toBuffer(), wallet.publicKey.toBuffer()], PROGRAM_ID
  );
  const [vaultPda] = PublicKey.findProgramAddressSync(
    [Buffer.from('vault'), roundPubkey.toBuffer()], PROGRAM_ID
  );

  const data = Buffer.from([62, 198, 214, 193, 213, 159, 108, 210]); // claim discriminator

  const ix = new TransactionInstruction({
    keys: [
      { pubkey: wallet.publicKey, isSigner: true, isWritable: true },
      { pubkey: roundPubkey, isSigner: false, isWritable: false },
      { pubkey: betPda, isSigner: false, isWritable: true },
      { pubkey: vaultPda, isSigner: false, isWritable: true },
      { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
    ],
    programId: PROGRAM_ID,
    data,
  });

  const tx = new Transaction().add(ix);
  tx.feePayer = wallet.publicKey;
  tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
  tx.sign(wallet);

  return await connection.sendRawTransaction(tx.serialize());
}

// Usage:
// const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed');
// const wallet = Keypair.fromSecretKey(...);
// await placeBet(connection, wallet, 'deepseek', 0.01);

Workflow Summary

1. GET ACTIVE ROUND
   └─> Read Config PDA → get active_round pubkey

2. CHECK ROUND STATUS
   └─> Read Round account → verify status=0 (Open), check end_ts

3. PLACE BET
   └─> Call place_bet(ship, amount)
   └─> Creates Bet PDA, transfers SOL to Vault

4. WAIT FOR ROUND TO END
   └─> Monitor: current_time > end_ts

5. WAIT FOR FINALIZATION
   └─> Monitor: Round.status == 1 (Finalized)
   └─> Check: Round.winner_ship

6. CLAIM (if won)
   └─> Call claim() if your ship == winner_ship
   └─> Receives: original_bet + share_of_losing_pool

Safety Rules

  • Never bet more than max_bet
  • Check end_ts before betting (avoid TooLate error)
  • Only one bet per round per user (but can add to existing bet)
  • Always verify round is Open before betting
  • Always verify round is Finalized before claiming
  • Keep SOL for transaction fees (~0.002 SOL recommended buffer)
安全使用建议
This skill appears to be a documentation/JS client for placing bets on a Solana program and is internally consistent, but proceed cautiously. Before installing or running anything: 1) Verify the Program ID and contract on a trusted Solana explorer and the crewmind.xyz site (the skill could point to a malicious program). 2) Never paste private keys into .env files or into an agent UI — use a wallet adapter or hardware wallet to sign transactions when possible. 3) Confirm who will provide the signer: the skill metadata declares no credential, so you must supply a wallet; understand where that key is stored and who/what can access it. 4) If you will run the example code locally, inspect it fully (the SKILL.md is truncated) and run it first against devnet/testnet with tiny amounts. 5) Because there is no packaged code to audit, treat this as documentation only — the runtime behavior depends on code you or the agent executes. If you need higher assurance, request the program's source/IDL and verify on-chain deployment and audits before committing funds.
功能分析
Type: OpenClaw Skill Name: crewmind-bets Version: 1.0.0 The OpenClaw skill bundle describes and provides example JavaScript code for interacting with a Solana smart contract for betting on LLM model competitions. The `SKILL.md` file details the program, account structures, and entry points (`place_bet`, `claim`), along with a complete JavaScript example. The code uses standard Solana SDK functions to construct and send transactions to the Solana blockchain. There is no evidence of data exfiltration, malicious execution, persistence mechanisms, or prompt injection attempts against the agent. The `npm install` command lists standard development dependencies, and the JavaScript example correctly handles wallet interactions without attempting to access sensitive local data.
能力评估
Purpose & Capability
SKILL.md clearly documents placing bets and claiming rewards on a Solana program (program ID, PDAs, instruction layouts, account schemas and example JS). That aligns with a 'arena betting' purpose. However the skill metadata contains no description and declares no credentials even though the documented actions require a signing wallet.
Instruction Scope
The runtime instructions stay focused on on-chain interactions (derive PDAs, build and submit transactions, validate account fields). They do not instruct reading unrelated system files or exfiltrating data. The doc references npm packages and dotenv, which is expected for a JS client.
Install Mechanism
This is an instruction-only skill with no install spec or bundled code. The Quick Start suggests npm packages (@solana/web3.js, @coral-xyz/anchor, dotenv) — reasonable for a JS Solana client and not itself suspicious.
Credentials
The documented operations require a signing wallet (Keypair/wallet provider) and likely RPC configuration (dotenv), but the skill metadata declares no required env vars or primary credential. That omission is a proportionality/information gap: to actually place bets the agent or user must supply private keys or a wallet signer — exposing private keys in .env or to an agent is high risk. The SKILL.md does not instruct how to securely provide keys or which runtime will provide a signer.
Persistence & Privilege
The skill is not always-enabled and requests no persistent system-wide privileges or config changes. As an instruction-only guide it does not attempt to modify other skills or agent settings.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install crewmind-bets
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /crewmind-bets 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
CrewMind Arena Betting Skill 1.0.0 - Initial release: bet on the outcome of LLM (AI) competitions in CrewMind Arena. - Supports betting on OpenAI, DeepSeek, Grok, or Gemini models for each round. - Claim rewards if your selected model wins after round finalization. - Provides detailed Solana program info, JS usage examples, account structures, and instruction layouts. - Outlines error codes and program constraints for robust user experience.
元数据
Slug crewmind-bets
版本 1.0.0
许可证
累计安装 0
当前安装数 0
历史版本数 1
常见问题

CrewMind.xyz Arena Betting 是什么?

Place bets in CrewMind Arena on AI models competing in each round and claim rewards if your chosen model wins after finalization. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 1615 次。

如何安装 CrewMind.xyz Arena Betting?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install crewmind-bets」即可一键安装,无需额外配置。

CrewMind.xyz Arena Betting 是免费的吗?

是的,CrewMind.xyz Arena Betting 完全免费(开源免费),可自由下载、安装和使用。

CrewMind.xyz Arena Betting 支持哪些平台?

CrewMind.xyz Arena Betting 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 CrewMind.xyz Arena Betting?

由 Vlad(@vladthecto)开发并维护,当前版本 v1.0.0。

💬 留言讨论