charli3_dendrite 1.6.6.dev0__tar.gz → 1.6.7.dev0__tar.gz

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.
Files changed (158) hide show
  1. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/PKG-INFO +1 -1
  2. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/pyproject.toml +2 -2
  3. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/forward.py +5 -5
  4. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/leaves.py +30 -134
  5. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/reproduce.py +2 -2
  6. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/_common.py +1 -1
  7. charli3_dendrite-1.6.7.dev0/src/charli3_dendrite/lending/liqwid/__init__.py +1 -0
  8. charli3_dendrite-1.6.7.dev0/src/charli3_dendrite/lending/liqwid/datums.py +112 -0
  9. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/units.py +20 -0
  10. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/LICENSE +0 -0
  11. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/README.md +0 -0
  12. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/__init__.py +0 -0
  13. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/__init__.py +0 -0
  14. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/backend_base.py +0 -0
  15. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/blockfrost/__init__.py +0 -0
  16. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/blockfrost/models.py +0 -0
  17. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/dbsync/__init__.py +0 -0
  18. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/dbsync/models.py +0 -0
  19. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/ogmios_kupo/__init__.py +0 -0
  20. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/ogmios_kupo/models.py +0 -0
  21. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/backend/utils.py +0 -0
  22. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dataclasses/__init__.py +0 -0
  23. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dataclasses/datums.py +0 -0
  24. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dataclasses/models.py +0 -0
  25. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/__init__.py +0 -0
  26. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/__init__.py +0 -0
  27. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/amm_base.py +0 -0
  28. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/amm_types.py +0 -0
  29. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/cswap.py +0 -0
  30. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/dano.py +0 -0
  31. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/minswap.py +0 -0
  32. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/muesli.py +0 -0
  33. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/multi_asset.py +0 -0
  34. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/spectrum.py +0 -0
  35. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/splash.py +0 -0
  36. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/sundae.py +0 -0
  37. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/sundae_v4.py +0 -0
  38. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/sundae_v4_banded_cl_math.py +0 -0
  39. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/sundae_v4_deployments.json +0 -0
  40. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/sundae_v4_stableswap_math.py +0 -0
  41. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/vyfi.py +0 -0
  42. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/amm/wingriders.py +0 -0
  43. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/core/__init__.py +0 -0
  44. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/core/base.py +0 -0
  45. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/core/errors.py +0 -0
  46. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/__init__.py +0 -0
  47. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/axo.py +0 -0
  48. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/cardanoswaps.py +0 -0
  49. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/chadswap.py +0 -0
  50. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/djed.py +0 -0
  51. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/geniusyield.py +0 -0
  52. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/ob_base.py +0 -0
  53. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/dexs/ob/saturnswap.py +0 -0
  54. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/__init__.py +0 -0
  55. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/base.py +0 -0
  56. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/__init__.py +0 -0
  57. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/constants.py +0 -0
  58. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/datums.py +0 -0
  59. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/loader.py +0 -0
  60. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/market.py +0 -0
  61. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/math.py +0 -0
  62. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/__init__.py +0 -0
  63. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/aggregator.py +0 -0
  64. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/aggregator_datums.py +0 -0
  65. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/deployments.py +0 -0
  66. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/locator.py +0 -0
  67. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/lp_pricing.py +0 -0
  68. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/recipes.json +0 -0
  69. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/redeemer.py +0 -0
  70. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/oracles/structured_datums.py +0 -0
  71. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/state.py +0 -0
  72. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/__init__.py +0 -0
  73. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/build.py +0 -0
  74. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/builder.py +0 -0
  75. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/context.py +0 -0
  76. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/create_loan.py +0 -0
  77. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/datum_synth.py +0 -0
  78. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/increase_loan.py +0 -0
  79. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/loan_ids.py +0 -0
  80. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/modify_collateral.py +0 -0
  81. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/oracle_redeemer.py +0 -0
  82. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/oracle_synth.py +0 -0
  83. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/redeemers.py +0 -0
  84. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/repay.py +0 -0
  85. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/topup_withdraw.py +0 -0
  86. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/danogo/transactions/verify.py +0 -0
  87. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/__init__.py +0 -0
  88. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/constants.py +0 -0
  89. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/datums.py +0 -0
  90. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/loader.py +0 -0
  91. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/market.py +0 -0
  92. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/math.py +0 -0
  93. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/oracles/__init__.py +0 -0
  94. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/oracles/feeds.py +0 -0
  95. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/oracles/fluid_api.py +0 -0
  96. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/oracles/witness.py +0 -0
  97. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/state.py +0 -0
  98. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/__init__.py +0 -0
  99. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/_common.py +0 -0
  100. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/borrow.py +0 -0
  101. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/borrow_terms.py +0 -0
  102. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/builder.py +0 -0
  103. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/change_collateral.py +0 -0
  104. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/context.py +0 -0
  105. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/datum_synth.py +0 -0
  106. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/lend.py +0 -0
  107. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/pool.py +0 -0
  108. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/recast.py +0 -0
  109. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/redeemers.py +0 -0
  110. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/repay.py +0 -0
  111. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/request.py +0 -0
  112. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/resolve.py +0 -0
  113. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens/transactions/utxos.py +0 -0
  114. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/__init__.py +0 -0
  115. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/constants.py +0 -0
  116. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/datums.py +0 -0
  117. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/indexing.py +0 -0
  118. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/loader.py +0 -0
  119. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/market.py +0 -0
  120. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/rates.py +0 -0
  121. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/state.py +0 -0
  122. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/__init__.py +0 -0
  123. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/borrow.py +0 -0
  124. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/builder.py +0 -0
  125. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/change_collateral.py +0 -0
  126. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/claim.py +0 -0
  127. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/common.py +0 -0
  128. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/lender_bond.py +0 -0
  129. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/loan_action.py +0 -0
  130. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/loan_terms.py +0 -0
  131. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/oracle.py +0 -0
  132. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_action.py +0 -0
  133. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_cancel.py +0 -0
  134. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_create.py +0 -0
  135. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_edit.py +0 -0
  136. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/pool_terms.py +0 -0
  137. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/recast.py +0 -0
  138. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/redeemers.py +0 -0
  139. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/repay.py +0 -0
  140. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/fluidtokens_v4/transactions/resolve.py +0 -0
  141. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/markets.py +0 -0
  142. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/math.py +0 -0
  143. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/normalized.py +0 -0
  144. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/__init__.py +0 -0
  145. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/charli3.py +0 -0
  146. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/dex_pooled.py +0 -0
  147. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/fluid.py +0 -0
  148. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/models.py +0 -0
  149. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/orcfax.py +0 -0
  150. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/oracles/qtoken.py +0 -0
  151. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/plutus.py +0 -0
  152. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/rates.py +0 -0
  153. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/registry.py +0 -0
  154. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/transactions/__init__.py +0 -0
  155. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/transactions/base.py +0 -0
  156. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/transactions/infra.py +0 -0
  157. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/lending/transactions/snapshot.py +0 -0
  158. {charli3_dendrite-1.6.6.dev0 → charli3_dendrite-1.6.7.dev0}/src/charli3_dendrite/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: charli3_dendrite
