Skip to main content

DPSN Plugin for Python SDK for GAME by Virtuals

Project description

🌐 DPSN Plugin for Virtuals Protocol (Python)

Decentralized Publish-Subscribe Network (DPSN) plugin for Virtuals Protocol agents, implemented in Python.

Virtuals Protocol Version License

📋 Overview

This plugin enables Virtuals Protocol agents (written in Python) to connect to, subscribe to, and interact with data streams available on the DPSN Data Streams Store.

Agents can leverage this plugin to consume real-time data for decision-making, reacting to events, or integrating external information feeds.

To provide personalized data streams for your agents, you can create and publish data into your own DPSN topics using the dpsn-client for Python.

For more information, visit:

✨ Features

  • Seamless Integration: Connects Virtuals Protocol agents (Python) to the DPSN decentralized pub/sub network.
  • Real-time Data Handling: Subscribe to topics and process incoming messages via a configurable callback.
  • Topic Management: Provides agent-executable functions to subscribe and unsubscribe from DPSN topics.
  • Error Handling: Includes basic error handling and logging for connection and subscription issues.
  • Graceful Shutdown: Allows the agent to explicitly shut down the DPSN connection.

⚙️ Configuration

Ensure the following environment variables are set, typically in a .env file in your project root:

Note: The EVM private key (PVT_KEY) is used solely for signing authentication messages with the DPSN network. This process does not execute any on-chain transactions or incur gas fees.

# Your EVM-compatible wallet private key (e.g., Metamask)
PVT_KEY=your_evm_wallet_private_key_here

# The URL of the DPSN node to connect to (e.g., betanet.dpsn.org)
DPSN_URL=betanet.dpsn.org

# Optional: Add VIRTUALS_API_KEY if required by your GameAgent setup
# VIRTUALS_API_KEY=your_virtuals_api_key_here

📚 Usage

Basic Setup

The DpsnPlugin is designed to be used within the Virtuals Protocol Game SDK framework. You would typically instantiate it and potentially pass it to your GameAgent or similar construct.

# Import the pre-instantiated plugin (recommended)
from plugins.dpsn.dpsn_plugin_gamesdk.dpsn_plugin import DpsnPlugin
load_dotenv()

dpsn_plugin=DpsnPlugin(
            dpsn_url=os.getenv("DPSN_URL"),
            pvt_key=os.getenv("PVT_KEY")
        )

# Define a simple message handler
def handle_message(message_data):
    topic = message_data.get('topic', 'unknown')
    payload = message_data.get('payload', {})
    print(f"Message on {topic}: {payload}")

# Register the message handler
dpsn_plugin.set_message_callback(handle_message)

# Subscribe to a topic
status, message, details = dpsn_plugin.subscribe(
    topic="0xe14768a6d8798e4390ec4cb8a4c991202c2115a5cd7a6c0a7ababcaf93b4d2d4/BTCUSDT/ticker"
)
print(f"Subscription status: {status}, Message: {message}")

# Later when done:
dpsn_plugin.unsubscribe(topic="0xe14768a6d8798e4390ec4cb8a4c991202c2115a5cd7a6c0a7ababcaf93b4d2d4/BTCUSDT/ticker")
dpsn_plugin.shutdown()

Interacting via Agent Tasks

The Game Agent interacts with the plugin by executing tasks that map to the plugin's Function objects. The exact syntax depends on your Game SDK's runTask or equivalent method.

from game_sdk.game.agent import Agent, WorkerConfig
from game_sdk.game.custom_types import FunctionResult
from dpsn_plugin_gamesdk.dpsn_plugin import DpsnPlugin

load_dotenv()

dpsn_plugin=DpsnPlugin(
            dpsn_url=os.getenv("DPSN_URL"),
            pvt_key=os.getenv("PVT_KEY")
        )
# --- Add Message Handler --- 
def handle_incoming_message(message_data: dict):
    """Callback function to process messages received via the plugin."""
    try:
        topic = message_data.get('topic', 'N/A')
        payload = message_data.get('payload', '{}')
        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print(f"\n--- Message Received ({timestamp}) ---")
        print(f"Topic: {topic}")
        # Pretty print payload if it's likely JSON/dict
        if isinstance(payload, (dict, list)):
            print(f"Payload:\n{json.dumps(payload, indent=2)}")
            return payload
        else:
            print(f"Payload: {payload}")
            return payload
        print("-----------------------------------")
    except Exception as e:
        print(f"Error in message handler: {e}")

# Set the callback in the plugin instance *before* running the agent
dpsn_plugin.set_message_callback(handle_incoming_message)

