polymarket-apis 0.3.5__py3-none-any.whl → 0.3.7__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.
@@ -1,10 +1,15 @@
1
1
  from json import load
2
2
  from pathlib import Path
3
- from typing import Literal, Optional
3
+ from typing import Literal
4
4
 
5
5
  from web3 import Web3
6
+ from web3.constants import MAX_INT
6
7
  from web3.exceptions import ContractCustomError
7
- from web3.middleware import ExtraDataToPOAMiddleware, SignAndSendRawMiddlewareBuilder
8
+ from web3.middleware import (
9
+ ExtraDataToPOAMiddleware,
10
+ SignAndSendRawMiddlewareBuilder,
11
+ )
12
+ from web3.types import ChecksumAddress, TxParams, Wei
8
13
 
9
14
  from ..types.common import EthAddress, Keccak256
10
15
  from ..utilities.config import get_contract_config
@@ -32,13 +37,14 @@ class PolymarketWeb3Client:
32
37
  def __init__(
33
38
  self,
34
39
  private_key: str,
35
- signature_type: Literal[1, 2] = 1,
40
+ signature_type: Literal[0, 1, 2] = 1,
36
41
  chain_id: Literal[137, 80002] = POLYGON,
37
42
  ):
38
43
  self.w3 = Web3(Web3.HTTPProvider("https://polygon-rpc.com"))
39
- self.w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
44
+ self.w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0) # type: ignore[arg-type]
40
45
  self.w3.middleware_onion.inject(
41
- SignAndSendRawMiddlewareBuilder.build(private_key), layer=0
46
+ SignAndSendRawMiddlewareBuilder.build(private_key), # type: ignore[arg-type]
47
+ layer=0,
42
48
  )
43
49
 
44
50
  self.account = self.w3.eth.account.from_key(private_key)
@@ -71,34 +77,51 @@ class PolymarketWeb3Client:
71
77
  self.neg_risk_exchange_address, self.neg_risk_exchange_abi
72
78
  )
73
79
 
74
- self.neg_risk_adapter_address = "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296"
80
+ self.neg_risk_adapter_address = Web3.to_checksum_address(
81
+ "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296"
82
+ )
75
83
  self.neg_risk_adapter_abi = _load_abi("NegRiskAdapter")
76
84
  self.neg_risk_adapter = self.contract(
77
85
  self.neg_risk_adapter_address, self.neg_risk_adapter_abi
78
86
  )
79
87
 
80
- self.proxy_factory_address = "0xaB45c5A4B0c941a2F231C04C3f49182e1A254052"
88
+ self.proxy_factory_address = Web3.to_checksum_address(
89
+ "0xaB45c5A4B0c941a2F231C04C3f49182e1A254052"
90
+ )
81
91
  self.proxy_factory_abi = _load_abi("ProxyWalletFactory")
82
92
  self.proxy_factory = self.contract(
83
93
  self.proxy_factory_address, self.proxy_factory_abi
84
94
  )
85
95
 
86
- self.safe_proxy_factory_address = "0xaacFeEa03eb1561C4e67d661e40682Bd20E3541b"
96
+ self.safe_proxy_factory_address = Web3.to_checksum_address(
97
+ "0xaacFeEa03eb1561C4e67d661e40682Bd20E3541b"
98
+ )
87
99
  self.safe_proxy_factory_abi = _load_abi("SafeProxyFactory")
88
100
  self.safe_proxy_factory = self.contract(
89
101
  self.safe_proxy_factory_address, self.safe_proxy_factory_abi
90
102
  )
91
103
 
92
104
  match self.signature_type:
105
+ case 0:
106
+ self.address = self.account.address
93
107
  case 1:
94
- self.proxy_address = self.get_poly_proxy_address()
108
+ self.address = self.get_poly_proxy_address()
95
109
  case 2:
96
- self.proxy_address = self.get_safe_proxy_address()
110
+ self.address = self.get_safe_proxy_address()
97
111
  self.safe_abi = _load_abi("Safe")