3
- Version: 1.6.6.dev0
3
+ Version: 1.6.7.dev0
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Elder Millenial
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "charli3_dendrite"
3
- version = "1.6.6-dev0"
3
+ version = "1.6.7-dev0"
4
4
  description = ""
5
5
  authors = ["Elder Millenial <eldermillenial@protonmail.com>"]
6
6
  readme = "README.md"
@@ -50,7 +50,7 @@ module = ["pycardano", "pycardano.*", "dotenv", "nox", "uplc", "uplc.*"]
50
50
  ignore_missing_imports = true
51
51
 
52
52
  [tool.bumpversion]
53
- current_version = "1.6.6-dev0"
53
+ current_version = "1.6.7-dev0"
54
54
  parse = """(?x)
55
55
  (?P<major>\\d+)\\.
56
56
  (?P<minor>\\d+)\\.
@@ -10,8 +10,6 @@ from dataclasses import dataclass
10
10
  from fractions import Fraction
11
11
  from typing import TYPE_CHECKING
12
12
 
13
- from charli3_dendrite.lending.danogo.oracles.leaves import liqwid_oracle_feed_id
14
- from charli3_dendrite.lending.danogo.oracles.leaves import parse_liqwid_oracle_v2
15
13
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_minswap_lp
16
14
  from charli3_dendrite.lending.danogo.oracles.locator import LeafHandle
17
15
  from charli3_dendrite.lending.danogo.oracles.locator import Recipe
@@ -19,6 +17,8 @@ from charli3_dendrite.lending.danogo.oracles.redeemer import OracleUtxoType
19
17
  from charli3_dendrite.lending.danogo.oracles.reproduce import OracleLeaf
20
18
  from charli3_dendrite.lending.danogo.oracles.reproduce import leaf_forward_rates
21
19
  from charli3_dendrite.lending.danogo.oracles.reproduce import splash_lp_candidate
20
+ from charli3_dendrite.lending.liqwid.datums import liqwid_oracle_feed_id
21
+ from charli3_dendrite.lending.liqwid.datums import parse_liqwid_oracle_v2
22
22
  from charli3_dendrite.lending.oracles.models import OraclePrice
23
23
  from charli3_dendrite.lending.oracles.models import OracleSource
24
24
  from charli3_dendrite.lending.oracles.models import PriceMap
@@ -57,9 +57,9 @@ def leaf_discriminator(otype: str, datum: str | None) -> str:
57
57
  Some source kinds live many-to-one behind a shared marker token at a common
58
58
  address, so the value alone cannot pin a UTxO; a stable datum field can:
59
59
 
60
- * Liqwid V2 oracles -> ``feed_id:priced_asset``. Neither part is unique on its own
61
- (one feed id spans many assets; one asset, e.g. ADA, can have several feeds), but
62
- together they pin the UTxO.
60
+ * Liqwid V2 oracles -> ``updater_key:priced_asset``. Neither part is unique on
61
+ its own (one updater key spans many assets; one asset, e.g. ADA, can have
62
+ several feeds), but together they pin the UTxO.
63
63
  * Minswap pools -> the ``asset_a|asset_b`` pair (all pools carry one MSP token).
64
64
 
65
65
  Returns "" for kinds already pinned by a unique NFT (no datum disambiguation
@@ -9,7 +9,6 @@ Verified bit-exact against on-chain ``OraclePriceCalcRdmr`` prices (tx
9
9
  929a7d68...de8237 and 590d...e6a069):
10
10
  * ``danogo_pool_dtoken_rate`` (``TDANOGO_POOL``).
11
11
  * ``parse_danogo_staking_rate`` (``TDANOGO_STAKING``).
12
- * ``parse_liqwid_oracle_v2`` (``TLIQWID_ORACLE_V2``) -- reproduces ADA = 16271/100000.
13
12
  * ``parse_minswap_lp`` + ``cpamm_price_from_reserves`` (``TMINSWAP_LP``) -- the
14
13
  STRIKE/ADA hop of a 3-hop derived price.
15
14
  * ``parse_djed`` (``TDJED``) -- pair rate decoded.
@@ -22,9 +21,9 @@ Value parsers landed; bit-exact end-to-end check pending the ``price_path`` deco
22
21
  (these source types only ever appear as intermediate hops on-chain, never as a
23
22
  standalone collateral price):
24
23
  * ``parse_indigo`` (``TINDIGO``) -- iAsset->ADA, 1e6 scale.
25
- * ``parse_liqwid_market_state`` (``TLIQWID_MARKET_STATE``) -- qToken exchange rate;
26
- reproduces the on-chain qToken price as ``rate/100/ada_usd`` for the one market
27
- that appears on-chain.
24
+
25
+ The Liqwid leaves (``TLIQWID_ORACLE_V2``, ``TLIQWID_MARKET_STATE`` and
26
+ ``TLIQWID_MARKET_PARAM``) are parsed by ``charli3_dendrite.lending.liqwid.datums``.
28
27
 
29
28
  Every ``OracleUtxoType`` observed in full mainnet history (9 of the 17 registry
30
29
  entries) now has a parser, including ``TLIQWID_MARKET_PARAM`` (a config record, not a
@@ -37,12 +36,21 @@ from __future__ import annotations
37
36
 
38
37
  import cbor2 # type: ignore[import-not-found]
39
38
 
40
- from charli3_dendrite.lending.danogo.datums import asset_unit
39
+ # Kept for compatibility: the Liqwid parsers live in
40
+ # ``charli3_dendrite.lending.liqwid.datums``. These re-exports will be removed in a
41
+ # later minor release.
42
+ from charli3_dendrite.lending.liqwid.datums import liqwid_oracle_feed_id # noqa: F401
43
+ from charli3_dendrite.lending.liqwid.datums import liqwid_qtoken_rate # noqa: F401
44
+ from charli3_dendrite.lending.liqwid.datums import ( # noqa: F401
45
+ parse_liqwid_market_param,
46
+ )
47
+ from charli3_dendrite.lending.liqwid.datums import ( # noqa: F401
48
+ parse_liqwid_market_state,
49
+ )
50
+ from charli3_dendrite.lending.liqwid.datums import parse_liqwid_oracle_v2 # noqa: F401
51
+ from charli3_dendrite.lending.units import plutus_fields
52
+ from charli3_dendrite.lending.units import tuple_asset_unit
41
53
 
42
- # Liqwid Oracle V2 datum field order: [feed_id, Constr1[[asset]], [num, denom],
43
- # timestamp_ms, validity_ms, config].
44
- _LIQWID_ASSET_FIELD = 1
45
- _LIQWID_PRICE_FIELD = 2
46
54
  # Minswap V2 pool datum field order: [stake, asset_a, asset_b, total_liquidity,
47
55
  # reserve_a, reserve_b, fee_a, fee_b, ...].
48
56
  _MS_ASSET_A_FIELD = 1
@@ -59,27 +67,6 @@ _SPLASH_ASSET_X_FIELD = 1
59
67
  _SPLASH_ASSET_Y_FIELD = 2
60
68
  _SPLASH_LP_FIELD = 3
61
69
  _SPLASH_MAX_LP = (1 << 63) - 1
62
- # Liqwid market-state datum: the qToken<->underlying exchange rate is the rational at
63
- # index 9 of the 11-field state record.
64
- _LIQWID_MARKET_RATE_FIELD = 9
65
- # Liqwid market-parameter (config) datum: interest-model + risk fields. Only a couple
66
- # carry unambiguous values; the leaf is not a price source.
67
- _LIQWID_PARAM_BASE_RATE_FIELD = 0
68
- _LIQWID_PARAM_COLLATERAL_RATIO_FIELD = 12
69
-
70
-
71
- def _fields(obj: object) -> list:
72
- """Positional fields of a CBOR Constr (or a bare list) as a Python list."""
73
- inner = obj.value if isinstance(obj, cbor2.CBORTag) else obj
74
- return list(inner)
75
-
76
-
77
- def _tuple_asset_unit(arr: object) -> str:
78
- """Dendrite unit string from a ``[policy, name]`` value (Constr-wrapped or bare)."""
79
- seq = _fields(arr)
80
- policy = seq[0] if len(seq) > 0 and isinstance(seq[0], bytes) else b""
81
- name = seq[1] if len(seq) > 1 and isinstance(seq[1], bytes) else b""
82
- return asset_unit(policy, name)
83
70
 
84
71
 
85
72
  def cpamm_price_from_reserves(
@@ -133,7 +120,7 @@ def parse_danogo_staking_rate(datum: str | bytes) -> tuple[int, int]:
133
120
  Raises ValueError on non-positive supply.
134
121
  """