def get_agent_state_fn(function_result: FunctionResult, current_state: dict) -> dict:
    """Update state based on the function results"""
    init_state = {}

    if current_state is None:
        return init_state

    if function_result.info is not None:
        current_state.update(function_result.info)

    return current_state

def get_worker_state(function_result: FunctionResult, current_state: dict) -> dict:
    """Update state based on the function results"""
    init_state = {}

    if current_state is None:
        return init_state

    if function_result.info is not None:
        current_state.update(function_result.info)

    return current_state


subscription_worker = WorkerConfig(
    id="subscription_worker",
    worker_description="Worker specialized in managing DPSN topic subscriptions, unsubscriptions, message handling, and shutdown.",
    get_state_fn=get_worker_state,
    action_space=[
        dpsn_plugin.get_function("subscribe"),
        dpsn_plugin.get_function("unsubscribe"),
        dpsn_plugin.get_function("shutdown")
    ],
)

# Initialize the agent
agent = Agent(
    api_key=os.environ.get("GAME_API_KEY"),
    name="DPSN Market Data Agent",
    agent_goal="Monitor SOLUSDT market data from DPSN and process real-time updates.",
    agent_description=(
        "You are an AI agent specialized in DPSN market data processing"
        "You can subscribe dpsn topic"
        "after 5 minutes unsubscribe the topic"
        "next 5 minutes close the connection"
        "\n\nAvailable topics:"
        "\n- 0xe14768a6d8798e4390ec4cb8a4c991202c2115a5cd7a6c0a7ababcaf93b4d2d4/SOLUSDT/ohlc"
    ),
    get_agent_state_fn=get_agent_state_fn,
    workers=[
        subscription_worker
    ]
)

📖 API Reference (DpsnPlugin)

Key components of the DpsnPlugin class:

  • __init__(dpsn_url: Optional[str] = ..., pvt_key: Optional[str] = ...): Constructor. Reads credentials from env vars by default. Raises ValueError if credentials are missing.
  • get_function(fn_name: str) -> Function: Retrieves the Function object (subscribe, unsubscribe, shutdown) for the Game SDK.
  • set_message_callback(callback: Callable[[Dict[str, Any]], None]): Registers the function to call when a message is received on a subscribed topic. The callback receives a dictionary (structure depends on the underlying dpsn-client).
  • subscribe(topic: str) -> Tuple[FunctionResultStatus, str, Dict[str, Any]]: (Executable Function) Subscribes to a topic. Handles initialization if needed. Returns status, message, and details.
  • unsubscribe(topic: str) -> Tuple[FunctionResultStatus, str, Dict[str, Any]]: (Executable Function) Unsubscribes from a topic. Handles initialization if needed. Returns status, message, and details.
  • shutdown() -> Tuple[FunctionResultStatus, str, Dict[str, Any]]: (Executable Function) Disconnects the DPSN client gracefully. Returns status, message, and details.
  • _ensure_initialized(): (Internal) Manages the lazy initialization of the DPSN client connection. Raises DpsnInitializationError on failure.

Agent-Executable Functions

The plugin exposes the following functions intended to be called via the Game Agent's task execution mechanism:

  • subscribe:
    • Description: Subscribe to a DPSN topic.
    • Args: topic (string, required) - The topic to subscribe to.
  • unsubscribe:
    • Description: Unsubscribe from a DPSN topic.
    • Args: topic (string, required) - The topic to unsubscribe from.
  • shutdown:
    • Description: Shutdown the DPSN client connection.
    • Args: None.

In case of any queries regarding DPSN, please reach out to the team on Telegram 📥.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dpsn_plugin_gamesdk-0.0.1.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dpsn_plugin_gamesdk-0.0.1-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file dpsn_plugin_gamesdk-0.0.1.tar.gz.

File metadata

  • Download URL: dpsn_plugin_gamesdk-0.0.1.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for dpsn_plugin_gamesdk-0.0.1.tar.gz
Algorithm Hash digest
SHA256 c9aff93855f95e90ed84e9c71d516177ffd15dd0dd04fcce0062f806cefc88e3
MD5 b0812601b289683f1f85b79176c4f73b
BLAKE2b-256 7acc0e8f58069d5de43044fdfad401f77a2ae84eeac64933f5971f278b2df3bf

See more details on using hashes here.

File details

Details for the file dpsn_plugin_gamesdk-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for dpsn_plugin_gamesdk-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0105f37c057db3249f3cbeddcb843eda3964e8a10434274b6c8b024432674756
MD5 40728835a885b26f7d953a3ccb46a1e2
BLAKE2b-256 42d8c9d88163dc95979b61d52f6c406f896fe3a5375eb55b9f3afe30ddc228f5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page