Skip to content

Commit 5ae5327

Browse files
authored
Merge pull request #106 from therealalchemist/TLedger_Plugin
TLedger Plugin
2 parents 1c26baf + dcfc12c commit 5ae5327

File tree

11 files changed

+738
-0
lines changed

11 files changed

+738
-0
lines changed

plugins/tLedger/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# TLedger Plugin for GAME SDK
2+
3+
## Features
4+
5+
- get_agent_details - Get the details of your agent, including the TLedger agent_id and the balances of the agent's wallets
6+
- create_payment - Create a payment request for a specific amount and currency
7+
- get_payment_by_id - Get the details of a payment request by its ID
8+
9+
## Admin Setup for doing agent to agent payments using TLedger Plugin
10+
11+
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.
12+
13+
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.
14+
To set up the necessary environment variables, please fill in thw details in the .env.setup file
15+
16+
```shell
17+
python3 ./setup.py
18+
```
19+
There are also two agents set for you incase you want to test the plugin. The agent details are as follows:
20+
21+
Agent 1:
22+
- Agent ID: `agt_59b17650-a689-4649-91fa-4bf5d0db56ad`
23+
- key: `ewSZjNQGPLle-vn5dMZoLOGUljEB6fbmox31o7KLKuI`
24+
- secret: `iqB7-iETCVBE0UV_0HfRAwCHkVXO9_4cCPJYmTIyUpHauHlVP4Hk5xSsCquRqBO_2_eQ6OK_Zu7P1X4LU7hSHg`
25+
26+
Agent 2:
27+
- Agent ID: `agt_3db52291-a9f8-4f04-a180-adb6e50ef5b0`
28+
- key: `j06KtBcRRbmrEAqIVSiXZc3DPAJSqymDimo__ERD0oQ`
29+
- secret: `h13ERQG797cYMeNeRLvwDF_3-DBt4o-kp0fL-bFHKstTUTS5xsLUFgDEUZG2GsoEKINxeSVusbAQxc24mHm1eQ`
30+
31+
### TLedger Account Setup
32+
For a complete list of TLedger setup APIs, please feel free to look at the public documentation at: https://docs.t54.ai/
33+
34+
### Toolkit Setup and Configuration
35+
36+
Import and initialize the plugin to use in your worker:
37+
38+
```python
39+
import os
40+
from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin
41+
42+
tledger_plugin = TLedgerPlugin(
43+
api_key=os.environ.get("SENDER_TLEDGER_API_KEY"),
44+
api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"),
45+
api_url=os.environ.get("TLEDGER_API_URL")
46+
)
47+
```
48+
49+
**Basic worker example:**
50+
51+
Install the tLedger plugin using the following command: `pip install tledger-plugin-gamesdk`
52+
For the latest version of tLedger plugin, please check the [tLedger Plugin](https://pypi.org/project/tledger-plugin-gamesdk/) page.
53+
54+
```python
55+
56+
def get_state_fn(function_result: FunctionResult, current_state: dict) -> dict:
57+
58+
tledger_worker = Worker(
59+
api_key=os.environ.get("GAME_API_KEY"),
60+
description="Worker specialized in doing payments on Tledger",
61+
get_state_fn=get_state_fn,
62+
action_space=tledger_plugin.get_tools(),
63+
)
64+
65+
tledger_worker.run("Get TLedger account details")
66+
```

plugins/tLedger/__init__.py

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
TLEDGER_API_URL=https://api-sandbox.t54.ai/api/v1/
2+
SENDER_TLEDGER_API_KEY=
3+
SENDER_TLEDGER_API_SECRET=
4+
RECEIVER_TLEDGER_API_KEY=
5+
RECEIVER_TLEDGER_API_SECRET=
6+
GAME_API_KEY=
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import os
2+
import time
3+
import warnings
4+
from typing import Any, Tuple
5+
from dotenv import load_dotenv
6+
from pathlib import Path
7+
8+
from typing_extensions import Dict
9+
10+
from game_sdk.game.chat_agent import ChatAgent
11+
from game_sdk.game.custom_types import Argument, Function, FunctionResultStatus, FunctionResult
12+
13+
from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin
14+
15+
from colorama import Fore, Style
16+
17+
# Load environment variables from .env file
18+
env_path = Path(__file__).parent / '.env.example'
19+
load_dotenv(dotenv_path=env_path)
20+
21+
# Define color variables
22+
AGENT_COLOR = Fore.GREEN # Agent's messages in green
23+
AGENT_ACTION_COLOR = Fore.BLUE # Agent's action messages in green
24+
USER_COLOR = Fore.CYAN # User's messages in cyan
25+
RESET = Style.RESET_ALL # Reset color after each print
26+
27+
28+
# ACTION SPACE
29+
30+
def post_twitter(object: str, **kwargs) -> tuple[FunctionResultStatus, str, dict[str, str]] | tuple[
31+
FunctionResultStatus, str, dict[str, Any]]:
32+
"""
33+
Specialized function to throw fruit objects.
34+
35+
This function demonstrates type-specific actions in the environment.
36+
37+
Args:
38+
object (str): Name of the fruit to throw.
39+
**kwargs: Additional arguments that might be passed.
40+
41+
Returns:
42+
Tuple[FunctionResultStatus, str, dict]: Status, feedback message, and state info.
43+
44+
Example:
45+
status, msg, info = throw_fruit("apple")
46+
"""
47+
return (
48+
FunctionResultStatus.DONE,
49+
"Successfully posted on twitter",
50+
{
51+
"response": "Token promoted",
52+
},
53+
)
54+
55+
sender_tledger_plugin = TLedgerPlugin(
56+
api_key=os.environ.get("SENDER_TLEDGER_API_KEY"),
57+
api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"),
58+
api_url=os.environ.get("TLEDGER_API_URL")
59+
)
60+
61+
receiver_tledger_plugin = TLedgerPlugin(
62+
api_key=os.environ.get("RECEIVER_TLEDGER_API_KEY"),
63+
api_secret=os.environ.get("RECEIVER_TLEDGER_API_SECRET"),
64+
api_url=os.environ.get("TLEDGER_API_URL")
65+
)
66+
67+
action_space = sender_tledger_plugin.get_tools()
68+
69+
aixbt_action_space = receiver_tledger_plugin.get_tools()
70+
71+
aixbt_action_space.append(
72+
Function(
73+
fn_name="post_twitter",
74+
fn_description="Make post on twitter",
75+
args=[Argument(name="object", type="string", description="Make post on twitter")],
76+
executable=post_twitter
77+
)
78+
)
79+
80+
api_key = os.environ.get("GAME_API_KEY")
81+
if not api_key:
82+
raise ValueError("GAME_API_KEY is not set")
83+
84+
85+
# CREATE AGENT
86+
autonomous_agent = ChatAgent(
87+
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",
88+
api_key=api_key
89+
)
90+
91+
aixbt = ChatAgent(
92+
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",
93+
api_key=api_key
94+
)
95+
96+
aixbt_state = {}
97+
98+
autonomous_agent_state = {}
99+
100+
101+
def get_aixbt_state() -> Dict[str, Any]:
102+
return aixbt_state
103+
104+
def get_autonomous_agent_state() -> Dict[str, Any]:
105+
return autonomous_agent_state
106+
107+
108+
aixbt_chat = aixbt.create_chat(
109+
partner_id="Autonomous Agent",
110+
partner_name="Autonomous Agent",
111+
action_space=aixbt_action_space
112+
113+
)
114+
115+
autonomous_agent_chat = autonomous_agent.create_chat(
116+
partner_id="Aixbt",
117+
partner_name="Aixbt",
118+
action_space=action_space
119+
)
120+
121+
chat_continue = True
122+
initialize_conversation: bool = True
123+
124+
125+
def update_agent_state(current_state: dict, function_result: FunctionResult) -> Dict[str, Any]:
126+
info = function_result.info
127+
# if not info["payment_id"]:
128+
# current_state["payment_id"] = info["payment_id"]
129+
return current_state
130+
131+
132+
while chat_continue:
133+
134+
time.sleep(10) # Wait for 10 seconds before making request
135+
136+
warnings.simplefilter("ignore", category=UserWarning)
137+
138+
meme_agent_turn: bool
139+
140+
if initialize_conversation:
141+
chat_response = autonomous_agent_chat.next("Hi")
142+
if chat_response.message:
143+
print(f"{AGENT_COLOR}Autonomous Response{RESET}: {chat_response.message}")
144+
initialize_conversation = False
145+
meme_agent_turn = False
146+
continue
147+
148+
149+
time.sleep(5) # Wait for 5 seconds before retrying
150+
if meme_agent_turn:
151+
updated_response = autonomous_agent_chat.next(chat_response.message)
152+
if updated_response.function_call:
153+
print(f"{AGENT_ACTION_COLOR}Autonomous Agent Action{RESET}: {updated_response.function_call.result.feedback_message}")
154+
#update_agent_state(autonomous_agent_chat.get_state_fn(), updated_response.function_call.result)
155+
156+
if updated_response.message:
157+
print(f"{AGENT_COLOR}Autonomous Agent Response{RESET}: {updated_response.message}")
158+
meme_agent_turn = False
159+
else:
160+
161+
updated_response = aixbt_chat.next(chat_response.message)
162+
163+
if updated_response.message:
164+
print(f"{USER_COLOR}Aixbt Response{RESET}: {updated_response.message}")
165+
meme_agent_turn = True
166+
167+
chat_response = updated_response
168+
169+
170+
171+
if chat_response.is_finished:
172+
chat_continue = False
173+
break
174+
175+
print("Chat ended")
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import os
2+
from game_sdk.game.worker import Worker
3+
from game_sdk.game.custom_types import FunctionResult
4+
from dotenv import load_dotenv
5+
from pathlib import Path
6+
7+
# Load environment variables from .env file
8+
env_path = Path(__file__).parent / '.env.example'
9+
load_dotenv(dotenv_path=env_path)
10+
11+
12+
from tledger_plugin_gamesdk.tLedger_plugin import TLedgerPlugin
13+
14+
def get_state_fn(function_result: FunctionResult, current_state: dict) -> dict:
15+
"""
16+
Update state based on the function results
17+
"""
18+
init_state = {}
19+
20+
if current_state is None:
21+
return init_state
22+
23+
# Update state with the function result info
24+
current_state.update(function_result.info)
25+
26+
return current_state
27+
28+
29+
30+
tledger_plugin = TLedgerPlugin(
31+
api_key=os.environ.get("SENDER_TLEDGER_API_KEY"),
32+
api_secret=os.environ.get("SENDER_TLEDGER_API_SECRET"),
33+
api_url = os.environ.get("TLEDGER_API_URL")
34+
)
35+
36+
# Create worker
37+
tledger_worker = Worker(
38+
api_key=os.environ.get("GAME_API_KEY"),
39+
description="Worker specialized in doing payments on Tledger",
40+
get_state_fn=get_state_fn,
41+
action_space=tledger_plugin.get_tools(),
42+
)
43+
44+
# # Run example query
45+
queries = [
46+
"Get TLedger account details",
47+
"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'",
48+
"Get payment by ID. Retrieve the payment ID using the previous query",
49+
]
50+
51+
for query in queries:
52+
print("-" * 100)
53+
print(f"Query: {query}")
54+
tledger_worker.run(query)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# General Information
2+
plugin_name: "tLedger_plugin_gamesdk"
3+
author: "tLedger Engineering Team"
4+
logo_url: "https://drive.google.com/file/d/1PQroliD6_3MraAAR2WbqLbNOJLLy5DAX/view?usp=share_link"
5+
release_date: "2025-04"
6+
7+
# Description
8+
short_description: "tLedger Plugin for Game SDK. TLedger is a blockchain-agnostic agent account management platform"
9+
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."
10+
11+
# Contact & Support
12+
x_account_handle: "@GAME_Virtuals"
13+
support_contact: "cfang@t54.ai"
14+
community_link: "https://t.me/virtuals"

plugins/tLedger/pyproject.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "tledger_plugin_gamesdk"
7+
version = "0.1.2"
8+
authors = [{ name = "Prateek Tiwari", email = "ptiwari@t54.ai" }, { name = "Akshit Arora", email = "aarora@t54.ai" }]
9+
description = "TLedger SDK for GAME by Virtuals"
10+
requires-python = ">=3.8"
11+
classifiers = [
12+
"Programming Language :: Python :: 3",
13+
"Programming Language :: Python :: 3.8",
14+
"Programming Language :: Python :: 3.9",
15+
"Programming Language :: Python :: 3.10",
16+
"Programming Language :: Python :: 3.11",
17+
"License :: OSI Approved :: MIT License",
18+
"Operating System :: OS Independent",
19+
"Development Status :: 3 - Alpha",
20+
"Intended Audience :: Developers",
21+
"Topic :: Software Development :: Libraries :: Python Modules",
22+
]
23+
dependencies = [
24+
"aiohttp>=3.11.11",
25+
"game-sdk>=0.1.1"
26+
]
27+
28+
[tool.hatch.build.targets.wheel]
29+
packages = ["tledger_plugin_gamesdk"]
30+
31+
[project.urls]
32+
"Homepage" = "https://github.com/game-by-virtuals/game-python/plugins/tLedger"
33+
"Bug Tracker" = "https://github.com/game-by-virtuals/game-python"
34+

0 commit comments

Comments
 (0)