98
- self.safe = self.contract(self.proxy_address, self.safe_abi)
99
- case _:
100
- msg = "Invalid signature_type: choose 1 for Magic/Email wallet or 2 for Safe/Gnosis wallet"
101
- raise ValueError(msg)
112
+ self.safe = self.contract(self.address, self.safe_abi)
113
+
114
+ def _encode_usdc_approve(self, address: ChecksumAddress) -> str:
115
+ return self.usdc.encode_abi(
116
+ abi_element_identifier="approve",
117
+ args=[address, int(MAX_INT, base=16)],
118
+ )
119
+
120
+ def _encode_condition_tokens_approve(self, address: ChecksumAddress) -> str:
121
+ return self.conditional_tokens.encode_abi(
122
+ abi_element_identifier="setApprovalForAll",
123
+ args=[address, True],
124
+ )
102
125
 
103
126
  def _encode_split(self, condition_id: Keccak256, amount: int) -> str:
104
127
  return self.conditional_tokens.encode_abi(
@@ -134,6 +157,139 @@ class PolymarketWeb3Client:
134
157
  args=[neg_risk_market_id, index_set, amount],
135
158
  )
136
159
 
160
+ def _build_transaction(self) -> TxParams:
161
+ """Build base transaction parameters."""
162
+ nonce = self.w3.eth.get_transaction_count(self.account.address)
163
+
164
+ current_gas_price: int = self.w3.eth.gas_price
165
+ adjusted_gas_price = Wei(int(current_gas_price * 1.05))
166
+
167
+ transaction: TxParams = {
168
+ "nonce": nonce,
169
+ "gasPrice": adjusted_gas_price,
170
+ "gas": 1000000,
171
+ "from": self.account.address,
172
+ }
173
+
174
+ return transaction
175
+
176
+ def _set_collateral_approval(self, spender: ChecksumAddress) -> str:
177
+ data = self._encode_usdc_approve(address=spender)
178
+ transaction = self._build_transaction()
179
+ txn_data: TxParams | None = None
180
+
181
+ match self.signature_type:
182
+ case 0:
183
+ txn_data = self.usdc.functions.approve(
184
+ spender, int(MAX_INT, base=16)
185
+ ).build_transaction(transaction=transaction)
186
+ case 1:
187
+ proxy_txn = {
188
+ "typeCode": 1,
189
+ "to": self.usdc_address,
190
+ "value": 0,
191
+ "data": data,
192
+ }
193
+ txn_data = self.proxy_factory.functions.proxy(
194
+ [proxy_txn]
195
+ ).build_transaction(transaction=transaction)
196
+ case 2:
197
+ safe_nonce = self.safe.functions.nonce().call()
198
+ safe_txn = {
199
+ "to": self.usdc_address,
200
+ "data": data,
201
+ "operation": 0, # 1 for delegatecall, 0 for call
202
+ "value": 0,
203
+ }
204
+ packed_sig = sign_safe_transaction(
205
+ self.account, self.safe, safe_txn, safe_nonce
206
+ )
207
+ txn_data = self.safe.functions.execTransaction(
208
+ safe_txn["to"],
209
+ safe_txn["value"],
210
+ safe_txn["data"],
211
+ safe_txn.get("operation", 0),
212
+ 0, # safeTxGas
213
+ 0, # baseGas
214
+ 0, # gasPrice
215
+ ADDRESS_ZERO, # gasToken
216
+ ADDRESS_ZERO, # refundReceiver
217
+ packed_sig,
218
+ ).build_transaction(transaction=transaction)
219
+
220
+ signed_txn = self.account.sign_transaction(txn_data)
221
+ tx_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
222
+ tx_hash_hex = tx_hash.hex()
223
+
224
+ print(f"Txn hash: 0x{tx_hash_hex}")
225
+
226
+ # Wait for transaction to be mined
227
+ self.w3.eth.wait_for_transaction_receipt(tx_hash)
228
+
229
+ print("Done!")
230
+
231
+ return f"0x{tx_hash_hex}"
232
+
233
+ def _set_conditional_tokens_approval(self, spender: ChecksumAddress) -> str:
234
+ data = self._encode_condition_tokens_approve(address=spender)
235
+ transaction = self._build_transaction()
236
+ txn_data: TxParams | None = None
237
+
238
+ match self.signature_type:
239
+ case 0:
240
+ txn_data = self.conditional_tokens.functions.setApprovalForAll(
241
+ spender, True
242
+ ).build_transaction(transaction=transaction)
243
+ case 1:
244
+ proxy_txn = {
245
+ "typeCode": 1,
246
+ "to": self.conditional_tokens_address,
247
+ "value": 0,
248
+ "data": data,
249
+ }
250
+ txn_data = self.proxy_factory.functions.proxy(
251
+ [proxy_txn]
252
+ ).build_transaction(transaction=transaction)
253
+ case 2:
254
+ safe_nonce = self.safe.functions.nonce().call()
255
+ safe_txn = {
256
+ "to": self.conditional_tokens_address,
257
+ "data": data,
258
+ "operation": 0, # 1 for delegatecall, 0 for call
259
+ "value": 0,
260
+ }
261
+ packed_sig = sign_safe_transaction(
262
+ self.account,
263
+ self.safe,
264
+ safe_txn,
265
+ safe_nonce,
266
+ )
267
+ txn_data = self.safe.functions.execTransaction(
268
+ safe_txn["to"],
269
+ safe_txn["value"],
270
+ safe_txn["data"],
271
+ safe_txn.get("operation", 0),
272
+ 0, # safeTxGas
273
+ 0, # baseGas
274
+ 0, # gasPrice
275
+ ADDRESS_ZERO, # gasToken
276
+ ADDRESS_ZERO, # refundReceiver
277
+ packed_sig,
278
+ ).build_transaction(transaction=transaction)
279
+
280
+ signed_txn = self.account.sign_transaction(txn_data)
281
+ tx_hash = self.w3.eth.send_raw_transaction(signed_txn.raw_transaction)
282
+ tx_hash_hex = tx_hash.hex()
283
+
284
+ print(f"Txn hash: 0x{tx_hash_hex}")
285
+
286
+ # Wait for transaction to be mined
287
+ self.w3.eth.wait_for_transaction_receipt(tx_hash)
288
+
289
+ print("Done!")
290
+
291
+ return f"0x{tx_hash_hex}"
292
+
137
293
  def contract(self, address, abi):
