opinion-clob-sdk 0.1.12__py3-none-any.whl → 0.1.14__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.

Potentially problematic release.


This version of opinion-clob-sdk might be problematic. Click here for more details.

Files changed (114) hide show
  1. opinion_clob_sdk/__init__.py +1 -1
  2. opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  3. opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  4. opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  5. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  6. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  7. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  8. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  9. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  10. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  11. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  12. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  13. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  14. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  15. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  16. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  17. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  18. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  19. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  20. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  21. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  22. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  23. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +1 -1
  24. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +32 -32
  25. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +26 -0
  26. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/__init__.py +0 -0
  27. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contract_caller.py +390 -0
  28. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/__init__.py +0 -0
  29. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/conditional_tokens.py +707 -0
  30. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/erc20.py +111 -0
  31. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/exception.py +11 -0
  32. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/__init__.py +0 -0
  33. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/__init__.py +0 -0
  34. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/base_builder.py +41 -0
  35. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/exception.py +2 -0
  36. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/order_builder.py +90 -0
  37. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/order_builder_test.py +40 -0
  38. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/constants.py +2 -0
  39. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/__init__.py +0 -0
  40. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/order.py +254 -0
  41. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/order_type.py +9 -0
  42. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/sides.py +8 -0
  43. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/signatures.py +8 -0
  44. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/signer.py +20 -0
  45. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +182 -0
  46. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/__init__.py +0 -0
  47. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/constants.py +19 -0
  48. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/eip712/__init__.py +176 -0
  49. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/enums.py +6 -0
  50. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/exceptions.py +94 -0
  51. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/multisend.py +347 -0
  52. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe.py +141 -0
  53. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/__init__.py +0 -0
  54. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/compatibility_fallback_handler_v1_3_0.py +327 -0
  55. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/multisend_v1_3_0.py +22 -0
  56. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/safe_v1_3_0.py +1035 -0
  57. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/utils.py +26 -0
  58. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_signature.py +364 -0
  59. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_test.py +37 -0
  60. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_tx.py +437 -0
  61. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/signatures.py +63 -0
  62. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/typing.py +17 -0
  63. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/utils.py +218 -0
  64. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/config.py +4 -0
  65. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/model.py +19 -0
  66. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/__init__.py +26 -0
  67. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/__init__.py +0 -0
  68. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contract_caller.py +390 -0
  69. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/__init__.py +0 -0
  70. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/conditional_tokens.py +707 -0
  71. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/contracts/erc20.py +111 -0
  72. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/exception.py +11 -0
  73. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/__init__.py +0 -0
  74. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/__init__.py +0 -0
  75. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/base_builder.py +41 -0
  76. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/exception.py +2 -0
  77. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/order_builder.py +90 -0
  78. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/builders/order_builder_test.py +40 -0
  79. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/constants.py +2 -0
  80. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/__init__.py +0 -0
  81. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/order.py +254 -0
  82. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/order_type.py +9 -0
  83. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/sides.py +8 -0
  84. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/model/signatures.py +8 -0
  85. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/signer.py +20 -0
  86. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/py_order_utils/utils.py +182 -0
  87. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/__init__.py +0 -0
  88. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/constants.py +19 -0
  89. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/eip712/__init__.py +176 -0
  90. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/enums.py +6 -0
  91. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/exceptions.py +94 -0
  92. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/multisend.py +347 -0
  93. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe.py +141 -0
  94. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/__init__.py +0 -0
  95. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/compatibility_fallback_handler_v1_3_0.py +327 -0
  96. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/multisend_v1_3_0.py +22 -0
  97. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/safe_v1_3_0.py +1035 -0
  98. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_contracts/utils.py +26 -0
  99. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_signature.py +364 -0
  100. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_test.py +37 -0
  101. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/safe_tx.py +437 -0
  102. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/signatures.py +63 -0
  103. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/typing.py +17 -0
  104. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/chain/safe/utils.py +218 -0
  105. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/config.py +4 -0
  106. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/model.py +19 -0
  107. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/sdk.py +957 -0
  108. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/sdk.py +957 -0
  109. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/verify_api_calls.py +135 -0
  110. opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/opinion_clob_sdk/verify_api_calls.py +135 -0
  111. {opinion_clob_sdk-0.1.12.dist-info → opinion_clob_sdk-0.1.14.dist-info}/METADATA +2 -2
  112. {opinion_clob_sdk-0.1.12.dist-info → opinion_clob_sdk-0.1.14.dist-info}/RECORD +114 -28
  113. {opinion_clob_sdk-0.1.12.dist-info → opinion_clob_sdk-0.1.14.dist-info}/WHEEL +0 -0
  114. {opinion_clob_sdk-0.1.12.dist-info → opinion_clob_sdk-0.1.14.dist-info}/top_level.txt +0 -0
