# Send Torch Prediction Market Kit to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "torchpredictionmarketkit",
    "name": "Torch Prediction Market Kit",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/mrsirg97-rgb/torchpredictionmarketkit",
    "canonicalUrl": "https://clawhub.ai/mrsirg97-rgb/torchpredictionmarketkit",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/torchpredictionmarketkit",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=torchpredictionmarketkit",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "agent.json",
      "audit.md",
      "verification.md",
      "SKILL.md",
      "design.md",
      "whitepaper.md"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/torchpredictionmarketkit"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/torchpredictionmarketkit",
    "downloadUrl": "https://openagent3.xyz/downloads/torchpredictionmarketkit",
    "agentUrl": "https://openagent3.xyz/skills/torchpredictionmarketkit/agent",
    "manifestUrl": "https://openagent3.xyz/skills/torchpredictionmarketkit/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/torchpredictionmarketkit/agent.md"
  }
}
```
## Documentation

### Torch Prediction Market Kit

You're here because you want to run prediction markets on Torch Market -- and you want to do it safely.

Every prediction market is a Torch token. The bonding curve is the AMM -- no LP setup, deterministic pricing, instant liquidity. The 10% treasury accumulates fees from every buy. Users buy the token to bet YES (price goes up), sell to bet NO (price goes down). At the deadline, the oracle checks the outcome and the bot records it.

Settlement model: token-as-signal. No payout mechanism. The token price IS the prediction. The bonding curve and treasury do the work.

That's where this bot comes in.

It reads your markets.json file, creates Torch tokens for pending markets, seeds them with initial liquidity from your vault, monitors price and volume, and resolves them at the deadline using an oracle (CoinGecko price feed or manual). All value routes through your vault. The agent wallet that signs transactions holds nothing.

This is not a read-only scanner. This is a fully operational market maker that generates its own keypair, verifies vault linkage, creates tokens, seeds liquidity, and resolves markets autonomously in a continuous loop.

### How It Works

┌─────────────────────────────────────────────────────────┐
│                   MARKET CYCLE LOOP                       │
│                                                          │
│  1. Load market definitions from markets.json            │
│  2. For each pending market:                             │
│     → buildCreateTokenTransaction(name, symbol, uri)     │
│     → sign + submit + confirm                            │
│     → buildBuyTransaction(vault, mint, seed SOL)         │
│     → sign + submit + confirm                            │
│     → update status to 'active', save mint address       │
│  3. For each active market:                              │
│     → getToken(mint) — snapshot price, volume, holders   │
│     → if deadline passed:                                │
│        → checkOracle(oracle) — price feed or manual      │
│        → update status to 'resolved', record outcome     │
│  4. Save updated markets.json                            │
│  5. Sleep SCAN_INTERVAL_MS, repeat                       │
│                                                          │
│  All SOL comes from vault. Agent wallet holds nothing.   │
│  Vault is the boundary.                                  │
└─────────────────────────────────────────────────────────┘

### The Agent Keypair

The bot generates a fresh Keypair in-process on every startup. No private key file. No environment variable (unless you want to provide one). The keypair is disposable -- it signs transactions but holds nothing of value.

On first run, the bot checks if this keypair is linked to your vault. If not, it prints the exact SDK call you need to link it:

--- ACTION REQUIRED ---
agent wallet is NOT linked to the vault.
link it by running (from your authority wallet):

  buildLinkWalletTransaction(connection, {
    authority: "<your-authority-pubkey>",
    vault_creator: "<your-vault-creator>",
    wallet_to_link: "<agent-pubkey>"
  })

then restart the bot.
-----------------------

Link it from your authority wallet (hardware wallet, multisig, whatever you use). The agent never needs the authority's key. The authority never needs the agent's key. They share a vault, not keys.

### The Vault

This is the same Torch Vault from the full Torch Market protocol. It holds all assets -- SOL and tokens. The agent is a disposable controller.

When the bot creates and seeds a market:

Token creation — agent signs as creator, no SOL cost beyond gas
Seed liquidity — SOL comes from the vault via buildBuyTransaction(vault=creator)
Tokens purchased — go to the vault's associated token account (ATA)

The human principal retains full control:

withdrawVault() — pull SOL at any time
withdrawTokens(mint) — pull market tokens at any time
unlinkWallet(agent) — revoke agent access instantly

If the agent keypair is compromised, the attacker gets dust and vault access that you revoke in one transaction.

### 1. Install

npm install torch-prediction-market-kit@2.0.2

Or use the bundled source from ClawHub — the Torch SDK is included in lib/torchsdk/ and the bot source is in lib/kit/.

### 2. Create and Fund a Vault (Human Principal)

From your authority wallet:

import { Connection } from "@solana/web3.js";
import {
  buildCreateVaultTransaction,
  buildDepositVaultTransaction,
} from "./lib/torchsdk/index.js";

const connection = new Connection(process.env.SOLANA_RPC_URL);

// Create vault
const { transaction: createTx } = await buildCreateVaultTransaction(connection, {
  creator: authorityPubkey,
});
// sign and submit with authority wallet...

// Fund vault with SOL for market creation + seed liquidity
const { transaction: depositTx } = await buildDepositVaultTransaction(connection, {
  depositor: authorityPubkey,
  vault_creator: authorityPubkey,
  amount_sol: 5_000_000_000, // 5 SOL
});
// sign and submit with authority wallet...

### 3. Define Markets

Create markets.json:

[
  {
    "id": "sol-200-mar",
    "question": "Will SOL be above $200 by March 1, 2026?",
    "symbol": "SOL200M",
    "name": "SOL Above 200 March",
    "oracle": {
      "type": "price_feed",
      "asset": "solana",
      "condition": "above",
      "target": 200
    },
    "deadline": 1740787200,
    "initialLiquidityLamports": 100000000,
    "metadataUri": "https://arweave.net/placeholder"
  }
]

### 4. Run the Bot

VAULT_CREATOR=<your-vault-creator-pubkey> SOLANA_RPC_URL=<rpc-url> npx torch-prediction-market-bot

On first run, the bot prints the agent keypair and instructions to link it. Link it from your authority wallet, then restart.

### 5. Configuration

VariableRequiredDefaultDescriptionSOLANA_RPC_URLYes--Solana RPC endpoint (HTTPS). Fallback: RPC_URLVAULT_CREATORYes--Vault creator pubkeySOLANA_PRIVATE_KEYNo--Disposable controller keypair (base58 or JSON byte array). If omitted, generates fresh keypair on startup (recommended)SCAN_INTERVAL_MSNo60000Milliseconds between market cycles (min 5000)LOG_LEVELNoinfodebug, info, warn, errorMARKETS_PATHNo./markets.jsonPath to market definitions file

### Architecture

packages/kit/src/
├── index.ts      — entry point: keypair generation, vault verification, market cycle loop
├── config.ts     — loadConfig(): validates SOLANA_RPC_URL, VAULT_CREATOR, MARKETS_PATH, etc.
├── types.ts      — Market, Oracle, MarketSnapshot, BotConfig interfaces
├── markets.ts    — loadMarkets(), saveMarkets(), createMarket(), snapshotMarket(), resolveMarket()
├── oracle.ts     — checkPriceFeed(), checkOracle() — CoinGecko price resolution
└── utils.ts      — sol(), createLogger(), decodeBase58(), withTimeout()

The bot is ~280 lines of TypeScript across 6 modules. It does three things: create markets, monitor them, and resolve them through the vault.

### Dependencies

PackageVersionPurpose@solana/web3.js1.98.4Solana RPC, keypair, transactiontorchsdk3.7.23Token queries, token creation, buy builder, vault queries

Two runtime dependencies. Both pinned to exact versions. No ^ or ~ ranges.

### Market Lifecycle

pending ──→ active ──→ resolved
              │
              └──→ cancelled

StatusDescriptionpendingMarket defined in markets.json, no token created yetactiveTorch token created on bonding curve, users can traderesolvedDeadline passed, oracle checked, outcome recorded (yes/no)cancelledMarket removed before resolution (manual edit)

### Market Definition

interface MarketDefinition {
  id: string                  // unique market identifier
  question: string            // human-readable question
  symbol: string              // token symbol (max 10 chars)
  name: string                // token name (max 32 chars)
  oracle: Oracle              // how the market resolves
  deadline: number            // unix timestamp (seconds)
  initialLiquidityLamports: number  // SOL to seed bonding curve (in lamports, max 10 SOL)
  metadataUri: string         // token metadata URI (allowlisted domains only)
}

### Input Validation

All pending markets are validated on load. Markets with invalid inputs are rejected before any on-chain action.

FieldConstraintRejected ExampleidMust be unique across all marketsDuplicate "sol-200-mar"metadataUriDomain must be in allowlist: arweave.net, gateway.irys.xyz, ipfs.io, cloudflare-ipfs.com, nftstorage.link, dweb.linkhttps://evil.com/payload.jsoninitialLiquidityLamportsMax 10 SOL (10,000,000,000 lamports), non-negative50000000000 (50 SOL)oracle.assetMust be in allowlist of known CoinGecko IDs (solana, bitcoin, ethereum, etc.)"arbitrary-string"

These constraints ensure a compromised markets.json cannot trigger arbitrary URI fetches, drain the vault, or make unintended API calls.

### Price Feed Oracle (CoinGecko)

The primary oracle. Fetches the current price of an asset and compares it against a target.

{
  "type": "price_feed",
  "asset": "solana",
  "condition": "above",
  "target": 200
}

asset — CoinGecko asset ID (e.g. "solana", "bitcoin", "ethereum")
condition — "above" or "below"
target — USD price threshold
Resolution: if condition is "above", outcome is "yes" when price > target, "no" otherwise

### Manual Oracle

Fallback for markets that can't be resolved by a price feed.

{
  "type": "manual",
  "source": "Twitter announcement from @torch_market"
}

Resolution: edit markets.json directly — set "status": "resolved" and "outcome": "yes" or "no".

### Vault Safety Model

The same seven guarantees from the Torch Market vault apply here:

PropertyGuaranteeFull custodyVault holds all SOL and all market tokens. Agent wallet holds nothing.Closed loopSeed liquidity SOL comes from vault, purchased tokens go to vault ATA. No leakage to agent.Authority separationCreator (immutable PDA seed) vs Authority (transferable admin) vs Controller (disposable signer).One link per walletAgent can only belong to one vault. PDA uniqueness enforces this on-chain.Permissionless depositsAnyone can top up the vault. Hardware wallet deposits, agent creates markets.Instant revocationAuthority can unlink the agent at any time. One transaction.Authority-only withdrawalsOnly the vault authority can withdraw SOL or tokens. The agent cannot extract value.

### The Closed Economic Loop for Market Creation

DirectionFlowSOL outVault → Bonding curve (seed liquidity buy)Tokens inBonding curve → Vault ATA (purchased tokens)Treasury10% of each buy accumulates in token treasury

The vault's seed tokens remain on the bonding curve. Users trade against the curve. Treasury grows from fees. The authority can withdraw vault tokens or SOL at any time.

### SDK Functions Used

The bot uses a focused subset of the Torch SDK:

FunctionPurposegetVault(connection, creator)Verify vault exists on startupgetVaultForWallet(connection, wallet)Verify agent is linked to vaultbuildCreateTokenTransaction(connection, params)Build token creation transaction for new marketbuildBuyTransaction(connection, params)Build vault-routed buy to seed initial liquiditygetToken(connection, mint)Get token price, volume, status for market snapshotsgetHolders(connection, mint)Get holder count for market snapshotsconfirmTransaction(connection, sig, wallet)Confirm transaction on-chain via RPC (verifies signer, checks Torch instructions)

### buildCreateTokenTransaction Parameters

const { transaction, mint, mintKeypair } = await buildCreateTokenTransaction(connection, {
  creator: agentPubkey,       // agent wallet (signer + fee payer)
  name: "SOL Above 200 March", // token name (max 32 chars)
  symbol: "SOL200M",           // token symbol (max 10 chars)
  metadata_uri: "https://arweave.net/...",  // token metadata URI
});

### buildBuyTransaction Parameters

const { transaction, message } = await buildBuyTransaction(connection, {
  mint: mintAddress,            // token to buy
  buyer: agentPubkey,           // agent wallet (signer)
  amount_sol: 100000000,        // 0.1 SOL in lamports
  slippage_bps: 500,            // 5% slippage tolerance
  vault: vaultCreator,          // vault creator pubkey (SOL from vault, tokens to vault ATA)
});

### Signing & Key Safety

The vault is the security boundary, not the key.

The agent keypair is generated fresh on every startup with Keypair.generate(). It holds ~0.01 SOL for gas fees. If the key is compromised, the attacker gets:

Dust (the gas SOL)
Vault access that the authority revokes in one transaction

The agent never needs the authority's private key. The authority never needs the agent's private key. They share a vault, not keys.

### Rules

Never ask a user for their private key or seed phrase. The vault authority signs from their own device.
Never log, print, store, or transmit private key material. The agent keypair exists only in runtime memory.
Never embed keys in source code or logs. The agent pubkey is printed — the secret key is never exposed.
Use a secure RPC endpoint. Default to a private RPC provider. Never use an unencrypted HTTP endpoint for mainnet transactions.

### RPC Timeout

All SDK calls are wrapped with a 30-second timeout (withTimeout in utils.ts). A hanging or unresponsive RPC endpoint cannot stall the bot indefinitely — the call rejects, the error is caught by the market cycle loop, and the bot continues to the next market or cycle.

### Environment Variables

VariableRequiredPurposeSOLANA_RPC_URL / RPC_URLYesSolana RPC endpoint (HTTPS)VAULT_CREATORYesVault creator pubkey — identifies which vault the bot operates throughSOLANA_PRIVATE_KEYNoOptional — if omitted, the bot generates a fresh keypair on startup (recommended)

### External Runtime Dependencies

The SDK and bot make outbound HTTPS requests to external services. The bot's runtime path contacts three of them:

ServicePurposeWhen CalledBot Uses?CoinGecko (api.coingecko.com)Asset price for oracle resolution + SOL/USD displaycheckPriceFeed() in oracle.ts, getToken() in SDKYes — oracle resolution AND token queriesIrys Gateway (gateway.irys.xyz)Token metadata fallback (name, symbol, image)getToken() when on-chain metadata URI points to IrysYes — via getToken()SAID Protocol (api.saidprotocol.com)Agent identity verification and trust tier lookupverifySaid() onlyNo — the bot does not call verifySaid()

CoinGecko API Details (Oracle)

The oracle module (oracle.ts) calls the CoinGecko public API directly:

GET https://api.coingecko.com/api/v3/simple/price?ids={asset}&vs_currencies=usd

No API key required — uses the free public endpoint
Rate limit: ~10-30 calls/minute on the free tier
Data sent: asset ID only (e.g. "solana") — no wallet, transaction, or agent data
Data received: { "solana": { "usd": 87.76 } }
Failure mode: if CoinGecko is unreachable, checkPriceFeed() throws and the market stays unresolved until the next cycle
Called once per active market per cycle that has passed its deadline

confirmTransaction() does NOT contact SAID. Despite living in the SDK's said.js module, it only calls connection.getParsedTransaction() (Solana RPC) to verify the transaction succeeded on-chain and determine the event type. No data is sent to any external service.

No credentials are sent to CoinGecko or Irys. All requests are read-only GET. If either service is unreachable, the bot degrades gracefully. No private key material is ever transmitted to any external endpoint.

### Log Output

=== torch prediction market bot ===
agent wallet: 7xK9...
vault creator: 4yN2...
markets file: ./markets.json
scan interval: 60000ms

[09:15:32] INFO  vault found — authority=8cpW...
[09:15:32] INFO  agent wallet linked to vault — starting market cycle
[09:15:32] INFO  treasury: 5.0000 SOL
[09:15:33] INFO  CREATING | sol-200-mar — "Will SOL be above $200 by March 1, 2026?"
[09:15:35] INFO  CREATED | sol-200-mar — mint=AqAgqKTypS... | seed=0.1000 SOL
[09:16:35] DEBUG SNAPSHOT | sol-200-mar — price=0.000012 SOL | mcap=0.0120 | holders=3
[09:17:35] INFO  RESOLVING | sol-200-mar — deadline reached
[09:17:36] INFO  RESOLVED | sol-200-mar — outcome=no

### Testing

Requires Surfpool running a mainnet fork:

surfpool start --network mainnet --no-tui
pnpm test

Test result: 9 passed, 1 informational (Surfpool RPC limitation on getTokenLargestAccounts for Token-2022 — works on mainnet).

TestWhat It ValidatesConnectionRPC reachableloadMarketsMarket file parsing and validationcheckPriceFeedCoinGecko oracle returns valid price databuildCreateTokenTransactionToken creation transaction builds correctlygetTokensDiscovers bonding/migrated tokensgetTokenToken metadata, price, statusgetHoldersHolder enumeration (skips on Surfpool limitation)getVaultForWalletVault link returns null for unlinked walletIn-process keypairNo external key required

### Error Codes

VAULT_NOT_FOUND: No vault exists for this creator
WALLET_NOT_LINKED: Agent wallet is not linked to the vault
INVALID_MINT: Token not found
BONDING_COMPLETE: Token has graduated — trade on DEX instead
NAME_TOO_LONG: Token name exceeds 32 characters
SYMBOL_TOO_LONG: Token symbol exceeds 10 characters

### Links

Prediction Market Kit (source): github.com/mrsirg97-rgb/torch-prediction-market-kit
Prediction Market Kit (npm): npmjs.com/package/torch-prediction-market-kit
Torch SDK (bundled): lib/torchsdk/ -- included in this skill
Torch SDK (source): github.com/mrsirg97-rgb/torchsdk
Torch SDK (npm): npmjs.com/package/torchsdk
Torch Market (protocol skill): clawhub.ai/mrsirg97-rgb/torchmarket
Whitepaper: torch.market/whitepaper.md
Security Audit: torch.market/audit.md
Website: torch.market
Program ID: 8hbUkonssSEEtkqzwM7ZcZrD9evacM92TcWSooVF4BeT

### v2.0.0

Upgraded torchsdk from 3.2.3 to 3.7.23. Major SDK update adds treasury lock PDAs (V27), dynamic Raydium network detection, auto-migration bundling on bonding curve completion (buildBuyTransaction now returns optional migrationTransaction), vault-routed Raydium CPMM swaps (buildVaultSwapTransaction), Token-2022 fee harvesting (buildHarvestFeesTransaction, buildSwapFeesToSolTransaction), bulk loan scanning (getAllLoanPositions), on-chain token metadata queries (getTokenMetadata), and ephemeral agent keypair factory (createEphemeralAgent).
Exported withTimeout utility. The timeout helper used internally by the bot is now a public export of the kit package, available to downstream consumers.
Updated env format in skill frontmatter. Environment variable declarations now use structured name/required format for compatibility with ClawHub and OpenClaw agent runners.

### v1.0.2

Updated kit to point to correct bundled sdk. The index.js file now imports the SDK from the local lib/torchsdk/ directory instead of the npm package. This ensures that the bot uses the exact bundled SDK version (3.2.3) included in the kit, rather than any potentially different version installed from npm. Addresses audit finding L-3.

### v1.0.1

Timeout on all external calls. Every SDK, RPC, and API call is now wrapped with a 30-second timeout (10 seconds for CoinGecko). If an RPC endpoint or CoinGecko becomes unresponsive, the call fails fast with a descriptive error instead of stalling the bot indefinitely. Addresses audit finding L-1.
Market ID uniqueness validation. loadMarkets() now rejects markets.json files containing duplicate market IDs on load, preventing unintended duplicate market creation and wasted vault SOL. Addresses audit finding L-2.

This bot exists because prediction markets need infrastructure. Torch bonding curves provide instant liquidity and deterministic pricing without LP setup. The vault makes it safe — all value stays in the escrow, all risk is bounded, and the human principal keeps the keys. The token price IS the prediction.
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: mrsirg97-rgb
- Version: 2.0.3
## Source health
- Status: healthy
- Source download looks usable.
- Yavira can redirect you to the upstream package for this source.
- Health scope: source
- Reason: direct_download_ok
- Checked at: 2026-04-30T16:55:25.780Z
- Expires at: 2026-05-07T16:55:25.780Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/torchpredictionmarketkit)
- [Send to Agent page](https://openagent3.xyz/skills/torchpredictionmarketkit/agent)
- [JSON manifest](https://openagent3.xyz/skills/torchpredictionmarketkit/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/torchpredictionmarketkit/agent.md)
- [Download page](https://openagent3.xyz/downloads/torchpredictionmarketkit)