Skip to content

Wingriders

WingRiders DEX Module.

AtoB dataclass

Bases: PlutusData

A to B.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
100
101
102
103
104
@dataclass
class AtoB(PlutusData):
    """A to B."""

    CONSTR_ID = 0

BtoA dataclass

Bases: PlutusData

B to A.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
107
108
109
110
111
@dataclass
class BtoA(PlutusData):
    """B to A."""

    CONSTR_ID = 1

LiquidityPool dataclass

Bases: PlutusData

Encode a liquidity pool for the WingRiders DEX.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
252
253
254
255
256
257
258
259
260
@dataclass
class LiquidityPool(PlutusData):
    """Encode a liquidity pool for the WingRiders DEX."""

    CONSTR_ID = 0
    assets: LiquidityPoolAssets
    last_swap: int
    quantity_a: int
    quantity_b: int

LiquidityPoolAssets dataclass

Bases: PlutusData

Encode a pair of assets for the WingRiders DEX.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
243
244
245
246
247
248
249
@dataclass
class LiquidityPoolAssets(PlutusData):
    """Encode a pair of assets for the WingRiders DEX."""

    CONSTR_ID = 0
    asset_a: AssetClass
    asset_b: AssetClass

RewardPlutusFullAddress dataclass

Bases: PlutusFullAddress

A full address, including payment and staking keys.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
57
58
59
60
61
62
63
@dataclass
class RewardPlutusFullAddress(PlutusFullAddress):
    """A full address, including payment and staking keys."""

    CONSTR_ID = 0

    payment: RewardPlutusPartAddress

RewardPlutusPartAddress dataclass

Bases: PlutusData

Encode a plutus address part (i.e. payment, stake, etc).

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
49
50
51
52
53
54
@dataclass
class RewardPlutusPartAddress(PlutusData):
    """Encode a plutus address part (i.e. payment, stake, etc)."""

    CONSTR_ID = 1
    address: bytes

WingRiderOrderConfig dataclass

Bases: PlutusData

Configuration for a WingRiders order.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
@dataclass
class WingRiderOrderConfig(PlutusData):
    """Configuration for a WingRiders order."""

    CONSTR_ID = 0

    full_address: Union[PlutusFullAddress, RewardPlutusFullAddress]
    address: bytes
    expiration: int
    assets: WingriderAssetClass

    @classmethod
    def create_config(
        cls,
        address: Address,
        expiration: int,
        in_assets: Assets,
        out_assets: Assets,
    ):
        """Create a WingRiders order configuration."""
        plutus_address = PlutusFullAddress.from_address(address)
        assets = WingriderAssetClass.from_assets(
            in_assets=in_assets,
            out_assets=out_assets,
        )

        return cls(
            full_address=plutus_address,
            address=bytes.fromhex(str(address.payment_part)),
            expiration=expiration,
            assets=assets,
        )

create_config(address: Address, expiration: int, in_assets: Assets, out_assets: Assets) classmethod

Create a WingRiders order configuration.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
@classmethod
def create_config(
    cls,
    address: Address,
    expiration: int,
    in_assets: Assets,
    out_assets: Assets,
):
    """Create a WingRiders order configuration."""
    plutus_address = PlutusFullAddress.from_address(address)
    assets = WingriderAssetClass.from_assets(
        in_assets=in_assets,
        out_assets=out_assets,
    )

    return cls(
        full_address=plutus_address,
        address=bytes.fromhex(str(address.payment_part)),
        expiration=expiration,
        assets=assets,
    )

WingRidersCPPState

Bases: AbstractConstantProductPoolState