135
122
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
136
- fields = _fields(cbor2.loads(raw))
123
+ fields = plutus_fields(cbor2.loads(raw))
137
124
  total, circulating = int(fields[0]), int(fields[1])
138
125
  if total <= 0 or circulating <= 0:
139
126
  raise ValueError("non-positive staking supply")
@@ -154,47 +141,13 @@ def parse_indigo(datum: str | bytes) -> tuple[int, int]:
154
141
  Raises ValueError on a non-positive price.
155
142
  """
156
143
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
157
- inner = _fields(_fields(cbor2.loads(raw))[0])
144
+ inner = plutus_fields(plutus_fields(cbor2.loads(raw))[0])
158
145
  price = int(inner[0])
159
146
  if price <= 0:
160
147
  raise ValueError("non-positive indigo price")
161
148
  return (price, _INDIGO_SCALE)
162
149
 
163
150
 
164
- def parse_liqwid_oracle_v2(datum: str | bytes) -> tuple[str, tuple[int, int]]:
165
- """Liqwid Oracle V2 leaf -> (priced_asset_unit, (num, denom)).
166
-
167
- Datum is a 6-field record ``[feed_id, Constr1[[asset]], [num, denom], ts, validity,
168
- config]``; the rate is the priced asset in the configured quote. Verified: ADA
169
- (the empty TupleAsset) at (16271, 100000) on tx 929a7d68...de8237 leaf
170
- ``(REF, TLIQWID_ORACLE_V2, 0)``.
171
-
172
- Raises ValueError on a non-positive denominator.
173
- """
174
- raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
175
- fields = _fields(cbor2.loads(raw))
176
- asset_unit_str = _tuple_asset_unit(_fields(fields[_LIQWID_ASSET_FIELD])[0])
177
- price = _fields(fields[_LIQWID_PRICE_FIELD])
178
- num, denom = int(price[0]), int(price[1])
179
- if denom <= 0:
180
- raise ValueError("non-positive liqwid oracle denom")
181
- return asset_unit_str, (num, denom)
182
-
183
-
184
- def liqwid_oracle_feed_id(datum: str | bytes) -> str:
185
- """Liqwid Oracle V2 feed identifier (datum field 0) as hex.
186
-
187
- Several Liqwid feeds can price the same asset (e.g. two ADA feeds) and share one
188
- marker token at a common address, so the asset alone does not pin a UTxO; the
189
- field-0 feed id does and is stable across price updates. Empty string if absent.
190
- """
191
- raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
192
- feed = _fields(cbor2.loads(raw))[0]
193
- if isinstance(feed, (bytes, bytearray)):
194
- return feed.hex()
195
- return str(feed)
196
-
197
-
198
151
  def parse_orcfax_fs(datum: str | bytes) -> tuple[str, tuple[int, int]]:
199
152
  """Orcfax Feed Status leaf -> (feed_name, (num, denom)).