138
294
  return self.w3.eth.contract(
139
295
  address=Web3.to_checksum_address(address),
@@ -159,7 +315,7 @@ class PolymarketWeb3Client:
159
315
  Explicitly passing the proxy address is faster due to only one contract function call.
160
316
  """
161
317
  if address is None:
162
- address = self.get_poly_proxy_address()
318
+ address = self.address
163
319
  balance_res = self.usdc.functions.balanceOf(address).call()
164
320
  return float(balance_res / 1e6)
165
321
 
@@ -168,20 +324,13 @@ class PolymarketWeb3Client:
168
324
  ) -> float:
169
325
  """Get the token balance of the given address."""
170
326
  if not address:
171
- match self.signature_type:
172
- case 1:
173
- address = self.get_poly_proxy_address(self.account.address)
174
- case 2:
175
- address = self.get_safe_proxy_address(self.account.address)
176
- case _:
177
- msg = "Invalid signature_type: choose 1 for Magic/Email wallet or 2 for Safe/Gnosis wallet"
178
- raise ValueError(msg)
327
+ address = self.address
179
328
  balance_res = self.conditional_tokens.functions.balanceOf(
180
329
  address, int(token_id)
181
330
  ).call()
182
331
  return float(balance_res / 1e6)
183
332
 
184
- def get_token_complement(self, token_id: str) -> Optional[str]:
333
+ def get_token_complement(self, token_id: str) -> str | None:
185
334
  """Get the complement of the given token."""
186
335
  try:
187
336
  return str(
@@ -199,6 +348,8 @@ class PolymarketWeb3Client:
199
348
  raise ContractCustomError(
200
349
  msg,
201
350
  ) from e2
351
+ return None
352
+ return None
202
353
 
203
354
  def get_condition_id_neg_risk(self, question_id: Keccak256) -> Keccak256:
204
355
  """
@@ -213,9 +364,41 @@ class PolymarketWeb3Client:
213
364
  + self.neg_risk_adapter.functions.getConditionId(question_id).call().hex()
214
365
  )
