-
Notifications
You must be signed in to change notification settings - Fork 89
TLedger Plugin #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Ang-dot
merged 19 commits into
game-by-virtuals:main
from
therealalchemist:TLedger_Plugin
May 5, 2025
Merged
TLedger Plugin #106
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
a95702d
TLedger Plugin
therealalchemist da933c7
Script for admin setup
therealalchemist ff1e597
Add to readme
therealalchemist dfe23cf
Changes for setup based on feedback
therealalchemist 429a6ea
Clean readme
therealalchemist 6398c27
Consolidate plugins into a single plugin
therealalchemist 295b739
Clean code
therealalchemist 9473b06
Chat example working
therealalchemist bddebfd
Update url
therealalchemist 6914103
New auth setup
therealalchemist 20005d6
Addressing feedback
therealalchemist 975ba73
Remove keys from the setup envs
therealalchemist f3d6c6a
Add plugin metadata
therealalchemist 867123d
Update plugins/tLedger/examples/.env.example
therealalchemist 63796ff
Use published tLedger plugin from pypi instead of relative paths
therealalchemist 9bdc65e
refactor: replace plugins/tLedger/examples/chat_agent.py with game_sd…
Ang-dot 77af138
refactor: use chat agent from game_sdk
Ang-dot 1ee52a5
docs: apply code style to credentials
Ang-dot dcfc12c
refactor: add empty line at EOF (POSIX)
Ang-dot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # TLedger Plugin for GAME SDK | ||
|
|
||
| ## Features | ||
|
|
||
| - get_agent_details - Get the details of your agent, including the TLedger agent_id and the balances of the agent's wallets | ||
| - create_payment - Create a payment request for a specific amount and currency | ||
| - get_payment_by_id - Get the details of a payment request by its ID | ||
|
|
||
| ## Admin Setup for doing agent to agent payments using TLedger Plugin | ||
|
|
||
| You are required to set up your account, project, agent profile, and keys in the TLedger platform to use the TLedger plugin for GAME SDK. | ||
|
|
||
| To make the setup easy, all you need to do is run the setup.py file in the tLedger plugin folder. This will install the plugin and set up the necessary environment variables for you. | ||
| To set up the necessary environment variables, please fill in thw details in the .env.setup file | ||
|
|
||
| ```shell | ||
| python3 ./setup.py | ||
| ``` | ||
| There are also two agents set for you incase you want to test the plugin. The agent details are as follows: | ||
|
|
||
| Agent 1: | ||
| - Agent ID: `agt_59b17650-a689-4649-91fa-4bf5d0db56ad` | ||
| - key: `ewSZjNQGPLle-vn5dMZoLOGUljEB6fbmox31o7KLKuI` | ||
| - secret: `iqB7-iETCVBE0UV_0HfRAwCHkVXO9_4cCPJYmTIyUpHauHlVP4Hk5xSsCquRqBO_2_eQ6OK_Zu7P1X4LU7hSHg` | ||
|
|
||
| Agent 2: | ||
| - Agent ID: `agt_3db52291-a9f8-4f04-a180-adb6e50ef5b0` | ||
| - key: `j06KtBcRRbmrEAqIVSiXZc3DPAJSqymDimo__ERD0oQ` | ||
| - secret: `h13ERQG797cYMeNeRLvwDF_3-DBt4o-kp0fL-bFHKstTUTS5xsLUFgDEUZG2GsoEKINxeSVusbAQxc24mHm1eQ` | ||
|
|
||
| ### TLedger Account Setup | ||
| For a complete list of TLedger setup APIs, please feel free to look at the public documentation at: https://docs.t54.ai/ | ||
|
|
||
| ### Toolkit Setup and Configuration | ||
|
|
||
| Import and initialize the plugin to use in your worker: | ||
|
|
||
| ```python | ||
| import os | ||
| from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin | ||
|
|
||
| tledger_plugin = TLedgerPlugin( | ||
| api_key=os.environ.get("SENDER_TLEDGER_API_KEY"), | ||
| api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"), | ||
| api_url=os.environ.get("TLEDGER_API_URL") | ||
| ) | ||
| ``` | ||
|
|
||
| **Basic worker example:** | ||
|
|
||
| Install the tLedger plugin using the following command: `pip install tledger-plugin-gamesdk` | ||
| For the latest version of tLedger plugin, please check the [tLedger Plugin](https://pypi.org/project/tledger-plugin-gamesdk/) page. | ||
|
|
||
| ```python | ||
|
|
||
| def get_state_fn(function_result: FunctionResult, current_state: dict) -> dict: | ||
|
|
||
| tledger_worker = Worker( | ||
| api_key=os.environ.get("GAME_API_KEY"), | ||
| description="Worker specialized in doing payments on Tledger", | ||
| get_state_fn=get_state_fn, | ||
| action_space=tledger_plugin.get_tools(), | ||
| ) | ||
|
|
||
| tledger_worker.run("Get TLedger account details") | ||
| ``` |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| TLEDGER_API_URL=https://api-sandbox.t54.ai/api/v1/ | ||
| SENDER_TLEDGER_API_KEY= | ||
| SENDER_TLEDGER_API_SECRET= | ||
| RECEIVER_TLEDGER_API_KEY= | ||
| RECEIVER_TLEDGER_API_SECRET= | ||
| GAME_API_KEY= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| import os | ||
| import time | ||
| import warnings | ||
| from typing import Any, Tuple | ||
| from dotenv import load_dotenv | ||
| from pathlib import Path | ||
|
|
||
| from typing_extensions import Dict | ||
|
|
||
| from game_sdk.game.chat_agent import ChatAgent | ||
| from game_sdk.game.custom_types import Argument, Function, FunctionResultStatus, FunctionResult | ||
|
|
||
| from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin | ||
|
|
||
| from colorama import Fore, Style | ||
|
|
||
| # Load environment variables from .env file | ||
| env_path = Path(__file__).parent / '.env.example' | ||
| load_dotenv(dotenv_path=env_path) | ||
|
|
||
| # Define color variables | ||
| AGENT_COLOR = Fore.GREEN # Agent's messages in green | ||
| AGENT_ACTION_COLOR = Fore.BLUE # Agent's action messages in green | ||
| USER_COLOR = Fore.CYAN # User's messages in cyan | ||
| RESET = Style.RESET_ALL # Reset color after each print | ||
|
|
||
|
|
||
| # ACTION SPACE | ||
|
|
||
| def post_twitter(object: str, **kwargs) -> tuple[FunctionResultStatus, str, dict[str, str]] | tuple[ | ||
| FunctionResultStatus, str, dict[str, Any]]: | ||
| """ | ||
| Specialized function to throw fruit objects. | ||
|
|
||
| This function demonstrates type-specific actions in the environment. | ||
|
|
||
| Args: | ||
| object (str): Name of the fruit to throw. | ||
| **kwargs: Additional arguments that might be passed. | ||
|
|
||
| Returns: | ||
| Tuple[FunctionResultStatus, str, dict]: Status, feedback message, and state info. | ||
|
|
||
| Example: | ||
| status, msg, info = throw_fruit("apple") | ||
| """ | ||
| return ( | ||
| FunctionResultStatus.DONE, | ||
| "Successfully posted on twitter", | ||
| { | ||
| "response": "Token promoted", | ||
| }, | ||
| ) | ||
|
|
||
| sender_tledger_plugin = TLedgerPlugin( | ||
| api_key=os.environ.get("SENDER_TLEDGER_API_KEY"), | ||
| api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"), | ||
| api_url=os.environ.get("TLEDGER_API_URL") | ||
| ) | ||
|
|
||
| receiver_tledger_plugin = TLedgerPlugin( | ||
| api_key=os.environ.get("RECEIVER_TLEDGER_API_KEY"), | ||
| api_secret=os.environ.get("RECEIVER_TLEDGER_API_SECRET"), | ||
| api_url=os.environ.get("TLEDGER_API_URL") | ||
| ) | ||
|
|
||
| action_space = sender_tledger_plugin.get_tools() | ||
|
|
||
| aixbt_action_space = receiver_tledger_plugin.get_tools() | ||
|
|
||
| aixbt_action_space.append( | ||
| Function( | ||
| fn_name="post_twitter", | ||
| fn_description="Make post on twitter", | ||
| args=[Argument(name="object", type="string", description="Make post on twitter")], | ||
| executable=post_twitter | ||
| ) | ||
| ) | ||
|
|
||
| api_key = os.environ.get("GAME_API_KEY") | ||
| if not api_key: | ||
| raise ValueError("GAME_API_KEY is not set") | ||
|
|
||
|
|
||
| # CREATE AGENT | ||
| autonomous_agent = ChatAgent( | ||
| prompt="You are an agent trying to promote your utility token $PYMT for peer to peer instant settlement on twitter and pay the influencers in any crypto they wish to receive only after they complete the work. Ask the influencer agent_id for its agent_id. Your settlement_network is solana, currency is SOL, and payment_amount is 0.1", | ||
| api_key=api_key | ||
| ) | ||
|
|
||
| aixbt = ChatAgent( | ||
| prompt="You are an influencer on twitter who charges 0.1 $SOL token to promote an asset by making twitter post. You accept payment only through tLedger Payment Platform via tLedger Agent Id. You can call tLedger to get your agent_details. Don't do a payment until you receive the payment and its completed", | ||
| api_key=api_key | ||
| ) | ||
|
|
||
| aixbt_state = {} | ||
|
|
||
| autonomous_agent_state = {} | ||
|
|
||
|
|
||
| def get_aixbt_state() -> Dict[str, Any]: | ||
| return aixbt_state | ||
|
|
||
| def get_autonomous_agent_state() -> Dict[str, Any]: | ||
| return autonomous_agent_state | ||
|
|
||
|
|
||
| aixbt_chat = aixbt.create_chat( | ||
| partner_id="Autonomous Agent", | ||
| partner_name="Autonomous Agent", | ||
| action_space=aixbt_action_space | ||
|
|
||
| ) | ||
|
|
||
| autonomous_agent_chat = autonomous_agent.create_chat( | ||
| partner_id="Aixbt", | ||
| partner_name="Aixbt", | ||
| action_space=action_space | ||
| ) | ||
|
|
||
| chat_continue = True | ||
| initialize_conversation: bool = True | ||
|
|
||
|
|
||
| def update_agent_state(current_state: dict, function_result: FunctionResult) -> Dict[str, Any]: | ||
| info = function_result.info | ||
| # if not info["payment_id"]: | ||
| # current_state["payment_id"] = info["payment_id"] | ||
| return current_state | ||
|
|
||
|
|
||
| while chat_continue: | ||
|
|
||
| time.sleep(10) # Wait for 10 seconds before making request | ||
|
|
||
| warnings.simplefilter("ignore", category=UserWarning) | ||
|
|
||
| meme_agent_turn: bool | ||
|
|
||
| if initialize_conversation: | ||
| chat_response = autonomous_agent_chat.next("Hi") | ||
| if chat_response.message: | ||
| print(f"{AGENT_COLOR}Autonomous Response{RESET}: {chat_response.message}") | ||
| initialize_conversation = False | ||
| meme_agent_turn = False | ||
| continue | ||
|
|
||
|
|
||
| time.sleep(5) # Wait for 5 seconds before retrying | ||
| if meme_agent_turn: | ||
| updated_response = autonomous_agent_chat.next(chat_response.message) | ||
| if updated_response.function_call: | ||
| print(f"{AGENT_ACTION_COLOR}Autonomous Agent Action{RESET}: {updated_response.function_call.result.feedback_message}") | ||
| #update_agent_state(autonomous_agent_chat.get_state_fn(), updated_response.function_call.result) | ||
|
|
||
| if updated_response.message: | ||
| print(f"{AGENT_COLOR}Autonomous Agent Response{RESET}: {updated_response.message}") | ||
| meme_agent_turn = False | ||
| else: | ||
|
|
||
| updated_response = aixbt_chat.next(chat_response.message) | ||
|
|
||
| if updated_response.message: | ||
| print(f"{USER_COLOR}Aixbt Response{RESET}: {updated_response.message}") | ||
| meme_agent_turn = True | ||
|
|
||
| chat_response = updated_response | ||
|
|
||
|
|
||
|
|
||
| if chat_response.is_finished: | ||
| chat_continue = False | ||
| break | ||
|
|
||
| print("Chat ended") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import os | ||
| from game_sdk.game.worker import Worker | ||
| from game_sdk.game.custom_types import FunctionResult | ||
| from dotenv import load_dotenv | ||
| from pathlib import Path | ||
|
|
||
| # Load environment variables from .env file | ||
| env_path = Path(__file__).parent / '.env.example' | ||
| load_dotenv(dotenv_path=env_path) | ||
|
|
||
|
|
||
| from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin | ||
|
|
||
| def get_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 | ||
|
|
||
| # Update state with the function result info | ||
| current_state.update(function_result.info) | ||
|
|
||
| return current_state | ||
|
|
||
|
|
||
|
|
||
| tledger_plugin = TLedgerPlugin( | ||
| api_key=os.environ.get("SENDER_TLEDGER_API_KEY"), | ||
| api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"), | ||
| api_url = os.environ.get("TLEDGER_API_URL") | ||
| ) | ||
|
|
||
| # Create worker | ||
| tledger_worker = Worker( | ||
| api_key=os.environ.get("GAME_API_KEY"), | ||
| description="Worker specialized in doing payments on Tledger", | ||
| get_state_fn=get_state_fn, | ||
| action_space=tledger_plugin.get_tools(), | ||
| ) | ||
|
|
||
| # # Run example query | ||
| queries = [ | ||
| "Get TLedger account details", | ||
| "Create payment of 1 SOL using the TLedger account details. The receiving agent's ID is 'agt_3db52291-a9f8-4f04-a180-adb6e50ef5b0', the payment amount is 1, the settlement network is 'solana', the currency is 'sol', and the conversation ID is 'conv1'", | ||
| "Get payment by ID. Retrieve the payment ID using the previous query", | ||
| ] | ||
|
|
||
| for query in queries: | ||
| print("-" * 100) | ||
| print(f"Query: {query}") | ||
| tledger_worker.run(query) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # General Information | ||
| plugin_name: "tLedger_plugin_gamesdk" | ||
| author: "tLedger Engineering Team" | ||
| logo_url: "https://drive.google.com/file/d/1PQroliD6_3MraAAR2WbqLbNOJLLy5DAX/view?usp=share_link" | ||
| release_date: "2025-04" | ||
|
|
||
| # Description | ||
| short_description: "tLedger Plugin for Game SDK. TLedger is a blockchain-agnostic agent account management platform" | ||
| detailed_description: "tLedger is t54’s foundational product—a blockchain-agnostic account & ledger designed to support AI agent-initiated financial transactions. It enables developers to create and manage agent-level virtual accounts, set programmable spending limits, and trigger on-chain payments via a lightweight SDK. Each agent is provisioned with multi-asset wallets (e.g., USDT, SOL), and all activity is surfaced through robust APIs and a web-based portal. The platform enforces compliance through Know Your Agent (KYA) protocols and centralized risk controls, giving developers the tooling to deploy financially autonomous agents at scale." | ||
|
|
||
| # Contact & Support | ||
| x_account_handle: "@GAME_Virtuals" | ||
| support_contact: "cfang@t54.ai" | ||
| community_link: "https://t.me/virtuals" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| [build-system] | ||
| requires = ["hatchling"] | ||
| build-backend = "hatchling.build" | ||
|
|
||
| [project] | ||
| name = "tledger_plugin_gamesdk" | ||
| version = "0.1.2" | ||
| authors = [{ name = "Prateek Tiwari", email = "ptiwari@t54.ai" }, { name = "Akshit Arora", email = "aarora@t54.ai" }] | ||
| description = "TLedger SDK for GAME by Virtuals" | ||
| requires-python = ">=3.8" | ||
| classifiers = [ | ||
| "Programming Language :: Python :: 3", | ||
| "Programming Language :: Python :: 3.8", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| "Programming Language :: Python :: 3.11", | ||
| "License :: OSI Approved :: MIT License", | ||
| "Operating System :: OS Independent", | ||
| "Development Status :: 3 - Alpha", | ||
| "Intended Audience :: Developers", | ||
| "Topic :: Software Development :: Libraries :: Python Modules", | ||
| ] | ||
| dependencies = [ | ||
| "aiohttp>=3.11.11", | ||
| "game-sdk>=0.1.1" | ||
| ] | ||
|
|
||
| [tool.hatch.build.targets.wheel] | ||
| packages = ["tledger_plugin_gamesdk"] | ||
|
|
||
| [project.urls] | ||
| "Homepage" = "https://github.com/game-by-virtuals/game-python/plugins/tLedger" | ||
| "Bug Tracker" = "https://github.com/game-by-virtuals/game-python" | ||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.