200
153
 
@@ -207,8 +160,8 @@ def parse_orcfax_fs(datum: str | bytes) -> tuple[str, tuple[int, int]]:
207
160
  Raises ValueError on a non-positive denominator.
208
161
  """
209
162
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
210
- body = _fields(_fields(cbor2.loads(raw))[0])
211
- price = _fields(body[2])
163
+ body = plutus_fields(plutus_fields(cbor2.loads(raw))[0])
164
+ price = plutus_fields(body[2])
212
165
  num, denom = int(price[0]), int(price[1])
213
166
  if denom <= 0:
214
167
  raise ValueError("non-positive orcfax denom")
@@ -227,8 +180,8 @@ def parse_djed(datum: str | bytes) -> tuple[str, tuple[int, int]]:
227
180
  Raises ValueError on a non-positive denominator.
228
181
  """
229
182
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
230
- inner = _fields(_fields(cbor2.loads(raw))[1])
231
- price = _fields(inner[0])
183
+ inner = plutus_fields(plutus_fields(cbor2.loads(raw))[1])
184
+ price = plutus_fields(inner[0])
232
185
  num, denom = int(price[0]), int(price[1])
233
186
  pair = inner[2]
234
187
  label = pair.decode() if isinstance(pair, bytes) else str(pair)