WingRiders CPP state.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
class WingRidersCPPState(AbstractConstantProductPoolState):
    """WingRiders CPP state."""

    fee: int = 35
    _batcher = Assets(lovelace=2000000)
    _deposit = Assets(lovelace=2000000)
    _stake_address: ClassVar[Address] = Address.from_primitive(
        "addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4",
    )

    @classmethod
    def dex(cls) -> str:
        return "WingRiders"

    @classmethod
    def order_selector(self) -> list[str]:
        return [self._stake_address.encode()]

    @classmethod
    def pool_selector(cls) -> PoolSelector:
        return PoolSelector(
            addresses=[
                "addr1w8nvjzjeydcn4atcd93aac8allvrpjn7pjr2qsweukpnayghhwcpj",
                "addr1wxvx34v0hlxzk9x0clv7as9hvhn7dlzwj5xfcf6g4n5uucg4tkd7w",
            ],
            assets=cls.dex_policy(),
        )

    @property
    def swap_forward(self) -> bool:
        return False

    @property
    def stake_address(self) -> Address:
        return self._stake_address

    @classmethod
    def order_datum_class(self) -> type[WingRidersOrderDatum]:
        return WingRidersOrderDatum

    @classmethod
    def pool_datum_class(self) -> type[WingRidersPoolDatum]:
        return WingRidersPoolDatum

    @classmethod
    def pool_policy(cls) -> str:
        return ["026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a570"]

    @classmethod
    def dex_policy(cls) -> str:
        return ["026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a5704c"]

    @property
    def pool_id(self) -> str:
        """A unique identifier for the pool."""
        return self.pool_nft.unit()

    @classmethod
    def skip_init(cls, values) -> bool:
        if "pool_nft" in values and "dex_nft" in values:
            if cls.dex_policy()[0] not in values["dex_nft"]:
                raise NotAPoolError("Invalid DEX NFT")
            if len(values["assets"]) == 3:
                # Send the ADA token to the end
                if isinstance(values["assets"], Assets):
                    values["assets"].root["lovelace"] = values["assets"].root.pop(
                        "lovelace",
                    )
                else:
                    values["assets"]["lovelace"] = values["assets"].pop("lovelace")
            values["assets"] = Assets.model_validate(values["assets"])
            return True
        else:
            return False

    @classmethod
    def post_init(cls, values):
        super().post_init(values)

        assets = values["assets"]
        datum = WingRidersPoolDatum.from_cbor(values["datum_cbor"])

        if len(assets) == 2:
            assets.root[assets.unit(0)] -= 3000000

        assets.root[assets.unit(0)] -= datum.datum.quantity_a
        assets.root[assets.unit(1)] -= datum.datum.quantity_b

    def deposit(
        self,
        in_assets: Assets | None = None,
        out_assets: Assets | None = None,
    ):
        merged_assets = in_assets + out_assets
        if "lovelace" in merged_assets:
            return Assets(lovelace=4000000) - self.batcher_fee(
                in_assets=in_assets,
                out_assets=out_assets,
            )
        else:
            return self._deposit

    def batcher_fee(
        self,
        in_assets: Assets | None = None,
        out_assets: Assets | None = None,
        extra_assets: Assets | None = None,
    ):
        merged_assets = in_assets + out_assets
        if "lovelace" in merged_assets:
            if merged_assets["lovelace"] <= 250000000:
                return Assets(lovelace=850000)
            elif merged_assets["lovelace"] <= 500000000:
                return Assets(lovelace=1500000)
        return self._batcher

pool_id: str property

A unique identifier for the pool.

WingRidersDepositDetail dataclass

Bases: PlutusData

WingRiders deposit detail.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
133
134
135
136
137
138
139
@dataclass
class WingRidersDepositDetail(PlutusData):
    """WingRiders deposit detail."""

    CONSTR_ID = 1

    min_lp_receive: int

WingRidersMaybeFeeClaimDetail dataclass

Bases: PlutusData

WingRiders maybe fee claim detail.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
152
153
154
155
156
@dataclass
class WingRidersMaybeFeeClaimDetail(PlutusData):
    """WingRiders maybe fee claim detail."""

    CONSTR_ID = 3

WingRidersOrderDatum dataclass

Bases: OrderDatum

