prediction-market-agent-tooling 0.65.9__py3-none-any.whl → 0.65.10__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.
@@ -0,0 +1,634 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ {
5
+ "internalType": "address",
6
+ "name": "_factory",
7
+ "type": "address"
8
+ },
9
+ {
10
+ "internalType": "address",
11
+ "name": "_WNativeToken",
12
+ "type": "address"
13
+ },
14
+ {
15
+ "internalType": "address",
16
+ "name": "_poolDeployer",
17
+ "type": "address"
18
+ }
19
+ ],
20
+ "stateMutability": "nonpayable",
21
+ "type": "constructor"
22
+ },
23
+ {
24
+ "inputs": [],
25
+ "name": "WNativeToken",
26
+ "outputs": [
27
+ {
28
+ "internalType": "address",
29
+ "name": "",
30
+ "type": "address"
31
+ }
32
+ ],
33
+ "stateMutability": "view",
34
+ "type": "function"
35
+ },
36
+ {
37
+ "inputs": [
38
+ {
39
+ "internalType": "int256",
40
+ "name": "amount0Delta",
41
+ "type": "int256"
42
+ },
43
+ {
44
+ "internalType": "int256",
45
+ "name": "amount1Delta",
46
+ "type": "int256"
47
+ },
48
+ {
49
+ "internalType": "bytes",
50
+ "name": "_data",
51
+ "type": "bytes"
52
+ }
53
+ ],
54
+ "name": "algebraSwapCallback",
55
+ "outputs": [],
56
+ "stateMutability": "nonpayable",
57
+ "type": "function"
58
+ },
59
+ {
60
+ "inputs": [
61
+ {
62
+ "components": [
63
+ {
64
+ "internalType": "bytes",
65
+ "name": "path",
66
+ "type": "bytes"
67
+ },
68
+ {
69
+ "internalType": "address",
70
+ "name": "recipient",
71
+ "type": "address"
72
+ },
73
+ {
74
+ "internalType": "uint256",
75
+ "name": "deadline",
76
+ "type": "uint256"
77
+ },
78
+ {
79
+ "internalType": "uint256",
80
+ "name": "amountIn",
81
+ "type": "uint256"
82
+ },
83
+ {
84
+ "internalType": "uint256",
85
+ "name": "amountOutMinimum",
86
+ "type": "uint256"
87
+ }
88
+ ],
89
+ "internalType": "struct ISwapRouter.ExactInputParams",
90
+ "name": "params",
91
+ "type": "tuple"
92
+ }
93
+ ],
94
+ "name": "exactInput",
95
+ "outputs": [
96
+ {
97
+ "internalType": "uint256",
98
+ "name": "amountOut",
99
+ "type": "uint256"
100
+ }
101
+ ],
102
+ "stateMutability": "payable",
103
+ "type": "function"
104
+ },
105
+ {
106
+ "inputs": [
107
+ {
108
+ "components": [
109
+ {
110
+ "internalType": "address",
111
+ "name": "tokenIn",
112
+ "type": "address"
113
+ },
114
+ {
115
+ "internalType": "address",
116
+ "name": "tokenOut",
117
+ "type": "address"
118
+ },
119
+ {
120
+ "internalType": "address",
121
+ "name": "recipient",
122
+ "type": "address"
123
+ },
124
+ {
125
+ "internalType": "uint256",
126
+ "name": "deadline",
127
+ "type": "uint256"
128
+ },
129
+ {
130
+ "internalType": "uint256",
131
+ "name": "amountIn",
132
+ "type": "uint256"
133
+ },
134
+ {
135
+ "internalType": "uint256",
136
+ "name": "amountOutMinimum",
137
+ "type": "uint256"
138
+ },
139
+ {
140
+ "internalType": "uint160",
141
+ "name": "limitSqrtPrice",
142
+ "type": "uint160"
143
+ }
144
+ ],
145
+ "internalType": "struct ISwapRouter.ExactInputSingleParams",
146
+ "name": "params",
147
+ "type": "tuple"
148
+ }
149
+ ],
150
+ "name": "exactInputSingle",
151
+ "outputs": [
152
+ {
153
+ "internalType": "uint256",
154
+ "name": "amountOut",
155
+ "type": "uint256"
156
+ }
157
+ ],
158
+ "stateMutability": "payable",
159
+ "type": "function"
160
+ },
161
+ {
162
+ "inputs": [
163
+ {
164
+ "components": [
165
+ {
166
+ "internalType": "address",
167
+ "name": "tokenIn",
168
+ "type": "address"
169
+ },
170
+ {
171
+ "internalType": "address",
172
+ "name": "tokenOut",
173
+ "type": "address"
174
+ },
175
+ {
176
+ "internalType": "address",
177
+ "name": "recipient",
178
+ "type": "address"
179
+ },
180
+ {
181
+ "internalType": "uint256",
182
+ "name": "deadline",
183
+ "type": "uint256"
184
+ },
185
+ {
186
+ "internalType": "uint256",
187
+ "name": "amountIn",
188
+ "type": "uint256"
189
+ },
190
+ {
191
+ "internalType": "uint256",
192
+ "name": "amountOutMinimum",
193
+ "type": "uint256"
194
+ },
195
+ {
196
+ "internalType": "uint160",
197
+ "name": "limitSqrtPrice",
198
+ "type": "uint160"
199
+ }
200
+ ],
201
+ "internalType": "struct ISwapRouter.ExactInputSingleParams",
202
+ "name": "params",
203
+ "type": "tuple"
204
+ }
205
+ ],
206
+ "name": "exactInputSingleSupportingFeeOnTransferTokens",
207
+ "outputs": [
208
+ {
209
+ "internalType": "uint256",
210
+ "name": "amountOut",
211
+ "type": "uint256"
212
+ }
213
+ ],
214
+ "stateMutability": "nonpayable",
215
+ "type": "function"
216
+ },
217
+ {
218
+ "inputs": [
219
+ {
220
+ "components": [
221
+ {
222
+ "internalType": "bytes",
223
+ "name": "path",
224
+ "type": "bytes"
225
+ },
226
+ {
227
+ "internalType": "address",
228
+ "name": "recipient",
229
+ "type": "address"
230
+ },
231
+ {
232
+ "internalType": "uint256",
233
+ "name": "deadline",
234
+ "type": "uint256"
235
+ },
236
+ {
237
+ "internalType": "uint256",
238
+ "name": "amountOut",
239
+ "type": "uint256"
240
+ },
241
+ {
242
+ "internalType": "uint256",
243
+ "name": "amountInMaximum",
244
+ "type": "uint256"
245
+ }
246
+ ],
247
+ "internalType": "struct ISwapRouter.ExactOutputParams",
248
+ "name": "params",
249
+ "type": "tuple"
250
+ }
251
+ ],
252
+ "name": "exactOutput",
253
+ "outputs": [
254
+ {
255
+ "internalType": "uint256",
256
+ "name": "amountIn",
257
+ "type": "uint256"
258
+ }
259
+ ],
260
+ "stateMutability": "payable",
261
+ "type": "function"
262
+ },
263
+ {
264
+ "inputs": [
265
+ {
266
+ "components": [
267
+ {
268
+ "internalType": "address",
269
+ "name": "tokenIn",
270
+ "type": "address"
271
+ },
272
+ {
273
+ "internalType": "address",
274
+ "name": "tokenOut",
275
+ "type": "address"
276
+ },
277
+ {
278
+ "internalType": "uint24",
279
+ "name": "fee",
280
+ "type": "uint24"
281
+ },
282
+ {
283
+ "internalType": "address",
284
+ "name": "recipient",
285
+ "type": "address"
286
+ },
287
+ {
288
+ "internalType": "uint256",
289
+ "name": "deadline",
290
+ "type": "uint256"
291
+ },
292
+ {
293
+ "internalType": "uint256",
294
+ "name": "amountOut",
295
+ "type": "uint256"
296
+ },
297
+ {
298
+ "internalType": "uint256",
299
+ "name": "amountInMaximum",
300
+ "type": "uint256"
301
+ },
302
+ {
303
+ "internalType": "uint160",
304
+ "name": "limitSqrtPrice",
305
+ "type": "uint160"
306
+ }
307
+ ],
308
+ "internalType": "struct ISwapRouter.ExactOutputSingleParams",
309
+ "name": "params",
310
+ "type": "tuple"
311
+ }
312
+ ],
313
+ "name": "exactOutputSingle",
314
+ "outputs": [
315
+ {
316
+ "internalType": "uint256",
317
+ "name": "amountIn",
318
+ "type": "uint256"
319
+ }
320
+ ],
321
+ "stateMutability": "payable",
322
+ "type": "function"
323
+ },
324
+ {
325
+ "inputs": [],
326
+ "name": "factory",
327
+ "outputs": [
328
+ {
329
+ "internalType": "address",
330
+ "name": "",
331
+ "type": "address"
332
+ }
333
+ ],
334
+ "stateMutability": "view",
335
+ "type": "function"
336
+ },
337
+ {
338
+ "inputs": [
339
+ {
340
+ "internalType": "bytes[]",
341
+ "name": "data",
342
+ "type": "bytes[]"
343
+ }
344
+ ],
345
+ "name": "multicall",
346
+ "outputs": [
347
+ {
348
+ "internalType": "bytes[]",
349
+ "name": "results",
350
+ "type": "bytes[]"
351
+ }
352
+ ],
353
+ "stateMutability": "payable",
354
+ "type": "function"
355
+ },
356
+ {
357
+ "inputs": [],
358
+ "name": "poolDeployer",
359
+ "outputs": [
360
+ {
361
+ "internalType": "address",
362
+ "name": "",
363
+ "type": "address"
364
+ }
365
+ ],
366
+ "stateMutability": "view",
367
+ "type": "function"
368
+ },
369
+ {
370
+ "inputs": [],
371
+ "name": "refundNativeToken",
372
+ "outputs": [],
373
+ "stateMutability": "payable",
374
+ "type": "function"
375
+ },
376
+ {
377
+ "inputs": [
378
+ {
379
+ "internalType": "address",
380
+ "name": "token",
381
+ "type": "address"
382
+ },
383
+ {
384
+ "internalType": "uint256",
385
+ "name": "value",
386
+ "type": "uint256"
387
+ },
388
+ {
389
+ "internalType": "uint256",
390
+ "name": "deadline",
391
+ "type": "uint256"
392
+ },
393
+ {
394
+ "internalType": "uint8",
395
+ "name": "v",
396
+ "type": "uint8"
397
+ },
398
+ {
399
+ "internalType": "bytes32",
400
+ "name": "r",
401
+ "type": "bytes32"
402
+ },
403
+ {
404
+ "internalType": "bytes32",
405
+ "name": "s",
406
+ "type": "bytes32"
407
+ }
408
+ ],
409
+ "name": "selfPermit",
410
+ "outputs": [],
411
+ "stateMutability": "payable",
412
+ "type": "function"
413
+ },
414
+ {
415
+ "inputs": [
416
+ {
417
+ "internalType": "address",
418
+ "name": "token",
419
+ "type": "address"
420
+ },
421
+ {
422
+ "internalType": "uint256",
423
+ "name": "nonce",
424
+ "type": "uint256"
425
+ },
426
+ {
427
+ "internalType": "uint256",
428
+ "name": "expiry",
429
+ "type": "uint256"
430
+ },
431
+ {
432
+ "internalType": "uint8",
433
+ "name": "v",
434
+ "type": "uint8"
435
+ },
436
+ {
437
+ "internalType": "bytes32",
438
+ "name": "r",
439
+ "type": "bytes32"
440
+ },
441
+ {
442
+ "internalType": "bytes32",
443
+ "name": "s",
444
+ "type": "bytes32"
445
+ }
446
+ ],
447
+ "name": "selfPermitAllowed",
448
+ "outputs": [],
449
+ "stateMutability": "payable",
450
+ "type": "function"
451
+ },
452
+ {
453
+ "inputs": [
454
+ {
455
+ "internalType": "address",
456
+ "name": "token",
457
+ "type": "address"
458
+ },
459
+ {
460
+ "internalType": "uint256",
461
+ "name": "nonce",
462
+ "type": "uint256"
463
+ },
464
+ {
465
+ "internalType": "uint256",
466
+ "name": "expiry",
467
+ "type": "uint256"
468
+ },
469
+ {
470
+ "internalType": "uint8",
471
+ "name": "v",
472
+ "type": "uint8"
473
+ },
474
+ {
475
+ "internalType": "bytes32",
476
+ "name": "r",
477
+ "type": "bytes32"
478
+ },
479
+ {
480
+ "internalType": "bytes32",
481
+ "name": "s",
482
+ "type": "bytes32"
483
+ }
484
+ ],
485
+ "name": "selfPermitAllowedIfNecessary",
486
+ "outputs": [],
487
+ "stateMutability": "payable",
488
+ "type": "function"
489
+ },
490
+ {
491
+ "inputs": [
492
+ {
493
+ "internalType": "address",
494
+ "name": "token",
495
+ "type": "address"
496
+ },
497
+ {
498
+ "internalType": "uint256",
499
+ "name": "value",
500
+ "type": "uint256"
501
+ },
502
+ {
503
+ "internalType": "uint256",
504
+ "name": "deadline",
505
+ "type": "uint256"
506
+ },
507
+ {
508
+ "internalType": "uint8",
509
+ "name": "v",
510
+ "type": "uint8"
511
+ },
512
+ {
513
+ "internalType": "bytes32",
514
+ "name": "r",
515
+ "type": "bytes32"
516
+ },
517
+ {
518
+ "internalType": "bytes32",
519
+ "name": "s",
520
+ "type": "bytes32"
521
+ }
522
+ ],
523
+ "name": "selfPermitIfNecessary",
524
+ "outputs": [],
525
+ "stateMutability": "payable",
526
+ "type": "function"
527
+ },
528
+ {
529
+ "inputs": [
530
+ {
531
+ "internalType": "address",
532
+ "name": "token",
533
+ "type": "address"
534
+ },
535
+ {
536
+ "internalType": "uint256",
537
+ "name": "amountMinimum",
538
+ "type": "uint256"
539
+ },
540
+ {
541
+ "internalType": "address",
542
+ "name": "recipient",
543
+ "type": "address"
544
+ }
545
+ ],
546
+ "name": "sweepToken",
547
+ "outputs": [],
548
+ "stateMutability": "payable",
549
+ "type": "function"
550
+ },
551
+ {
552
+ "inputs": [
553
+ {
554
+ "internalType": "address",
555
+ "name": "token",
556
+ "type": "address"
557
+ },
558
+ {
559
+ "internalType": "uint256",
560
+ "name": "amountMinimum",
561
+ "type": "uint256"
562
+ },
563
+ {
564
+ "internalType": "address",
565
+ "name": "recipient",
566
+ "type": "address"
567
+ },
568
+ {
569
+ "internalType": "uint256",
570
+ "name": "feeBips",
571
+ "type": "uint256"
572
+ },
573
+ {
574
+ "internalType": "address",
575
+ "name": "feeRecipient",
576
+ "type": "address"
577
+ }
578
+ ],
579
+ "name": "sweepTokenWithFee",
580
+ "outputs": [],
581
+ "stateMutability": "payable",
582
+ "type": "function"
583
+ },
584
+ {
585
+ "inputs": [
586
+ {
587
+ "internalType": "uint256",
588
+ "name": "amountMinimum",
589
+ "type": "uint256"
590
+ },
591
+ {
592
+ "internalType": "address",
593
+ "name": "recipient",
594
+ "type": "address"
595
+ }
596
+ ],
597
+ "name": "unwrapWNativeToken",
598
+ "outputs": [],
599
+ "stateMutability": "payable",
600
+ "type": "function"
601
+ },
602
+ {
603
+ "inputs": [
604
+ {
605
+ "internalType": "uint256",
606
+ "name": "amountMinimum",
607
+ "type": "uint256"
608
+ },
609
+ {
610
+ "internalType": "address",
611
+ "name": "recipient",
612
+ "type": "address"
613
+ },
614
+ {
615
+ "internalType": "uint256",
616
+ "name": "feeBips",
617
+ "type": "uint256"
618
+ },
619
+ {
620
+ "internalType": "address",
621
+ "name": "feeRecipient",
622
+ "type": "address"
623
+ }
624
+ ],
625
+ "name": "unwrapWNativeTokenWithFee",
626
+ "outputs": [],
627
+ "stateMutability": "payable",
628
+ "type": "function"
629
+ },
630
+ {
631
+ "stateMutability": "payable",
632
+ "type": "receive"
633
+ }
634
+ ]
@@ -456,4 +456,4 @@ class Benchmarker:
456
456
  md += "\n\n"