@@ -248,11 +201,11 @@ def parse_minswap_lp(datum: str | bytes) -> tuple[str, int, str, int]:
248
201
  feed the STRIKE->ADA hop of a 3-hop derived price.
249
202
  """
250
203
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
251
- fields = _fields(cbor2.loads(raw))
204
+ fields = plutus_fields(cbor2.loads(raw))
252
205
  return (
253
- _tuple_asset_unit(fields[_MS_ASSET_A_FIELD]),
206
+ tuple_asset_unit(fields[_MS_ASSET_A_FIELD]),
254
207
  int(fields[_MS_RESERVE_A_FIELD]),
255
- _tuple_asset_unit(fields[_MS_ASSET_B_FIELD]),
208
+ tuple_asset_unit(fields[_MS_ASSET_B_FIELD]),
256
209
  int(fields[_MS_RESERVE_B_FIELD]),
257
210
  )
258
211
 
@@ -265,11 +218,11 @@ def parse_splash_cpamm_g3(datum: str | bytes) -> tuple[str, str, str]:
265
218
  quote-side reserve and the LP balance. See ``splash_lp_token_price``.
266
219
  """
267
220
  raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
268
- fields = _fields(cbor2.loads(raw))
221
+ fields = plutus_fields(cbor2.loads(raw))
269
222
  return (
270
- _tuple_asset_unit(fields[_SPLASH_ASSET_X_FIELD]),
271
- _tuple_asset_unit(fields[_SPLASH_ASSET_Y_FIELD]),
272
- _tuple_asset_unit(fields[_SPLASH_LP_FIELD]),
223
+ tuple_asset_unit(fields[_SPLASH_ASSET_X_FIELD]),
224
+ tuple_asset_unit(fields[_SPLASH_ASSET_Y_FIELD]),
225
+ tuple_asset_unit(fields[_SPLASH_LP_FIELD]),
273
226
  )
274
227
 
275
228
 