WingRiders order datum.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
@dataclass
class WingRidersOrderDatum(OrderDatum):
    """WingRiders order datum."""

    config: WingRiderOrderConfig
    detail: Union[
        WingRidersDepositDetail,
        WingRidersMaybeFeeClaimDetail,
        WingRidersStakeRewardDetail,
        WingRidersOrderDetail,
        WingRidersWithdrawDetail,
    ]

    @classmethod
    def create_datum(
        cls,
        address_source: Address,
        in_assets: Assets,
        out_assets: Assets,
        batcher_fee: Assets,
        deposit: Assets,
        address_target: Address | None = None,
        datum_target: PlutusData | None = None,
    ):
        """Create a WingRiders order datum."""
        timeout = int(((datetime.utcnow() + timedelta(days=360)).timestamp()) * 1000)

        config = WingRiderOrderConfig.create_config(
            address=address_source,
            expiration=timeout,
            in_assets=in_assets,
            out_assets=out_assets,
        )
        detail = WingRidersOrderDetail.from_assets(
            in_assets=in_assets,
            out_assets=out_assets,
        )

        return cls(config=config, detail=detail)

    def address_source(self) -> Address:
        return self.config.full_address.to_address()

    def requested_amount(self) -> Assets:
        if isinstance(self.detail, WingRidersDepositDetail):
            return Assets({"lp": self.detail.min_lp_receive})
        elif isinstance(self.detail, WingRidersOrderDetail):
            if isinstance(self.detail.direction, BtoA):
                return Assets(
                    {self.config.assets.asset_a.assets.unit(): self.detail.min_receive},
                )
            else:
                return Assets(
                    {self.config.assets.asset_b.assets.unit(): self.detail.min_receive},
                )
        elif isinstance(self.detail, WingRidersWithdrawDetail):
            return Assets(
                {
                    self.config.assets.asset_a.assets.unit(): self.detail.min_amount_a,
                    self.config.assets.asset_b.assets.unit(): self.detail.min_amount_b,
                },
            )
        elif isinstance(self.detail, WingRidersMaybeFeeClaimDetail):
            return Assets({})

    def order_type(self) -> OrderType | None:
        order_type = None
        if isinstance(self.detail, WingRidersOrderDetail):
            order_type = OrderType.swap
        elif isinstance(self.detail, WingRidersDepositDetail):
            order_type = OrderType.deposit
        elif isinstance(self.detail, WingRidersWithdrawDetail):
            order_type = OrderType.withdraw

        return order_type

create_datum(address_source: Address, in_assets: Assets, out_assets: Assets, batcher_fee: Assets, deposit: Assets, address_target: Address | None = None, datum_target: PlutusData | None = None) classmethod

Create a WingRiders order datum.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
@classmethod
def create_datum(
    cls,
    address_source: Address,
    in_assets: Assets,
    out_assets: Assets,
    batcher_fee: Assets,
    deposit: Assets,
    address_target: Address | None = None,
    datum_target: PlutusData | None = None,
):
    """Create a WingRiders order datum."""
    timeout = int(((datetime.utcnow() + timedelta(days=360)).timestamp()) * 1000)

    config = WingRiderOrderConfig.create_config(
        address=address_source,
        expiration=timeout,
        in_assets=in_assets,
        out_assets=out_assets,
    )
    detail = WingRidersOrderDetail.from_assets(
        in_assets=in_assets,
        out_assets=out_assets,
    )

    return cls(config=config, detail=detail)

WingRidersOrderDetail dataclass

Bases: PlutusData

WingRiders order detail.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
@dataclass
class WingRidersOrderDetail(PlutusData):
    """WingRiders order detail."""

    CONSTR_ID = 0

    direction: Union[AtoB, BtoA]
    min_receive: int

    @classmethod
    def from_assets(cls, in_assets: Assets, out_assets: Assets):
        """Create a WingRidersOrderDetail from a pair of assets."""
        merged = in_assets + out_assets
        if in_assets.unit() == merged.unit():
            return cls(direction=AtoB(), min_receive=out_assets.quantity())
        else:
            return cls(direction=BtoA(), min_receive=out_assets.quantity())

from_assets(in_assets: Assets, out_assets: Assets) classmethod