215
366
 
367
+ def set_all_approvals(self) -> None:
368
+ """Sets both collateral and conditional tokens approvals."""
369
+ print("Approving ConditionalTokens as spender on USDC")
370
+ self._set_collateral_approval(
371
+ spender=self.conditional_tokens_address,
372
+ )
373
+ print("Approving CTFExchange as spender on USDC")
374
+ self._set_collateral_approval(
375
+ spender=self.exchange_address,
376
+ )
377
+ print("Approving NegRiskCtfExchange as spender on USDC")
378
+ self._set_collateral_approval(
379
+ spender=self.neg_risk_exchange_address,
380
+ )
381
+ print("Approving NegRiskAdapter as spender on USDC")
382
+ self._set_collateral_approval(
383
+ spender=self.neg_risk_adapter_address,
384
+ )
385
+ print("Approving CTFExchange as spender on ConditionalTokens")
386
+ self._set_conditional_tokens_approval(
387
+ spender=self.exchange_address,
388
+ )
389
+ print("Approving NegRiskCtfExchange as spender on ConditionalTokens")
390
+ self._set_conditional_tokens_approval(
391
+ spender=self.neg_risk_exchange_address,
392
+ )
393
+ print("Approving NegRiskAdapter as spender on ConditionalTokens")
394
+ self._set_conditional_tokens_approval(
395
+ spender=self.neg_risk_adapter_address,
396
+ )
397
+ print("All approvals set!")
398
+
216
399
  def split_position(
217
- self, condition_id: Keccak256, amount: int, neg_risk: bool = True
218
- ):
400
+ self, condition_id: Keccak256, amount: float, neg_risk: bool = True
401
+ ) -> str:
219
402
  """Splits usdc into two complementary positions of equal size."""
220
403
  amount = int(amount * 1e6)
221
404
  data = self._encode_split(condition_id, amount)
@@ -224,40 +407,42 @@ class PolymarketWeb3Client:
224
407
  if neg_risk
225
408
  else self.conditional_tokens_address
226
409
  )
410
+ transaction = self._build_transaction()
411
+ txn_data: TxParams | None = None
227
412
 
228
413
  match self.signature_type:
414
+ case 0:
415
+ contract = (
416
+ self.neg_risk_adapter if neg_risk else self.conditional_tokens
417
+ )
418
+ txn_data = contract.functions.splitPosition(
419
+ self.usdc_address,
420
+ HASH_ZERO,
421
+ condition_id,
422
+ [1, 2],
423
+ amount,
424
+ ).build_transaction(transaction=transaction)
229
425
  case 1:
230
- nonce = self.w3.eth.get_transaction_count(self.account.address)
231
426
  proxy_txn = {
232
427
  "typeCode": 1,
233
428
  "to": to,
234
429
  "value": 0,
235
430
  "data": data,
236
431
  }
237
-
238
432
  txn_data = self.proxy_factory.functions.proxy(
239
433
  [proxy_txn]
240
- ).build_transaction(
241
- {
242
- "nonce": nonce,
243
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
244
- "gas": 1000000,
245
- "from": self.account.address,
246
- }
247
- )
434
+ ).build_transaction(transaction=transaction)
248
435
  case 2:
249
- nonce = self.safe.functions.nonce().call()
436
+ safe_nonce = self.safe.functions.nonce().call()
250
437
  safe_txn = {
251
438
  "to": to,
252
439
  "data": data,
253
440
  "operation": 0, # 1 for delegatecall, 0 for call
254
441
  "value": 0,
255
442
  }
256
-
257
443
  packed_sig = sign_safe_transaction(
258
- self.account, self.safe, safe_txn, nonce
444
+ self.account, self.safe, safe_txn, safe_nonce
259
445
  )
260
-
261
446
  txn_data = self.safe.functions.execTransaction(
262
447
  safe_txn["to"],
263
448
  safe_txn["value"],
@@ -269,16 +454,7 @@ class PolymarketWeb3Client:
269
454
  ADDRESS_ZERO, # gasToken
270
455
  ADDRESS_ZERO, # refundReceiver
271
456
  packed_sig,
272
- ).build_transaction(
273
- {
274
- "nonce": self.w3.eth.get_transaction_count(
275
- self.account.address
276
- ),
277
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
278
- "gas": 1000000,
279
- "from": self.account.address,
280
- }
281
- )
457
+ ).build_transaction(transaction=transaction)
282
458
 
283
459
  # Sign and send transaction
284
460
  signed_txn = self.account.sign_transaction(txn_data)
@@ -292,9 +468,11 @@ class PolymarketWeb3Client:
292
468
 
293
469
  print("Done!")
294
470
 
471
+ return f"0x{tx_hash_hex}"
472
+
295
473
  def merge_position(
296
- self, condition_id: Keccak256, amount: int, neg_risk: bool = True
297
- ):
474
+ self, condition_id: Keccak256, amount: float, neg_risk: bool = True
475
+ ) -> str:
298
476
  """Merges two complementary positions into usdc."""
299
477
  amount = int(amount * 1e6)
300
478
  data = self._encode_merge(condition_id, amount)
@@ -303,10 +481,22 @@ class PolymarketWeb3Client:
303
481
  if neg_risk
304
482
  else self.conditional_tokens_address
305
483
  )
484
+ transaction = self._build_transaction()
485
+ txn_data: TxParams | None = None
306
486
 
307
487
  match self.signature_type:
488
+ case 0:
489
+ contract = (
490
+ self.neg_risk_adapter if neg_risk else self.conditional_tokens
491
+ )
492
+ txn_data = contract.functions.mergePositions(
493
+ self.usdc_address,
494
+ HASH_ZERO,
495
+ condition_id,
496
+ [1, 2],
497
+ amount,
498
+ ).build_transaction(transaction=transaction)
308
499
  case 1:
309
- nonce = self.w3.eth.get_transaction_count(self.account.address)
310
500
  proxy_txn = {
311
501
  "typeCode": 1,
312
502
  "to": to,
@@ -316,25 +506,17 @@ class PolymarketWeb3Client:
316
506
 
317
507
  txn_data = self.proxy_factory.functions.proxy(
318
508
  [proxy_txn]
319
- ).build_transaction(
320
- {
321
- "nonce": nonce,
322
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
323
- "gas": 1000000,
324
- "from": self.account.address,
325
- }
326
- )
509
+ ).build_transaction(transaction=transaction)
327
510
  case 2:
328
- nonce = self.safe.functions.nonce().call()
511
+ safe_nonce = self.safe.functions.nonce().call()
329
512
  safe_txn = {
330
513
  "to": to,
331
514
  "data": data,
332
515
  "operation": 0, # 1 for delegatecall, 0 for call
333
516
  "value": 0,
334
517
  }
335
-
336
518
  packed_sig = sign_safe_transaction(
337
- self.account, self.safe, safe_txn, nonce
519
+ self.account, self.safe, safe_txn, safe_nonce
338
520
  )