@@ -297,60 +250,3 @@ def splash_lp_token_price(
297
250
  if circulating_lp <= 0 or reserve_quote <= 0:
298
251
  raise ValueError("non-positive circulating LP or reserve")
299
252
  return (2 * reserve_quote, circulating_lp)
300
-
301
-
302
- def parse_liqwid_market_state(datum: str | bytes) -> tuple[int, int]:
303
- """Liqwid market-state leaf -> qToken<->underlying exchange rate (state field 9).
304
-
305
- The 11-field state record carries the exchange rate as the rational at index 9
306
- (underlying per qToken). Returns (num, denom).
307
-
308
- Verified for the one Liqwid market that appears on-chain: with the rate
309
- 360073866973321/12033383669199582 the qToken collateral price reproduces exactly
310
- as ``rate / 100 / ada_usd`` (tx 578fae97...), where the ``/100`` is the
311
- underlying's price and ``ada_usd`` the Liqwid ADA oracle. The two extra factors
312
- are separate path hops, not part of this leaf. All 8 on-chain occurrences are the
313
- same market, so the index-9 location is confirmed but not yet cross-checked
314
- against a second market.
315
-
316
- Raises ValueError on a non-positive rate.
317
- """
318
- raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
319
- rate = _fields(cbor2.loads(raw))[_LIQWID_MARKET_RATE_FIELD]
320
- num, denom = int(rate[0]), int(rate[1])
321
- if num <= 0 or denom <= 0:
322
- raise ValueError("non-positive liqwid market exchange rate")
323
- return (num, denom)
324
-
325
-
326
- def parse_liqwid_market_param(
327
- datum: str | bytes,
328
- ) -> tuple[tuple[int, int], tuple[int, int]]:
329
- """Liqwid market-parameter (config) leaf -> (base_rate, collateral_ratio).
330
-
331
- This leaf is NOT a price source: it carries the market's interest-rate model and
332
- risk parameters (the Danogo oracle takes the qToken exchange rate from the
333
- market-*state* leaf, never from here). Only the two unambiguously-typed rationals
334
- are surfaced -- the per-block base rate at field 0 and the collateral ratio at
335
- field 12 -- both as (num, denom); the remaining 30+ fields are left raw. Decoded
336
- for completeness so the source type is no longer an unparsed gap, and for future
337
- borrow-APY / health-factor work.
338
-
339
- On-chain config (tx daf74541...): base_rate=1/50, collateral_ratio=8696/10000.
340
- """
341
- raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
342
- fields = _fields(cbor2.loads(raw))
343
- base = fields[_LIQWID_PARAM_BASE_RATE_FIELD]
344
- coll = fields[_LIQWID_PARAM_COLLATERAL_RATIO_FIELD]
345
- return ((int(base[0]), int(base[1])), (int(coll[0]), int(coll[1])))
346
-
347
-
348
- def liqwid_qtoken_rate(
349
- *,
350
- qtoken_rate_num: int,
351
- qtoken_rate_denom: int,
352
- ) -> tuple[int, int]:
353
- """QToken -> underlying rate as (num, denom). Raises on non-positive denom/num."""
354
- if qtoken_rate_num <= 0 or qtoken_rate_denom <= 0:
355
- raise ValueError("non-positive qtoken rate")
356
- return (qtoken_rate_num, qtoken_rate_denom)
@@ -43,12 +43,12 @@ from charli3_dendrite.lending.danogo.oracles.leaves import danogo_pool_dtoken_ra
43
43
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_danogo_staking_rate
44
44
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_djed
45
45
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_indigo
46
- from charli3_dendrite.lending.danogo.oracles.leaves import parse_liqwid_market_state
47
- from charli3_dendrite.lending.danogo.oracles.leaves import parse_liqwid_oracle_v2
48
46
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_minswap_lp
49
47
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_splash_cpamm_g3
50
48
  from charli3_dendrite.lending.danogo.oracles.leaves import splash_lp_token_price
51
49
  from charli3_dendrite.lending.danogo.oracles.redeemer import OracleUtxoType
50
+ from charli3_dendrite.lending.liqwid.datums import parse_liqwid_market_state
51
+ from charli3_dendrite.lending.liqwid.datums import parse_liqwid_oracle_v2
52
52
 
53
53
  # Liqwid market qToken: the on-chain price divides the field-9 exchange rate by the
54
54
  # underlying's (cent-denominated) price; that constant is folded into the leaf rate so
@@ -49,7 +49,6 @@ from charli3_dendrite.lending.danogo.oracles.forward import LiveLeaf
49
49
  from charli3_dendrite.lending.danogo.oracles.forward import compose_cross_quote
50
50
  from charli3_dendrite.lending.danogo.oracles.forward import leaf_discriminator
51
51
  from charli3_dendrite.lending.danogo.oracles.forward import replay_recipe
52
- from charli3_dendrite.lending.danogo.oracles.leaves import parse_liqwid_market_state
53
52
  from charli3_dendrite.lending.danogo.oracles.leaves import parse_orcfax_fs
54
53
  from charli3_dendrite.lending.danogo.oracles.locator import Recipe
55
54
  from charli3_dendrite.lending.danogo.oracles.locator import load_registry
@@ -77,6 +76,7 @@ from charli3_dendrite.lending.danogo.transactions.context import TopupWithdrawSn
77
76
  from charli3_dendrite.lending.danogo.transactions.oracle_synth import (
78
77
  synthesize_oracle_redeemer,
79
78
  )
79
+ from charli3_dendrite.lending.liqwid.datums import parse_liqwid_market_state
80
80
  from charli3_dendrite.lending.math import floor_div
81
81
  from charli3_dendrite.lending.transactions.infra import OUTPUT_MIN_ADA
82
82
  from charli3_dendrite.lending.transactions.infra import PLACEHOLDER_FEE
@@ -0,0 +1 @@
1
+ """Liqwid Finance on-chain datum parsers."""
@@ -0,0 +1,112 @@
1
+ """Liqwid Finance datum parsers.
2
+
3
+ Pure decoders for the Liqwid on-chain records that are read as price and rate
4
+ sources: the Oracle V2 price feed, the market state (qToken exchange rate), and the
5
+ market parameters (risk configuration). Each parser takes the datum as CBOR hex or
6
+ raw bytes.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import cbor2 # type: ignore[import-not-found]
12
+
13
+ from charli3_dendrite.lending.units import plutus_fields
14
+ from charli3_dendrite.lending.units import tuple_asset_unit
15
+
16
+ # Liqwid Oracle V2 datum field order: [updater_key, Constr1[[asset]], [num, denom],
17
+ # timestamp_ms, validity_ms, config].
18
+ _LIQWID_ASSET_FIELD = 1
19
+ _LIQWID_PRICE_FIELD = 2
20
+ # Liqwid market-state datum: the qToken<->underlying exchange rate is the rational at
21
+ # index 9 of the 11-field state record.
22
+ _LIQWID_MARKET_RATE_FIELD = 9
23
+ # Liqwid market-parameter (config) datum: the initial qToken exchange rate at field 0
24
+ # and the maximum loan-to-value on weighted collateral at field 12.
25
+ _LIQWID_PARAM_INITIAL_QTOKEN_RATE_FIELD = 0
26
+ _LIQWID_PARAM_MAX_LTV_FIELD = 12
27
+
28
+
29
+ def parse_liqwid_oracle_v2(datum: str | bytes) -> tuple[str, tuple[int, int]]:
30
+ """Liqwid Oracle V2 datum -> (priced_asset_unit, (num, denom)).
31
+
32
+ Datum is a 6-field record ``[updater_key, Constr1[[asset]], [num, denom], ts,
33
+ validity, config]``; the rate is the priced asset (field 1) in the feed's
34
+ configured quote. ADA (the empty TupleAsset) is ``"lovelace"``.
35
+
36
+ Raises ValueError on a non-positive denominator.
37
+ """
38
+ raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
39
+ fields = plutus_fields(cbor2.loads(raw))
40
+ asset_unit_str = tuple_asset_unit(plutus_fields(fields[_LIQWID_ASSET_FIELD])[0])
41
+ price = plutus_fields(fields[_LIQWID_PRICE_FIELD])
42
+ num, denom = int(price[0]), int(price[1])
43
+ if denom <= 0:
44
+ raise ValueError("non-positive liqwid oracle denom")
45
+ return asset_unit_str, (num, denom)
46
+
47
+
48
+ def liqwid_oracle_feed_id(datum: str | bytes) -> str:
49
+ """Liqwid Oracle V2 datum field 0 -- the oracle updater's key -- as hex.
50
+
51
+ The updater key is shared by every feed that updater publishes, so it does not
52
+ identify a feed on its own. Nor does the oracle token plus the priced asset
53
+ (field 1, see ``parse_liqwid_oracle_v2``): one oracle token can carry more than
54
+ one feed for the same asset. The updater key together with the priced asset
55
+ distinguishes the feeds that share an oracle token. A field 0 that is not a
56
+ bytestring is returned as its ``str``.
57
+ """
58
+ raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
59
+ feed = plutus_fields(cbor2.loads(raw))[0]
60
+ if isinstance(feed, (bytes, bytearray)):
61
+ return feed.hex()
62
+ return str(feed)
63
+
64
+
65
+ def parse_liqwid_market_state(datum: str | bytes) -> tuple[int, int]:
66
+ """Liqwid market-state datum -> qToken exchange rate (state field 9).
67
+
68
+ Field 9 of the 11-field state record is the qToken exchange rate (underlying per
69
+ qToken), a rational. Returns (num, denom).
70
+
71
+ Raises ValueError on a non-positive rate.
72
+ """
73
+ raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
74
+ rate = plutus_fields(cbor2.loads(raw))[_LIQWID_MARKET_RATE_FIELD]
75
+ num, denom = int(rate[0]), int(rate[1])
76
+ if num <= 0 or denom <= 0:
77
+ raise ValueError("non-positive liqwid market exchange rate")
78
+ return (num, denom)
79
+
80
+
81
+ def parse_liqwid_market_param(
82
+ datum: str | bytes,
83
+ ) -> tuple[tuple[int, int], tuple[int, int]]:
84
+ """Liqwid market-parameter (config) datum -> (initial_qtoken_rate, max_ltv).
85
+
86
+ This datum is the market's interest-model and risk configuration, not a price
87
+ source (the live qToken exchange rate is read from the market-state datum, see
88
+ ``parse_liqwid_market_state``). Two rationals are surfaced, both as (num, denom):
89
+
90
+ * field 0, the initial qToken exchange rate (underlying per qToken) a new market
91
+ starts from, e.g. 1/50;
92
+ * field 12, the maximum loan-to-value on weighted collateral; the protocol's
93
+ minimum health factor is its reciprocal.
94
+
95
+ The remaining fields are left raw.
96
+ """
97
+ raw = bytes.fromhex(datum) if isinstance(datum, str) else datum
98
+ fields = plutus_fields(cbor2.loads(raw))
99
+ initial = fields[_LIQWID_PARAM_INITIAL_QTOKEN_RATE_FIELD]
100
+ max_ltv = fields[_LIQWID_PARAM_MAX_LTV_FIELD]
101
+ return ((int(initial[0]), int(initial[1])), (int(max_ltv[0]), int(max_ltv[1])))
102
+
103
+
104
+ def liqwid_qtoken_rate(
105
+ *,
106
+ qtoken_rate_num: int,
107
+ qtoken_rate_denom: int,
108
+ ) -> tuple[int, int]:
109
+ """QToken -> underlying rate as (num, denom). Raises on non-positive denom/num."""
110
+ if qtoken_rate_num <= 0 or qtoken_rate_denom <= 0:
111
+ raise ValueError("non-positive qtoken rate")
112
+ return (qtoken_rate_num, qtoken_rate_denom)
@@ -25,6 +25,26 @@ def asset_unit(policy: bytes, name: bytes) -> str:
25
25
  return policy.hex() + name.hex()
26
26
 
27
27
 
28
+ def plutus_fields(obj: object) -> list:
29
+ """Positional fields of a compact-form CBOR Constr (or a bare list) as a list.
30
+
31
+ Any ``cbor2.CBORTag`` is unwrapped without checking its tag, so this suits the
32
+ compact constructor tags (121-127, 1280+) and bare lists. A general-form
33
+ constructor (tag 102) wraps ``[alt, fields]`` and would come back as that pair;
34
+ use ``constr`` for it.
35
+ """
36
+ inner = obj.value if isinstance(obj, cbor2.CBORTag) else obj
37
+ return list(inner)
38
+
39
+
40
+ def tuple_asset_unit(arr: object) -> str:
41
+ """Dendrite unit string from a ``[policy, name]`` value (Constr-wrapped or bare)."""
42
+ seq = plutus_fields(arr)
43
+ policy = seq[0] if len(seq) > 0 and isinstance(seq[0], bytes) else b""
44
+ name = seq[1] if len(seq) > 1 and isinstance(seq[1], bytes) else b""
45
+ return asset_unit(policy, name)
46
+
47
+
28
48
  def script_payment_address(script_hash_hex: str) -> str:
29
49
  """Mainnet enterprise address whose payment credential is ``script_hash_hex``.
30
50