457
457
  md += "### Markets\n\n"
458
458
  md += pd.DataFrame(self.get_markets_summary()).to_markdown(index=False)
459
- return md
459
+ return str(md)
@@ -1,4 +1,5 @@
1
1
  import typing as t
2
+ from datetime import timedelta
2
3
  from urllib.parse import urljoin
3
4
 
4
5
  from pydantic import BaseModel, ConfigDict, Field
@@ -13,12 +14,14 @@ from prediction_market_agent_tooling.gtypes import (
13
14
  OutcomeStr,
14
15
  OutcomeWei,
15
16
  Web3Wei,
17
+ Wei,
16
18
  )
17
19
  from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
18
20
  SeerParentMarket,
19
21
  )
20
22
  from prediction_market_agent_tooling.tools.contract import ContractERC20OnGnosisChain
21
23
  from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
24
+ from prediction_market_agent_tooling.tools.utils import utcnow
22
25
 
23
26
 
24
27
  class CreateCategoricalMarketsParams(BaseModel):
@@ -133,3 +136,19 @@ class RedeemParams(BaseModel):
133
136
  market: ChecksumAddress
134
137
  outcome_indices: list[int] = Field(alias="outcomeIndexes")
135
138
  amounts: list[OutcomeWei]
139
+
140
+
141
+ class ExactInputSingleParams(BaseModel):
142
+ # from https://gnosisscan.io/address/0xffb643e73f280b97809a8b41f7232ab401a04ee1#code
143
+ model_config = ConfigDict(populate_by_name=True)
144
+ token_in: ChecksumAddress = Field(alias="tokenIn")
145
+ token_out: ChecksumAddress = Field(alias="tokenOut")
146
+ recipient: ChecksumAddress
147
+ deadline: int = Field(
148
+ default_factory=lambda: int((utcnow() + timedelta(minutes=10)).timestamp())
149
+ )
150
+ amount_in: Wei = Field(alias="amountIn")
151
+ amount_out_minimum: Wei = Field(alias="amountOutMinimum")
152
+ limit_sqrt_price: Wei = Field(
153
+ alias="limitSqrtPrice", default_factory=lambda: Wei(0)
154
+ ) # 0 for convenience, we also don't expect major price shifts
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import typing as t
2
3
  from datetime import timedelta