339
521
  txn_data = self.safe.functions.execTransaction(
340
522
  safe_txn["to"],
@@ -347,16 +529,7 @@ class PolymarketWeb3Client:
347
529
  ADDRESS_ZERO, # gasToken
348
530
  ADDRESS_ZERO, # refundReceiver
349
531
  packed_sig,
350
- ).build_transaction(
351
- {
352
- "nonce": self.w3.eth.get_transaction_count(
353
- self.account.address
354
- ),
355
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
356
- "gas": 1000000,
357
- "from": self.account.address,
358
- }
359
- )
532
+ ).build_transaction(transaction=transaction)
360
533
 
361
534
  # Sign and send transaction
362
535
  signed_txn = self.account.sign_transaction(txn_data)
@@ -370,9 +543,11 @@ class PolymarketWeb3Client:
370
543
 
371
544
  print("Done!")
372
545
 
546
+ return f"0x{tx_hash_hex}"
547
+
373
548
  def redeem_position(
374
549
  self, condition_id: Keccak256, amounts: list[float], neg_risk: bool = True
375
- ):
550
+ ) -> str:
376
551
  """
377
552
  Redeem a position into usdc.
378
553
 
@@ -380,9 +555,9 @@ class PolymarketWeb3Client:
380
555
  where x is the number of shares of the first outcome
381
556
  y is the number of shares of the second outcome.
382
557
  """
383
- amounts = [int(amount * 1e6) for amount in amounts]
558
+ int_amounts = [int(amount * 1e6) for amount in amounts]
384
559
  data = (
385
- self._encode_redeem_neg_risk(condition_id, amounts)
560
+ self._encode_redeem_neg_risk(condition_id, int_amounts)
386
561
  if neg_risk
387
562
  else self._encode_redeem(condition_id)
388
563
  )
@@ -391,38 +566,45 @@ class PolymarketWeb3Client:
391
566
  if neg_risk
392
567
  else self.conditional_tokens_address
393
568
  )
569
+ transaction = self._build_transaction()
570
+ txn_data: TxParams | None = None
394
571
 
395
572
  match self.signature_type:
573
+ case 0:
574
+ contract = (
575
+ self.neg_risk_adapter if neg_risk else self.conditional_tokens
576
+ )
577
+ if neg_risk:
578
+ txn_data = contract.functions.redeemPositions(
579
+ condition_id, int_amounts
580
+ ).build_transaction(transaction=transaction)
581
+ else:
582
+ txn_data = contract.functions.redeemPositions(
583
+ self.usdc_address,
584
+ HASH_ZERO,
585
+ condition_id,
586
+ [1, 2],
587
+ ).build_transaction(transaction=transaction)
396
588
  case 1:
397
- nonce = self.w3.eth.get_transaction_count(self.account.address)
398
589
  proxy_txn = {
399
590
  "typeCode": 1,
400
591
  "to": to,
401
592
  "value": 0,
402
593
  "data": data,
403
594
  }
404
-
405
595
  txn_data = self.proxy_factory.functions.proxy(
406
596
  [proxy_txn]
407
- ).build_transaction(
408
- {
409
- "nonce": nonce,
410
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
411
- "gas": 1000000,
412
- "from": self.account.address,
413
- }
414
- )
597
+ ).build_transaction(transaction=transaction)
415
598
  case 2:
416
- nonce = self.safe.functions.nonce().call()
599
+ safe_nonce = self.safe.functions.nonce().call()
417
600
  safe_txn = {
418
601
  "to": to,
419
602
  "data": data,
420
603
  "operation": 0, # 1 for delegatecall, 0 for call
421
604
  "value": 0,
422
605
  }
423
-
424
606
  packed_sig = sign_safe_transaction(
425
- self.account, self.safe, safe_txn, nonce
607
+ self.account, self.safe, safe_txn, safe_nonce
426
608
  )
