charli3_dendrite 1.4.10.dev1__tar.gz → 1.4.11.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.
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/PKG-INFO +1 -1
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/pyproject.toml +4 -3
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/__init__.py +1 -0
- charli3_dendrite-1.4.11.dev0/src/charli3_dendrite/dexs/ob/cardanoswaps.py +711 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/utility.py +35 -1
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/LICENSE +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/README.md +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/backend_base.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/blockfrost/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/blockfrost/models.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/dbsync/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/dbsync/models.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/ogmios_kupo/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/ogmios_kupo/models.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/utils.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dataclasses/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dataclasses/datums.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dataclasses/models.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/amm_base.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/amm_types.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/cswap.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/dano.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/minswap.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/muesli.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/spectrum.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/splash.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/sundae.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/vyfi.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/wingriders.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/core/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/core/base.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/core/errors.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/__init__.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/axo.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/chadswap.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/djed.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/geniusyield.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/ob_base.py +0 -0
- {charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/saturnswap.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "charli3_dendrite"
|
|
3
|
-
version = "1.4.
|
|
3
|
+
version = "1.4.11-dev0"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["Elder Millenial <eldermillenial@protonmail.com>"]
|
|
6
6
|
readme = "README.md"
|
|
@@ -32,6 +32,7 @@ mkdocs = "^1.6.0"
|
|
|
32
32
|
mkdocs-material = "^9.5.32"
|
|
33
33
|
mkdocstrings = { extras = ["python"], version = "^0.25.2" }
|
|
34
34
|
pytest-subtests = "^0.14.1"
|
|
35
|
+
uplc = "^1.3.2"
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
[build-system]
|
|
@@ -45,11 +46,11 @@ profile = "black"
|
|
|
45
46
|
plugins = ["pydantic.mypy"]
|
|
46
47
|
|
|
47
48
|
[[tool.mypy.overrides]]
|
|
48
|
-
module = ["pycardano", "pycardano.*", "dotenv", "nox"]
|
|
49
|
+
module = ["pycardano", "pycardano.*", "dotenv", "nox", "uplc", "uplc.*"]
|
|
49
50
|
ignore_missing_imports = true
|
|
50
51
|
|
|
51
52
|
[tool.bumpversion]
|
|
52
|
-
current_version = "1.4.
|
|
53
|
+
current_version = "1.4.11-dev0"
|
|
53
54
|
parse = """(?x)
|
|
54
55
|
(?P<major>\\d+)\\.
|
|
55
56
|
(?P<minor>\\d+)\\.
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/__init__.py
RENAMED
|
@@ -24,6 +24,7 @@ from charli3_dendrite.dexs.amm.wingriders import WingRidersCPPState
|
|
|
24
24
|
from charli3_dendrite.dexs.amm.wingriders import WingRidersSSPState
|
|
25
25
|
from charli3_dendrite.dexs.amm.wingriders import WingRidersV2CPPState
|
|
26
26
|
from charli3_dendrite.dexs.amm.wingriders import WingRidersV2SSPState
|
|
27
|
+
from charli3_dendrite.dexs.ob.cardanoswaps import CardanoSwapsOrderState
|
|
27
28
|
from charli3_dendrite.dexs.ob.chadswap import ChadSwapOrderBook
|
|
28
29
|
from charli3_dendrite.dexs.ob.chadswap import ChadSwapOrderState
|
|
29
30
|
from charli3_dendrite.dexs.ob.djed import DjedOrderBook
|
|
@@ -0,0 +1,711 @@
|
|
|
1
|
+
"""Cardano-Swaps v2 one-way order book module.
|
|
2
|
+
|
|
3
|
+
Cardano-Swaps is a fully on-chain, batcher-less peer-to-peer order book. A
|
|
4
|
+
resting *one-way* swap UTxO offers one asset and asks for another at a fixed
|
|
5
|
+
``Rational`` price (ask-per-offer). Any counterparty may fill it directly by
|
|
6
|
+
spending the UTxO; there is no batcher and no protocol fee.
|
|
7
|
+
|
|
8
|
+
This module provides *parse* support for v2 one-way swaps: it decodes the
|
|
9
|
+
on-chain ``SwapDatum`` and exposes it through the standard order-book interface
|
|
10
|
+
(price/available/get_amount_out). The create/fill/close transaction builders
|
|
11
|
+
are implemented separately.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import hashlib
|
|
15
|
+
import time
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from typing import Union
|
|
18
|
+
|
|
19
|
+
from pycardano import Address
|
|
20
|
+
from pycardano import Network
|
|
21
|
+
from pycardano import PlutusData
|
|
22
|
+
from pycardano import PlutusV2Script
|
|
23
|
+
from pycardano import Redeemer
|
|
24
|
+
from pycardano import ScriptHash
|
|
25
|
+
from pycardano import TransactionBuilder
|
|
26
|
+
from pycardano import TransactionId
|
|
27
|
+
from pycardano import TransactionInput
|
|
28
|
+
from pycardano import TransactionOutput
|
|
29
|
+
from pycardano import UTxO
|
|
30
|
+
from pycardano.utils import min_lovelace
|
|
31
|
+
|
|
32
|
+
from charli3_dendrite.dataclasses.datums import OrderDatum
|
|
33
|
+
from charli3_dendrite.dataclasses.datums import PlutusNone
|
|
34
|
+
from charli3_dendrite.dataclasses.models import Assets
|
|
35
|
+
from charli3_dendrite.dataclasses.models import OrderType
|
|
36
|
+
from charli3_dendrite.dataclasses.models import PoolSelector
|
|
37
|
+
from charli3_dendrite.dexs.ob.ob_base import AbstractOrderState
|
|
38
|
+
from charli3_dendrite.utility import asset_to_value
|
|
39
|
+
|
|
40
|
+
# v2 one-way beacon minting policy id (also stored verbatim in the datum's
|
|
41
|
+
# ``beacon_id`` field).
|
|
42
|
+
BEACON_POLICY_ID = "c4d7d117d9ebcde6db28db40837ff2b1401e9eaaa6eecea9e070e209"
|
|
43
|
+
|
|
44
|
+
# v2 one-way swap spending validator hash.
|
|
45
|
+
SWAP_VALIDATOR_HASH = "1d6cff26bcab91d2061aad0bd259cbb7d76d25ced2eeaed5926a42ad"
|
|
46
|
+
|
|
47
|
+
# Compiled Plutus V2 scripts, inlined verbatim (no on-chain reference script, so
|
|
48
|
+
# they are attached to the witness set directly). The swap validator is
|
|
49
|
+
# un-parameterized; the beacon minting policy is parameterized by ``dapp_hash``
|
|
50
|
+
# (= the swap validator hash), applied here via the aiken blueprint, so
|
|
51
|
+
# ``PlutusV2Script(bytes.fromhex(...))`` hashes to the constants above (swap
|
|
52
|
+
# validator -> SWAP_VALIDATOR_HASH, beacon policy -> BEACON_POLICY_ID).
|
|
53
|
+
SWAP_VALIDATOR_SCRIPT_HEX = "591193010000323232323232323223232322322533300832323232323253233300f300c007132323232323232323253330183016301a3754010264a666032602c60366ea80044c94ccc068cc03d241225374616b696e672063726564656e7469616c20646964206e6f7420617070726f7665003330103020301d375460406042603a6ea8c080c074dd5001002001899807a4812c426561636f6e20736372697074206e6f74206578656375746564206173206d696e74696e6720706f6c6963790033301a3232533302000114a22940c94ccc070c068c078dd50008a5eb7bdb1804dd59811180f9baa001323300100100222533302100114c0103d87a8000132323253330203371e00e6eb8c08800c4c050cc094dd3000a5eb804cc014014008dd598110011812801181180099198008008039129998100008a5eb7bdb1804c8c8c8c94ccc080c048008400c4cc094cdd81ba9002374c0026600c00c0066eacc08800cdd7181000118120011811000a504a22940dd7180f980e1baa018163300b006301e301b37540102c6eb0c074c078c078008dd5980e000980e180e0011bab301a001301a301a301a301a0023758603000260286ea8c05c008c058c05c004c048dd50040a9998079806803899191919191919299980b180a180c1baa0061325333017301430193754002264a6660306601a921225374616b696e672063726564656e7469616c20646964206e6f7420617070726f76650033300e301e301b3754603c603e60366ea8c078c06cdd5001002001899806a4812c426561636f6e20736372697074206e6f74206578656375746564206173207374616b696e6720736372697074003300f004300c3301d3374a90011980e9ba90014bd7025eb805281bae301d301a375402c2c66012008603860326ea801858dd6180d980e180e0011bab301a001301a301a301a301a301a301a0023758603000260286ea8c05c008c058c05c004c048dd5004099191919191919299980b180a180c1baa0061323253330183015301a37540022646464646464646464646666666666666646464444444444444464646464a66606c6464a666070606c60746ea800452889919299981d181b981e1baa003132533303b3038303d3754006266030920127696e76616c69642d686572656166746572206d757374206265203c3d2065787069726174696f6e00337126eb4c104c0f8dd50018008011bad3040303d37540060022a66074920126696e76616c69642d68657265616674657220726571756972656420627574206e6f74207365740016303b00230390013376000a02026464646464646464a66607ca66607ca66607c606002829444c0c004452889980da49194164612063616e206f6e6c79206265206465706f73697465640033712900019b810030061533303e33033491264661696c3a206f666665725f74616b656e202a207072696365203c3d2061736b5f676976656e003371266e08004028cdc1001004899819a4812b5468652061736b2061737365742063616e6e6f742062652074616b656e2066726f6d207468652073776170003371290000010a5016337026eb4c10c01cdd6982180219b81375a60840046eb4c108014dd6982098210009820800991980080081311299981f8008a9981e248123436f72726573706f6e64696e672073776170206f7574707574206e6f7420666f756e6400161323232323253330403375e01c608c608e0042a66608066ebc06400c4ccccccccc07000406005c05805405004c0480444cc01c01c0144cc01c01c014dd5982280098228011821800981f9baa30420023042001375a607c607e002607c00266666666602402201c01a01801601401201000e2c6eb4c0ecc0f0008dd6981d000981b1baa0033374a90021981b98131981b9ba900a3303737520126606e6ea4020cc0dcdd48039981b9ba900633037375200a6606e6ea4010cc0dcdd48019981b8011981b98131981b80e25eb80cc0dc0052f5c097ae0222222222323232323232325333034300730363754607460760042660726ea0014cc0e4dd40019981c9ba80014bd700a9981aa49165554784f206861732077726f6e6720626561636f6e730016375a607200260720046eb4c0dc004c0dc008dd6981a80099980600525eb84101000081010000810100008103d879800011191919191919191929919981c980080a099191919299981e9808181f9baa30430041533303d0021533303d0031330423750016660846ea0024cc108dd40039982119981ea514c103d87a80004c0103d87980004bd7000080080088069807181e9baa30413042002300d303c375460806082608200266602e01097ae10103d87980008103d87980008103d8798000111919191929919199820980100d899823199820800a6103d87a80004c0103d8798000330463330410044c0103d87a80004c0103d8798000330463330410034c0103d87a80004c0103d87980004bd700a999820980100c09982319982080326103d87a80004c0103d8798000330463330410014c0103d87a80004c0103d8798000330463330410034c0103d87a80004c0103d87980004bd700a999820980100a89982319982080326103d87a80004c0103d8798000330463330410044c0103d87a80004c0103d8798000330463330410014c0103d87a80004c0103d87980004bd700a998212481165554784f206861732077726f6e6720626561636f6e730016303e375a608600e6e3cdd71820803180898201baa304430450023010303f375460860026086004601c607a6ea8c10400454c8c8c8c8ccc0f4c0bc0344c94ccc0f8c0ecc100dd50008992991998200028998229ba830070023304537500186608a6ea0004cc114ccc100025300103d87a80004c0103d87980004bd700a9998200020998229ba800e330453750600c0046608a6ea0004cc114ccc10002530103d87a80004c0103d87980004bd700998229ba800e3304537500186608a6ea0004cc114ccc100025300103d87a80004c0103d87980004bd7019b80009001375a608860826ea800458c8cc004004034894ccc10c004530103d87a8000132323253330423034375c60880062606c6608e6ea00052f5c026600a00a0046eb4c110008c11c008c11400454ccc0f54ccc0f400840045280a9998208060a9981f249284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161325333042001132323253330413371e00203226608c6ea0c020008cc118dd4006998231ba800b3304633304100a4c0103d87a80004c0103d87980004bd700a99982099b8f001016133046375001e6608c6ea0c01c008cc118dd400599823199820805260103d87a80004c0103d87980004bd700a998212481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375c60840046eb4c108004c11003454ccc108c1140044c8c8c8c8c8c94ccc110cdc780180e0a99982219b8f00101913304937506016008660926ea0c028008cc124dd400719824999822006a6103d87a80004c0103d87980004bd700a99822a481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016153330443371e0060322a66608866e3c0040704cc124dd41805801198249ba8300a00433049375001c6609266608801a980103d87a80004c0103d87980004bd700a99822a481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161533045491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375c608a0086eb4c11400cdd718218019bad30430023045002304400d153303f4901284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016304400c1533303d0021533304100c153303e4901284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f001615333041304400c13232533303f3371e6eb8c10400805c4cc110dd41803000998221ba800b3304437500126608866607e010980103d87a80004c0103d87980004bd700a998202481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375a608200260860182a6607c921284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161533303d0011533304100c153303e491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f001615333041304400c13232533303f3371e6eb8c1040080504cc110dd4006998221ba830050013304437500126608866607e010980103d87a80004c0103d87980004bd700a998202481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375a608200260860182a6607c921284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016153303e491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f001630040123003014370000c6e0001cdc78041805181c9baa303d303e002375a607800260780046eb4c0e8004c0e8010dd6981c0019bab3034003375c60640046e2120002253330253330250014a094454cc098008584004888c8ccc00400401000c8894ccc0b000840044ccc00c00cc0bc008cc010c0b8008004dd59814181480519192999812181118131baa0011301833029302a3027375400297ae014c103d87a800030293026375460526054604c6ea8038c090dd500698140051bae3028009375c60500106eb8c0a001cdd718140031bae3028005375c60500086eb8c0a000cdd71814001181400098141814981480098140009813800981300098128009812000981180098110009810800980e1baa018301b3754603c603e60366ea8c078c06cdd50008b19805002800980e180c9baa00616301b301c301c301c301c301c00237586034002603460340046eb0c060004c050dd5180b801180b180b80098091baa008371e9110022323300100100322533301500114c0103d87a80001323253330133375e6032602c6ea80080144c01ccc0600092f5c02660080080026032004602e0026e95200022533300d33300d0014a094454cc03800840044004888c8c94ccc03cc034004528899299980818068010992999808980718099baa0011325333012300f30143754002264646600200201044a66603200229404c94ccc058cdc79bae301c00200414a226600600600260380026eb8c060c054dd5000801980b980a1baa00100230163013375400600226600c008602a60246ea8008c040dd50009809980a18081baa00322323300100100322533301100114a0264a66601c66ebc010c040c050008528899801801800980a00098051baa00314984d958c94ccc01cc01000454ccc02cc028dd50010a4c2c2a66600e600a0022a66601660146ea800852616153330073370e90020008a99980598051baa00214985858c020dd5000a999802180098031baa003132323232323232323232323232323232323232323232533301e30210021323232498c94ccc074c0680044c8c94ccc08cc09800852616375a604800260406ea801054ccc074c06c00454ccc084c080dd50020a4c2c2c603c6ea800cc94ccc070c0640044c8c94ccc088c0940084c926533301e301b30203754002264646464a66604c6052004264932999811180f98121baa003132325333028302b002149858dd7181480098129baa0031616375a604e002604e004604a00260426ea80045858c08c004c07cdd50028a99980e180d0008a999810180f9baa00514985858c074dd5002299980d180b980e1baa00513232323253330223025002149858dd6981180098118011bad3021001301d375400a2c2c603e002603e004603a002603a004603600260360046eb8c064004c064008dd7180b800980b8011bae30150013015002375c602600260260046eb8c044004c044008dd7180780098078011bae300d001300d002375c6016002600e6ea800c58dc3a40006e1d20025734ae7155ceaab9e5573eae815d0aba201" # noqa: E501
|
|
54
|
+
BEACON_POLICY_SCRIPT_HEX = "5911ed010000332323232323232322322323232322533300932533300a30060011323232533300d3370e900318079baa0011533300d3009300f3754602660206ea80045288010011809180998079baa004153300c4913c546869732072656465656d65722063616e206f6e6c79206265207573656420746f2072656769737465722074686520626561636f6e207363726970740016300c37540042646464646464646464a666026601c0142646464666600802864a66602e602600226eb8c074c068dd5001899299980c1809001099299980c980a980d9baa001132533301a3015301c375400226eb8c080c074dd5000801980f980e1baa001002301e301b37540080022a6603092012852656465656d6572206e6f7420757365642077697468206d696e74696e6720657865637574696f6e00163018375400460166038603a603a603a603a603a0026eb0c070004c070c070c060dd5180d801180d180d800980b1baa00b13232323333004014325333017301130193754006264a666030602860346ea80044c94ccc064c050c06cdd500089bae301f301c3754002006603c60366ea8004008c074c068dd50018008a9980ba4812852656465656d6572206e6f7420757365642077697468207374616b696e6720657865637574696f6e0016300b301c301d301d301d301d301d001375860380026038603860306ea8c06c008c068c06c004c058dd5005911119199800800801251222533301d00210011333003003302000232323232323232325333025001100913253330260011533023491364f6e652d776179207377617073206d75737420686176652065786163746c79207468726565206b696e6473206f6620626561636f6e730016132533302700115330244901364f6e652d776179207377617073206d75737420686176652065786163746c79207468726565206b696e6473206f6620626561636f6e73001615333027302a0011323232533302600e153330263301632330160014911a204441707020616464726573732077697468207374616b696e67003301549114426561636f6e206d75737420676f20746f2061200049010053330263375e01066e9520023302b375202897ae01533302630223028375400e29445280a50132323232323232323232323232323232323232323232323232533303f32325333041303c3043375400229444c8c94ccc10cc0fcc114dd50018992999822182018231baa00315333044330354912745787069726174696f6e206d757374206265203e3d20696e76616c69642d68657265616674657200337126eb4c128c11cdd500180089981aa481234d7573742075736520312d6d696e2065787069726174696f6e20696e74657276616c730030403370c002906054838a50002375a6092608c6ea800c00454cc10d240126696e76616c69642d68657265616674657220726571756972656420627574206e6f742073657400163044002304200133760608a608c608c0120562a66607e6605e92010f57726f6e6720626561636f6e5f6964003371e0580302a66607e6605e9201274f666665722061737365742063616e6e6f742062652073616d652061732061736b2061737365740033303f3375e01000e941288a99981f99817a491157726f6e6720706169725f626561636f6e003371e02c64646464646460706464660760020086607400200466072a66608a601200a291010100001005375c6096609800ca6660886010004291010100001002375c609260940046eb8c120004c110dd50049bae3046001304237540102a66607e6605e9211257726f6e67206f666665725f626561636f6e003371e020606466066911010100330330140121533303f3302f49011057726f6e672061736b5f626561636f6e003371e0146064660669110102003303300e00c1533303f3302f49011e737761705f70726963652064656e6f6d696e61746f72206e6f74203e20300030020041533303f3302f49011c737761705f7072696365206e756d657261746f72206e6f74203e203000300200513371290000008a5014a029405280a5014a0294058dd698221919191919192999822180398231baa304a304b002133049375000a660926ea000ccc124dd4000a5eb8054cc115241165554784f206861732077726f6e6720626561636f6e730016375a609200260920046eb4c11c004c11c008dd69822800999818011a5eb84101000081010000810100008103d8798000111919191919191919299199824980081b0991919192999826980818279baa30530041533304d0021533304d0031330523750016660a46ea0024cc148dd400399829199826a514c103d87a80004c0103d87980004bd700008008008806980718269baa30513052002300d304c375460a060a260a200266607601097ae10103d87980008103d87980008103d8798000111919191929919199828980101409982b199828800a6103d87a80004c0103d8798000330563330510044c0103d87a80004c0103d8798000330563330510034c0103d87a80004c0103d87980004bd700a999828980101109982b19982880326103d87a80004c0103d8798000330563330510014c0103d87a80004c0103d8798000330563330510034c0103d87a80004c0103d87980004bd700a999828980100e09982b19982880326103d87a80004c0103d8798000330563330510044c0103d87a80004c0103d8798000330563330510014c0103d87a80004c0103d87980004bd700a998292481165554784f206861732077726f6e6720626561636f6e730016304b375a60a600e6e3cdd71828803180898281baa305430550023010304f375460a600260a6004601c609a6ea8c14400454c8c8c8c8ccc134c0440344c94ccc138c128c140dd500089929919982800289982a9ba83007002330553750018660aa6ea0004cc154ccc140025300103d87a80004c0103d87980004bd700a99982800209982a9ba800e330553750600c004660aa6ea0004cc154ccc14002530103d87a80004c0103d87980004bd7009982a9ba800e330553750018660aa6ea0004cc154ccc140025300103d87a80004c0103d87980004bd7019b80009001375a60a860a26ea800458c8cc004004034894ccc14c004530103d87a8000132323253330523016375c60a800626090660ae6ea00052f5c026600a00a0046eb4c150008c15c008c15400454ccc1354ccc13400840045280a9998288060a99827249284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161325333052001132323253330513371e0020482660ac6ea0c020008cc158dd40069982b1ba800b3305633305100a4c0103d87a80004c0103d87980004bd700a99982899b8f00101e133056375001e660ac6ea0c01c008cc158dd40059982b199828805260103d87a80004c0103d87980004bd700a998292481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375c60a40046eb4c148004c15003454ccc148c1540044c8c8c8c8c8c94ccc150cdc78018138a99982a19b8f00102113305937506016008660b26ea0c028008cc164dd40071982c99982a006a6103d87a80004c0103d87980004bd700a9982aa481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016153330543371e0060422a6660a866e3c00409c4cc164dd418058011982c9ba8300a00433059375001c660b26660a801a980103d87a80004c0103d87980004bd700a9982aa481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161533055491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375c60aa0086eb4c15400cdd718298019bad30530023055002305400d153304f4901284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016305400c1533304d0021533305100c153304e4901284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f001615333051305400c13232533304f3371e6eb8c1440080884cc150dd418030009982a1ba800b330543750012660a866609e010980103d87a80004c0103d87980004bd700a998282481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375a60a200260a60182a6609c921284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f00161533304d0011533305100c153304e491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f001615333051305400c13232533304f3371e6eb8c1440080704cc150dd40069982a1ba83005001330543750012660a866609e010980103d87a80004c0103d87980004bd700a998282481284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016375a60a200260a60182a6609c921284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016153304e491284e6f2065787472616e656f75732061737365747320616c6c6f77656420696e20746865205554784f0016300401b3003020370000c6e0001cdc7804180518249baa304d304e002375a609800260980046eb4c128004c128010dd698240019bab3044003375c60840046e212000371e91100375a608260840046eb4c100004c0f0dd5181f80198171981e9ba90073303d375200a97ae0302d3303c3752018660786ea40292f5c0607a0046eb8c0ec004c0ec008dd7181c800981c8011bae30370013037002375c606a002606a0046eb8c0cc004c0cc008dd7181880098188011bae302f001302f002375c605a00260526ea94ccc098c080c0a0dd5005099190012999813981198149baa001132323232323232323232323232323232323232323232533304130440021323232498c94ccc100c0f00044c8c94ccc118c12400852616375a608e00260866ea801054ccc100c0ec00454ccc110c10cdd50020a4c2c2c60826ea800cc94ccc0fcc0ec0044c8c94ccc114c1200084c9265333041303d30433754002264646464a6660926098004264932999822982098239baa00313232533304b304e002149858dd7182600098241baa0031616375a60940026094004609000260886ea80045858c118004c108dd50028a99981f981d0008a99982198211baa00514985858c100dd5002299981e981c981f9baa00513232323253330453048002149858dd6982300098230011bad30440013040375400a2c2c6084002608400460800026080004607c002607c0046eb8c0f0004c0f0008dd7181d000981d0011bae30380013038002375c606c002606c0046eb8c0d0004c0d0008dd7181900098190011bae30300013030002375c605c00260546ea800458c0b0c0a4dd50050a99813a48125416c6c207377617020646174756d73206d75737420626520696e6c696e6520646174756d73001614a02940c0ac00cc0a800cc0a400c54cc0912401364f6e652d776179207377617073206d75737420686176652065786163746c79207468726565206b696e6473206f6620626561636f6e73001630290013028001325333021301c30233754002297adef6c6013756604e60486ea8004c8cc004004018894ccc098004530103d87a8000132323253330253371e0246eb8c09c00c4c06ccc0a8dd3000a5eb804cc014014008dd598138011815001181400098129813001181200098101baa30230043022302300237566042002604200260386ea8c07c00888cdcb001000912999809199809000a504a22a660260042002200244a666022666022002941288a998090010b080091119199800800802001911299980c00108008999801801980d80119802180d00100091b92001223371400400246464a66601c601260206ea80044c010cc04cc050c044dd5000a5eb80530103d87a80003013301037546026602860206ea8008c038dd50009ba548000c02cdd50030a4c26cac64a66601060080022a66601860166ea8014526161533300830030011533300c300b375400a2930b0a99980418010008a99980618059baa00514985858c024dd50021b8748010dc3a40046e1d2000375c002ae695ce2ab9d5573caae7d5d02ba157449811e581c1d6cff26bcab91d2061aad0bd259cbb7d76d25ced2eeaed5926a42ad0001" # noqa: E501
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class SpendWithMint(PlutusData):
|
|
59
|
+
"""Spending redeemer: spend a swap UTxO while minting/burning beacons (CLOSE)."""
|
|
60
|
+
|
|
61
|
+
CONSTR_ID = 0
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class SpendWithStake(PlutusData):
|
|
66
|
+
"""Spending redeemer: spend a swap UTxO with staking execution (in-place update)."""
|
|
67
|
+
|
|
68
|
+
CONSTR_ID = 1
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class Swap(PlutusData):
|
|
73
|
+
"""Spending redeemer: fill a resting swap UTxO (FILL)."""
|
|
74
|
+
|
|
75
|
+
CONSTR_ID = 2
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class RegisterBeaconScript(PlutusData):
|
|
80
|
+
"""Beacon redeemer: register the beacon staking script."""
|
|
81
|
+
|
|
82
|
+
CONSTR_ID = 0
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class CreateOrCloseSwaps(PlutusData):
|
|
87
|
+
"""Beacon redeemer: mint (CREATE) or burn (CLOSE) the three beacons."""
|
|
88
|
+
|
|
89
|
+
CONSTR_ID = 1
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass
|
|
93
|
+
class UpdateSwaps(PlutusData):
|
|
94
|
+
"""Beacon redeemer: staking-execution twin of CreateOrCloseSwaps (no mint)."""
|
|
95
|
+
|
|
96
|
+
CONSTR_ID = 2
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _sha256(data: bytes) -> bytes:
|
|
100
|
+
"""sha2_256 digest (32 bytes), used for all three beacon token names."""
|
|
101
|
+
return hashlib.sha256(data).digest()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def pair_beacon_name(
|
|
105
|
+
offer_id: bytes,
|
|
106
|
+
offer_name: bytes,
|
|
107
|
+
ask_id: bytes,
|
|
108
|
+
ask_name: bytes,
|
|
109
|
+
) -> bytes:
|
|
110
|
+
"""The pair-beacon token name.
|
|
111
|
+
|
|
112
|
+
``sha2_256(a1_id ++ offer_name ++ a2_id ++ ask_name)`` where an empty policy
|
|
113
|
+
id (ADA) is substituted with ``0x00`` for *both* legs. The order is
|
|
114
|
+
offer-then-ask (NOT canonically sorted).
|
|
115
|
+
"""
|
|
116
|
+
a1 = offer_id if offer_id != b"" else b"\x00"
|
|
117
|
+
a2 = ask_id if ask_id != b"" else b"\x00"
|
|
118
|
+
return _sha256(a1 + offer_name + a2 + ask_name)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def offer_beacon_name(offer_id: bytes, offer_name: bytes) -> bytes:
|
|
122
|
+
"""The offer-beacon token name: ``sha2_256(0x01 ++ offer_id ++ offer_name)``.
|
|
123
|
+
|
|
124
|
+
No ``0x00`` substitution: an ADA offer hashes ``sha2_256(0x01)``.
|
|
125
|
+
"""
|
|
126
|
+
return _sha256(b"\x01" + offer_id + offer_name)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def ask_beacon_name(ask_id: bytes, ask_name: bytes) -> bytes:
|
|
130
|
+
"""The ask-beacon token name: ``sha2_256(0x02 ++ ask_id ++ ask_name)``.
|
|
131
|
+
|
|
132
|
+
No ``0x00`` substitution: an ADA ask hashes ``sha2_256(0x02)``.
|
|
133
|
+
"""
|
|
134
|
+
return _sha256(b"\x02" + ask_id + ask_name)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _unit(policy: bytes, name: bytes) -> str:
|
|
138
|
+
"""Build a dendrite asset unit from on-chain policy + name bytes.
|
|
139
|
+
|
|
140
|
+
An empty policy id is the on-chain encoding of ADA/lovelace.
|
|
141
|
+
"""
|
|
142
|
+
if policy == b"":
|
|
143
|
+
return "lovelace"
|
|
144
|
+
return policy.hex() + name.hex()
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass
|
|
148
|
+
class CardanoSwapsRational(PlutusData):
|
|
149
|
+
"""A positive rational price (numerator / denominator)."""
|
|
150
|
+
|
|
151
|
+
CONSTR_ID = 0
|
|
152
|
+
numerator: int
|
|
153
|
+
denominator: int
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@dataclass
|
|
157
|
+
class CardanoSwapsTxId(PlutusData):
|
|
158
|
+
"""A transaction id wrapper."""
|
|
159
|
+
|
|
160
|
+
CONSTR_ID = 0
|
|
161
|
+
tx_hash: bytes
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@dataclass
|
|
165
|
+
class CardanoSwapsOutputReference(PlutusData):
|
|
166
|
+
"""A reference to a transaction output (tx id + output index)."""
|
|
167
|
+
|
|
168
|
+
CONSTR_ID = 0
|
|
169
|
+
transaction_id: CardanoSwapsTxId
|
|
170
|
+
output_index: int
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@dataclass
|
|
174
|
+
class CardanoSwapsSomeOutRef(PlutusData):
|
|
175
|
+
"""``Some`` wrapper for an optional output reference."""
|
|
176
|
+
|
|
177
|
+
CONSTR_ID = 0
|
|
178
|
+
value: CardanoSwapsOutputReference
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass
|
|
182
|
+
class CardanoSwapsSomeInt(PlutusData):
|
|
183
|
+
"""``Some`` wrapper for an optional integer (POSIX millis expiration)."""
|
|
184
|
+
|
|
185
|
+
CONSTR_ID = 0
|
|
186
|
+
value: int
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass
|
|
190
|
+
class CardanoSwapsSwapDatum(OrderDatum):
|
|
191
|
+
"""The v2 one-way swap datum (single constructor, 11 fields).
|
|
192
|
+
|
|
193
|
+
Asset policy/name pairs are kept as separate flat bytestrings (not an
|
|
194
|
+
``AssetClass``) to match the on-chain 11-field wire format exactly. ADA is
|
|
195
|
+
the empty bytestring in the ``*_id`` / ``*_name`` fields.
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
CONSTR_ID = 0
|
|
199
|
+
|
|
200
|
+
beacon_id: bytes
|
|
201
|
+
pair_beacon: bytes
|
|
202
|
+
offer_id: bytes
|
|
203
|
+
offer_name: bytes
|
|
204
|
+
offer_beacon: bytes
|
|
205
|
+
ask_id: bytes
|
|
206
|
+
ask_name: bytes
|
|
207
|
+
ask_beacon: bytes
|
|
208
|
+
swap_price: CardanoSwapsRational
|
|
209
|
+
prev_input: Union[CardanoSwapsSomeOutRef, PlutusNone]
|
|
210
|
+
expiration: Union[CardanoSwapsSomeInt, PlutusNone]
|
|
211
|
+
|
|
212
|
+
def offer_unit(self) -> str:
|
|
213
|
+
"""The dendrite unit of the offered (output) asset."""
|
|
214
|
+
return _unit(self.offer_id, self.offer_name)
|
|
215
|
+
|
|
216
|
+
def ask_unit(self) -> str:
|
|
217
|
+
"""The dendrite unit of the asked (input) asset."""
|
|
218
|
+
return _unit(self.ask_id, self.ask_name)
|
|
219
|
+
|
|
220
|
+
def offer_assets(self) -> Assets:
|
|
221
|
+
"""The offered asset as a zero-quantity Assets bag."""
|
|
222
|
+
return Assets(root={self.offer_unit(): 0})
|
|
223
|
+
|
|
224
|
+
def ask_assets(self) -> Assets:
|
|
225
|
+
"""The asked asset as a zero-quantity Assets bag."""
|
|
226
|
+
return Assets(root={self.ask_unit(): 0})
|
|
227
|
+
|
|
228
|
+
def pool_pair(self) -> Assets | None:
|
|
229
|
+
"""The traded pair (offer + ask), both at zero quantity."""
|
|
230
|
+
return self.offer_assets() + self.ask_assets()
|
|
231
|
+
|
|
232
|
+
def address_source(self) -> str | None:
|
|
233
|
+
"""The owner is the UTxO address staking credential, not the datum."""
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def requested_amount(self) -> Assets:
|
|
237
|
+
"""The asset the order is asking for."""
|
|
238
|
+
return self.ask_assets()
|
|
239
|
+
|
|
240
|
+
def order_type(self) -> OrderType:
|
|
241
|
+
"""A resting swap order."""
|
|
242
|
+
return OrderType.swap
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class CardanoSwapsOrderState(AbstractOrderState):
|
|
246
|
+
"""A resting Cardano-Swaps v2 one-way swap UTxO.
|
|
247
|
+
|
|
248
|
+
From the taker's view: ``in`` is the ask asset (taker gives) and ``out`` is
|
|
249
|
+
the offer asset (taker receives). ``available`` is the offer asset held in
|
|
250
|
+
the UTxO. The datum's ``swap_price`` is ask-per-offer, so the price tuple is
|
|
251
|
+
returned as ``[numerator, denominator]`` and assets are oriented so that
|
|
252
|
+
``unit(0)`` is the ask (in) and ``unit(1)`` is the offer (out); then
|
|
253
|
+
``out = in * denominator / numerator`` falls out of the base class.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
tx_hash: str
|
|
257
|
+
tx_index: int
|
|
258
|
+
datum_cbor: str
|
|
259
|
+
datum_hash: str
|
|
260
|
+
inactive: bool = False
|
|
261
|
+
fee: int = 0
|
|
262
|
+
|
|
263
|
+
_batcher: Assets = Assets(lovelace=0)
|
|
264
|
+
_datum_parsed: PlutusData | None = None
|
|
265
|
+
_deposit: Assets = Assets(lovelace=0)
|
|
266
|
+
|
|
267
|
+
@classmethod
|
|
268
|
+
def dex(cls) -> str:
|
|
269
|
+
"""Official dex name."""
|
|
270
|
+
return "CardanoSwaps"
|
|
271
|
+
|
|
272
|
+
@classmethod
|
|
273
|
+
def order_datum_class(cls) -> type[PlutusData]:
|
|
274
|
+
"""Returns data class used for handling order datums."""
|
|
275
|
+
return CardanoSwapsSwapDatum
|
|
276
|
+
|
|
277
|
+
@classmethod
|
|
278
|
+
def default_script_class(cls) -> type[PlutusV2Script]:
|
|
279
|
+
"""The swap spending validator is a Plutus V2 script."""
|
|
280
|
+
return PlutusV2Script
|
|
281
|
+
|
|
282
|
+
@classmethod
|
|
283
|
+
def dex_policy(cls) -> list[str] | None:
|
|
284
|
+
"""The beacon minting policy id used to discover swap UTxOs."""
|
|
285
|
+
return [BEACON_POLICY_ID]
|
|
286
|
+
|
|
287
|
+
@classmethod
|
|
288
|
+
def extract_dex_nft(cls, values: dict) -> Assets | None:
|
|
289
|
+
"""Strip the beacon tokens from the UTxO assets.
|
|
290
|
+
|
|
291
|
+
A one-way swap UTxO carries up to three beacon tokens under one policy
|
|
292
|
+
(pair, offer, ask beacons). They identify the swap but are not part of
|
|
293
|
+
the tradable balance, so remove every beacon-policy token from the
|
|
294
|
+
assets and record them as the dex nft.
|
|
295
|
+
"""
|
|
296
|
+
assets = values["assets"]
|
|
297
|
+
|
|
298
|
+
beacons = [
|
|
299
|
+
asset
|
|
300
|
+
for asset in assets
|
|
301
|
+
if any(asset.startswith(policy) for policy in (cls.dex_policy() or []))
|
|
302
|
+
]
|
|
303
|
+
|
|
304
|
+
if "dex_nft" in values:
|
|
305
|
+
return values["dex_nft"]
|
|
306
|
+
|
|
307
|
+
if not beacons:
|
|
308
|
+
return None
|
|
309
|
+
|
|
310
|
+
dex_nft = Assets(root={beacon: assets.root.pop(beacon) for beacon in beacons})
|
|
311
|
+
values["dex_nft"] = dex_nft
|
|
312
|
+
|
|
313
|
+
return dex_nft
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def volume_fee(self) -> int:
|
|
317
|
+
"""Batcher-less and fee-less: no volume fee."""
|
|
318
|
+
return 0
|
|
319
|
+
|
|
320
|
+
@property
|
|
321
|
+
def price(self) -> tuple[int, int]:
|
|
322
|
+
"""Ask-per-offer price as ``(numerator, denominator)``."""
|
|
323
|
+
return (
|
|
324
|
+
self.order_datum.swap_price.numerator,
|
|
325
|
+
self.order_datum.swap_price.denominator,
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def available(self) -> Assets:
|
|
330
|
+
"""Max offer asset that can be taken (the offer balance in the UTxO).
|
|
331
|
+
|
|
332
|
+
When the offer asset is ADA, this includes the UTxO's mandatory min-ADA
|
|
333
|
+
(the continuing/owner output must still carry it), so the figure is an
|
|
334
|
+
upper bound on the genuinely-takeable amount. The contract has no
|
|
335
|
+
separate offered-amount field, so the held balance is the only signal;
|
|
336
|
+
the fill builder nets out the min-UTxO.
|
|
337
|
+
"""
|
|
338
|
+
return Assets(root={self.out_unit: self.assets[self.out_unit]})
|
|
339
|
+
|
|
340
|
+
@property
|
|
341
|
+
def tvl(self) -> int:
|
|
342
|
+
"""Total value locked in the order (the available offer asset)."""
|
|
343
|
+
return self.available
|
|
344
|
+
|
|
345
|
+
@property
|
|
346
|
+
def pool_id(self) -> str:
|
|
347
|
+
"""A stable identifier for the swap (the pair beacon name, hex)."""
|
|
348
|
+
return self.order_datum.pair_beacon.hex()
|
|
349
|
+
|
|
350
|
+
@classmethod
|
|
351
|
+
def order_selector(cls) -> list[str]:
|
|
352
|
+
"""Order selection: discovery is by beacon policy, not address."""
|
|
353
|
+
return []
|
|
354
|
+
|
|
355
|
+
@classmethod
|
|
356
|
+
def pool_selector(cls) -> PoolSelector:
|
|
357
|
+
"""Pool selection: discover by beacon policy id, not address."""
|
|
358
|
+
return PoolSelector(addresses=[], assets=[BEACON_POLICY_ID])
|
|
359
|
+
|
|
360
|
+
@property
|
|
361
|
+
def swap_forward(self) -> bool:
|
|
362
|
+
"""Swap forwarding is supported."""
|
|
363
|
+
return True
|
|
364
|
+
|
|
365
|
+
@property
|
|
366
|
+
def stake_address(self) -> Address | None:
|
|
367
|
+
"""No batcher stake address."""
|
|
368
|
+
return None
|
|
369
|
+
|
|
370
|
+
@classmethod
|
|
371
|
+
def post_init(cls, values: dict) -> dict:
|
|
372
|
+
"""Enforce taker orientation: unit(0)=ask (in), unit(1)=offer (out).
|
|
373
|
+
|
|
374
|
+
Rebuild the assets dict in a fixed order — ask first, offer second, then
|
|
375
|
+
any residual tokens (e.g. the UTxO's min-ADA when it is neither the offer
|
|
376
|
+
nor the ask). ``Assets`` is insertion-ordered (its sort only floats
|
|
377
|
+
``lovelace`` to the front on construction), so reassigning ``root`` in
|
|
378
|
+
this order makes ``unit(0)`` the ask and ``unit(1)`` the offer.
|
|
379
|
+
"""
|
|
380
|
+
datum = cls.order_datum_class().from_cbor(values["datum_cbor"])
|
|
381
|
+
|
|
382
|
+
ask_unit = datum.ask_unit()
|
|
383
|
+
offer_unit = datum.offer_unit()
|
|
384
|
+
|
|
385
|
+
assets = values["assets"]
|
|
386
|
+
root = assets.root
|
|
387
|
+
|
|
388
|
+
# Both legs must be present so unit(0)/unit(1) are well defined, even if a
|
|
389
|
+
# side is absent from the balance (a normal one-way swap holds only the
|
|
390
|
+
# offer asset; the taker brings the ask asset).
|
|
391
|
+
ordered: dict[str, int] = {
|
|
392
|
+
ask_unit: root.pop(ask_unit, 0),
|
|
393
|
+
offer_unit: root.pop(offer_unit, 0),
|
|
394
|
+
}
|
|
395
|
+
# Preserve any residual tokens (e.g. min-ADA) after the traded pair.
|
|
396
|
+
ordered.update(root)
|
|
397
|
+
|
|
398
|
+
assets.root = ordered
|
|
399
|
+
|
|
400
|
+
# A one-way swap whose expiration is in the past is no longer fillable on
|
|
401
|
+
# chain (the validator requires the tx validity interval to end at or
|
|
402
|
+
# before the expiration), so mark it inactive — mirroring the sibling
|
|
403
|
+
# order-book classes. ``expiration`` is POSIX milliseconds; ``PlutusNone``
|
|
404
|
+
# means the swap never expires.
|
|
405
|
+
expiration = datum.expiration
|
|
406
|
+
values["inactive"] = isinstance(expiration, CardanoSwapsSomeInt) and (
|
|
407
|
+
int(time.time() * 1000) >= expiration.value
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
return values
|
|
411
|
+
|
|
412
|
+
# --- transaction builders --------------------------------------------
|
|
413
|
+
|
|
414
|
+
@staticmethod
|
|
415
|
+
def _swap_script() -> PlutusV2Script:
|
|
416
|
+
"""The (inline) one-way swap spending validator."""
|
|
417
|
+
return PlutusV2Script(bytes.fromhex(SWAP_VALIDATOR_SCRIPT_HEX))
|
|
418
|
+
|
|
419
|
+
@staticmethod
|
|
420
|
+
def _beacon_script() -> PlutusV2Script:
|
|
421
|
+
"""The (inline) beacon minting/staking policy."""
|
|
422
|
+
return PlutusV2Script(bytes.fromhex(BEACON_POLICY_SCRIPT_HEX))
|
|
423
|
+
|
|
424
|
+
@staticmethod
|
|
425
|
+
def beacon_address(owner_address: Address) -> Address:
|
|
426
|
+
"""The beacon-tagged swap address for an owner.
|
|
427
|
+
|
|
428
|
+
The payment credential is the swap spending validator hash; the staking
|
|
429
|
+
credential is the owner's (carried over from ``owner_address``). The
|
|
430
|
+
owner *is* this staking credential — beacons can only be paid to a staked
|
|
431
|
+
DApp address, so a resting swap always carries one.
|
|
432
|
+
"""
|
|
433
|
+
return Address(
|
|
434
|
+
payment_part=ScriptHash(bytes.fromhex(SWAP_VALIDATOR_HASH)),
|
|
435
|
+
staking_part=owner_address.staking_part,
|
|
436
|
+
network=owner_address.network or Network.MAINNET,
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
@staticmethod
|
|
440
|
+
def _beacon_mint_assets(datum: CardanoSwapsSwapDatum, quantity: int) -> Assets:
|
|
441
|
+
"""The three beacons (pair/offer/ask) at +1 (CREATE) or -1 (CLOSE)."""
|
|
442
|
+
return Assets(
|
|
443
|
+
root={
|
|
444
|
+
BEACON_POLICY_ID + datum.pair_beacon.hex(): quantity,
|
|
445
|
+
BEACON_POLICY_ID + datum.offer_beacon.hex(): quantity,
|
|
446
|
+
BEACON_POLICY_ID + datum.ask_beacon.hex(): quantity,
|
|
447
|
+
},
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
@staticmethod
|
|
451
|
+
def _accumulate_mint(tx_builder: TransactionBuilder, mint_assets: Assets) -> None:
|
|
452
|
+
"""Add ``mint_assets`` to the builder's mint field (creating it if unset)."""
|
|
453
|
+
multi_asset = asset_to_value(mint_assets).multi_asset
|
|
454
|
+
if tx_builder.mint is None:
|
|
455
|
+
tx_builder.mint = multi_asset
|
|
456
|
+
else:
|
|
457
|
+
tx_builder.mint += multi_asset
|
|
458
|
+
|
|
459
|
+
@classmethod
|
|
460
|
+
def build_create(
|
|
461
|
+
cls,
|
|
462
|
+
owner_address: Address,
|
|
463
|
+
offer: Assets,
|
|
464
|
+
ask: Assets,
|
|
465
|
+
price: tuple[int, int],
|
|
466
|
+
tx_builder: TransactionBuilder,
|
|
467
|
+
expiration: int | None = None,
|
|
468
|
+
) -> tuple[TransactionOutput, CardanoSwapsSwapDatum]:
|
|
469
|
+
"""Build a CREATE: mint the three beacons and emit the resting swap UTxO.
|
|
470
|
+
|
|
471
|
+
Mints +1 of each beacon (pair/offer/ask) under the beacon policy with
|
|
472
|
+
``CreateOrCloseSwaps`` and produces one output at the owner's
|
|
473
|
+
beacon-tagged swap address carrying the offer asset, the three beacons
|
|
474
|
+
and an inline ``SwapDatum``. No swap-UTxO is spent.
|
|
475
|
+
|
|
476
|
+
Args:
|
|
477
|
+
owner_address: The owner's address; its staking credential identifies
|
|
478
|
+
the owner and is carried onto the swap address.
|
|
479
|
+
offer: The offered (output) asset and quantity (one token).
|
|
480
|
+
ask: The asked (input) asset, quantity ignored (one token).
|
|
481
|
+
price: ``(numerator, denominator)`` ask-per-offer rational.
|
|
482
|
+
tx_builder: The builder to mutate.
|
|
483
|
+
expiration: Optional POSIX-millis expiration (must be a 60000-multiple).
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
The swap output and its inline ``SwapDatum``.
|
|
487
|
+
"""
|
|
488
|
+
offer_unit = offer.unit()
|
|
489
|
+
ask_unit = ask.unit()
|
|
490
|
+
offer_id, offer_name = cls._split_unit(offer_unit)
|
|
491
|
+
ask_id, ask_name = cls._split_unit(ask_unit)
|
|
492
|
+
|
|
493
|
+
num, den = price
|
|
494
|
+
exp = (
|
|
495
|
+
CardanoSwapsSomeInt(value=expiration)
|
|
496
|
+
if expiration is not None
|
|
497
|
+
else (PlutusNone())
|
|
498
|
+
)
|
|
499
|
+
datum = CardanoSwapsSwapDatum(
|
|
500
|
+
beacon_id=bytes.fromhex(BEACON_POLICY_ID),
|
|
501
|
+
pair_beacon=pair_beacon_name(offer_id, offer_name, ask_id, ask_name),
|
|
502
|
+
offer_id=offer_id,
|
|
503
|
+
offer_name=offer_name,
|
|
504
|
+
offer_beacon=offer_beacon_name(offer_id, offer_name),
|
|
505
|
+
ask_id=ask_id,
|
|
506
|
+
ask_name=ask_name,
|
|
507
|
+
ask_beacon=ask_beacon_name(ask_id, ask_name),
|
|
508
|
+
swap_price=CardanoSwapsRational(numerator=num, denominator=den),
|
|
509
|
+
prev_input=PlutusNone(),
|
|
510
|
+
expiration=exp,
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
# Mint the three beacons.
|
|
514
|
+
tx_builder.add_minting_script(
|
|
515
|
+
script=cls._beacon_script(),
|
|
516
|
+
redeemer=Redeemer(CreateOrCloseSwaps()),
|
|
517
|
+
)
|
|
518
|
+
cls._accumulate_mint(tx_builder, cls._beacon_mint_assets(datum, 1))
|
|
519
|
+
|
|
520
|
+
# Emit the resting swap output: offer + 3 beacons + min-ADA, inline datum.
|
|
521
|
+
swap_address = cls.beacon_address(owner_address)
|
|
522
|
+
output_assets = offer + cls._beacon_mint_assets(datum, 1)
|
|
523
|
+
txo = TransactionOutput(
|
|
524
|
+
address=swap_address,
|
|
525
|
+
amount=asset_to_value(output_assets),
|
|
526
|
+
datum=datum,
|
|
527
|
+
)
|
|
528
|
+
txo.amount.coin = max(
|
|
529
|
+
txo.amount.coin,
|
|
530
|
+
min_lovelace(tx_builder.context, output=txo),
|
|
531
|
+
)
|
|
532
|
+
tx_builder.add_output(txo)
|
|
533
|
+
|
|
534
|
+
return txo, datum
|
|
535
|
+
|
|
536
|
+
@staticmethod
|
|
537
|
+
def _split_unit(unit: str) -> tuple[bytes, bytes]:
|
|
538
|
+
"""Split a dendrite unit into on-chain (policy, name) bytes (ADA -> empty)."""
|
|
539
|
+
if unit == "lovelace":
|
|
540
|
+
return b"", b""
|
|
541
|
+
return bytes.fromhex(unit[:56]), bytes.fromhex(unit[56:])
|
|
542
|
+
|
|
543
|
+
def _input_utxo(self, owner_address: Address) -> UTxO:
|
|
544
|
+
"""The synthetic resting swap UTxO (offer + 3 beacons), inline datum.
|
|
545
|
+
|
|
546
|
+
Its address payment part is the swap validator hash (so the inline script
|
|
547
|
+
resolves) and its staking part is the owner's.
|
|
548
|
+
"""
|
|
549
|
+
beacons = self.dex_nft if self.dex_nft is not None else Assets(root={})
|
|
550
|
+
amount = self.assets + Assets(root=dict(beacons.root))
|
|
551
|
+
return UTxO(
|
|
552
|
+
TransactionInput(
|
|
553
|
+
transaction_id=TransactionId(bytes.fromhex(self.tx_hash)),
|
|
554
|
+
index=self.tx_index,
|
|
555
|
+
),
|
|
556
|
+
output=TransactionOutput(
|
|
557
|
+
address=self.beacon_address(owner_address),
|
|
558
|
+
amount=asset_to_value(amount),
|
|
559
|
+
datum=self.order_datum,
|
|
560
|
+
),
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
def swap_utxo(
|
|
564
|
+
self,
|
|
565
|
+
address_source: Address,
|
|
566
|
+
in_assets: Assets,
|
|
567
|
+
out_assets: Assets,
|
|
568
|
+
tx_builder: TransactionBuilder,
|
|
569
|
+
extra_assets: Assets | None = None,
|
|
570
|
+
address_target: Address | None = None,
|
|
571
|
+
datum_target: PlutusData | None = None,
|
|
572
|
+
owner_address: Address | None = None,
|
|
573
|
+
) -> tuple[TransactionOutput | None, PlutusData]:
|
|
574
|
+
"""Build a FILL: spend the resting swap UTxO and fill at price or better.
|
|
575
|
+
|
|
576
|
+
Spends the resting UTxO with the ``Swap`` spending redeemer (inline
|
|
577
|
+
script — no on-chain reference) and emits the contract-mandated
|
|
578
|
+
continuing output back to the same swap address: the three beacons are
|
|
579
|
+
preserved, the offer balance is decremented by the amount taken, and the
|
|
580
|
+
ask paid in (at price or better) accumulates into this same output. The
|
|
581
|
+
datum is otherwise identical to the input, with ``prev_input`` pointing
|
|
582
|
+
at the consumed UTxO. No beacons are minted or burned, and there is no
|
|
583
|
+
separate maker payment — the maker collects the accumulated ask on CLOSE.
|
|
584
|
+
|
|
585
|
+
``out_assets`` is the offer asset the taker receives; ``in_assets`` is the
|
|
586
|
+
ask asset they pay. Purity (only offer leaves, only ask is added) and the
|
|
587
|
+
``offer_taken * price_num <= ask_given * price_den`` price check are
|
|
588
|
+
enforced by the validator; this builder constructs a balanced fill.
|
|
589
|
+
|
|
590
|
+
Returns:
|
|
591
|
+
``(continuing_output, continuing_datum)`` — the validator always
|
|
592
|
+
requires a continuing beacon output (a full fill simply leaves the
|
|
593
|
+
offer balance at ~0); only CLOSE removes the beacons.
|
|
594
|
+
"""
|
|
595
|
+
owner = owner_address if owner_address is not None else address_source
|
|
596
|
+
|
|
597
|
+
# in/out orientation: out = offer (taker receives), in = ask (taker pays).
|
|
598
|
+
if out_assets.unit() != self.out_unit:
|
|
599
|
+
raise ValueError("out_assets must be the offer asset.")
|
|
600
|
+
if in_assets.unit() != self.in_unit:
|
|
601
|
+
raise ValueError("in_assets must be the ask asset.")
|
|
602
|
+
|
|
603
|
+
offer_unit = self.out_unit
|
|
604
|
+
ask_unit = self.in_unit
|
|
605
|
+
|
|
606
|
+
num, den = self.price
|
|
607
|
+
offer_taken = out_assets.quantity()
|
|
608
|
+
# Minimum ask the maker must receive for this offer at price-or-better:
|
|
609
|
+
# offer_taken*num <= ask_given*den => ask_given >= ceil(offer_taken*num/den).
|
|
610
|
+
ask_given = -(-offer_taken * num // den) # ceil division
|
|
611
|
+
|
|
612
|
+
input_utxo = self._input_utxo(owner)
|
|
613
|
+
|
|
614
|
+
tx_builder.add_script_input(
|
|
615
|
+
utxo=input_utxo,
|
|
616
|
+
script=self._swap_script(),
|
|
617
|
+
redeemer=Redeemer(Swap()),
|
|
618
|
+
)
|
|
619
|
+
tx_builder.datums.update({self.order_datum.hash(): self.order_datum})
|
|
620
|
+
|
|
621
|
+
# The swap is a single accumulating UTxO: the taker removes the offer
|
|
622
|
+
# they take and deposits the ask (at price or better) back into the SAME
|
|
623
|
+
# continuing output. The validator reads ``ask_given = ask_out - ask_in``
|
|
624
|
+
# and ``offer_taken = offer_in - offer_out`` from this output — there is
|
|
625
|
+
# no separate maker payment; the maker collects the accumulated ask on
|
|
626
|
+
# CLOSE. The datum is identical to the input EXCEPT prev_input = consumed
|
|
627
|
+
# TxOutRef.
|
|
628
|
+
cont_datum = CardanoSwapsSwapDatum.from_cbor(self.order_datum.to_cbor())
|
|
629
|
+
cont_datum.prev_input = CardanoSwapsSomeOutRef(
|
|
630
|
+
value=CardanoSwapsOutputReference(
|
|
631
|
+
transaction_id=CardanoSwapsTxId(tx_hash=bytes.fromhex(self.tx_hash)),
|
|
632
|
+
output_index=self.tx_index,
|
|
633
|
+
),
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
# Continuing value = consumed value, less the offer taken, plus the ask
|
|
637
|
+
# paid in. Beacons and any min-ADA carrier are preserved verbatim.
|
|
638
|
+
cont_balance: dict[str, int] = {"lovelace": input_utxo.output.amount.coin}
|
|
639
|
+
multi_asset = input_utxo.output.amount.multi_asset
|
|
640
|
+
if multi_asset is not None:
|
|
641
|
+
for policy, names in multi_asset.data.items():
|
|
642
|
+
for name, qty in names.items():
|
|
643
|
+
cont_balance[bytes(policy).hex() + bytes(name).hex()] = qty
|
|
644
|
+
cont_balance[offer_unit] = cont_balance.get(offer_unit, 0) - offer_taken
|
|
645
|
+
cont_balance[ask_unit] = cont_balance.get(ask_unit, 0) + ask_given
|
|
646
|
+
cont_assets = Assets(
|
|
647
|
+
root={
|
|
648
|
+
unit: qty
|
|
649
|
+
for unit, qty in cont_balance.items()
|
|
650
|
+
if qty != 0 or unit == "lovelace"
|
|
651
|
+
},
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
cont_txo = TransactionOutput(
|
|
655
|
+
address=input_utxo.output.address,
|
|
656
|
+
amount=asset_to_value(cont_assets),
|
|
657
|
+
datum=cont_datum,
|
|
658
|
+
)
|
|
659
|
+
cont_txo.amount.coin = max(
|
|
660
|
+
cont_txo.amount.coin,
|
|
661
|
+
min_lovelace(tx_builder.context, output=cont_txo),
|
|
662
|
+
)
|
|
663
|
+
tx_builder.add_output(cont_txo)
|
|
664
|
+
|
|
665
|
+
return cont_txo, cont_datum
|
|
666
|
+
|
|
667
|
+
def build_close(
|
|
668
|
+
self,
|
|
669
|
+
tx_builder: TransactionBuilder,
|
|
670
|
+
owner_address: Address | None = None,
|
|
671
|
+
) -> CardanoSwapsSwapDatum:
|
|
672
|
+
"""Build a CLOSE: spend the swap UTxO and burn the three beacons.
|
|
673
|
+
|
|
674
|
+
Spends the resting UTxO with ``SpendWithMint`` and burns -1 of each
|
|
675
|
+
beacon under the beacon policy with ``CreateOrCloseSwaps``. The owner's
|
|
676
|
+
stake credential must authorize the spend (sign with the stake key for a
|
|
677
|
+
vkey stake credential, or run the stake script); reclaim of the offer
|
|
678
|
+
asset to the owner is handled by change.
|
|
679
|
+
|
|
680
|
+
Returns:
|
|
681
|
+
The spent (resting) ``SwapDatum``.
|
|
682
|
+
"""
|
|
683
|
+
if owner_address is None:
|
|
684
|
+
raise ValueError("build_close requires the owner address.")
|
|
685
|
+
|
|
686
|
+
input_utxo = self._input_utxo(owner_address)
|
|
687
|
+
tx_builder.add_script_input(
|
|
688
|
+
utxo=input_utxo,
|
|
689
|
+
script=self._swap_script(),
|
|
690
|
+
redeemer=Redeemer(SpendWithMint()),
|
|
691
|
+
)
|
|
692
|
+
tx_builder.datums.update({self.order_datum.hash(): self.order_datum})
|
|
693
|
+
|
|
694
|
+
# Burn the three beacons.
|
|
695
|
+
tx_builder.add_minting_script(
|
|
696
|
+
script=self._beacon_script(),
|
|
697
|
+
redeemer=Redeemer(CreateOrCloseSwaps()),
|
|
698
|
+
)
|
|
699
|
+
self._accumulate_mint(
|
|
700
|
+
tx_builder,
|
|
701
|
+
self._beacon_mint_assets(self.order_datum, -1),
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
# NOTE: the validator gates the close on the swap address' STAKING
|
|
705
|
+
# credential, not its payment credential. For a vkey stake credential the
|
|
706
|
+
# owner's stake key must be among the signatories — the caller supplies it
|
|
707
|
+
# via ``build_and_sign(signing_keys=[...])`` and/or
|
|
708
|
+
# ``tx_builder.required_signers``; for a script stake credential the stake
|
|
709
|
+
# script must be executed (a withdrawal). This builder only assembles the
|
|
710
|
+
# spend + burn; signing/withdrawal is the caller's responsibility.
|
|
711
|
+
return self.order_datum
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/utility.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Utility functions for
|
|
1
|
+
"""Utility functions for assets and Plutus scripts."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
from datetime import datetime
|
|
@@ -168,3 +168,37 @@ def naturalize_assets(assets: Assets) -> dict[str, Decimal]:
|
|
|
168
168
|
nat_assets[unit] = Decimal(quantity) / Decimal(10 ** asset_decimals(unit))
|
|
169
169
|
|
|
170
170
|
return nat_assets
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def apply_params_to_script(script_cbor: bytes, *params: bytes | int) -> bytes:
|
|
174
|
+
"""Apply Plutus ``Data`` parameters to a parameterized Plutus script.
|
|
175
|
+
|
|
176
|
+
A pure-Python equivalent of ``aiken blueprint apply`` (via the optional
|
|
177
|
+
``uplc`` library, imported lazily): the script term is wrapped in an
|
|
178
|
+
``Apply`` node per parameter and re-serialized, so a parameterized
|
|
179
|
+
validator's deployed script — and hence its on-chain script hash /
|
|
180
|
+
minting-policy id — can be derived without external tooling.
|
|
181
|
+
|
|
182
|
+
Parameters are applied left-to-right as ``Data`` constants (``bytes`` -> a
|
|
183
|
+
Data bytestring, ``int`` -> a Data integer). ``script_cbor`` and the return
|
|
184
|
+
value are the CBOR-wrapped flat encodings used by ``PlutusV2Script`` and
|
|
185
|
+
``plutus.json`` ``compiledCode``.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
script_cbor: The un-applied compiled script, CBOR-wrapped.
|
|
189
|
+
*params: The Data parameters to apply, in order.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
The parameter-applied compiled script, CBOR-wrapped.
|
|
193
|
+
"""
|
|
194
|
+
from uplc.ast import PlutusByteString # type: ignore[import-untyped]
|
|
195
|
+
from uplc.ast import PlutusInteger # type: ignore[import-untyped]
|
|
196
|
+
from uplc.tools import apply # type: ignore[import-untyped]
|
|
197
|
+
from uplc.tools import flatten # type: ignore[import-untyped]
|
|
198
|
+
from uplc.tools import unflatten # type: ignore[import-untyped]
|
|
199
|
+
|
|
200
|
+
constants = [
|
|
201
|
+
PlutusByteString(p) if isinstance(p, bytes) else PlutusInteger(p)
|
|
202
|
+
for p in params
|
|
203
|
+
]
|
|
204
|
+
return flatten(apply(unflatten(script_cbor), *constants))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/backend/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/cswap.py
RENAMED
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/dano.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/amm/vyfi.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/core/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/axo.py
RENAMED
|
File without changes
|
|
File without changes
|
{charli3_dendrite-1.4.10.dev1 → charli3_dendrite-1.4.11.dev0}/src/charli3_dendrite/dexs/ob/djed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|