3
4
 
@@ -15,6 +16,7 @@ from prediction_market_agent_tooling.gtypes import (
15
16
  OutcomeStr,
16
17
  OutcomeToken,
17
18
  OutcomeWei,
19
+ Wei,
18
20
  xDai,
19
21
  )
20
22
  from prediction_market_agent_tooling.loggers import logger
@@ -46,16 +48,21 @@ from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
46
48
  from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
47
49
  NewMarketEvent,
48
50
  )
51
+ from prediction_market_agent_tooling.markets.seer.swap_pool_handler import (
52
+ SwapPoolHandler,
53
+ )
49
54
  from prediction_market_agent_tooling.tools.contract import (
50
55
  ContractERC20OnGnosisChain,
51
56
  init_collateral_token_contract,
52
57
  to_gnosis_chain_contract,
53
58
  )
54
59
  from prediction_market_agent_tooling.tools.cow.cow_order import (
60
+ cancel_order,
55
61
  get_buy_token_amount_else_raise,
56
62
  get_orders_by_owner,
57
63
  get_trades_by_owner,
58
64
  swap_tokens_waiting,
65
+ wait_for_order_completion,
59
66
  )
60
67
  from prediction_market_agent_tooling.tools.datetime_utc import DatetimeUTC
61
68
  from prediction_market_agent_tooling.tools.tokens.auto_deposit import (
@@ -441,6 +448,60 @@ class SeerAgentMarket(AgentMarket):
441
448
  outcome_idx = self.outcomes.index(outcome)
442
449
  return self.wrapped_tokens[outcome_idx]
443
450
 
451
+ def _swap_tokens_with_fallback(
452
+ self,
453
+ sell_token: ChecksumAddress,
454
+ buy_token: ChecksumAddress,
455
+ amount_wei: Wei,
456
+ api_keys: APIKeys,
457
+ web3: Web3 | None,
458
+ ) -> str:
459
+ """
460
+ Helper method to swap tokens with a fallback to direct pool swapping if the order times out.
461
+
462
+ Args:
463
+ sell_token: Address of the token to sell
464
+ buy_token: Address of the token to buy
465
+ amount_wei: Amount to swap in wei
466
+ api_keys: API keys for the transaction
467
+ web3: Web3 instance
468
+
469
+ Returns:
470
+ Transaction hash of the successful swap
471
+ """
472
+ _, order = swap_tokens_waiting(
473
+ amount_wei=amount_wei,
474
+ sell_token=sell_token,
475
+ buy_token=buy_token,
476
+ api_keys=api_keys,
477
+ web3=web3,
478
+ wait_order_complete=False,
479
+ )
480
+
481
+ try:
482
+ order_metadata = asyncio.run(wait_for_order_completion(order=order))
483
+ logger.debug(
484
+ f"Swapped {sell_token} for {buy_token}. Order details {order_metadata}"
485
+ )
486
+ return order_metadata.uid.root
487
+
488
+ except TimeoutError:
489
+ # Since timeout occurred, we need to cancel the order before trying to swap again.
490
+ asyncio.run(cancel_order(order_uids=[order.uid.root], api_keys=api_keys))
491
+ logger.info("TimeoutError. Trying to swap directly on Swapr pools.")
492
+
493
+ tx_receipt = SwapPoolHandler(
494
+ api_keys=api_keys,
495
+ market_id=self.id,
496
+ collateral_token_address=self.collateral_token_contract_address_checksummed,
497
+ ).buy_or_sell_outcome_token(
498
+ token_in=sell_token,
499
+ token_out=buy_token,
500
+ amount_wei=amount_wei,
501
+ web3=web3,
502
+ )
503
+ return tx_receipt["transactionHash"].hex()
504
+
444
505
  def place_bet(
445
506
  self,
446
507
  outcome: OutcomeStr,
@@ -449,6 +510,7 @@ class SeerAgentMarket(AgentMarket):
449
510
  web3: Web3 | None = None,
450
511
  api_keys: APIKeys | None = None,
451
512
  ) -> str:
513
+ outcome_token = self.get_wrapped_token_for_outcome(outcome)
452
514
  api_keys = api_keys if api_keys is not None else APIKeys()
453
515
  if not self.can_be_traded():
454
516
  raise ValueError(
@@ -464,27 +526,21 @@ class SeerAgentMarket(AgentMarket):
464
526
  collateral_contract, amount_wei, api_keys, web3
465
527
  )
466
528
 
467
- collateral_balance = collateral_contract.balanceOf(api_keys.bet_from_address)
529
+ collateral_balance = collateral_contract.balanceOf(
530
+ api_keys.bet_from_address, web3=web3
531
+ )
468
532
  if collateral_balance < amount_wei:
469
533
  raise ValueError(
470
534
  f"Balance {collateral_balance} not enough for bet size {amount}"
471
535
  )
472
536
 
473
- outcome_token = self.get_wrapped_token_for_outcome(outcome)
474
-
475
- # Sell sDAI using token address
476
- order_metadata = swap_tokens_waiting(
477
- amount_wei=amount_wei,
537
+ return self._swap_tokens_with_fallback(
478
538
  sell_token=collateral_contract.address,
479
539
  buy_token=outcome_token,
540
+ amount_wei=amount_wei,
480
541
  api_keys=api_keys,
481
542
  web3=web3,
482
543
  )
483
- logger.debug(
484
- f"Purchased {outcome_token} in exchange for {collateral_contract.address}. Order details {order_metadata}"
485
- )
486
-
487
- return order_metadata.uid.root
488
544
 
489
545
  def sell_tokens(
490
546
  self,
@@ -506,21 +562,27 @@ class SeerAgentMarket(AgentMarket):
506
562
  else self.get_in_token(amount).as_wei
507
563
  )
508
564
 
509
- order_metadata = swap_tokens_waiting(
510
- amount_wei=token_amount,
565
+ return self._swap_tokens_with_fallback(
511
566
  sell_token=outcome_token,
512
567
  buy_token=Web3.to_checksum_address(
513
568
  self.collateral_token_contract_address_checksummed
514
569
  ),
570
+ amount_wei=token_amount,
515
571
  api_keys=api_keys,
516
572
  web3=web3,
517
573
  )
518
574
 
519
- logger.debug(
520
- f"Sold {outcome_token} in exchange for {self.collateral_token_contract_address_checksummed}. Order details {order_metadata}"
575
+ def get_token_balance(
576
+ self, user_id: str, outcome: OutcomeStr, web3: Web3 | None = None
577
+ ) -> OutcomeToken:
578
+ erc20_token = ContractERC20OnGnosisChain(
579
+ address=self.get_wrapped_token_for_outcome(outcome)
580
+ )
581
+ return OutcomeToken.from_token(
582
+ erc20_token.balance_of_in_tokens(
583
+ for_address=Web3.to_checksum_address(user_id), web3=web3
584
+ )
521
585
  )
522
-
523
- return order_metadata.uid.root
524
586
 
525
587
 
526
588
  def seer_create_market_tx(
@@ -11,11 +11,15 @@ from prediction_market_agent_tooling.gtypes import (
11
11
  TxReceipt,
12
12
  xDai,
13
13
  )
14
- from prediction_market_agent_tooling.markets.seer.data_models import RedeemParams
14
+ from prediction_market_agent_tooling.markets.seer.data_models import (
15
+ ExactInputSingleParams,
16
+ RedeemParams,
17
+ )
15
18
  from prediction_market_agent_tooling.markets.seer.subgraph_data_models import (
16
19
  CreateCategoricalMarketsParams,
17
20
  )
18
21
  from prediction_market_agent_tooling.tools.contract import (
22
+ ContractERC20OnGnosisChain,
19
23
  ContractOnGnosisChain,
20
24
  abi_field_validator,
21
25
  )
@@ -110,3 +114,38 @@ class GnosisRouter(ContractOnGnosisChain):
110
114
  web3=web3,
111
115
  )
112
116
  return receipt_tx
117
+
118
+
119
+ class SwaprRouterContract(ContractOnGnosisChain):
120
+ # File content taken from https://github.com/protofire/omen-exchange/blob/master/app/src/abi/marketMaker.json.
121
+ abi: ABI = abi_field_validator(
122
+ os.path.join(
123
+ os.path.dirname(os.path.realpath(__file__)),
124
+ "../../abis/swapr_router.abi.json",
125
+ )
126
+ )
127
+
128
+ address: ChecksumAddress = Web3.to_checksum_address(
129
+ "0xffb643e73f280b97809a8b41f7232ab401a04ee1"
130
+ )
131
+
132
+ def exact_input_single(
133
+ self,
134
+ api_keys: APIKeys,
135
+ params: ExactInputSingleParams,
136
+ web3: Web3 | None = None,
137
+ ) -> TxReceipt:
138
+ erc20_token = ContractERC20OnGnosisChain(address=params.token_in)
139
+
140
+ if (
141
+ erc20_token.allowance(api_keys.bet_from_address, self.address, web3=web3)
142
+ < params.amount_in
143
+ ):
144
+ erc20_token.approve(api_keys, self.address, params.amount_in, web3=web3)
145
+
146
+ return self.send(
147
+ api_keys=api_keys,
148
+ function_name="exactInputSingle",
149
+ function_params=[tuple(dict(params).values())],
150
+ web3=web3,
151
+ )
@@ -0,0 +1,96 @@
1
+ from web3 import Web3
2
+
3
+ from prediction_market_agent_tooling.config import APIKeys
4
+ from prediction_market_agent_tooling.gtypes import (
5
+ ChecksumAddress,
6
+ CollateralToken,
7
+ HexBytes,
8
+ HexStr,
9
+ TxReceipt,
10
+ Wei,
11
+ )
12
+ from prediction_market_agent_tooling.markets.seer.data_models import (
13
+ ExactInputSingleParams,
14
+ )
15
+ from prediction_market_agent_tooling.markets.seer.price_manager import PriceManager
16
+ from prediction_market_agent_tooling.markets.seer.seer_contracts import (
17
+ SwaprRouterContract,
18
+ )
19
+ from prediction_market_agent_tooling.markets.seer.seer_subgraph_handler import (
20
+ SeerSubgraphHandler,
21
+ )
22
+
23
+
24
+ class SwapPoolHandler:
25
+ def __init__(
26
+ self,
27
+ api_keys: APIKeys,
28
+ market_id: str,
29
+ collateral_token_address: ChecksumAddress,
30
+ seer_subgraph: SeerSubgraphHandler | None = None,
31
+ ):
32
+ self.api_keys = api_keys
33
+ self.market_id = market_id
34
+ self.collateral_token_address = collateral_token_address
35
+ self.seer_subgraph = seer_subgraph or SeerSubgraphHandler()
36
+
37
+ def _calculate_amount_out_minimum(
38
+ self,
39
+ amount_wei: Wei,
40
+ token_in: ChecksumAddress,
41
+ price_outcome_token: CollateralToken,
42
+ buffer_pct: float = 0.05,
43
+ ) -> Wei:
44
+ is_buying_outcome = token_in == self.collateral_token_address
45
+
46
+ if is_buying_outcome:
47
+ value = amount_wei.value * (1.0 - buffer_pct) / price_outcome_token.value
48
+ else:
49
+ value = amount_wei.value * price_outcome_token.value * (1.0 - buffer_pct)
50
+ return Wei(int(value))
51
+
52
+ def buy_or_sell_outcome_token(
53
+ self,
54
+ amount_wei: Wei,
55
+ token_in: ChecksumAddress,
56
+ token_out: ChecksumAddress,
57
+ web3: Web3 | None = None,
58
+ ) -> TxReceipt:
59
+ """Buys/sells outcome_tokens in exchange for collateral tokens"""
60
+ if self.collateral_token_address not in [token_in, token_out]:
61
+ raise ValueError(
62
+ f"trading outcome_token for a token different than collateral_token {self.collateral_token_address} is not supported. {token_in=} {token_out=}"
63
+ )
64
+
65
+ outcome_token = (
66
+ token_in if token_in != self.collateral_token_address else token_out
67
+ )
68
+
69
+ # We could use a quoter contract (https://github.com/SwaprHQ/swapr-sdk/blob/develop/src/entities/trades/swapr-v3/constants.ts#L7), but since there is normally 1 pool per outcome token/collateral pair, it's not necessary.
70
+
71
+ price_outcome_token = PriceManager.build(
72
+ HexBytes(HexStr(self.market_id))
73
+ ).get_token_price_from_pools(token=outcome_token)
74
+ if not price_outcome_token:
75
+ raise ValueError(
76
+ f"Could not find price for {outcome_token=} and {self.collateral_token_address}"
77
+ )
78
+
79
+ amount_out_minimum = self._calculate_amount_out_minimum(
80
+ amount_wei=amount_wei,
81
+ token_in=token_in,
82
+ price_outcome_token=price_outcome_token,
83
+ )
84
+
85
+ p = ExactInputSingleParams(
86
+ token_in=token_in,
87
+ token_out=token_out,
88
+ recipient=self.api_keys.bet_from_address,
89
+ amount_in=amount_wei,
90
+ amount_out_minimum=amount_out_minimum,
91
+ )
92
+
93
+ tx_receipt = SwaprRouterContract().exact_input_single(
94
+ api_keys=self.api_keys, params=p, web3=web3
95
+ )
96
+ return tx_receipt
@@ -9,11 +9,17 @@ from cowdao_cowpy.common.api.errors import UnexpectedResponseError
9
9
  from cowdao_cowpy.common.chains import Chain
10
10
  from cowdao_cowpy.common.config import SupportedChainId
11
11
  from cowdao_cowpy.common.constants import CowContractAddress
12
+ from cowdao_cowpy.contracts.domain import domain
13
+ from cowdao_cowpy.contracts.sign import SigningScheme, sign_order_cancellations
12
14
  from cowdao_cowpy.cow.swap import CompletedOrder, get_order_quote, swap_tokens
13
15
  from cowdao_cowpy.order_book.api import OrderBookApi
14
16
  from cowdao_cowpy.order_book.config import Envs, OrderBookAPIConfigFactory
15
17
  from cowdao_cowpy.order_book.generated.model import (
18
+ UID,
16
19
  Address,
20
+ EcdsaSignature,
21
+ EcdsaSigningScheme,
22
+ OrderCancellations,
17
23
  OrderMetaData,
18
24
  OrderQuoteRequest,
19
25
  OrderQuoteResponse,
@@ -24,6 +30,9 @@ from cowdao_cowpy.order_book.generated.model import (
24
30
  OrderStatus,
25
31
  TokenAmount,
26
32
  )
33
+ from eth_account import Account
34
+ from eth_account.signers.local import LocalAccount
35
+ from eth_keys.datatypes import PrivateKey as eth_keys_PrivateKey
27
36
  from tenacity import (
28
37
  retry_if_not_exception_type,
29
38
  stop_after_attempt,
@@ -33,7 +42,13 @@ from tenacity import (
33
42
  from web3 import Web3
34
43
 
35
44
  from prediction_market_agent_tooling.config import APIKeys
36
- from prediction_market_agent_tooling.gtypes import ChecksumAddress, HexBytes, Wei
45
+ from prediction_market_agent_tooling.gtypes import (
46
+ ChecksumAddress,
47
+ HexBytes,
48
+ HexStr,
49
+ PrivateKey,
50
+ Wei,
51
+ )
37
52
  from prediction_market_agent_tooling.loggers import logger
38
53
  from prediction_market_agent_tooling.markets.omen.cow_contracts import (
39
54
  CowGPv2SettlementContract,
@@ -153,21 +168,12 @@ def get_buy_token_amount_else_raise(
153
168
  return Wei(order_quote.quote.buyAmount.root)
154
169
 
155
170
 
156
- @tenacity.retry(
157
- stop=stop_after_attempt(3),
158
- wait=wait_fixed(1),
159
- retry=tenacity.retry_if_not_exception_type((TimeoutError, OrderStatusError)),
160
- after=lambda x: logger.debug(f"swap_tokens_waiting failed, {x.attempt_number=}."),
161
- )
162
- def swap_tokens_waiting(
163
- amount_wei: Wei,
164
- sell_token: ChecksumAddress,
165
- buy_token: ChecksumAddress,
171
+ def handle_allowance(
166
172
  api_keys: APIKeys,
167
- chain: Chain = Chain.GNOSIS,
168
- env: Envs = "prod",
173
+ sell_token: ChecksumAddress,
174
+ amount_wei: Wei,
169
175
  web3: Web3 | None = None,
170
- ) -> OrderMetaData:
176
+ ) -> None:
171
177
  # Approve the CoW Swap Vault Relayer to get the sell token only if allowance not sufficient.
172
178
  for_address = Web3.to_checksum_address(CowContractAddress.VAULT_RELAYER.value)
173
179
  current_allowance = ContractERC20OnGnosisChain(address=sell_token).allowance(
@@ -183,24 +189,47 @@ def swap_tokens_waiting(
183
189
  web3=web3,
184
190
  )
185
191
 
192
+
193
+ @tenacity.retry(
194
+ stop=stop_after_attempt(3),
195
+ wait=wait_fixed(1),
196
+ retry=tenacity.retry_if_not_exception_type((TimeoutError, OrderStatusError)),
197
+ after=lambda x: logger.debug(f"swap_tokens_waiting failed, {x.attempt_number=}."),
198
+ )
199
+ def swap_tokens_waiting(
200
+ amount_wei: Wei,
201
+ sell_token: ChecksumAddress,
202
+ buy_token: ChecksumAddress,
203
+ api_keys: APIKeys,
204
+ chain: Chain = Chain.GNOSIS,
205
+ env: Envs = "prod",
206
+ web3: Web3 | None = None,
207
+ wait_order_complete: bool = True,
208
+ ) -> tuple[OrderMetaData | None, CompletedOrder]:
186
209
  # CoW library uses async, so we need to wrap the call in asyncio.run for us to use it.
187
210
  return asyncio.run(
188
211
  swap_tokens_waiting_async(
189
- amount_wei, sell_token, buy_token, api_keys, chain, env
212
+ amount_wei,
213
+ sell_token,
214
+ buy_token,
215
+ api_keys,
216
+ chain,
217
+ env,
218
+ web3=web3,
219
+ wait_order_complete=wait_order_complete,
190
220
  )
191
221
  )
192
222
 
193
223
 
194
- async def swap_tokens_waiting_async(
224
+ async def place_swap_order(
225
+ api_keys: APIKeys,
195
226
  amount_wei: Wei,
196
227
  sell_token: ChecksumAddress,
197
228
  buy_token: ChecksumAddress,
198
- api_keys: APIKeys,
199
229
  chain: Chain,
200
230
  env: Envs,
201
- timeout: timedelta = timedelta(seconds=120),
202
231
  slippage_tolerance: float = 0.01,
203
- ) -> OrderMetaData:
232
+ ) -> CompletedOrder:
204
233
  account = api_keys.get_account()
205
234
  safe_address = api_keys.safe_address_checksum
206
235
 
@@ -220,6 +249,12 @@ async def swap_tokens_waiting_async(
220
249
  logger.info(f"Safe is used. Signing the order after its creation.")
221
250
  await sign_safe_cow_swap(api_keys, order, chain, env)
222
251
 
252
+ return order
253
+
254
+
255
+ async def wait_for_order_completion(
256
+ order: CompletedOrder, timeout: timedelta = timedelta(seconds=120)
257
+ ) -> OrderMetaData:
223
258
  start_time = utcnow()
224
259
 
225
260
  while True:
@@ -249,6 +284,36 @@ async def swap_tokens_waiting_async(
249
284
  await asyncio.sleep(3.14)
250
285
 
251
286
 
287
+ async def swap_tokens_waiting_async(
288
+ amount_wei: Wei,
289
+ sell_token: ChecksumAddress,
290
+ buy_token: ChecksumAddress,
291
+ api_keys: APIKeys,
292
+ chain: Chain,
293
+ env: Envs,
294
+ timeout: timedelta = timedelta(seconds=120),
295
+ slippage_tolerance: float = 0.01,
296
+ web3: Web3 | None = None,
297
+ wait_order_complete: bool = True,
298
+ ) -> tuple[OrderMetaData | None, CompletedOrder]:
299
+ handle_allowance(
300
+ api_keys=api_keys, sell_token=sell_token, amount_wei=amount_wei, web3=web3
301
+ )
302
+ order = await place_swap_order(
303
+ api_keys=api_keys,
304
+ amount_wei=amount_wei,
305
+ sell_token=sell_token,
306
+ buy_token=buy_token,
307
+ chain=chain,
308
+ env=env,
309
+ slippage_tolerance=slippage_tolerance,
310
+ )
311
+ if wait_order_complete:
312
+ order_metadata = await wait_for_order_completion(order=order, timeout=timeout)
313
+ return order_metadata, order
314
+ return None, order
315
+
316
+
252
317
  @tenacity.retry(
253
318
  stop=tenacity.stop_after_attempt(3),
254
319
  wait=tenacity.wait_fixed(1),
@@ -323,3 +388,33 @@ def paginate_endpoint(url: str, limit: int = 1000) -> t.Any:
323
388
  offset += limit
324
389
 
325
390
  return results
391
+
392
+
393
+ async def cancel_order(
394
+ order_uids: t.Sequence[str],
395
+ api_keys: APIKeys,
396
+ chain: Chain = Chain.GNOSIS,
397
+ env: Envs = "prod",
398
+ ) -> None:
399
+ """Cancels orders that were created by the user corresponding to the api_keys.."""
400
+ order_domain = domain(
401
+ chain=chain, verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
402
+ )
403
+ owner = build_account(api_keys.bet_from_private_key)
404
+ order_signature = sign_order_cancellations(
405
+ order_domain, list(order_uids), owner, SigningScheme.EIP712
406
+ )
407
+ oc = OrderCancellations(
408
+ signature=EcdsaSignature(root=order_signature.data),
409
+ orderUids=[UID(root=order_uid) for order_uid in order_uids],
410
+ signingScheme=EcdsaSigningScheme.eip712,
411
+ )
412
+ order_book_api = get_order_book_api(env, chain)
413
+ await order_book_api.delete_order(orders_cancelation=oc)
414
+
415
+
416
+ def build_account(private_key: PrivateKey) -> LocalAccount:
417
+ return LocalAccount(
418
+ key=eth_keys_PrivateKey(HexBytes(HexStr(private_key.get_secret_value()))),
419
+ account=Account.from_key(private_key.get_secret_value()),
420
+ )
@@ -67,17 +67,23 @@ def unwrap_generic_value(value: Any) -> Any:
67
67
  return value.value
68
68
  elif isinstance(value, list):
69
69
  return [unwrap_generic_value(v) for v in value]
70
+ elif isinstance(value, tuple):
71
+ return tuple(unwrap_generic_value(v) for v in value)
70
72
  elif isinstance(value, dict):
71
73
  return {k: unwrap_generic_value(v) for k, v in value.items()}
72
74
  return value
73
75
 
74
76
 
75
- def parse_function_params(params: Optional[list[Any] | dict[str, Any]]) -> list[Any]:
77
+ def parse_function_params(
78
+ params: Optional[list[Any] | tuple[Any] | dict[str, Any]]
79
+ ) -> list[Any] | tuple[Any]:
76
80
  params = unwrap_generic_value(params)
77
81
  if params is None:
78
82
  return []
79
83
  if isinstance(params, list):
80
- return params
84
+ return [unwrap_generic_value(i) for i in params]
85
+ if isinstance(params, tuple):
86
+ return tuple(unwrap_generic_value(i) for i in params)
81
87
  if isinstance(params, dict):
82
88
  return list(params.values())
83
89
  raise ValueError(f"Invalid type for function parameters: {type(params)}")
@@ -117,8 +123,8 @@ def prepare_tx(
117
123
 
118
124
  # Build the transaction.
119
125
  function_call = contract.functions[function_name](*parse_function_params(function_params)) # type: ignore # TODO: Fix Mypy, as this works just OK.
120
- tx_params_new = function_call.build_transaction(tx_params_new)
121
- return tx_params_new
126
+ built_tx_params: TxParams = function_call.build_transaction(tx_params_new)
127
+ return built_tx_params
122
128
 
123
129
 
124
130
  def _prepare_tx_params(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.65.9
3
+ Version: 0.65.10
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -18,9 +18,10 @@ prediction_market_agent_tooling/abis/ownable_erc721.abi.json,sha256=9sxm588MAQmq
18
18
  prediction_market_agent_tooling/abis/proxy.abi.json,sha256=h24GXZ6Q0bSZlwh7zOv0EiDvbqUz_PHtWfKHTyPJ1w4,644
19
19
  prediction_market_agent_tooling/abis/seer_gnosis_router.abi.json,sha256=DyADzOXhy9MDS31ReVrG7ibpWbw1jVy19nExZ80xfRY,6839
20
20
  prediction_market_agent_tooling/abis/seer_market_factory.abi.json,sha256=g7RVxZVUWlTXIgTV2W6kO4twQM909Qv58zAr7Dk4XIc,13553
21
+ prediction_market_agent_tooling/abis/swapr_router.abi.json,sha256=Y1wK20D1-zdbdlzkzV0BHY-HXMJrog6dgSHEzKzrQOU,13346
21
22
  prediction_market_agent_tooling/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
23
  prediction_market_agent_tooling/benchmark/agents.py,sha256=zC5tUM6pPTWtqSddOOSYV_fxHYmZb5uGAb4Ru87Tah8,4221
23
- prediction_market_agent_tooling/benchmark/benchmark.py,sha256=KwMZzwise3sgmhdjw7xCgHMmjKHdHqQC-zc9untOLWg,17832
24
+ prediction_market_agent_tooling/benchmark/benchmark.py,sha256=hpIpjjePDFTLhK841sGftFbhu8bDDZr28KO4VTneewM,17837
24
25
  prediction_market_agent_tooling/benchmark/utils.py,sha256=xQd7p9H08-OtN3iC4QT2i9bkUTmrXa6rxGXeg9yMhgU,2986
25
26
  prediction_market_agent_tooling/chains.py,sha256=1qQstoqXMwqwM7k-KH7MjMz8Ei-D83KZByvDbCZpAxs,116
26
27
  prediction_market_agent_tooling/config.py,sha256=-kJfdDr-m0R-tGZ1KRI-hJJk0mXDt142CAlvwaJ2N2I,11778
@@ -66,13 +67,14 @@ prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=U1SXTz9
66
67
  prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=wCwpZ8Kppy8JG_1HZDfEK_Gg1g1sL7NCbGoPeTeMSko,12756
67
68
  prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=meAhQ5_gwVDvlSxhGGVAvRB7B47zKLnRvZ-_13tKtwY,3433
68
69
  prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=8kTeVjXPcXC6DkDvWYsZQLY7x8DS6CEp_yznSEazsNU,2037
69
- prediction_market_agent_tooling/markets/seer/data_models.py,sha256=G0i-fnVaK16KWDYVI6w3lvyte6Op7ca_iIC8IfrXmlM,4702
70
+ prediction_market_agent_tooling/markets/seer/data_models.py,sha256=osM9WaLsxQf-pfVGq0O-IkM93ehP9a7fVUf-hi2VlMs,5523
70
71
  prediction_market_agent_tooling/markets/seer/exceptions.py,sha256=cEObdjluivD94tgOLzmimR7wgQEOt6SRakrYdhsRQtk,112
71
72
  prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=MClY2NGwOV70nZYIcmzXFy6Ogd8NBIq7telQcQ3VcU4,6243
72
- prediction_market_agent_tooling/markets/seer/seer.py,sha256=IsFK8XXjHq8UBvIkueiWpm_b3ddMslr84DqF_qNFQw0,21745
73
- prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=kH9nPXsx6UM5er42g2f3fLvy36sY5JM2f_beXeuNgUc,3790
73
+ prediction_market_agent_tooling/markets/seer/seer.py,sha256=_2Ld3EepmZuzpgAmW6f7eAS5-geXE25XgUKPUrFCWoI,23864
74
+ prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=uMzpHpI6_tgfhWxPzupLdUJlZ1P2wr0rRiYjAGClKgU,4984
74
75
  prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=pJxch9_u0EdiIatQP1-UFClt8UEfMZAXBlk5wDO_ovk,9940
75
76
  prediction_market_agent_tooling/markets/seer/subgraph_data_models.py,sha256=0izxS8Mtzonfdl9UqvFVXrdj0hVzieroekXhogfZKCw,1817
77
+ prediction_market_agent_tooling/markets/seer/swap_pool_handler.py,sha256=y0pDL2BoxayROy3warEN3r8Fs3rPCPPZ191bgrgZikg,3403
76
78
  prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
79
  prediction_market_agent_tooling/tools/_generic_value.py,sha256=pD_PI13lpPp1gFoljHwa_Lzlp-u2pu0m-Z7LcxwDM2U,10618
78
80
  prediction_market_agent_tooling/tools/balances.py,sha256=Osab21btfJDw2Y-jT_TV-KHGrseCRxcsYeW6WcOMB8E,1050
@@ -84,7 +86,7 @@ prediction_market_agent_tooling/tools/caches/inmemory_cache.py,sha256=ZW5iI5rmjq
84
86
  prediction_market_agent_tooling/tools/caches/serializers.py,sha256=vFDx4fsPxclXp2q0sv27j4al_M_Tj9aR2JJP-xNHQXA,2151
85
87
  prediction_market_agent_tooling/tools/contract.py,sha256=pdr9ZYmj4QVUfgVKdvOU6ucYdBpJGdha_FMR_LgtcEs,22912
86
88
  prediction_market_agent_tooling/tools/costs.py,sha256=EaAJ7v9laD4VEV3d8B44M4u3_oEO_H16jRVCdoZ93Uw,954
87
- prediction_market_agent_tooling/tools/cow/cow_order.py,sha256=KpklYy5DY3j-aIlf6dB_o0mEX4MD3fqMiZK3tJs5Gro,10129
89
+ prediction_market_agent_tooling/tools/cow/cow_order.py,sha256=yTUG6VPVe292R_5IG8F90kfZfAeun8G1TL6mHsnaXM0,12984
88
90
  prediction_market_agent_tooling/tools/cow/models.py,sha256=ZWGW0og5vXjgZVXxkx4uV2m61Q8AmL-L-D_D4f7ApR0,379
89
91
  prediction_market_agent_tooling/tools/custom_exceptions.py,sha256=Fh8z1fbwONvP4-j7AmV_PuEcoqb6-QXa9PJ9m7guMcM,93
90
92
  prediction_market_agent_tooling/tools/datetime_utc.py,sha256=8_WackjtjC8zHXrhQFTGQ6e6Fz_6llWoKR4CSFvIv9I,2766
@@ -120,9 +122,9 @@ prediction_market_agent_tooling/tools/tokens/token_utils.py,sha256=fhs-FH9m9IbzG
120
122
  prediction_market_agent_tooling/tools/tokens/usd.py,sha256=yuW8iPPtcpP4eLH2nORMDAfztcq0Nv2ascSrCquF1f8,3115
121
123
  prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
122
124
  prediction_market_agent_tooling/tools/utils.py,sha256=RlWSlzS2LavMIWrpwn1fevbzgPZruD4VcXTa-XxjWnE,7343
123
- prediction_market_agent_tooling/tools/web3_utils.py,sha256=zRq-eeBGWt8uUGN9G_WfjmJ0eVvO8aWE9S0Pz_Y6AOA,12342
124
- prediction_market_agent_tooling-0.65.9.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
125
- prediction_market_agent_tooling-0.65.9.dist-info/METADATA,sha256=fwrbaHBiT91jMhqYkTWJ-vPB2dav-bxrgqfV7oDjGHY,8734
126
- prediction_market_agent_tooling-0.65.9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
127
- prediction_market_agent_tooling-0.65.9.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
128
- prediction_market_agent_tooling-0.65.9.dist-info/RECORD,,
125
+ prediction_market_agent_tooling/tools/web3_utils.py,sha256=0r26snqCXGdLKCWA8jpe7DV8x2NPYWZwOy4oyKyDCYk,12615
126
+ prediction_market_agent_tooling-0.65.10.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
127
+ prediction_market_agent_tooling-0.65.10.dist-info/METADATA,sha256=vlhpH2uSRf9E9HKpHsW3ovlHqMl-rFt_GqyJqxjH5ao,8735
128
+ prediction_market_agent_tooling-0.65.10.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
129
+ prediction_market_agent_tooling-0.65.10.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
130
+ prediction_market_agent_tooling-0.65.10.dist-info/RECORD,,