427
609
  txn_data = self.safe.functions.execTransaction(
428
610
  safe_txn["to"],
@@ -435,16 +617,7 @@ class PolymarketWeb3Client:
435
617
  ADDRESS_ZERO, # gasToken
436
618
  ADDRESS_ZERO, # refundReceiver
437
619
  packed_sig,
438
- ).build_transaction(
439
- {
440
- "nonce": self.w3.eth.get_transaction_count(
441
- self.account.address
442
- ),
443
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
444
- "gas": 1000000,
445
- "from": self.account.address,
446
- }
447
- )
620
+ ).build_transaction(transaction=transaction)
448
621
 
449
622
  # Sign and send transaction
450
623
  signed_txn = self.account.sign_transaction(txn_data)
@@ -458,19 +631,30 @@ class PolymarketWeb3Client:
458
631
 
459
632
  print("Done!")
460
633
 
634
+ return f"0x{tx_hash_hex}"
635
+
461
636
  def convert_positions(
462
- self, question_ids: list[Keccak256], neg_risk_market_id: Keccak256, amount: int
463
- ):
464
- nonce = self.w3.eth.get_transaction_count(self.account.address)
637
+ self,
638
+ question_ids: list[Keccak256],
639
+ amount: float,
640
+ ) -> str:
465
641
  amount = int(amount * 1e6)
642
+ neg_risk_market_id = question_ids[0][:-2] + "00"
466
643
  data = self._encode_convert(
467
644
  neg_risk_market_id, get_index_set(question_ids), amount
468
645
  )
469
646
  to = self.neg_risk_adapter_address
647
+ transaction = self._build_transaction()
648
+ txn_data: TxParams | None = None
470
649
 
471
650
  match self.signature_type:
651
+ case 0:
652
+ txn_data = self.neg_risk_adapter.functions.convertPositions(
653
+ neg_risk_market_id,
654
+ get_index_set(question_ids),
655
+ amount,
656
+ ).build_transaction(transaction=transaction)
472
657
  case 1:
473
- nonce = self.w3.eth.get_transaction_count(self.account.address)
474
658
  proxy_txn = {
475
659
  "typeCode": 1,
476
660
  "to": to,
@@ -480,16 +664,9 @@ class PolymarketWeb3Client:
480
664
 
481
665
  txn_data = self.proxy_factory.functions.proxy(
482
666
  [proxy_txn]
483
- ).build_transaction(
484
- {
485
- "nonce": nonce,
486
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
487
- "gas": 1000000,
488
- "from": self.account.address,
489
- }
490
- )
667
+ ).build_transaction(transaction=transaction)
491
668
  case 2:
492
- nonce = self.safe.functions.nonce().call()
669
+ safe_nonce = self.safe.functions.nonce().call()
493
670
  safe_txn = {
494
671
  "to": to,
495
672
  "data": data,
@@ -498,7 +675,7 @@ class PolymarketWeb3Client:
498
675
  }
499
676
 
500
677
  packed_sig = sign_safe_transaction(
501
- self.account, self.safe, safe_txn, nonce
678
+ self.account, self.safe, safe_txn, safe_nonce
502
679
  )
503
680
  txn_data = self.safe.functions.execTransaction(
504
681
  safe_txn["to"],
@@ -511,16 +688,7 @@ class PolymarketWeb3Client:
511
688
  ADDRESS_ZERO, # gasToken
512
689
  ADDRESS_ZERO, # refundReceiver
513
690
  packed_sig,
514
- ).build_transaction(
515
- {
516
- "nonce": self.w3.eth.get_transaction_count(
517
- self.account.address
518
- ),
519
- "gasPrice": int(1.05 * self.w3.eth.gas_price),
520
- "gas": 1000000,
521
- "from": self.account.address,
522
- }
523
- )
691
+ ).build_transaction(transaction=transaction)
524
692
 
525
693
  # Sign and send transaction
526
694
  signed_txn = self.account.sign_transaction(txn_data)
@@ -533,3 +701,5 @@ class PolymarketWeb3Client:
533
701
  self.w3.eth.wait_for_transaction_receipt(tx_hash)
534
702
 
535
703
  print("Done!")
704
+
705
+ return f"0x{tx_hash_hex}"