@@ -77,8 +77,8 @@ def calculate_order_amounts(price: float, maker_amount: int, side: OrderSide, de
77
77
  """
78
78
  Calculate the maker and taker amounts based on the price and side.
79
79
 
80
- Uses precise Decimal arithmetic to ensure precision within 6 significant digits
81
- (matching the matching engine's precision limit).
80
+ Uses precise Decimal arithmetic to ensure precision within 4 significant digits
81
+ (to stay well within the matching engine's 6-digit precision limit).
82
82
 
83
83
  Args:
84
84
  price: The price of the order (between 0.001 and 0.999)
@@ -113,59 +113,59 @@ def calculate_order_amounts(price: float, maker_amount: int, side: OrderSide, de
113
113
 
114
114
  if side == OrderSide.BUY:
115
115
  # For BUY: price = maker/taker
116
- # Goal: Calculate taker and maker with only 6 significant digits each
117
- # to match the matching engine's precision requirement
116
+ # Goal: Calculate taker and maker with only 4 significant digits each
117
+ # to stay well within the matching engine's 6-digit precision limit
118
118
  #
119
119
  # Strategy:
120
- # 1. Round maker_amount to 6 significant digits
121
- # 2. Calculate taker = round(maker_6digit / price) to 6 significant digits
122
- # 3. Recalculate maker = round(taker_6digit * price) to verify precision
120
+ # 1. Round maker_amount to 4 significant digits
121
+ # 2. Calculate taker = round(maker_4digit / price) to 4 significant digits
122
+ # 3. Recalculate maker = round(taker_4digit * price) to verify precision
123
123
  #
124
- # This ensures: maker_6digit / taker_6digit = price (exact match within 6 digits)
124
+ # This ensures: maker_4digit / taker_4digit = price (exact match within 4 digits)
125
125
 
126
- # Step 1: Round maker to 6 significant digits
127
- maker_6digit = round_to_significant_digits(maker_amount, 6)
126
+ # Step 1: Round maker to 4 significant digits
127
+ maker_4digit = round_to_significant_digits(maker_amount, 4)
128
128
 
129
129
  # Step 2: Calculate taker = maker / price
130
- exact_taker = Decimal(str(maker_6digit)) / price_decimal
130
+ exact_taker = Decimal(str(maker_4digit)) / price_decimal
131
131
  taker_amount = int(exact_taker)
132
132
 
133
- # Step 3: Round taker to 6 significant digits
134
- taker_6digit = round_to_significant_digits(taker_amount, 6)
133
+ # Step 3: Round taker to 4 significant digits
134
+ taker_4digit = round_to_significant_digits(taker_amount, 4)
135
135
 
136
- # Step 4: Recalculate maker using 6-digit taker to ensure precision
137
- recalculated_maker_decimal = Decimal(str(taker_6digit)) * price_decimal
136
+ # Step 4: Recalculate maker using 4-digit taker to ensure precision
137
+ recalculated_maker_decimal = Decimal(str(taker_4digit)) * price_decimal
138
138
  recalculated_maker_amount = int(recalculated_maker_decimal)
139
139
 
140
- # Step 5: Round recalculated maker to 6 significant digits
141
- recalculated_maker_6digit = round_to_significant_digits(recalculated_maker_amount, 6)
140
+ # Step 5: Round recalculated maker to 4 significant digits
141
+ recalculated_maker_4digit = round_to_significant_digits(recalculated_maker_amount, 4)
142
142
 
143
- # Use the 6-digit values
144
- taker_amount = taker_6digit
145
- recalculated_maker_amount = recalculated_maker_6digit
143
+ # Use the 4-digit values
144
+ taker_amount = taker_4digit
145
+ recalculated_maker_amount = recalculated_maker_4digit
146
146
 
147
147
  else: # SELL
148
148
  # For SELL: price = taker/maker
149
- # Goal: Calculate taker and maker with only 6 significant digits each
149
+ # Goal: Calculate taker and maker with only 4 significant digits each
150
150
  #
151
151
  # Strategy:
152
- # 1. Round maker_amount to 6 significant digits
153
- # 2. Calculate taker = round(maker_6digit * price) to 6 significant digits
154
- # 3. This ensures: taker_6digit / maker_6digit = price (exact match within 6 digits)
152
+ # 1. Round maker_amount to 4 significant digits
153
+ # 2. Calculate taker = round(maker_4digit * price) to 4 significant digits
154
+ # 3. This ensures: taker_4digit / maker_4digit = price (exact match within 4 digits)
155
155
 
156
- # Step 1: Round maker to 6 significant digits
157
- maker_6digit = round_to_significant_digits(maker_amount, 6)
156
+ # Step 1: Round maker to 4 significant digits
157
+ maker_4digit = round_to_significant_digits(maker_amount, 4)
158
158
 
159
159
  # Step 2: Calculate taker = maker * price
160
- exact_taker = Decimal(str(maker_6digit)) * price_decimal
160
+ exact_taker = Decimal(str(maker_4digit)) * price_decimal
161
161
  taker_amount = int(exact_taker)
162
162
 
163
- # Step 3: Round taker to 6 significant digits
164
- taker_6digit = round_to_significant_digits(taker_amount, 6)
163
+ # Step 3: Round taker to 4 significant digits
164
+ taker_4digit = round_to_significant_digits(taker_amount, 4)
165
165
 
166
- # Use the 6-digit values
167
- taker_amount = taker_6digit
168
- recalculated_maker_amount = maker_6digit
166
+ # Use the 4-digit values
167
+ taker_amount = taker_4digit
168
+ recalculated_maker_amount = maker_4digit
169
169
 
170
170
  # Ensure amounts are at least 1
171
171
  taker_amount = int(max(1, taker_amount))
@@ -12,7 +12,7 @@ from opinion_clob_sdk.chain.exception import (
12
12
  InsufficientGasBalance
13
13
  )
14
14
 
15
- __version__ = "0.1.12"
15
+ __version__ = "0.1.14"
16
16
  __all__ = [
17
17
  "Client",
18
18
  "TopicStatus",
@@ -77,8 +77,8 @@ def calculate_order_amounts(price: float, maker_amount: int, side: OrderSide, de
77
77
  """
78
78
  Calculate the maker and taker amounts based on the price and side.
79
79
 
80
- Uses precise Decimal arithmetic to ensure precision within 6 significant digits
81
- (matching the matching engine's precision limit).
80
+ Uses precise Decimal arithmetic to ensure precision within 4 significant digits
81
+ (to stay well within the matching engine's 6-digit precision limit).
82
82
 
83
83
  Args:
84
84
  price: The price of the order (between 0.001 and 0.999)
@@ -113,59 +113,59 @@ def calculate_order_amounts(price: float, maker_amount: int, side: OrderSide, de
113
113
 
114
114
  if side == OrderSide.BUY:
115
115
  # For BUY: price = maker/taker
116
- # Goal: Calculate taker and maker with only 6 significant digits each
117
- # to match the matching engine's precision requirement
116
+ # Goal: Calculate taker and maker with only 4 significant digits each
117
+ # to stay well within the matching engine's 6-digit precision limit
118
118
  #
119
119
  # Strategy:
120
- # 1. Round maker_amount to 6 significant digits
121
- # 2. Calculate taker = round(maker_6digit / price) to 6 significant digits
122
- # 3. Recalculate maker = round(taker_6digit * price) to verify precision
120
+ # 1. Round maker_amount to 4 significant digits
121
+ # 2. Calculate taker = round(maker_4digit / price) to 4 significant digits
122
+ # 3. Recalculate maker = round(taker_4digit * price) to verify precision
123
123
  #
124
- # This ensures: maker_6digit / taker_6digit = price (exact match within 6 digits)
124
+ # This ensures: maker_4digit / taker_4digit = price (exact match within 4 digits)
125
125
 
126
- # Step 1: Round maker to 6 significant digits
127
- maker_6digit = round_to_significant_digits(maker_amount, 6)
126
+ # Step 1: Round maker to 4 significant digits
127
+ maker_4digit = round_to_significant_digits(maker_amount, 4)
128
128
 
129
129
  # Step 2: Calculate taker = maker / price
130
- exact_taker = Decimal(str(maker_6digit)) / price_decimal
130
+ exact_taker = Decimal(str(maker_4digit)) / price_decimal
131
131
  taker_amount = int(exact_taker)
132
132
 
133
- # Step 3: Round taker to 6 significant digits
134
- taker_6digit = round_to_significant_digits(taker_amount, 6)
133
+ # Step 3: Round taker to 4 significant digits
134
+ taker_4digit = round_to_significant_digits(taker_amount, 4)
135
135
 
136
- # Step 4: Recalculate maker using 6-digit taker to ensure precision
137
- recalculated_maker_decimal = Decimal(str(taker_6digit)) * price_decimal
136
+ # Step 4: Recalculate maker using 4-digit taker to ensure precision
137
+ recalculated_maker_decimal = Decimal(str(taker_4digit)) * price_decimal
138
138
  recalculated_maker_amount = int(recalculated_maker_decimal)
139
139
 
140
- # Step 5: Round recalculated maker to 6 significant digits
141
- recalculated_maker_6digit = round_to_significant_digits(recalculated_maker_amount, 6)
140
+ # Step 5: Round recalculated maker to 4 significant digits
141
+ recalculated_maker_4digit = round_to_significant_digits(recalculated_maker_amount, 4)
142
142
 
143
- # Use the 6-digit values
144
- taker_amount = taker_6digit
145
- recalculated_maker_amount = recalculated_maker_6digit
143
+ # Use the 4-digit values
144
+ taker_amount = taker_4digit
145
+ recalculated_maker_amount = recalculated_maker_4digit
146
146
 
147
147
  else: # SELL
148
148
  # For SELL: price = taker/maker
149
- # Goal: Calculate taker and maker with only 6 significant digits each
149
+ # Goal: Calculate taker and maker with only 4 significant digits each
150
150
  #
151
151
  # Strategy:
152
- # 1. Round maker_amount to 6 significant digits
153
- # 2. Calculate taker = round(maker_6digit * price) to 6 significant digits
154
- # 3. This ensures: taker_6digit / maker_6digit = price (exact match within 6 digits)
152
+ # 1. Round maker_amount to 4 significant digits
153
+ # 2. Calculate taker = round(maker_4digit * price) to 4 significant digits
154
+ # 3. This ensures: taker_4digit / maker_4digit = price (exact match within 4 digits)
155
155
 
156
- # Step 1: Round maker to 6 significant digits
157
- maker_6digit = round_to_significant_digits(maker_amount, 6)
156
+ # Step 1: Round maker to 4 significant digits
157
+ maker_4digit = round_to_significant_digits(maker_amount, 4)
158
158
 
159
159
  # Step 2: Calculate taker = maker * price
160
- exact_taker = Decimal(str(maker_6digit)) * price_decimal
160
+ exact_taker = Decimal(str(maker_4digit)) * price_decimal
161
161
  taker_amount = int(exact_taker)
162
162
 
163
- # Step 3: Round taker to 6 significant digits
164
- taker_6digit = round_to_significant_digits(taker_amount, 6)
163
+ # Step 3: Round taker to 4 significant digits
164
+ taker_4digit = round_to_significant_digits(taker_amount, 4)
165
165
 
166
- # Use the 6-digit values
167
- taker_amount = taker_6digit
168
- recalculated_maker_amount = maker_6digit
166
+ # Use the 4-digit values
167
+ taker_amount = taker_4digit
168
+ recalculated_maker_amount = maker_4digit
169
169
 
170
170
  # Ensure amounts are at least 1
171
171
  taker_amount = int(max(1, taker_amount))
@@ -0,0 +1,26 @@
1
+ """Opinion CLOB SDK - Python SDK for Opinion Prediction Market CLOB API"""
2
+
3
+ from opinion_clob_sdk.sdk import (
4
+ Client,
5
+ CHAIN_ID_BASE_MAINNET,
6
+ SUPPORTED_CHAIN_IDS
7
+ )
8
+ from opinion_clob_sdk.model import TopicStatus, TopicType, TopicStatusFilter
9
+ from opinion_clob_sdk.chain.exception import (
10
+ BalanceNotEnough,
11
+ NoPositionsToRedeem,
12
+ InsufficientGasBalance
13
+ )
14
+
15
+ __version__ = "0.1.14"
16
+ __all__ = [
17
+ "Client",
18
+ "TopicStatus",
19
+ "TopicType",
20
+ "TopicStatusFilter",
21
+ "CHAIN_ID_BASE_MAINNET",
22
+ "SUPPORTED_CHAIN_IDS",
23
+ "BalanceNotEnough",
24
+ "NoPositionsToRedeem",
25
+ "InsufficientGasBalance"
26
+ ]
@@ -0,0 +1,390 @@
1
+ from typing import List, Any
2
+ import time
3
+ import logging
4
+
5
+ from eth_typing import HexStr, ChecksumAddress, Hash32
6
+ from hexbytes import HexBytes
7
+ from web3 import Web3
8
+ from web3.contract import Contract
9
+ from web3.providers import HTTPProvider
10
+
11
+ from .exception import BalanceNotEnough, NoPositionsToRedeem, InsufficientGasBalance
12
+ from .safe.constants import NULL_HASH
13
+ from .safe.multisend import MultiSendTx, MultiSendOperation
14
+ from .safe.safe import Safe
15
+ from .py_order_utils.signer import Signer
16
+ from .safe.utils import get_empty_tx_params
17
+
18
+
19
+ class ContractCaller:
20
+ def __init__(self, rpc_url='', private_key: HexStr = '', multi_sig_addr: ChecksumAddress = '',
21
+ conditional_tokens_addr: ChecksumAddress = '', multisend_addr: ChecksumAddress = '',
22
+ enable_trading_check_interval=3600):
23
+ """
24
+ Initialize ContractCaller for blockchain interactions.
25
+
26
+ Args:
27
+ rpc_url: RPC endpoint URL
28
+ private_key: Private key for signing transactions
29
+ multi_sig_addr: Multi-signature wallet address
30
+ conditional_tokens_addr: Conditional tokens contract address
31
+ multisend_addr: Multisend contract address
32
+ enable_trading_check_interval: Time interval (in seconds) to cache enable_trading checks.
33
+ Default is 3600 (1 hour). Within this interval, enable_trading() will return
34
+ immediately without checking blockchain state, improving performance significantly.
35
+ """
36
+ self.private_key = private_key
37
+ self.signer = Signer(self.private_key)
38
+
39
+ self.multi_sig_addr = multi_sig_addr
40
+ self.conditional_tokens_addr = conditional_tokens_addr
41
+ self.multisend_addr = multisend_addr
42
+ w3 = Web3(HTTPProvider(rpc_url))
43
+ self.w3 = w3
44
+ self.safe = Safe(w3, private_key, multi_sig_addr, multisend_addr)
45
+ self.__enable_trading_check_interval: int = enable_trading_check_interval
46
+ self.__enable_trading_last_time: float = None
47
+ # Cache for token decimals to avoid repeated contract calls
48
+ self._token_decimals_cache: dict = {}
49
+
50
+ @property
51
+ def conditional_tokens(self) -> Contract:
52
+ from .contracts.conditional_tokens import abi
53
+ return self.w3.eth.contract(self.conditional_tokens_addr, abi=abi)
54
+
55
+ def get_erc20_contract(self, address: ChecksumAddress):
56
+ from .contracts.erc20 import abi
57
+ return self.w3.eth.contract(address, abi=abi)
58
+
59
+ def get_token_decimals(self, token_address: ChecksumAddress) -> int:
60
+ """Get token decimals with caching to avoid repeated contract calls"""
61
+ token_key = token_address.lower()
62
+
63
+ if token_key not in self._token_decimals_cache:
64
+ erc20_contract = self.get_erc20_contract(token_address)
65
+ try:
66
+ decimals = erc20_contract.functions.decimals().call()
67
+ self._token_decimals_cache[token_key] = decimals
68
+ logging.info(f'Token {token_address} uses {decimals} decimals')
69
+ except Exception as e:
70
+ logging.warning(f'Failed to get decimals for {token_address}, defaulting to 18: {e}')
71
+ # Default to 18 if call fails (standard for most tokens)
72
+ decimals = 18
73
+ self._token_decimals_cache[token_key] = decimals
74
+
75
+ return self._token_decimals_cache[token_key]
76
+
77
+ def check_gas_balance(self, estimated_gas: int = 500000) -> None:
78
+ """
79
+ Check if signer has enough gas tokens (ETH) to execute transaction.
80
+
81
+ Args:
82
+ estimated_gas: Estimated gas units needed (default: 500000)
83
+
84
+ Raises:
85
+ InsufficientGasBalance: If signer doesn't have enough ETH for gas
86
+ """
87
+ signer_address = self.signer.address()
88
+ gas_balance = self.w3.eth.get_balance(signer_address)
89
+
90
+ # Get current gas price with safety margin
91
+ base_fee = self.w3.eth.get_block('latest').get('baseFeePerGas', 0)
92
+
93
+ # For EIP-1559 chains, calculate max fee
94
+ if base_fee > 0:
95
+ # Priority fee (tip) - typically 1-2 gwei on Base
96
+ max_priority_fee = self.w3.to_wei(2, 'gwei')
97
+ # Max fee = base fee * 2 + priority fee (allows for 2x base fee increase)
98
+ max_fee_per_gas = (base_fee * 2) + max_priority_fee
99
+ gas_price = max_fee_per_gas
100
+ else:
101
+ # Fallback for legacy transactions
102
+ gas_price = self.w3.eth.gas_price
103
+
104
+ # Add 20% safety margin to estimated gas
105
+ estimated_gas_with_margin = int(estimated_gas * 1.2)
106
+
107
+ # Calculate required ETH (gas * gas_price)
108
+ required_eth = estimated_gas_with_margin * gas_price
109
+
110
+ if gas_balance < required_eth:
111
+ gas_balance_eth = self.w3.from_wei(gas_balance, 'ether')
112
+ required_eth_formatted = self.w3.from_wei(required_eth, 'ether')
113
+ gas_price_gwei = self.w3.from_wei(gas_price, 'gwei')
114
+ raise InsufficientGasBalance(
115
+ f"Insufficient gas balance. Signer {signer_address} has {gas_balance_eth} ETH, "
116
+ f"but needs approximately {required_eth_formatted} ETH for gas "
117
+ f"(gas: {estimated_gas_with_margin}, price: {gas_price_gwei} gwei)"
118
+ )
119
+
120
+ logging.info(
121
+ f"Gas balance check passed. Signer has {self.w3.from_wei(gas_balance, 'ether')} ETH, "
122
+ f"estimated cost: {self.w3.from_wei(required_eth, 'ether')} ETH "
123
+ f"(gas: {estimated_gas_with_margin}, price: {self.w3.from_wei(gas_price, 'gwei')} gwei)"
124
+ )
125
+
126
+ def estimate_transaction_gas(self, tx_params: dict) -> int:
127
+ """
128
+ Estimate gas for a transaction using web3's gas estimation.
129
+
130
+ Args:
131
+ tx_params: Transaction parameters dict with 'from', 'to', 'data', etc.
132
+
133
+ Returns:
134
+ Estimated gas units needed
135
+ """
136
+ try:
137
+ estimated = self.w3.eth.estimate_gas(tx_params)
138
+ logging.debug(f"Estimated gas for transaction: {estimated}")
139
+ return estimated
140
+ except Exception as e:
141
+ logging.warning(f"Gas estimation failed, using fallback: {e}")
142
+ # Fallback to conservative estimate
143
+ return 500000
144
+
145
+
146
+ def split(self, collateral_token: ChecksumAddress, condition_id: Hash32,
147
+ amount: int, partition: list = [1, 2], parent_collection_id: Hash32 = NULL_HASH) -> tuple[HexBytes, HexBytes, Any]:
148
+
149
+ # Check gas balance before executing transaction
150
+ self.check_gas_balance(estimated_gas=300000)
151
+
152
+ # Check balance of collateral
153
+ balance = self.get_erc20_contract(collateral_token).functions \
154
+ .balanceOf(self.multi_sig_addr).call()
155
+ logging.info(f'Collateral balance: {balance}')
156
+ if balance < amount:
157
+ raise BalanceNotEnough()
158
+
159
+ multi_send_txs: List[MultiSendTx] = []
160
+
161
+ data = HexBytes(
162
+ self.conditional_tokens.functions.splitPosition(
163
+ collateral_token, parent_collection_id, condition_id, partition, amount
164
+ ).build_transaction(get_empty_tx_params())["data"]
165
+ )
166
+
167
+ multi_send_txs.append(MultiSendTx(
168
+ operation=MultiSendOperation.CALL.value,
169
+ to=self.conditional_tokens_addr,
170
+ value=0,
171
+ data=data,
172
+ ))
173
+
174
+ tx_hash, safe_tx_hash, return_value = self.safe.execute_multisend(multi_send_txs)
175
+
176
+ # Validate transaction was successful
177
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
178
+ if receipt['status'] != 1:
179
+ raise Exception(f"Split transaction failed. Transaction hash: {tx_hash.hex()}")
180
+
181
+ logging.info(f"Split successful. Transaction hash: {tx_hash.hex()}")
182
+ return tx_hash, safe_tx_hash, return_value
183
+
184
+ def merge(self, collateral_token: ChecksumAddress, condition_id: Hash32,
185
+ amount: int, partition: list = [1, 2], parent_collection_id: Hash32 = NULL_HASH) -> tuple[HexBytes, HexBytes, Any]:
186
+
187
+ # Check gas balance before executing transaction
188
+ self.check_gas_balance(estimated_gas=300000)
189
+
190
+ # Check balance of positions
191
+ for index_set in partition:
192
+ position_id = self.get_position_id(condition_id, index_set=index_set, collateral_token=collateral_token)
193
+ balance = self.conditional_tokens.functions \
194
+ .balanceOf(self.multi_sig_addr, position_id).call()
195
+ # print('balance: {}'.format(balance))
196
+ if balance < amount:
197
+ raise BalanceNotEnough()
198
+
199
+ multi_send_txs: List[MultiSendTx] = []
200
+
201
+ data = HexBytes(
202
+ self.conditional_tokens.functions.mergePositions(
203
+ collateral_token, parent_collection_id, condition_id, partition, amount
204
+ ).build_transaction(get_empty_tx_params())["data"]
205
+ )
206
+
207
+ multi_send_txs.append(MultiSendTx(
208
+ operation=MultiSendOperation.CALL.value,
209
+ to=self.conditional_tokens_addr,
210
+ value=0,
211
+ data=data,
212
+ ))
213
+
214
+ tx_hash, safe_tx_hash, return_value = self.safe.execute_multisend(multi_send_txs)
215
+
216
+ # Validate transaction was successful
217
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
218
+ if receipt['status'] != 1:
219
+ raise Exception(f"Merge transaction failed. Transaction hash: {tx_hash.hex()}")
220
+
221
+ logging.info(f"Merge successful. Transaction hash: {tx_hash.hex()}")
222
+ return tx_hash, safe_tx_hash, return_value
223
+
224
+ def redeem(self, collateral_token: ChecksumAddress, condition_id: Hash32,
225
+ partition: list = [1, 2], parent_collection_id: Hash32 = NULL_HASH) -> tuple[HexBytes, HexBytes, Any]:
226
+
227
+ # Check gas balance before executing transaction
228
+ self.check_gas_balance(estimated_gas=300000)
229
+
230
+ # Check balance of positions
231
+ has_positions = False
232
+ for index_set in partition:
233
+ position_id = self.get_position_id(condition_id, index_set=index_set, collateral_token=collateral_token)
234
+ balance = self.conditional_tokens.functions \
235
+ .balanceOf(self.multi_sig_addr, position_id).call()
236
+ # print('balance: {}'.format(balance))
237
+ if balance > 0:
238
+ has_positions = True
239
+ break
240
+
241
+ if not has_positions:
242
+ raise NoPositionsToRedeem
243
+
244
+ multi_send_txs: List[MultiSendTx] = []
245
+
246
+ data = HexBytes(
247
+ self.conditional_tokens.functions.redeemPositions(
248
+ collateral_token, parent_collection_id, condition_id, partition
249
+ ).build_transaction(get_empty_tx_params())["data"]
250
+ )
251
+
252
+ multi_send_txs.append(MultiSendTx(
253
+ operation=MultiSendOperation.CALL.value,
254
+ to=self.conditional_tokens_addr,
255
+ value=0,
256
+ data=data,
257
+ ))
258
+
259
+ tx_hash, safe_tx_hash, return_value = self.safe.execute_multisend(multi_send_txs)
260
+
261
+ # Validate transaction was successful
262
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
263
+ if receipt['status'] != 1:
264
+ raise Exception(f"Redeem transaction failed. Transaction hash: {tx_hash.hex()}")
265
+
266
+ logging.info(f"Redeem successful. Transaction hash: {tx_hash.hex()}")
267
+ return tx_hash, safe_tx_hash, return_value
268
+
269
+ def enable_trading(self, supported_quote_tokens: dict) -> tuple[HexBytes, HexBytes, Any]:
270
+ if self.__enable_trading_last_time is not None and \
271
+ time.time() - self.__enable_trading_last_time < self.__enable_trading_check_interval:
272
+ return HexBytes(b'0x'), HexBytes(b'0x'), None
273
+
274
+ self.__enable_trading_last_time = time.time()
275
+
276
+ # Check gas balance before executing transaction (approve operations can be gas-heavy)
277
+ self.check_gas_balance(estimated_gas=500000)
278
+
279
+ multi_send_txs: List[MultiSendTx] = []
280
+
281
+ from .contracts.erc20 import abi
282
+ for erc20_address, ctf_exchange_address in supported_quote_tokens.items():
283
+ erc20_contract = self.w3.eth.contract(erc20_address, abi=abi)
284
+ allowance = erc20_contract.functions.allowance(self.multi_sig_addr, ctf_exchange_address).call()
285
+
286
+ # Get actual token decimals from contract
287
+ decimals = self.get_token_decimals(erc20_address)
288
+
289
+ # Used for trading on ctf_exchange
290
+ min_threshold = 1000000000 * 10**decimals
291
+ allowance_to_update = 2*1000000000 * 10**decimals
292
+ if allowance < min_threshold:
293
+ # DH1 Fix: Reset approval to 0 first (required for some tokens like USDT)
294
+ # to prevent approval race condition attack
295
+ if allowance > 0:
296
+ reset_data = HexBytes(
297
+ erc20_contract.functions.approve(
298
+ ctf_exchange_address, 0
299
+ ).build_transaction(get_empty_tx_params())["data"]
300
+ )
301
+ multi_send_txs.append(MultiSendTx(
302
+ operation=MultiSendOperation.CALL.value,
303
+ to=erc20_address,
304
+ value=0,
305
+ data=reset_data,
306
+ ))
307
+ logging.info(f'Resetting approval to 0 for {erc20_address} -> {ctf_exchange_address}')
308
+
309
+ # Now set the new approval amount
310
+ data = HexBytes(
311
+ erc20_contract.functions.approve(
312
+ ctf_exchange_address, allowance_to_update
313
+ ).build_transaction(get_empty_tx_params())["data"]
314
+ )
315
+
316
+ multi_send_txs.append(MultiSendTx(
317
+ operation=MultiSendOperation.CALL.value,
318
+ to=erc20_address,
319
+ value=0,
320
+ data=data,
321
+ ))
322
+
323
+ # Used for splitting
324
+ allowance = erc20_contract.functions.allowance(self.multi_sig_addr, self.conditional_tokens_addr).call()
325
+ if allowance < min_threshold:
326
+ # DH1 Fix: Reset approval to 0 first (required for some tokens like USDT)
327
+ if allowance > 0:
328
+ reset_data = HexBytes(
329
+ erc20_contract.functions.approve(
330
+ self.conditional_tokens_addr, 0
331
+ ).build_transaction(get_empty_tx_params())["data"]
332
+ )
333
+ multi_send_txs.append(MultiSendTx(
334
+ operation=MultiSendOperation.CALL.value,
335
+ to=erc20_address,
336
+ value=0,
337
+ data=reset_data,
338
+ ))
339
+ logging.info(f'Resetting approval to 0 for {erc20_address} -> {self.conditional_tokens_addr}')
340
+
341
+ # Now set the new approval amount
342
+ data = HexBytes(
343
+ erc20_contract.functions.approve(
344
+ self.conditional_tokens_addr, allowance_to_update
345
+ ).build_transaction(get_empty_tx_params())["data"]
346
+ )
347
+
348
+ multi_send_txs.append(MultiSendTx(
349
+ operation=MultiSendOperation.CALL.value,
350
+ to=erc20_address,
351
+ value=0,
352
+ data=data,
353
+ ))
354
+
355
+ # Approve ctf_exchange for using conditional tokens
356
+ is_approved_for_all = self.conditional_tokens.functions.isApprovedForAll(
357
+ self.multi_sig_addr, ctf_exchange_address).call()
358
+ if is_approved_for_all is False:
359
+ data = HexBytes(
360
+ self.conditional_tokens.functions.setApprovalForAll(
361
+ ctf_exchange_address, True
362
+ ).build_transaction(get_empty_tx_params())["data"]
363
+ )
364
+
365
+ multi_send_txs.append(MultiSendTx(
366
+ operation=MultiSendOperation.CALL.value,
367
+ to=self.conditional_tokens_addr,
368
+ value=0,
369
+ data=data,
370
+ ))
371
+
372
+ if len(multi_send_txs) > 0:
373
+ tx_hash, safe_tx_hash, return_value = self.safe.execute_multisend(multi_send_txs)
374
+
375
+ # Validate transaction was successful
376
+ receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash, timeout=120)
377
+ if receipt['status'] != 1:
378
+ raise Exception(f"Enable trading transaction failed. Transaction hash: {tx_hash.hex()}")
379
+
380
+ logging.info(f"Enable trading successful. Transaction hash: {tx_hash.hex()}")
381
+ return tx_hash, safe_tx_hash, return_value
382
+ else:
383
+ return HexBytes(b'0x'), HexBytes(b'0x'), None
384
+
385
+ def get_position_id(self, condition_id: Hash32, index_set: int, collateral_token: ChecksumAddress,
386
+ parent_condition_id=NULL_HASH):
387
+ collection_id = self.conditional_tokens.functions.getCollectionId(
388
+ parent_condition_id, condition_id, index_set).call()
389
+
390
+ return self.conditional_tokens.functions.getPositionId(collateral_token, collection_id).call()