acp-plugin-gamesdk 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- acp_plugin_gamesdk/acp_client.py +44 -27
- acp_plugin_gamesdk/acp_plugin.py +50 -17
- acp_plugin_gamesdk/acp_token.py +18 -8
- acp_plugin_gamesdk/interface.py +95 -11
- {acp_plugin_gamesdk-0.1.7.dist-info → acp_plugin_gamesdk-0.1.8.dist-info}/METADATA +6 -3
- acp_plugin_gamesdk-0.1.8.dist-info/RECORD +8 -0
- acp_plugin_gamesdk-0.1.7.dist-info/RECORD +0 -8
- {acp_plugin_gamesdk-0.1.7.dist-info → acp_plugin_gamesdk-0.1.8.dist-info}/WHEEL +0 -0
acp_plugin_gamesdk/acp_client.py
CHANGED
@@ -1,12 +1,16 @@
|
|
1
|
-
|
2
|
-
from typing import List, Optional
|
3
|
-
from web3 import Web3
|
1
|
+
import json
|
4
2
|
import requests
|
5
|
-
from acp_plugin_gamesdk.interface import AcpAgent, AcpJobPhases, AcpOffering, AcpState
|
6
|
-
from acp_plugin_gamesdk.acp_token import AcpToken, MemoType
|
7
3
|
import time
|
8
4
|
import traceback
|
9
5
|
|
6
|
+
from datetime import datetime, timedelta, timezone
|
7
|
+
from typing import List, Optional
|
8
|
+
from web3 import Web3
|
9
|
+
|
10
|
+
from acp_plugin_gamesdk.interface import AcpAgent, AcpJobPhases, AcpOffering, AcpState, AcpJobPhasesDesc
|
11
|
+
from acp_plugin_gamesdk.acp_token import AcpToken, MemoType
|
12
|
+
from dacite import from_dict, Config
|
13
|
+
|
10
14
|
|
11
15
|
class AcpClient:
|
12
16
|
def __init__(self, api_key: str, acp_token: AcpToken, acp_base_url: Optional[str] = None):
|
@@ -25,22 +29,29 @@ class AcpClient:
|
|
25
29
|
f"{self.base_url}/states/{self.agent_wallet_address}",
|
26
30
|
headers={"x-api-key": self.api_key}
|
27
31
|
)
|
28
|
-
|
32
|
+
payload = response.json()
|
33
|
+
result = from_dict(data_class=AcpState, data=payload, config=Config(type_hooks={AcpJobPhasesDesc: AcpJobPhasesDesc}))
|
34
|
+
return result
|
29
35
|
|
30
|
-
def browse_agents(
|
36
|
+
def browse_agents(
|
37
|
+
self,
|
38
|
+
cluster: Optional[str] = None,
|
39
|
+
query: Optional[str] = None,
|
40
|
+
rerank: Optional[bool] = True,
|
41
|
+
top_k: Optional[int] = 1,
|
42
|
+
) -> List[AcpAgent]:
|
43
|
+
|
31
44
|
url = f"{self.acp_base_url}/agents"
|
32
45
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
46
|
+
params = {
|
47
|
+
"search": query,
|
48
|
+
"filters[cluster]": cluster,
|
49
|
+
"filters[walletAddress][$notIn]": self.agent_wallet_address,
|
50
|
+
"rerank": "true" if rerank else "false",
|
51
|
+
"top_k": top_k,
|
52
|
+
}
|
53
|
+
response = requests.get(url, params=params)
|
41
54
|
|
42
|
-
response = requests.get(url)
|
43
|
-
|
44
55
|
if response.status_code != 200:
|
45
56
|
raise Exception(
|
46
57
|
f"Error occured in browse_agents function. Failed to browse agents.\n"
|
@@ -65,19 +76,26 @@ class AcpClient:
|
|
65
76
|
name=agent["name"],
|
66
77
|
description=agent["description"],
|
67
78
|
wallet_address=agent["walletAddress"],
|
68
|
-
offerings=offerings
|
79
|
+
offerings=offerings,
|
80
|
+
score=agent["score"],
|
81
|
+
explanation=agent["explanation"]
|
69
82
|
)
|
70
83
|
)
|
71
84
|
|
72
85
|
return result
|
73
86
|
|
74
|
-
def create_job(
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
evaluator_address
|
80
|
-
|
87
|
+
def create_job(
|
88
|
+
self,
|
89
|
+
provider_address: str,
|
90
|
+
price: float,
|
91
|
+
job_description: str,
|
92
|
+
evaluator_address: str,
|
93
|
+
expired_at: datetime,
|
94
|
+
) -> int:
|
95
|
+
tx_result = self.acp_token.create_job(
|
96
|
+
provider_address = provider_address,
|
97
|
+
evaluator_address = evaluator_address,
|
98
|
+
expire_at = expired_at
|
81
99
|
)
|
82
100
|
|
83
101
|
job_id = None
|
@@ -129,7 +147,7 @@ class AcpClient:
|
|
129
147
|
"providerAddress": provider_address,
|
130
148
|
"description": job_description,
|
131
149
|
"price": price,
|
132
|
-
"expiredAt":
|
150
|
+
"expiredAt": expired_at.astimezone(timezone.utc).isoformat(),
|
133
151
|
"evaluatorAddress": evaluator_address
|
134
152
|
}
|
135
153
|
|
@@ -231,7 +249,6 @@ class AcpClient:
|
|
231
249
|
f"Response status code: {response.status_code}\n"
|
232
250
|
f"Response description: {response.text}\n"
|
233
251
|
)
|
234
|
-
raise Exception(f"Failed to reset state: {response.status_code} {response.text}")
|
235
252
|
|
236
253
|
def delete_completed_job(self, job_id: int) -> None:
|
237
254
|
response = requests.delete(
|
acp_plugin_gamesdk/acp_plugin.py
CHANGED
@@ -3,8 +3,9 @@ import signal
|
|
3
3
|
import sys
|
4
4
|
from typing import List, Dict, Any, Optional,Tuple
|
5
5
|
import json
|
6
|
-
from dataclasses import dataclass
|
7
|
-
from datetime import datetime
|
6
|
+
from dataclasses import dataclass, asdict
|
7
|
+
from datetime import datetime, timezone, timedelta
|
8
|
+
import traceback
|
8
9
|
|
9
10
|
import socketio
|
10
11
|
import socketio.client
|
@@ -26,6 +27,7 @@ class AcpPluginOptions:
|
|
26
27
|
evaluator_cluster: Optional[str] = None
|
27
28
|
on_evaluate: Optional[Callable[[IDeliverable], Tuple[bool, str]]] = None
|
28
29
|
on_phase_change: Optional[Callable[[AcpJob], None]] = None
|
30
|
+
job_expiry_duration_mins: Optional[int] = None
|
29
31
|
|
30
32
|
|
31
33
|
SocketEvents = {
|
@@ -74,6 +76,7 @@ class AcpPlugin:
|
|
74
76
|
if options.on_phase_change is not None:
|
75
77
|
self.on_phase_change = options.on_phase_change
|
76
78
|
self.initializeSocket()
|
79
|
+
self.job_expiry_duration_mins = options.job_expiry_duration_mins if options.job_expiry_duration_mins is not None else 1440
|
77
80
|
|
78
81
|
|
79
82
|
|
@@ -152,8 +155,9 @@ class AcpPlugin:
|
|
152
155
|
|
153
156
|
def get_acp_state(self) -> Dict:
|
154
157
|
server_state = self.acp_client.get_state()
|
155
|
-
server_state
|
156
|
-
|
158
|
+
server_state.inventory.produced = self.produced_inventory
|
159
|
+
state = asdict(server_state)
|
160
|
+
return state
|
157
161
|
|
158
162
|
def get_worker(self, data: Optional[Dict] = None) -> WorkerConfig:
|
159
163
|
functions = data.get("functions") if data else [
|
@@ -201,18 +205,42 @@ class AcpPlugin:
|
|
201
205
|
def _search_agents_executable(self,reasoning: str, keyword: str) -> Tuple[FunctionResultStatus, str, dict]:
|
202
206
|
if not reasoning:
|
203
207
|
return FunctionResultStatus.FAILED, "Reasoning for the search must be provided. This helps track your decision-making process for future reference.", {}
|
204
|
-
|
205
|
-
agents = self.acp_client.browse_agents(self.cluster, keyword)
|
206
|
-
|
208
|
+
|
209
|
+
agents = self.acp_client.browse_agents(self.cluster, keyword, rerank=True, top_k=1)
|
210
|
+
|
207
211
|
if not agents:
|
208
212
|
return FunctionResultStatus.FAILED, "No other trading agents found in the system. Please try again later when more agents are available.", {}
|
209
|
-
|
210
|
-
return
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
213
|
+
|
214
|
+
return (
|
215
|
+
FunctionResultStatus.DONE,
|
216
|
+
json.dumps(
|
217
|
+
{
|
218
|
+
"availableAgents": [
|
219
|
+
{
|
220
|
+
"id": agent.id,
|
221
|
+
"name": agent.name,
|
222
|
+
"description": agent.description,
|
223
|
+
"wallet_address": agent.wallet_address,
|
224
|
+
"offerings": (
|
225
|
+
[
|
226
|
+
{"name": offering.name, "price": offering.price}
|
227
|
+
for offering in agent.offerings
|
228
|
+
]
|
229
|
+
if agent.offerings
|
230
|
+
else []
|
231
|
+
),
|
232
|
+
"score": agent.score,
|
233
|
+
"explanation": agent.explanation
|
234
|
+
}
|
235
|
+
for agent in agents
|
236
|
+
],
|
237
|
+
"totalAgentsFound": len(agents),
|
238
|
+
"timestamp": datetime.now().timestamp(),
|
239
|
+
"note": "Use the walletAddress when initiating a job with your chosen trading partner.",
|
240
|
+
}
|
241
|
+
),
|
242
|
+
{},
|
243
|
+
)
|
216
244
|
|
217
245
|
@property
|
218
246
|
def search_agents_functions(self) -> Function:
|
@@ -319,7 +347,7 @@ class AcpPlugin:
|
|
319
347
|
evaluatorAddress = self.acp_token_client.get_agent_wallet_address()
|
320
348
|
|
321
349
|
if require_evaluation:
|
322
|
-
validators = self.acp_client.browse_agents(self.evaluator_cluster, evaluatorKeyword)
|
350
|
+
validators = self.acp_client.browse_agents(self.evaluator_cluster, evaluatorKeyword, rerank=True, top_k=1)
|
323
351
|
|
324
352
|
if len(validators) == 0:
|
325
353
|
return FunctionResultStatus.FAILED, "No evaluator found - try a different keyword", {}
|
@@ -327,11 +355,13 @@ class AcpPlugin:
|
|
327
355
|
evaluatorAddress = validators[0].wallet_address
|
328
356
|
|
329
357
|
# ... Rest of validation logic ...
|
358
|
+
expired_at = datetime.now(timezone.utc) + timedelta(minutes=self.job_expiry_duration_mins)
|
330
359
|
job_id = self.acp_client.create_job(
|
331
360
|
sellerWalletAddress,
|
332
361
|
float(price),
|
333
362
|
serviceRequirements,
|
334
|
-
evaluatorAddress
|
363
|
+
evaluatorAddress,
|
364
|
+
expired_at
|
335
365
|
)
|
336
366
|
|
337
367
|
if (hasattr(self, 'twitter_plugin') and self.twitter_plugin is not None and tweetContent is not None):
|
@@ -349,6 +379,7 @@ class AcpPlugin:
|
|
349
379
|
"timestamp": datetime.now().timestamp(),
|
350
380
|
}), {}
|
351
381
|
except Exception as e:
|
382
|
+
print(traceback.format_exc())
|
352
383
|
return FunctionResultStatus.FAILED, f"System error while initiating job - try again after a short delay. {str(e)}", {}
|
353
384
|
|
354
385
|
@property
|
@@ -522,6 +553,7 @@ class AcpPlugin:
|
|
522
553
|
"timestamp": datetime.now().timestamp()
|
523
554
|
}), {}
|
524
555
|
except Exception as e:
|
556
|
+
print(traceback.format_exc())
|
525
557
|
return FunctionResultStatus.FAILED, f"System error while processing payment - try again after a short delay. {str(e)}", {}
|
526
558
|
|
527
559
|
@property
|
@@ -592,7 +624,7 @@ class AcpPlugin:
|
|
592
624
|
return FunctionResultStatus.FAILED, f"Cannot deliver - job is in '{job['phase']}' phase, must be in 'transaction' phase", {}
|
593
625
|
|
594
626
|
produced = next(
|
595
|
-
(i for i in self.produced_inventory if i
|
627
|
+
(i for i in self.produced_inventory if i.jobId == job["jobId"]),
|
596
628
|
None
|
597
629
|
)
|
598
630
|
|
@@ -627,4 +659,5 @@ class AcpPlugin:
|
|
627
659
|
"timestamp": datetime.now().timestamp()
|
628
660
|
}), {}
|
629
661
|
except Exception as e:
|
662
|
+
print(traceback.format_exc())
|
630
663
|
return FunctionResultStatus.FAILED, f"System error while delivering items - try again after a short delay. {str(e)}", {}
|
acp_plugin_gamesdk/acp_token.py
CHANGED
@@ -8,6 +8,7 @@ from acp_plugin_gamesdk.acp_token_abi import ACP_TOKEN_ABI
|
|
8
8
|
import requests
|
9
9
|
from eth_account.messages import encode_defunct
|
10
10
|
import json
|
11
|
+
import traceback
|
11
12
|
|
12
13
|
class MemoType(IntEnum):
|
13
14
|
MESSAGE = 0
|
@@ -97,6 +98,7 @@ class AcpToken:
|
|
97
98
|
response = requests.post(f"{self.acp_base_url}/acp-agent-wallets/trx-result", json={"userOpHash": hash_value})
|
98
99
|
return response.json()
|
99
100
|
except Exception as error:
|
101
|
+
print(traceback.format_exc())
|
100
102
|
raise Exception(f"Failed to get job_id {error}")
|
101
103
|
|
102
104
|
def create_job(
|
@@ -134,8 +136,8 @@ class AcpToken:
|
|
134
136
|
# Return transaction hash or response ID
|
135
137
|
return {"txHash": response.json().get("data", {}).get("userOpHash", "")}
|
136
138
|
|
137
|
-
except Exception as
|
138
|
-
raise
|
139
|
+
except Exception as e:
|
140
|
+
raise
|
139
141
|
|
140
142
|
def approve_allowance(self, price_in_wei: int) -> str:
|
141
143
|
try:
|
@@ -158,8 +160,9 @@ class AcpToken:
|
|
158
160
|
raise Exception(f"Failed to approve allowance {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
159
161
|
|
160
162
|
return response.json()
|
161
|
-
except Exception as
|
162
|
-
|
163
|
+
except Exception as e:
|
164
|
+
print(f"An error occurred while approving allowance: {e}")
|
165
|
+
raise
|
163
166
|
|
164
167
|
def create_memo(
|
165
168
|
self,
|
@@ -170,6 +173,7 @@ class AcpToken:
|
|
170
173
|
next_phase: int
|
171
174
|
) -> dict:
|
172
175
|
retries = 3
|
176
|
+
error = None
|
173
177
|
while retries > 0:
|
174
178
|
try:
|
175
179
|
trx_data, signature = self._sign_transaction(
|
@@ -190,12 +194,15 @@ class AcpToken:
|
|
190
194
|
raise Exception(f"Failed to create memo {response.json().get('error').get('status')}, Message: {response.json().get('error').get('message')}")
|
191
195
|
|
192
196
|
return { "txHash": response.json().get("txHash", response.json().get("id", "")), "memoId": response.json().get("memoId", "")}
|
193
|
-
except Exception as
|
194
|
-
print(f"{
|
197
|
+
except Exception as e:
|
198
|
+
print(f"{e}")
|
199
|
+
print(traceback.format_exc())
|
200
|
+
error = e
|
195
201
|
retries -= 1
|
196
202
|
time.sleep(2 * (3 - retries))
|
197
203
|
|
198
|
-
|
204
|
+
if error:
|
205
|
+
raise Exception(f"{error}")
|
199
206
|
|
200
207
|
def _sign_transaction(self, method_name: str, args: list, contract_address: Optional[str] = None) -> Tuple[dict, str]:
|
201
208
|
if contract_address:
|
@@ -225,6 +232,7 @@ class AcpToken:
|
|
225
232
|
reason: Optional[str] = ""
|
226
233
|
) -> str:
|
227
234
|
retries = 3
|
235
|
+
error = None
|
228
236
|
while retries > 0:
|
229
237
|
try:
|
230
238
|
trx_data, signature = self._sign_transaction(
|
@@ -246,8 +254,10 @@ class AcpToken:
|
|
246
254
|
|
247
255
|
return response.json()
|
248
256
|
|
249
|
-
except Exception as
|
257
|
+
except Exception as e:
|
258
|
+
error = e
|
250
259
|
print(f"{error}")
|
260
|
+
print(traceback.format_exc())
|
251
261
|
retries -= 1
|
252
262
|
time.sleep(2 * (3 - retries))
|
253
263
|
|
acp_plugin_gamesdk/interface.py
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
2
|
from enum import IntEnum, Enum
|
3
|
-
from typing import List,
|
3
|
+
from typing import List, Literal, Optional
|
4
4
|
|
5
5
|
@dataclass
|
6
6
|
class AcpOffering:
|
7
7
|
name: str
|
8
8
|
price: float
|
9
|
+
|
10
|
+
def __str__(self) -> str:
|
11
|
+
output = (
|
12
|
+
f"Offering(name={self.name}, price={self.price})"
|
13
|
+
)
|
14
|
+
return output
|
15
|
+
|
9
16
|
@dataclass
|
10
17
|
class AcpAgent:
|
11
18
|
id: str
|
@@ -13,6 +20,23 @@ class AcpAgent:
|
|
13
20
|
description: str
|
14
21
|
wallet_address: str
|
15
22
|
offerings: Optional[List[AcpOffering]]
|
23
|
+
score: Optional[float]
|
24
|
+
explanation: Optional[str]
|
25
|
+
|
26
|
+
def __str__(self) -> str:
|
27
|
+
offer = ""
|
28
|
+
if self.offerings:
|
29
|
+
for index, off in enumerate(self.offerings):
|
30
|
+
offer += f"{index+1}. {str(off)}\n"
|
31
|
+
|
32
|
+
output = (
|
33
|
+
f"😎 Agent ID={self.id}\n"
|
34
|
+
f"Name={self.name}, Description={self.description}, Wallet={self.wallet_address}\n"
|
35
|
+
f"Offerings:\n{offer}"
|
36
|
+
f"Score:\n{self.score}"
|
37
|
+
f"Explanation:\n{self.explanation}"
|
38
|
+
)
|
39
|
+
return output
|
16
40
|
|
17
41
|
class AcpJobPhases(IntEnum):
|
18
42
|
REQUEST = 0
|
@@ -33,7 +57,11 @@ class AcpJobPhasesDesc(str, Enum):
|
|
33
57
|
@dataclass
|
34
58
|
class AcpRequestMemo:
|
35
59
|
id: int
|
36
|
-
|
60
|
+
createdAt: int
|
61
|
+
|
62
|
+
def __repr__(self) -> str:
|
63
|
+
output = f"Memo(ID: {self.id}, created at: {self.createdAt})"
|
64
|
+
return output
|
37
65
|
|
38
66
|
@dataclass
|
39
67
|
class ITweet:
|
@@ -41,29 +69,59 @@ class ITweet:
|
|
41
69
|
tweet_id: str
|
42
70
|
content: str
|
43
71
|
created_at: int
|
72
|
+
|
44
73
|
@dataclass
|
45
74
|
class AcpJob:
|
46
|
-
|
75
|
+
jobId: Optional[int]
|
47
76
|
desc: str
|
48
77
|
price: str
|
49
78
|
phase: AcpJobPhasesDesc
|
50
79
|
memo: List[AcpRequestMemo]
|
51
|
-
|
52
|
-
|
80
|
+
lastUpdated: int
|
81
|
+
tweetHistory : ITweet | List
|
82
|
+
lastUpdated: int
|
83
|
+
|
84
|
+
def __repr__(self) -> str:
|
85
|
+
output =(
|
86
|
+
f"Job ID: {self.jobId}, "
|
87
|
+
f"Description: {self.desc}, "
|
88
|
+
f"Price: {self.price}, "
|
89
|
+
f"Phase: {self.phase.value}, "
|
90
|
+
f"Memo: {self.memo}, "
|
91
|
+
f"Last Updated: {self.lastUpdated})"
|
92
|
+
f"Tweet History: {self.tweetHistory}, "
|
93
|
+
f"Last Updated: {self.lastUpdated})"
|
94
|
+
)
|
95
|
+
return output
|
53
96
|
|
54
97
|
@dataclass
|
55
98
|
class IDeliverable:
|
56
|
-
type:
|
99
|
+
type: str
|
57
100
|
value: str
|
58
101
|
|
59
102
|
@dataclass
|
60
103
|
class IInventory(IDeliverable):
|
61
|
-
|
104
|
+
jobId: int
|
62
105
|
|
63
106
|
@dataclass
|
64
107
|
class AcpJobsSection:
|
65
|
-
|
66
|
-
|
108
|
+
asABuyer: List[AcpJob]
|
109
|
+
asASeller: List[AcpJob]
|
110
|
+
|
111
|
+
def __str__(self) -> str:
|
112
|
+
buyer_jobs = ""
|
113
|
+
for index, job in enumerate(self.asABuyer):
|
114
|
+
buyer_jobs += f"#{index+1} {str(job)} \n"
|
115
|
+
|
116
|
+
seller_jobs = ""
|
117
|
+
for index, job in enumerate(self.asASeller):
|
118
|
+
seller_jobs += f"#{index+1} {str(job)} \n"
|
119
|
+
|
120
|
+
output = (
|
121
|
+
f"As Buyer:\n{buyer_jobs}\n"
|
122
|
+
f"As Seller:\n{seller_jobs}\n"
|
123
|
+
)
|
124
|
+
return output
|
67
125
|
|
68
126
|
@dataclass
|
69
127
|
class AcpJobs:
|
@@ -71,12 +129,38 @@ class AcpJobs:
|
|
71
129
|
completed: List[AcpJob]
|
72
130
|
cancelled: List[AcpJob]
|
73
131
|
|
132
|
+
def __str__(self) -> str:
|
133
|
+
output = (
|
134
|
+
f"💻 Jobs\n"
|
135
|
+
f"🌕 Active Jobs:\n{self.active}\n"
|
136
|
+
f"🟢 Completed:\n{self.completed}\n"
|
137
|
+
f"🔴 Cancelled:\n{self.cancelled}\n"
|
138
|
+
)
|
139
|
+
return output
|
140
|
+
|
74
141
|
@dataclass
|
75
142
|
class AcpInventory:
|
76
|
-
|
77
|
-
produced: List[IInventory]
|
143
|
+
acquired: List[IInventory]
|
144
|
+
produced: Optional[List[IInventory]]
|
145
|
+
|
146
|
+
def __str__(self) -> str:
|
147
|
+
output = (
|
148
|
+
f"💼 Inventory\n"
|
149
|
+
f"Acquired: {self.acquired}\n"
|
150
|
+
f"Produced: {self.produced}\n"
|
151
|
+
)
|
152
|
+
return output
|
78
153
|
|
79
154
|
@dataclass
|
80
155
|
class AcpState:
|
81
156
|
inventory: AcpInventory
|
82
157
|
jobs: AcpJobs
|
158
|
+
|
159
|
+
def __str__(self) -> str:
|
160
|
+
output = (
|
161
|
+
f"🤖 Agent State".center(50, '=') + "\n" + \
|
162
|
+
f"{str(self.inventory)}\n" + \
|
163
|
+
f"{str(self.jobs)}\n" + \
|
164
|
+
f"State End".center(50, '=') + "\n"
|
165
|
+
)
|
166
|
+
return output
|
@@ -1,23 +1,26 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: acp-plugin-gamesdk
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.8
|
4
4
|
Summary: ACP Plugin for Python SDK for GAME by Virtuals
|
5
5
|
Author: Steven Lee Soon Fatt
|
6
6
|
Author-email: steven@virtuals.io
|
7
|
-
Requires-Python: >=3.
|
7
|
+
Requires-Python: >=3.9,<3.13
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
9
10
|
Classifier: Programming Language :: Python :: 3.10
|
10
11
|
Classifier: Programming Language :: Python :: 3.11
|
11
12
|
Classifier: Programming Language :: Python :: 3.12
|
12
|
-
Classifier: Programming Language :: Python :: 3.13
|
13
13
|
Requires-Dist: aiohttp (>=3.11.14,<4.0.0)
|
14
|
+
Requires-Dist: dacite (>=1.9.2,<2.0.0)
|
14
15
|
Requires-Dist: eth-account (>=0.13.6,<0.14.0)
|
15
16
|
Requires-Dist: eth-typing (>=5.2.0,<6.0.0)
|
16
17
|
Requires-Dist: eth-utils (>=5.2.0,<6.0.0)
|
17
18
|
Requires-Dist: game-sdk (>=0.1.5)
|
18
19
|
Requires-Dist: pydantic (>=2.10.6,<3.0.0)
|
20
|
+
Requires-Dist: python-dotenv (>=1.1.0,<2.0.0)
|
19
21
|
Requires-Dist: python-socketio (>=5.11.1,<6.0.0)
|
20
22
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
23
|
+
Requires-Dist: rich (>=14.0.0,<15.0.0)
|
21
24
|
Requires-Dist: twitter-plugin-gamesdk (>=0.2.2)
|
22
25
|
Requires-Dist: virtuals-sdk (>=0.1.6,<0.2.0)
|
23
26
|
Requires-Dist: web3 (>=7.9.0,<8.0.0)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
acp_plugin_gamesdk/acp_client.py,sha256=zF-FLFJ2PbS3LeI3cDx63pJyWCAVb8YQn7yZHQQ9wtY,9254
|
2
|
+
acp_plugin_gamesdk/acp_plugin.py,sha256=pFQ9QzGvs8EQ8kAkC_VAqc2tSTu9knueOBcK51oy9rk,28262
|
3
|
+
acp_plugin_gamesdk/acp_token.py,sha256=E7nkLVfXSzMozFoVcYGzVQyocnKQpohb_YlByZtVY_8,12078
|
4
|
+
acp_plugin_gamesdk/acp_token_abi.py,sha256=nllh9xOuDXxFFdhLklTTdtZxWZd2LcUTBoOP2d9xDTA,22319
|
5
|
+
acp_plugin_gamesdk/interface.py,sha256=TsNQ74qW80YcUESOmBWX0wWzCTXG7S9eSF1mnfoJj0U,3983
|
6
|
+
acp_plugin_gamesdk-0.1.8.dist-info/METADATA,sha256=hh41VpuRlSke7KOjtp3Tbv9rlX29q7VNIIc0_Gh19eU,12223
|
7
|
+
acp_plugin_gamesdk-0.1.8.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
8
|
+
acp_plugin_gamesdk-0.1.8.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
acp_plugin_gamesdk/acp_client.py,sha256=juFDXMaRUAMhf1ullsDC0_krxPBNr80JDZ7eXiBVDls,8925
|
2
|
-
acp_plugin_gamesdk/acp_plugin.py,sha256=NkKjuEQZ5L3KD1GcuiUen8Q2nOewpj28p1IGoIwA5NI,27038
|
3
|
-
acp_plugin_gamesdk/acp_token.py,sha256=Wx87e2Wd-5QUKoMWX_wf3IBEP-cl1pSyA9IZr1yYIDE,11796
|
4
|
-
acp_plugin_gamesdk/acp_token_abi.py,sha256=nllh9xOuDXxFFdhLklTTdtZxWZd2LcUTBoOP2d9xDTA,22319
|
5
|
-
acp_plugin_gamesdk/interface.py,sha256=mWZ41SycGrNQbnC_IfBq8K6TgpguCvvbVTqFg8Uxy58,1549
|
6
|
-
acp_plugin_gamesdk-0.1.7.dist-info/METADATA,sha256=Z0qpNdTJG32s_Yl9zceDYWrkX08HGxqTYXBQde8ziMA,12098
|
7
|
-
acp_plugin_gamesdk-0.1.7.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
8
|
-
acp_plugin_gamesdk-0.1.7.dist-info/RECORD,,
|
File without changes
|