Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions plugins/spraay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Spraay Plugin for GAME SDK

**Batch crypto payments for AI agents on Base.**

Give your [GAME](https://docs.game.virtuals.io/)-powered AI agents the ability to send ETH and ERC-20 tokens to up to 200 recipients in a single transaction using the [Spraay](https://spraay.app) smart contract on Base.

## Why Spraay?

- **~80% gas savings** vs individual transfers
- **200 recipients** per transaction
- **ETH + any ERC-20** (USDC, DAI, WETH, etc.)
- **0.3% protocol fee** — no subscriptions, no minimums
- **Verified on BaseScan** — OpenZeppelin security (ReentrancyGuard + Pausable)

## Installation

```bash
pip install spraay-plugin-gamesdk
```

Or install from source:

```bash
git clone https://github.com/plagtech/spraay-game-plugin.git
cd spraay-game-plugin
pip install -e .
```

## Quick Start

### As a Worker (add to existing agent)

```python
from spraay_plugin_gamesdk import SpraayPlugin
from game_sdk.game.agent import WorkerConfig

spraay = SpraayPlugin(private_key="0x...")

spraay_worker = WorkerConfig(
id="batch_payments",
worker_description="Batch payment worker powered by Spraay on Base.",
action_space=spraay.get_tools(),
get_state_fn=lambda: {"wallet": spraay.wallet_address},
)

# Add spraay_worker to your agent's workers list
```

### Standalone Agent

```python
from spraay_plugin_gamesdk import SpraayPlugin
from game_sdk.game.agent import Agent, WorkerConfig

spraay = SpraayPlugin(private_key="0x...")

agent = Agent(
api_key="your_game_api_key",
name="Payment Agent",
agent_goal="Batch-send crypto payments efficiently on Base.",
agent_description="AI agent with Spraay batch payment capabilities.",
workers=[
WorkerConfig(
id="spraay_worker",
worker_description="Handles batch ETH and token payments.",
action_space=spraay.get_tools(),
),
],
)

agent.compile()
agent.run(60, {"verbose": True})
```

## Available Functions

| Function | Description |
|---|---|
| `spraay_batch_eth` | Send variable ETH amounts to multiple recipients |
| `spraay_batch_eth_equal` | Send equal ETH to multiple recipients |
| `spraay_batch_erc20` | Send variable ERC-20 amounts to multiple recipients |
| `spraay_batch_erc20_equal` | Send equal ERC-20 to multiple recipients |
| `spraay_check_balance` | Check ETH and token balances |
| `spraay_estimate_cost` | Estimate total cost before sending |

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `SPRAAY_PRIVATE_KEY` | Yes | Wallet private key for signing transactions |
| `BASE_RPC_URL` | No | Base RPC endpoint (default: `https://mainnet.base.org`) |
| `GAME_API_KEY` | Yes* | GAME API key (*only if running a GAME agent) |

## Supported Tokens

Built-in shortcuts for common Base tokens:

| Symbol | Address |
|---|---|
| USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| DAI | `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb` |
| WETH | `0x4200000000000000000000000000000000000006` |
| cbETH | `0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22` |
| USDbC | `0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA` |

You can also use any ERC-20 token by passing its contract address directly.

## Contract

- **Address:** `0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC`
- **Network:** Base Mainnet (Chain ID: 8453)
- **BaseScan:** [View Contract](https://basescan.org/address/0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC)

## Use Cases

- **DAO Payroll** — Agent pays team members monthly
- **Airdrop Distribution** — Agent sprays tokens to community wallets
- **Bounty Payments** — Agent rewards contributors with variable amounts
- **Revenue Sharing** — Agent distributes earnings to stakeholders
- **Agent-to-Agent Commerce** — Spraay as settlement layer in ACP workflows

## Links

- **Website:** [spraay.app](https://spraay.app)
- **GitHub:** [github.com/plagtech](https://github.com/plagtech)
- **Twitter:** [@lostpoet](https://twitter.com/lostpoet)
- **Farcaster:** [@plag](https://warpcast.com/plag)

## License

MIT
56 changes: 56 additions & 0 deletions plugins/spraay/example_add_worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Example: Using Spraay as a Worker in an existing GAME agent.

This is the most common integration pattern — you already have a GAME
agent and want to add batch payment capabilities as a new worker.

Prerequisites:
pip install game-sdk spraay-plugin-gamesdk
"""

import os
from game_sdk.game.agent import WorkerConfig
from spraay_plugin_gamesdk import SpraayPlugin


# ── Quick Setup ─────────────────────────────────────────────────────

spraay = SpraayPlugin(
private_key=os.environ.get("SPRAAY_PRIVATE_KEY"),
)

# Create a WorkerConfig you can add to any existing GAME agent
spraay_worker = WorkerConfig(
id="batch_payments",
worker_description=(
"Batch payment worker powered by Spraay. Can send ETH or ERC-20 "
"tokens to up to 200 recipients in a single Base transaction. "
"Use for airdrops, payroll, bounties, and reward distributions. "
"Always check balance first, then estimate cost, then execute."
),
action_space=spraay.get_tools(),
get_state_fn=lambda: {
"wallet": spraay.wallet_address,
"network": "Base Mainnet",
"contract": "0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC",
},
)

# ── Add to your existing agent ──────────────────────────────────────
#
# from game_sdk.game.agent import Agent
#
# agent = Agent(
# api_key=os.environ.get("GAME_API_KEY"),
# name="My Agent",
# agent_goal="...",
# agent_description="...",
# workers=[
# your_existing_worker,
# spraay_worker, # <-- Just add this
# ],
# )

print("Spraay worker configured!")
print(f"Wallet: {spraay.wallet_address}")
print(f"Available tools: {[f.fn_name for f in spraay.get_tools()]}")
86 changes: 86 additions & 0 deletions plugins/spraay/example_spraay_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Example: AI Agent with Spraay batch payment capabilities.

This demonstrates how to create a GAME-powered agent that can
autonomously batch-send ETH and ERC-20 tokens on Base using Spraay.

Prerequisites:
pip install game-sdk spraay-plugin-gamesdk

Environment variables:
GAME_API_KEY=your_game_api_key # From https://console.game.virtuals.io/
SPRAAY_PRIVATE_KEY=your_private_key # Wallet private key for signing txs
BASE_RPC_URL=https://mainnet.base.org # Optional: custom RPC
"""

import os
from game_sdk.game.agent import Agent, WorkerConfig
from game_sdk.game.custom_types import Function, Argument, FunctionResultStatus
from spraay_plugin_gamesdk import SpraayPlugin


# ── Initialize Spraay Plugin ────────────────────────────────────────

spraay = SpraayPlugin(
private_key=os.environ.get("SPRAAY_PRIVATE_KEY"),
rpc_url=os.environ.get("BASE_RPC_URL", "https://mainnet.base.org"),
)


# ── Define Agent State ──────────────────────────────────────────────

def get_agent_state() -> dict:
"""Provide the agent with awareness of its environment."""
return {
"network": "Base (Chain ID: 8453)",
"spraay_contract": "0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC",
"supported_tokens": "ETH, USDC, DAI, WETH, cbETH, USDbC",
"max_recipients_per_tx": 200,
"service_fee": "0.3%",
"wallet_address": spraay.wallet_address or "Not configured",
}


# ── Create the Agent ────────────────────────────────────────────────

agent = Agent(
api_key=os.environ.get("GAME_API_KEY", ""),
name="Spraay Payment Agent",
agent_goal=(
"Help users batch-send ETH and ERC-20 tokens to multiple recipients "
"efficiently on Base. Always check balances before sending. "
"Estimate costs when asked. Use equal-send functions when all "
"recipients get the same amount."
),
agent_description=(
"You are an AI payment agent powered by Spraay, a batch payment "
"protocol on Base. You can send ETH or any ERC-20 token to up to "
"200 recipients in a single transaction, saving ~80% on gas costs. "
"You operate on the Base blockchain (Layer 2 on Ethereum). "
"Always verify wallet balances before executing transactions. "
"Be cautious with funds and confirm large transactions."
),
get_agent_state_fn=get_agent_state,
workers=[
WorkerConfig(
id="spraay_worker",
worker_description=(
"Handles all batch payment operations: sending ETH, "
"sending ERC-20 tokens, checking balances, and "
"estimating transaction costs via the Spraay protocol."
),
action_space=spraay.get_tools(),
get_state_fn=lambda: {
"wallet": spraay.wallet_address,
"network": "Base Mainnet",
},
),
],
)


# ── Run ─────────────────────────────────────────────────────────────

if __name__ == "__main__":
agent.compile()
agent.run(60, {"verbose": True})
36 changes: 36 additions & 0 deletions plugins/spraay/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "spraay-plugin-gamesdk"
version = "0.1.0"
description = "Spraay batch payments plugin for GAME SDK by Virtuals Protocol. Enables AI agents to batch-send ETH and ERC-20 tokens on Base."
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.9"
authors = [
{name = "plagtech", email = "spraay@proton.me"},
]
keywords = ["game-sdk", "virtuals", "spraay", "batch-payments", "base", "ethereum", "ai-agents", "defi"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Topic :: Software Development :: Libraries :: Python Modules",
]

dependencies = [
"game-sdk>=0.1.1",
"web3>=6.0.0",
]

[project.urls]
Homepage = "https://spraay.app"
Repository = "https://github.com/plagtech/spraay-game-plugin"
Documentation = "https://spraay.app"
Issues = "https://github.com/plagtech/spraay-game-plugin/issues"

[tool.setuptools.packages.find]
include = ["spraay_plugin_gamesdk*"]
3 changes: 3 additions & 0 deletions plugins/spraay/spraay_plugin_gamesdk/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from spraay_plugin_gamesdk.spraay_plugin import SpraayPlugin, KNOWN_TOKENS

__all__ = ["SpraayPlugin", "KNOWN_TOKENS"]
Loading