Create a WingRidersOrderDetail from a pair of assets.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
123
124
125
126
127
128
129
130
@classmethod
def from_assets(cls, in_assets: Assets, out_assets: Assets):
    """Create a WingRidersOrderDetail from a pair of assets."""
    merged = in_assets + out_assets
    if in_assets.unit() == merged.unit():
        return cls(direction=AtoB(), min_receive=out_assets.quantity())
    else:
        return cls(direction=BtoA(), min_receive=out_assets.quantity())

WingRidersPoolDatum dataclass

Bases: PoolDatum

WingRiders pool datum.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
263
264
265
266
267
268
269
270
271
@dataclass
class WingRidersPoolDatum(PoolDatum):
    """WingRiders pool datum."""

    lp_hash: bytes
    datum: LiquidityPool

    def pool_pair(self) -> Assets | None:
        return self.datum.assets.asset_a.assets + self.datum.assets.asset_b.assets

WingRidersSSPState

Bases: AbstractStableSwapPoolState, WingRidersCPPState

WingRiders SSP state.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
class WingRidersSSPState(AbstractStableSwapPoolState, WingRidersCPPState):
    """WingRiders SSP state."""

    fee: int = 6
    _batcher = Assets(lovelace=1500000)
    _deposit = Assets(lovelace=2000000)
    _stake_address = Address.from_primitive(
        "addr1w8z7qwzszt2lqy93m3atg2axx22yq5k7yvs9rmrvuwlawts2wzadz",
    )

    @classmethod
    def pool_policy(cls) -> str:
        return ["980e8c567670d34d4ec13a0c3b6de6199f260ae5dc9dc9e867bc5c93"]

    @classmethod
    def dex_policy(cls) -> str:
        return ["980e8c567670d34d4ec13a0c3b6de6199f260ae5dc9dc9e867bc5c934c"]

WingRidersStakeRewardDetail dataclass

Bases: PlutusData

WingRiders stake reward detail.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
159
160
161
162
163
@dataclass
class WingRidersStakeRewardDetail(PlutusData):
    """WingRiders stake reward detail."""

    CONSTR_ID = 4

WingRidersWithdrawDetail dataclass

Bases: PlutusData

WingRiders withdraw detail.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
142
143
144
145
146
147
148
149
@dataclass
class WingRidersWithdrawDetail(PlutusData):
    """WingRiders withdraw detail."""

    CONSTR_ID = 2

    min_amount_a: int
    min_amount_b: int

WingriderAssetClass dataclass

Bases: PlutusData

Encode a pair of assets for the WingRiders DEX.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@dataclass
class WingriderAssetClass(PlutusData):
    """Encode a pair of assets for the WingRiders DEX."""

    CONSTR_ID = 0

    asset_a: AssetClass
    asset_b: AssetClass

    @classmethod
    def from_assets(cls, in_assets: Assets, out_assets: Assets):
        """Create a WingRiderAssetClass from a pair of assets."""
        merged = in_assets + out_assets
        if in_assets.unit() == merged.unit():
            return cls(
                asset_a=AssetClass.from_assets(in_assets),
                asset_b=AssetClass.from_assets(out_assets),
            )
        else:
            return cls(
                asset_a=AssetClass.from_assets(out_assets),
                asset_b=AssetClass.from_assets(in_assets),
            )

from_assets(in_assets: Assets, out_assets: Assets) classmethod

Create a WingRiderAssetClass from a pair of assets.

Source code in src/charli3_dendrite/dexs/amm/wingriders.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@classmethod
def from_assets(cls, in_assets: Assets, out_assets: Assets):
    """Create a WingRiderAssetClass from a pair of assets."""
    merged = in_assets + out_assets
    if in_assets.unit() == merged.unit():
        return cls(
            asset_a=AssetClass.from_assets(in_assets),
            asset_b=AssetClass.from_assets(out_assets),
        )
    else:
        return cls(
            asset_a=AssetClass.from_assets(out_assets),
            asset_b=AssetClass.from_assets(in_assets),
        )