rango-basic-sdk 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2008 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Optional, Union
4
+
5
+ import os
6
+
7
+ from pydantic import TypeAdapter
8
+
9
+ import httpx
10
+ import logging
11
+
12
+ from . import models
13
+
14
+ # First ``servers`` URL from the OpenAPI document (``None`` if the spec defines none).
15
+ DEFAULT_SERVER_URL: Optional[str] = "https://api.rango.exchange"
16
+
17
+ _log = logging.getLogger(__name__)
18
+ _MAX_HTTP_DEBUG_BODY = 16_384
19
+
20
+
21
+ def _truncate_debug_text(s: str, limit: int = _MAX_HTTP_DEBUG_BODY) -> str:
22
+ if len(s) <= limit:
23
+ return s
24
+ return s[:limit] + "…(truncated)"
25
+
26
+
27
+ def _sync_http_debug_event_hooks() -> Dict[str, List[Any]]:
28
+ """Log each request/response pair at DEBUG after the response is received."""
29
+
30
+ def on_response(response: httpx.Response) -> None:
31
+ response.read()
32
+ req = response.request
33
+ req_body = ""
34
+ try:
35
+ raw = req.content
36
+ if raw:
37
+ req_body = _truncate_debug_text(raw.decode("utf-8", errors="replace"))
38
+ except Exception:
39
+ req_body = "<request body unavailable>"
40
+ resp_body = ""
41
+ try:
42
+ if response.content:
43
+ resp_body = _truncate_debug_text(response.text)
44
+ except Exception:
45
+ resp_body = "<response body unavailable>"
46
+ _log.debug(
47
+ "HTTP %s %s -> %s %s | request_headers=%r request_body=%r | "
48
+ "response_headers=%r response_body=%r",
49
+ req.method,
50
+ req.url,
51
+ response.status_code,
52
+ response.reason_phrase,
53
+ dict(req.headers),
54
+ req_body or "(empty)",
55
+ dict(response.headers),
56
+ resp_body or "(empty)",
57
+ )
58
+
59
+ return {"response": [on_response]}
60
+
61
+
62
+ def _async_http_debug_event_hooks() -> Dict[str, List[Any]]:
63
+ async def on_response(response: httpx.Response) -> None:
64
+ await response.aread()
65
+ req = response.request
66
+ req_body = ""
67
+ try:
68
+ raw = req.content
69
+ if raw:
70
+ req_body = _truncate_debug_text(raw.decode("utf-8", errors="replace"))
71
+ except Exception:
72
+ req_body = "<request body unavailable>"
73
+ resp_body = ""
74
+ try:
75
+ if response.content:
76
+ resp_body = _truncate_debug_text(response.text)
77
+ except Exception:
78
+ resp_body = "<response body unavailable>"
79
+ _log.debug(
80
+ "HTTP %s %s -> %s %s | request_headers=%r request_body=%r | "
81
+ "response_headers=%r response_body=%r",
82
+ req.method,
83
+ req.url,
84
+ response.status_code,
85
+ response.reason_phrase,
86
+ dict(req.headers),
87
+ req_body or "(empty)",
88
+ dict(response.headers),
89
+ resp_body or "(empty)",
90
+ )
91
+
92
+ return {"response": [on_response]}
93
+
94
+
95
+ def _security_value_from_kw_or_env(
96
+ value: Optional[str], env_name: str
97
+ ) -> Optional[str]:
98
+ """Use the constructor keyword when provided; otherwise read *env_name* from the OS environment."""
99
+ if value is not None:
100
+ return value
101
+ found = os.environ.get(env_name)
102
+ return found if found else None
103
+
104
+
105
+ class BalanceOperations:
106
+ """Operations with tag ``Balance``."""
107
+
108
+ def __init__(self, root: Client) -> None:
109
+ self._root = root
110
+
111
+ def balance(
112
+ self, blockchain: models.Blockchain, address: str
113
+ ) -> Optional[models.WalletDetailsResponse]:
114
+ """
115
+ Balance
116
+
117
+ Get all tokens' balances for the given wallet address.
118
+
119
+ Args:
120
+ blockchain (models.Blockchain): Blockchain Wire name ``blockchain`` (query).
121
+ address (str): User's wallet address Wire name ``address`` (query).
122
+
123
+ Returns:
124
+ ``Optional[models.WalletDetailsResponse]`` — JSON response parsed into the
125
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
126
+ empty body.
127
+
128
+ Examples:
129
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
130
+ result = client.balance.balance(blockchain=models.Blockchain.BSC, address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88")
131
+ print(result)
132
+ """
133
+ url = f"/basic/balance"
134
+ params: Dict[str, Any] = {}
135
+ params["blockchain"] = blockchain
136
+ params["address"] = address
137
+ req_headers: Dict[str, str] = {}
138
+ self._root._apply_security(["apiKey"], params, req_headers, None)
139
+
140
+ response = self._root._client.request(
141
+ "GET",
142
+ url,
143
+ params=params or None,
144
+ headers=req_headers or None,
145
+ )
146
+ response.raise_for_status()
147
+ if response.status_code in (204, 205) or not response.content:
148
+ return None
149
+ return models.WalletDetailsResponse.model_validate(response.json())
150
+
151
+ def get_token_balance(
152
+ self,
153
+ wallet_address: str,
154
+ blockchain: models.Blockchain,
155
+ symbol: str,
156
+ address: Optional[str] = None,
157
+ ) -> Optional[models.TokenBalanceResponse]:
158
+ """
159
+ Token Balance
160
+
161
+ Get balance of the given wallet address for a specific token.
162
+
163
+ Args:
164
+ wallet_address (str): User's wallet address Wire name ``walletAddress``
165
+ (query).
166
+ blockchain (models.Blockchain): Blockchain Wire name ``blockchain`` (query).
167
+ symbol (str): Token Symbol Wire name ``symbol`` (query).
168
+ address (Optional[str]): Token Address, This is ignored or null for native
169
+ tokens which have no address Wire name ``address``
170
+ (query).
171
+
172
+ Returns:
173
+ ``Optional[models.TokenBalanceResponse]`` — JSON response parsed into the
174
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
175
+ empty body.
176
+
177
+ Examples:
178
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
179
+ result = client.balance.get_token_balance(wallet_address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88", blockchain=models.Blockchain.BSC, symbol="USDT", address="0x55d398326f99059ff775485246999027b3197955")
180
+ print(result)
181
+ """
182
+ url = f"/basic/token-balance"
183
+ params: Dict[str, Any] = {}
184
+ params["walletAddress"] = wallet_address
185
+ params["blockchain"] = blockchain
186
+ params["symbol"] = symbol
187
+ if address is not None:
188
+ params["address"] = address
189
+ req_headers: Dict[str, str] = {}
190
+ self._root._apply_security(["apiKey"], params, req_headers, None)
191
+
192
+ response = self._root._client.request(
193
+ "GET",
194
+ url,
195
+ params=params or None,
196
+ headers=req_headers or None,
197
+ )
198
+ response.raise_for_status()
199
+ if response.status_code in (204, 205) or not response.content:
200
+ return None
201
+ return models.TokenBalanceResponse.model_validate(response.json())
202
+
203
+
204
+ class MetadataOperations:
205
+ """Operations with tag ``Metadata``."""
206
+
207
+ def __init__(self, root: Client) -> None:
208
+ self._root = root
209
+
210
+ def get_blockchains(self) -> Optional[List[models.BasicApiBlockchainMeta]]:
211
+ """
212
+ Blockchains Metadata
213
+
214
+ Metadata of all blockchains
215
+
216
+ Returns:
217
+ ``Optional[List[models.BasicApiBlockchainMeta]]`` — JSON response parsed
218
+ into the declared type when the body is non-empty; ``None`` for HTTP 204/205
219
+ or an empty body.
220
+
221
+ Examples:
222
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
223
+ result = client.metadata.get_blockchains()
224
+ print(result)
225
+ """
226
+ url = f"/basic/meta/blockchains"
227
+ params: Dict[str, Any] = {}
228
+ req_headers: Dict[str, str] = {}
229
+ self._root._apply_security(["apiKey"], params, req_headers, None)
230
+
231
+ response = self._root._client.request(
232
+ "GET",
233
+ url,
234
+ params=params or None,
235
+ headers=req_headers or None,
236
+ )
237
+ response.raise_for_status()
238
+ if response.status_code in (204, 205) or not response.content:
239
+ return None
240
+ return [
241
+ models.BasicApiBlockchainMeta.model_validate(x) for x in response.json()
242
+ ]
243
+
244
+ def get_custom_token_data(
245
+ self, blockchain: models.Blockchain, address: str
246
+ ) -> Optional[models.BasicCustomTokenResponse]:
247
+ """
248
+ Custom token
249
+
250
+ Returns the token details for user desired token that is not available on Rango
251
+ official list. currently supports Solana and EVM based blockchains
252
+
253
+ Args:
254
+ blockchain (models.Blockchain): The blockchain of the custom token Wire name
255
+ ``blockchain`` (query).
256
+ address (str): The address of the custom token Wire name ``address``
257
+ (query).
258
+
259
+ Returns:
260
+ ``Optional[models.BasicCustomTokenResponse]`` — JSON response parsed into
261
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
262
+ an empty body.
263
+
264
+ Examples:
265
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
266
+ result = client.metadata.get_custom_token_data(blockchain=models.Blockchain.BSC, address="0x5ac5e6Af46Ef285B3536833E65D245c49b608d9b")
267
+ print(result)
268
+ """
269
+ url = f"/basic/meta/custom-token"
270
+ params: Dict[str, Any] = {}
271
+ params["blockchain"] = blockchain
272
+ params["address"] = address
273
+ req_headers: Dict[str, str] = {}
274
+ self._root._apply_security(["apiKey"], params, req_headers, None)
275
+
276
+ response = self._root._client.request(
277
+ "GET",
278
+ url,
279
+ params=params or None,
280
+ headers=req_headers or None,
281
+ )
282
+ response.raise_for_status()
283
+ if response.status_code in (204, 205) or not response.content:
284
+ return None
285
+ return models.BasicCustomTokenResponse.model_validate(response.json())
286
+
287
+ def get_messaging_protocols(self) -> Optional[models.MessagingProtocolsResponse]:
288
+ """
289
+ Messaging Protocols Metadata
290
+
291
+ Metadata of all messaging protocols
292
+
293
+ Returns:
294
+ ``Optional[models.MessagingProtocolsResponse]`` — JSON response parsed into
295
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
296
+ an empty body.
297
+
298
+ Examples:
299
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
300
+ result = client.metadata.get_messaging_protocols()
301
+ print(result)
302
+ """
303
+ url = f"/basic/meta/messaging-protocols"
304
+ params: Dict[str, Any] = {}
305
+ req_headers: Dict[str, str] = {}
306
+ self._root._apply_security(["apiKey"], params, req_headers, None)
307
+
308
+ response = self._root._client.request(
309
+ "GET",
310
+ url,
311
+ params=params or None,
312
+ headers=req_headers or None,
313
+ )
314
+ response.raise_for_status()
315
+ if response.status_code in (204, 205) or not response.content:
316
+ return None
317
+ return models.MessagingProtocolsResponse.model_validate(response.json())
318
+
319
+ def get_swappers(self) -> Optional[List[models.SwapperMetaFullDto]]:
320
+ """
321
+ Swappers Metadata
322
+
323
+ Metadata of all swappers
324
+
325
+ Returns:
326
+ ``Optional[List[models.SwapperMetaFullDto]]`` — JSON response parsed into
327
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
328
+ an empty body.
329
+
330
+ Examples:
331
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
332
+ result = client.metadata.get_swappers()
333
+ print(result)
334
+ """
335
+ url = f"/basic/meta/swappers"
336
+ params: Dict[str, Any] = {}
337
+ req_headers: Dict[str, str] = {}
338
+ self._root._apply_security(["apiKey"], params, req_headers, None)
339
+
340
+ response = self._root._client.request(
341
+ "GET",
342
+ url,
343
+ params=params or None,
344
+ headers=req_headers or None,
345
+ )
346
+ response.raise_for_status()
347
+ if response.status_code in (204, 205) or not response.content:
348
+ return None
349
+ return [models.SwapperMetaFullDto.model_validate(x) for x in response.json()]
350
+
351
+ def meta(
352
+ self,
353
+ blockchains: Optional[List[models.Blockchain]] = None,
354
+ blockchains_exclude: Optional[bool] = None,
355
+ swappers: Optional[List[str]] = None,
356
+ swappers_exclude: Optional[bool] = None,
357
+ swapper_groups: Optional[List[str]] = None,
358
+ swappers_groups_exclude: Optional[bool] = None,
359
+ transaction_types: Optional[List[models.GenericTransactionType]] = None,
360
+ transaction_types_exclude: Optional[bool] = None,
361
+ exclude_non_populars: Optional[bool] = None,
362
+ ) -> Optional[models.BasicApiMetaResponse]:
363
+ """
364
+ Metadata (tokens, swappers, blockchains)
365
+
366
+ Get all tokens, DEX, and bridges metadata.
367
+
368
+ Args:
369
+ blockchains (Optional[List[models.Blockchain]]): The list of all accepted
370
+ blockchains. An empty list
371
+ means no filter is required
372
+ Wire name ``blockchains``
373
+ (query).
374
+ blockchains_exclude (Optional[bool]): Defines the provided blockchains as
375
+ the include/exclude list. Default is
376
+ false (include) Wire name
377
+ ``blockchainsExclude`` (query).
378
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
379
+ list means no filter is required Wire name
380
+ ``swappers`` (query).
381
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
382
+ include/exclude list. Default is false
383
+ (include) Wire name ``swappersExclude``
384
+ (query).
385
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
386
+ swappers based on tag, empty list
387
+ means no filter is required Wire name
388
+ ``swapperGroups`` (query).
389
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
390
+ tags as the include/exclude list.
391
+ Default is false (include) Wire
392
+ name ``swappersGroupsExclude``
393
+ (query).
394
+ transaction_types (Optional[List[models.GenericTransactionType]]): Blockchain Type Wire
395
+ name
396
+ ``transactionTypes``
397
+ (query).
398
+ transaction_types_exclude (Optional[bool]): Defines the provided swappers'
399
+ tags as the include/exclude
400
+ list. Default is false (include)
401
+ Wire name
402
+ ``transactionTypesExclude``
403
+ (query).
404
+ exclude_non_populars (Optional[bool]): Exclude non popular tokens. Default
405
+ is false (include) Wire name
406
+ ``excludeNonPopulars`` (query).
407
+
408
+ Returns:
409
+ ``Optional[models.BasicApiMetaResponse]`` — JSON response parsed into the
410
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
411
+ empty body.
412
+
413
+ Examples:
414
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
415
+ result = client.metadata.meta()
416
+ print(result)
417
+ """
418
+ url = f"/basic/meta"
419
+ params: Dict[str, Any] = {}
420
+ if blockchains is not None:
421
+ params["blockchains"] = blockchains
422
+ if blockchains_exclude is not None:
423
+ params["blockchainsExclude"] = blockchains_exclude
424
+ if swappers is not None:
425
+ params["swappers"] = swappers
426
+ if swappers_exclude is not None:
427
+ params["swappersExclude"] = swappers_exclude
428
+ if swapper_groups is not None:
429
+ params["swapperGroups"] = swapper_groups
430
+ if swappers_groups_exclude is not None:
431
+ params["swappersGroupsExclude"] = swappers_groups_exclude
432
+ if transaction_types is not None:
433
+ params["transactionTypes"] = transaction_types
434
+ if transaction_types_exclude is not None:
435
+ params["transactionTypesExclude"] = transaction_types_exclude
436
+ if exclude_non_populars is not None:
437
+ params["excludeNonPopulars"] = exclude_non_populars
438
+ req_headers: Dict[str, str] = {}
439
+ self._root._apply_security(["apiKey"], params, req_headers, None)
440
+
441
+ response = self._root._client.request(
442
+ "GET",
443
+ url,
444
+ params=params or None,
445
+ headers=req_headers or None,
446
+ )
447
+ response.raise_for_status()
448
+ if response.status_code in (204, 205) or not response.content:
449
+ return None
450
+ return models.BasicApiMetaResponse.model_validate(response.json())
451
+
452
+
453
+ class RoutingOperations:
454
+ """Operations with tag ``Routing``."""
455
+
456
+ def __init__(self, root: Client) -> None:
457
+ self._root = root
458
+
459
+ def get_connected_assets(
460
+ self, from_: str
461
+ ) -> Optional[models.ConnectedAssetsResponse]:
462
+ """
463
+ Connected Assets
464
+
465
+ Get all tokens which has route with single-step swap from intended asset. Empty
466
+ `asset` list in response indicates all assets on that chain are connected
467
+
468
+ Args:
469
+ from_ (str): The asset which is going to be swapped into other assets Wire
470
+ name ``from`` (query).
471
+
472
+ Returns:
473
+ ``Optional[models.ConnectedAssetsResponse]`` — JSON response parsed into the
474
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
475
+ empty body.
476
+
477
+ Examples:
478
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
479
+ result = client.routing.get_connected_assets(from_="ETH.USDC--0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
480
+ print(result)
481
+ """
482
+ url = f"/basic/connected-assets"
483
+ params: Dict[str, Any] = {}
484
+ params["from"] = from_
485
+ req_headers: Dict[str, str] = {}
486
+ self._root._apply_security(["apiKey"], params, req_headers, None)
487
+
488
+ response = self._root._client.request(
489
+ "GET",
490
+ url,
491
+ params=params or None,
492
+ headers=req_headers or None,
493
+ )
494
+ response.raise_for_status()
495
+ if response.status_code in (204, 205) or not response.content:
496
+ return None
497
+ return models.ConnectedAssetsResponse.model_validate(response.json())
498
+
499
+ def quote(
500
+ self,
501
+ from_: str,
502
+ to: str,
503
+ amount: int,
504
+ slippage: Optional[float] = None,
505
+ swappers: Optional[List[str]] = None,
506
+ swappers_exclude: Optional[bool] = None,
507
+ swapper_groups: Optional[List[str]] = None,
508
+ swappers_groups_exclude: Optional[bool] = None,
509
+ messaging_protocols: Optional[List[models.ParamMessagingProtocolsItem]] = None,
510
+ im_message: Optional[str] = None,
511
+ source_contract: Optional[str] = None,
512
+ destination_contract: Optional[str] = None,
513
+ contract_call: Optional[bool] = None,
514
+ referrer_code: Optional[str] = None,
515
+ referrer_fee: Optional[float] = None,
516
+ avoid_native_fee: Optional[bool] = None,
517
+ enable_centralized_swappers: Optional[bool] = None,
518
+ header_x_rango_id: Optional[str] = None,
519
+ ) -> Optional[models.BasicApiQuoteResponse]:
520
+ """
521
+ Quote (Get Best Route)
522
+
523
+ Get the best route for swapping X to Y via Rango Exchange routing protocol
524
+
525
+ Args:
526
+ from_ (str): The asset X that user likes to swap Wire name ``from`` (query).
527
+ to (str): The asset Y that user wants to swap X into that Wire name ``to``
528
+ (query).
529
+ amount (int): The machine-readable amount of asset X that is going to be
530
+ swapped Wire name ``amount`` (query).
531
+ slippage (Optional[float]): Amount of user's preferred slippage in percent.
532
+ if you don't send it, it will assume 0.5%
533
+ slippage Wire name ``slippage`` (query).
534
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
535
+ list means no filter is required Wire name
536
+ ``swappers`` (query).
537
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
538
+ include/exclude list. Default is false
539
+ (include) Wire name ``swappersExclude``
540
+ (query).
541
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
542
+ swappers based on tag, empty list
543
+ means no filter is required Wire name
544
+ ``swapperGroups`` (query).
545
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
546
+ tags as the include/exclude list.
547
+ Default is false (include) Wire
548
+ name ``swappersGroupsExclude``
549
+ (query).
550
+ messaging_protocols (Optional[List[models.ParamMessagingProtocolsItem]]): Message protocols which
551
+ will be used to call
552
+ message before or after
553
+ swap Wire name
554
+ ``messagingProtocols``
555
+ (query).
556
+ im_message (Optional[str]): Message to call after or before swap transaction
557
+ Wire name ``imMessage`` (query).
558
+ source_contract (Optional[str]): Contract address which should be called
559
+ before swap transaction Wire name
560
+ ``sourceContract`` (query).
561
+ destination_contract (Optional[str]): Contract address which should be
562
+ called after swap transaction Wire
563
+ name ``destinationContract`` (query).
564
+ contract_call (Optional[bool]): set this parameter to `true` if you wants to
565
+ send transactions through a contract Wire
566
+ name ``contractCall`` (query).
567
+ referrer_code (Optional[str]): Referrer code Wire name ``referrerCode``
568
+ (query).
569
+ referrer_fee (Optional[float]): Referrer fee in percent Wire name
570
+ ``referrerFee`` (query).
571
+ avoid_native_fee (Optional[bool]): When it is true, Swappers that have
572
+ native tokens as fee must be excluded.
573
+ example: when you call it from AA
574
+ account. Wire name ``avoidNativeFee``
575
+ (query).
576
+ enable_centralized_swappers (Optional[bool]): Specify that centralized
577
+ swappers must be included in
578
+ swappers or not. Default is
579
+ false (exclude) Wire name
580
+ ``enableCentralizedSwappers``
581
+ (query).
582
+ header_x_rango_id (Optional[str]): A unique client generated Id, better use
583
+ UUID Wire name ``X-Rango-Id`` (header).
584
+
585
+ Returns:
586
+ ``Optional[models.BasicApiQuoteResponse]`` — JSON response parsed into the
587
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
588
+ empty body.
589
+
590
+ Examples:
591
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
592
+ result = client.routing.quote(from_="BSC.BNB", to="AVAX_CCHAIN.USDT.E--0xc7198437980c041c805a1edcba50c1ce5db95118", amount=100000000000000000, slippage=8.5)
593
+ print(result)
594
+ """
595
+ url = f"/basic/quote"
596
+ params: Dict[str, Any] = {}
597
+ params["from"] = from_
598
+ params["to"] = to
599
+ params["amount"] = amount
600
+ if slippage is not None:
601
+ params["slippage"] = slippage
602
+ if swappers is not None:
603
+ params["swappers"] = swappers
604
+ if swappers_exclude is not None:
605
+ params["swappersExclude"] = swappers_exclude
606
+ if swapper_groups is not None:
607
+ params["swapperGroups"] = swapper_groups
608
+ if swappers_groups_exclude is not None:
609
+ params["swappersGroupsExclude"] = swappers_groups_exclude
610
+ if messaging_protocols is not None:
611
+ params["messagingProtocols"] = messaging_protocols
612
+ if im_message is not None:
613
+ params["imMessage"] = im_message
614
+ if source_contract is not None:
615
+ params["sourceContract"] = source_contract
616
+ if destination_contract is not None:
617
+ params["destinationContract"] = destination_contract
618
+ if contract_call is not None:
619
+ params["contractCall"] = contract_call
620
+ if referrer_code is not None:
621
+ params["referrerCode"] = referrer_code
622
+ if referrer_fee is not None:
623
+ params["referrerFee"] = referrer_fee
624
+ if avoid_native_fee is not None:
625
+ params["avoidNativeFee"] = avoid_native_fee
626
+ if enable_centralized_swappers is not None:
627
+ params["enableCentralizedSwappers"] = enable_centralized_swappers
628
+ req_headers: Dict[str, str] = {}
629
+ if header_x_rango_id is not None:
630
+ req_headers["X-Rango-Id"] = str(header_x_rango_id)
631
+ self._root._apply_security(["apiKey"], params, req_headers, None)
632
+
633
+ response = self._root._client.request(
634
+ "GET",
635
+ url,
636
+ params=params or None,
637
+ headers=req_headers or None,
638
+ )
639
+ response.raise_for_status()
640
+ if response.status_code in (204, 205) or not response.content:
641
+ return None
642
+ return models.BasicApiQuoteResponse.model_validate(response.json())
643
+
644
+
645
+ class TransactionOperations:
646
+ """Operations with tag ``Transaction``."""
647
+
648
+ def __init__(self, root: Client) -> None:
649
+ self._root = root
650
+
651
+ def is_approved(
652
+ self, request_id: str, tx_id: str
653
+ ) -> Optional[models.CheckApprovalResponse]:
654
+ """
655
+ Check Approval TX Status
656
+
657
+ When swap endpoint returns a non-null value for the approval transaction, and
658
+ user signs that tx, you should periodically call this endpoint to see if the
659
+ approval tx is completed. After a successful check, you could proceed with the
660
+ main transaction.
661
+
662
+ Args:
663
+ request_id (str): unique ID generated by quote endpoint Wire name
664
+ ``requestId`` (query).
665
+ tx_id (str): Approve transaction tx id Wire name ``txId`` (query).
666
+
667
+ Returns:
668
+ ``Optional[models.CheckApprovalResponse]`` — JSON response parsed into the
669
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
670
+ empty body.
671
+
672
+ Examples:
673
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
674
+ result = client.transaction.is_approved(request_id="b3a12c6d-86b8-4c21-97e4-809151dd4036", tx_id="0x7f17aaba51d1f24204cd8b02251001d3704add46d84840a5826b95ef49b8b74f")
675
+ print(result)
676
+ """
677
+ url = f"/basic/is-approved"
678
+ params: Dict[str, Any] = {}
679
+ params["requestId"] = request_id
680
+ params["txId"] = tx_id
681
+ req_headers: Dict[str, str] = {}
682
+ self._root._apply_security(["apiKey"], params, req_headers, None)
683
+
684
+ response = self._root._client.request(
685
+ "GET",
686
+ url,
687
+ params=params or None,
688
+ headers=req_headers or None,
689
+ )
690
+ response.raise_for_status()
691
+ if response.status_code in (204, 205) or not response.content:
692
+ return None
693
+ return models.CheckApprovalResponse.model_validate(response.json())
694
+
695
+ def report_tx(
696
+ self, body: models.BasicApiReportTransactionRequest
697
+ ) -> Optional[models.BasicApiReportTransactionResponse]:
698
+ """
699
+ Report Failed TX
700
+
701
+ Use it when the user rejects the transaction in wallet or the wallet fails to
702
+ handle the transaction. Calling this endpoint is not required, but is useful for
703
+ reporting and we recommend you to call it.Consider that transactions include
704
+ Inbound tx, cannot be reported as failed or canceled!!
705
+
706
+ Args:
707
+ body (models.BasicApiReportTransactionRequest): JSON request body.
708
+
709
+ Returns:
710
+ ``Optional[models.BasicApiReportTransactionResponse]`` — JSON response
711
+ parsed into the declared type when the body is non-empty; ``None`` for HTTP
712
+ 204/205 or an empty body.
713
+
714
+ Examples:
715
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
716
+ result = client.transaction.report_tx(body=models.BasicApiReportTransactionRequest(request_id="688b308e-a06b-4a4e-a837-220d458b8642", event_type=models.BasicApiReportTransactionRequestEventType.USER_REJECT))
717
+ print(result)
718
+ """
719
+ url = f"/basic/report-tx"
720
+ params: Dict[str, Any] = {}
721
+ req_headers: Dict[str, str] = {}
722
+ self._root._apply_security(["apiKey"], params, req_headers, None)
723
+
724
+ json_body: Any = None
725
+ if body is not None:
726
+ json_body = body.model_dump(
727
+ mode="json",
728
+ by_alias=True,
729
+ exclude_none=True,
730
+ )
731
+ response = self._root._client.request(
732
+ "POST",
733
+ url,
734
+ params=params or None,
735
+ headers=req_headers or None,
736
+ json=json_body,
737
+ )
738
+ response.raise_for_status()
739
+ if response.status_code in (204, 205) or not response.content:
740
+ return None
741
+ return models.BasicApiReportTransactionResponse.model_validate(response.json())
742
+
743
+ def status(
744
+ self, request_id: str, tx_id: str
745
+ ) -> Optional[models.BasicApiStatusResponse]:
746
+ """
747
+ Check TX Status
748
+
749
+ Check if the user swapp has succeeded or not. When a user signs the swap
750
+ transaction on his/her wallet, you should call this endpoint periodically to see
751
+ the swap status.
752
+
753
+ Args:
754
+ request_id (str): unique ID generated by quote endpoint Wire name
755
+ ``requestId`` (query).
756
+ tx_id (str): Last signed transaction's id Wire name ``txId`` (query).
757
+
758
+ Returns:
759
+ ``Optional[models.BasicApiStatusResponse]`` — JSON response parsed into the
760
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
761
+ empty body.
762
+
763
+ Examples:
764
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
765
+ result = client.transaction.status(request_id="b3a12c6d-86b8-4c21-97e4-809151dd4036", tx_id="0xfa88b705a5b4049adac7caff50c887d9600ef023ef1a937f8f8b6f44e90042b5")
766
+ print(result)
767
+ """
768
+ url = f"/basic/status"
769
+ params: Dict[str, Any] = {}
770
+ params["requestId"] = request_id
771
+ params["txId"] = tx_id
772
+ req_headers: Dict[str, str] = {}
773
+ self._root._apply_security(["apiKey"], params, req_headers, None)
774
+
775
+ response = self._root._client.request(
776
+ "GET",
777
+ url,
778
+ params=params or None,
779
+ headers=req_headers or None,
780
+ )
781
+ response.raise_for_status()
782
+ if response.status_code in (204, 205) or not response.content:
783
+ return None
784
+ return models.BasicApiStatusResponse.model_validate(response.json())
785
+
786
+ def swap(
787
+ self,
788
+ from_: str,
789
+ to: str,
790
+ amount: int,
791
+ slippage: float,
792
+ from_address: str,
793
+ to_address: str,
794
+ disable_estimate: Optional[bool] = None,
795
+ swappers: Optional[List[str]] = None,
796
+ swappers_exclude: Optional[bool] = None,
797
+ swapper_groups: Optional[List[str]] = None,
798
+ swappers_groups_exclude: Optional[bool] = None,
799
+ messaging_protocols: Optional[List[models.ParamMessagingProtocolsItem]] = None,
800
+ im_message: Optional[str] = None,
801
+ source_contract: Optional[str] = None,
802
+ destination_contract: Optional[str] = None,
803
+ infinite_approve: Optional[bool] = None,
804
+ contract_call: Optional[bool] = None,
805
+ referrer_fee: Optional[float] = None,
806
+ referrer_address: Optional[str] = None,
807
+ referrer_code: Optional[str] = None,
808
+ avoid_native_fee: Optional[bool] = None,
809
+ enable_centralized_swappers: Optional[bool] = None,
810
+ use_max_native_token_balance: Optional[bool] = None,
811
+ header_x_rango_id: Optional[str] = None,
812
+ ) -> Optional[models.BasicApiSwapResponse]:
813
+ """
814
+ Create TX (Swap)
815
+
816
+ Generating the transaction data for calling dex/bridge contract via Rango
817
+ Exchange.
818
+
819
+ Args:
820
+ from_ (str): The asset X that user likes to swap Wire name ``from`` (query).
821
+ to (str): The asset Y that user wants to swap X into that Wire name ``to``
822
+ (query).
823
+ amount (int): The machine-readable amount of asset X that is going to be
824
+ swapped Wire name ``amount`` (query).
825
+ slippage (float): Amount of user's preferred slippage in percent Wire name
826
+ ``slippage`` (query).
827
+ from_address (str): User wallet address Wire name ``fromAddress`` (query).
828
+ to_address (str): Destination wallet address Wire name ``toAddress``
829
+ (query).
830
+ disable_estimate (Optional[bool]): This field should be false when the
831
+ client wants to preview the route to the
832
+ user and true when the user accepts the
833
+ swap. If it's true, the server will be
834
+ much slower to respond but will check
835
+ some prerequisites, including the balance
836
+ of X and any required fees in the user's
837
+ wallets. Wire name ``disableEstimate``
838
+ (query).
839
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
840
+ list means no filter is required. Wire name
841
+ ``swappers`` (query).
842
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
843
+ include/exclude list. Default is false
844
+ (include) Wire name ``swappersExclude``
845
+ (query).
846
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
847
+ swappers based on tag, empty list
848
+ means no filter is required Wire name
849
+ ``swapperGroups`` (query).
850
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
851
+ tags as the include/exclude list.
852
+ Default is false (include) Wire
853
+ name ``swappersGroupsExclude``
854
+ (query).
855
+ messaging_protocols (Optional[List[models.ParamMessagingProtocolsItem]]): Message protocols which
856
+ will be used to call
857
+ message before or after
858
+ swap Wire name
859
+ ``messagingProtocols``
860
+ (query).
861
+ im_message (Optional[str]): Message to call after or before swap transaction
862
+ Wire name ``imMessage`` (query).
863
+ source_contract (Optional[str]): Contract address which should be called
864
+ before swap transaction Wire name
865
+ ``sourceContract`` (query).
866
+ destination_contract (Optional[str]): Contract address which should be
867
+ called after swap transaction Wire
868
+ name ``destinationContract`` (query).
869
+ infinite_approve (Optional[bool]): Use this parameter if you want infinite
870
+ approve from user Wire name
871
+ ``infiniteApprove`` (query).
872
+ contract_call (Optional[bool]): set this parameter to `true` if you wants to
873
+ send transactions through a contract Wire
874
+ name ``contractCall`` (query).
875
+ referrer_fee (Optional[float]): Referrer fee in percent Wire name
876
+ ``referrerFee`` (query).
877
+ referrer_address (Optional[str]): Referrer wallet address Wire name
878
+ ``referrerAddress`` (query).
879
+ referrer_code (Optional[str]): Referrer code Wire name ``referrerCode``
880
+ (query).
881
+ avoid_native_fee (Optional[bool]): When it is true, Swappers that have
882
+ native tokens as fee must be excluded.
883
+ example: when you call it from AA
884
+ account. Wire name ``avoidNativeFee``
885
+ (query).
886
+ enable_centralized_swappers (Optional[bool]): Specify that centralized
887
+ swappers must be included in
888
+ swappers or not. Default is
889
+ false (exclude) Wire name
890
+ ``enableCentralizedSwappers``
891
+ (query).
892
+ use_max_native_token_balance (Optional[bool]): Forces transaction creation
893
+ by subtracting fees from
894
+ input if balance is
895
+ insufficient. Wire name
896
+ ``useMaxNativeTokenBalance``
897
+ (query).
898
+ header_x_rango_id (Optional[str]): A unique client generated Id, better use
899
+ UUID Wire name ``X-Rango-Id`` (header).
900
+
901
+ Returns:
902
+ ``Optional[models.BasicApiSwapResponse]`` — JSON response parsed into the
903
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
904
+ empty body.
905
+
906
+ Examples:
907
+ with Client(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
908
+ result = client.transaction.swap(from_="BSC.BNB", to="AVAX_CCHAIN.USDT.E--0xc7198437980c041c805a1edcba50c1ce5db95118", amount=100000000000000000, slippage=8.5, from_address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88", to_address="0x6f33bb1763eebead07cf8815a62fcd7b30311fa3", disable_estimate=False, infinite_approve=False, referrer_fee=0.3, referrer_address="0x6f33bb1763eebead07cf8815a62fcd7b30311fa3")
909
+ print(result)
910
+ """
911
+ url = f"/basic/swap"
912
+ params: Dict[str, Any] = {}
913
+ params["from"] = from_
914
+ params["to"] = to
915
+ params["amount"] = amount
916
+ params["slippage"] = slippage
917
+ params["fromAddress"] = from_address
918
+ params["toAddress"] = to_address
919
+ if disable_estimate is not None:
920
+ params["disableEstimate"] = disable_estimate
921
+ if swappers is not None:
922
+ params["swappers"] = swappers
923
+ if swappers_exclude is not None:
924
+ params["swappersExclude"] = swappers_exclude
925
+ if swapper_groups is not None:
926
+ params["swapperGroups"] = swapper_groups
927
+ if swappers_groups_exclude is not None:
928
+ params["swappersGroupsExclude"] = swappers_groups_exclude
929
+ if messaging_protocols is not None:
930
+ params["messagingProtocols"] = messaging_protocols
931
+ if im_message is not None:
932
+ params["imMessage"] = im_message
933
+ if source_contract is not None:
934
+ params["sourceContract"] = source_contract
935
+ if destination_contract is not None:
936
+ params["destinationContract"] = destination_contract
937
+ if infinite_approve is not None:
938
+ params["infiniteApprove"] = infinite_approve
939
+ if contract_call is not None:
940
+ params["contractCall"] = contract_call
941
+ if referrer_fee is not None:
942
+ params["referrerFee"] = referrer_fee
943
+ if referrer_address is not None:
944
+ params["referrerAddress"] = referrer_address
945
+ if referrer_code is not None:
946
+ params["referrerCode"] = referrer_code
947
+ if avoid_native_fee is not None:
948
+ params["avoidNativeFee"] = avoid_native_fee
949
+ if enable_centralized_swappers is not None:
950
+ params["enableCentralizedSwappers"] = enable_centralized_swappers
951
+ if use_max_native_token_balance is not None:
952
+ params["useMaxNativeTokenBalance"] = use_max_native_token_balance
953
+ req_headers: Dict[str, str] = {}
954
+ if header_x_rango_id is not None:
955
+ req_headers["X-Rango-Id"] = str(header_x_rango_id)
956
+ self._root._apply_security(["apiKey"], params, req_headers, None)
957
+
958
+ response = self._root._client.request(
959
+ "GET",
960
+ url,
961
+ params=params or None,
962
+ headers=req_headers or None,
963
+ )
964
+ response.raise_for_status()
965
+ if response.status_code in (204, 205) or not response.content:
966
+ return None
967
+ return models.BasicApiSwapResponse.model_validate(response.json())
968
+
969
+
970
+ class Client:
971
+ """
972
+ Simple and Easy to use APIs for Rango Aggregation protocols for dApps and Wallets
973
+ for single step cross-chain and on-chain swaps using the best route and all the
974
+ available on-chain liquidity across all blockchain networks.
975
+
976
+ Pass ``log_http_debug=True`` and configure logging for this module (e.g.
977
+ ``logging.getLogger(__name__).setLevel(logging.DEBUG)`` on ``…client``) to emit each
978
+ HTTP request and response at DEBUG, including headers and bodies. This may log
979
+ credentials—use only in trusted environments.
980
+
981
+ Optional ``proxy`` is forwarded to the underlying ``httpx`` client (a proxy URL
982
+ string or ``httpx.URL``).
983
+
984
+ Security credentials may be passed as constructor keyword arguments or read from
985
+ environment variables (see the README); constructor values take precedence when both
986
+ are set.
987
+ """
988
+
989
+ def __init__(
990
+ self,
991
+ base_url: Optional[str] = None,
992
+ *,
993
+ api_key: Optional[str] = None,
994
+ headers: Optional[Dict[str, str]] = None,
995
+ timeout: float = 30.0,
996
+ proxy: Optional[Union[str, httpx.URL]] = None,
997
+ log_http_debug: bool = False,
998
+ ) -> None:
999
+ _resolved = base_url if base_url is not None else DEFAULT_SERVER_URL
1000
+ if not _resolved:
1001
+ raise ValueError(
1002
+ "No base URL: pass base_url=… or define servers in the OpenAPI document.",
1003
+ )
1004
+ self._base_url = _resolved.rstrip("/")
1005
+ self._headers = dict(headers or {})
1006
+ self._proxy = proxy
1007
+ self._sec_apiKey = _security_value_from_kw_or_env(
1008
+ api_key,
1009
+ "RANGO_BASIC_API_KEY",
1010
+ )
1011
+ if not self._sec_apiKey:
1012
+ raise ValueError(
1013
+ "OpenAPI security scheme "
1014
+ + "apiKey"
1015
+ + ": pass keyword argument "
1016
+ + "api_key"
1017
+ + ", or set environment variable "
1018
+ + "RANGO_BASIC_API_KEY"
1019
+ + "."
1020
+ )
1021
+
1022
+ _hooks: Optional[Dict[str, List[Any]]] = (
1023
+ _sync_http_debug_event_hooks() if log_http_debug else None
1024
+ )
1025
+ self._client = httpx.Client(
1026
+ base_url=self._base_url,
1027
+ headers=self._headers,
1028
+ timeout=timeout,
1029
+ proxy=self._proxy,
1030
+ event_hooks=_hooks,
1031
+ )
1032
+ self.balance = BalanceOperations(self)
1033
+ self.metadata = MetadataOperations(self)
1034
+ self.routing = RoutingOperations(self)
1035
+ self.transaction = TransactionOperations(self)
1036
+
1037
+ def _apply_security(
1038
+ self,
1039
+ operation_scheme_keys: List[str],
1040
+ params: Dict[str, Any],
1041
+ headers: Dict[str, str],
1042
+ cookies: Optional[Dict[str, str]],
1043
+ ) -> None:
1044
+ if "apiKey" in operation_scheme_keys and self._sec_apiKey is not None:
1045
+ params["apiKey"] = self._sec_apiKey
1046
+
1047
+ def close(self) -> None:
1048
+ self._client.close()
1049
+
1050
+ def __enter__(self) -> "Client":
1051
+ return self
1052
+
1053
+ def __exit__(self, *args: object) -> None:
1054
+ self.close()
1055
+
1056
+
1057
+ class AsyncBalanceOperations:
1058
+ """Operations with tag ``Balance``."""
1059
+
1060
+ def __init__(self, root: AsyncClient) -> None:
1061
+ self._root = root
1062
+
1063
+ async def balance(
1064
+ self, blockchain: models.Blockchain, address: str
1065
+ ) -> Optional[models.WalletDetailsResponse]:
1066
+ """
1067
+ Balance
1068
+
1069
+ Get all tokens' balances for the given wallet address.
1070
+
1071
+ Args:
1072
+ blockchain (models.Blockchain): Blockchain Wire name ``blockchain`` (query).
1073
+ address (str): User's wallet address Wire name ``address`` (query).
1074
+
1075
+ Returns:
1076
+ ``Optional[models.WalletDetailsResponse]`` — JSON response parsed into the
1077
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1078
+ empty body.
1079
+
1080
+ Examples:
1081
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1082
+ result = await client.balance.balance(blockchain=models.Blockchain.BSC, address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88")
1083
+ print(result)
1084
+ """
1085
+ url = f"/basic/balance"
1086
+ params: Dict[str, Any] = {}
1087
+ params["blockchain"] = blockchain
1088
+ params["address"] = address
1089
+ req_headers: Dict[str, str] = {}
1090
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1091
+
1092
+ response = await self._root._client.request(
1093
+ "GET",
1094
+ url,
1095
+ params=params or None,
1096
+ headers=req_headers or None,
1097
+ )
1098
+ response.raise_for_status()
1099
+ if response.status_code in (204, 205) or not response.content:
1100
+ return None
1101
+ return models.WalletDetailsResponse.model_validate(response.json())
1102
+
1103
+ async def get_token_balance(
1104
+ self,
1105
+ wallet_address: str,
1106
+ blockchain: models.Blockchain,
1107
+ symbol: str,
1108
+ address: Optional[str] = None,
1109
+ ) -> Optional[models.TokenBalanceResponse]:
1110
+ """
1111
+ Token Balance
1112
+
1113
+ Get balance of the given wallet address for a specific token.
1114
+
1115
+ Args:
1116
+ wallet_address (str): User's wallet address Wire name ``walletAddress``
1117
+ (query).
1118
+ blockchain (models.Blockchain): Blockchain Wire name ``blockchain`` (query).
1119
+ symbol (str): Token Symbol Wire name ``symbol`` (query).
1120
+ address (Optional[str]): Token Address, This is ignored or null for native
1121
+ tokens which have no address Wire name ``address``
1122
+ (query).
1123
+
1124
+ Returns:
1125
+ ``Optional[models.TokenBalanceResponse]`` — JSON response parsed into the
1126
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1127
+ empty body.
1128
+
1129
+ Examples:
1130
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1131
+ result = await client.balance.get_token_balance(wallet_address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88", blockchain=models.Blockchain.BSC, symbol="USDT", address="0x55d398326f99059ff775485246999027b3197955")
1132
+ print(result)
1133
+ """
1134
+ url = f"/basic/token-balance"
1135
+ params: Dict[str, Any] = {}
1136
+ params["walletAddress"] = wallet_address
1137
+ params["blockchain"] = blockchain
1138
+ params["symbol"] = symbol
1139
+ if address is not None:
1140
+ params["address"] = address
1141
+ req_headers: Dict[str, str] = {}
1142
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1143
+
1144
+ response = await self._root._client.request(
1145
+ "GET",
1146
+ url,
1147
+ params=params or None,
1148
+ headers=req_headers or None,
1149
+ )
1150
+ response.raise_for_status()
1151
+ if response.status_code in (204, 205) or not response.content:
1152
+ return None
1153
+ return models.TokenBalanceResponse.model_validate(response.json())
1154
+
1155
+
1156
+ class AsyncMetadataOperations:
1157
+ """Operations with tag ``Metadata``."""
1158
+
1159
+ def __init__(self, root: AsyncClient) -> None:
1160
+ self._root = root
1161
+
1162
+ async def get_blockchains(self) -> Optional[List[models.BasicApiBlockchainMeta]]:
1163
+ """
1164
+ Blockchains Metadata
1165
+
1166
+ Metadata of all blockchains
1167
+
1168
+ Returns:
1169
+ ``Optional[List[models.BasicApiBlockchainMeta]]`` — JSON response parsed
1170
+ into the declared type when the body is non-empty; ``None`` for HTTP 204/205
1171
+ or an empty body.
1172
+
1173
+ Examples:
1174
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1175
+ result = await client.metadata.get_blockchains()
1176
+ print(result)
1177
+ """
1178
+ url = f"/basic/meta/blockchains"
1179
+ params: Dict[str, Any] = {}
1180
+ req_headers: Dict[str, str] = {}
1181
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1182
+
1183
+ response = await self._root._client.request(
1184
+ "GET",
1185
+ url,
1186
+ params=params or None,
1187
+ headers=req_headers or None,
1188
+ )
1189
+ response.raise_for_status()
1190
+ if response.status_code in (204, 205) or not response.content:
1191
+ return None
1192
+ return [
1193
+ models.BasicApiBlockchainMeta.model_validate(x) for x in response.json()
1194
+ ]
1195
+
1196
+ async def get_custom_token_data(
1197
+ self, blockchain: models.Blockchain, address: str
1198
+ ) -> Optional[models.BasicCustomTokenResponse]:
1199
+ """
1200
+ Custom token
1201
+
1202
+ Returns the token details for user desired token that is not available on Rango
1203
+ official list. currently supports Solana and EVM based blockchains
1204
+
1205
+ Args:
1206
+ blockchain (models.Blockchain): The blockchain of the custom token Wire name
1207
+ ``blockchain`` (query).
1208
+ address (str): The address of the custom token Wire name ``address``
1209
+ (query).
1210
+
1211
+ Returns:
1212
+ ``Optional[models.BasicCustomTokenResponse]`` — JSON response parsed into
1213
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
1214
+ an empty body.
1215
+
1216
+ Examples:
1217
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1218
+ result = await client.metadata.get_custom_token_data(blockchain=models.Blockchain.BSC, address="0x5ac5e6Af46Ef285B3536833E65D245c49b608d9b")
1219
+ print(result)
1220
+ """
1221
+ url = f"/basic/meta/custom-token"
1222
+ params: Dict[str, Any] = {}
1223
+ params["blockchain"] = blockchain
1224
+ params["address"] = address
1225
+ req_headers: Dict[str, str] = {}
1226
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1227
+
1228
+ response = await self._root._client.request(
1229
+ "GET",
1230
+ url,
1231
+ params=params or None,
1232
+ headers=req_headers or None,
1233
+ )
1234
+ response.raise_for_status()
1235
+ if response.status_code in (204, 205) or not response.content:
1236
+ return None
1237
+ return models.BasicCustomTokenResponse.model_validate(response.json())
1238
+
1239
+ async def get_messaging_protocols(
1240
+ self,
1241
+ ) -> Optional[models.MessagingProtocolsResponse]:
1242
+ """
1243
+ Messaging Protocols Metadata
1244
+
1245
+ Metadata of all messaging protocols
1246
+
1247
+ Returns:
1248
+ ``Optional[models.MessagingProtocolsResponse]`` — JSON response parsed into
1249
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
1250
+ an empty body.
1251
+
1252
+ Examples:
1253
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1254
+ result = await client.metadata.get_messaging_protocols()
1255
+ print(result)
1256
+ """
1257
+ url = f"/basic/meta/messaging-protocols"
1258
+ params: Dict[str, Any] = {}
1259
+ req_headers: Dict[str, str] = {}
1260
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1261
+
1262
+ response = await self._root._client.request(
1263
+ "GET",
1264
+ url,
1265
+ params=params or None,
1266
+ headers=req_headers or None,
1267
+ )
1268
+ response.raise_for_status()
1269
+ if response.status_code in (204, 205) or not response.content:
1270
+ return None
1271
+ return models.MessagingProtocolsResponse.model_validate(response.json())
1272
+
1273
+ async def get_swappers(self) -> Optional[List[models.SwapperMetaFullDto]]:
1274
+ """
1275
+ Swappers Metadata
1276
+
1277
+ Metadata of all swappers
1278
+
1279
+ Returns:
1280
+ ``Optional[List[models.SwapperMetaFullDto]]`` — JSON response parsed into
1281
+ the declared type when the body is non-empty; ``None`` for HTTP 204/205 or
1282
+ an empty body.
1283
+
1284
+ Examples:
1285
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1286
+ result = await client.metadata.get_swappers()
1287
+ print(result)
1288
+ """
1289
+ url = f"/basic/meta/swappers"
1290
+ params: Dict[str, Any] = {}
1291
+ req_headers: Dict[str, str] = {}
1292
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1293
+
1294
+ response = await self._root._client.request(
1295
+ "GET",
1296
+ url,
1297
+ params=params or None,
1298
+ headers=req_headers or None,
1299
+ )
1300
+ response.raise_for_status()
1301
+ if response.status_code in (204, 205) or not response.content:
1302
+ return None
1303
+ return [models.SwapperMetaFullDto.model_validate(x) for x in response.json()]
1304
+
1305
+ async def meta(
1306
+ self,
1307
+ blockchains: Optional[List[models.Blockchain]] = None,
1308
+ blockchains_exclude: Optional[bool] = None,
1309
+ swappers: Optional[List[str]] = None,
1310
+ swappers_exclude: Optional[bool] = None,
1311
+ swapper_groups: Optional[List[str]] = None,
1312
+ swappers_groups_exclude: Optional[bool] = None,
1313
+ transaction_types: Optional[List[models.GenericTransactionType]] = None,
1314
+ transaction_types_exclude: Optional[bool] = None,
1315
+ exclude_non_populars: Optional[bool] = None,
1316
+ ) -> Optional[models.BasicApiMetaResponse]:
1317
+ """
1318
+ Metadata (tokens, swappers, blockchains)
1319
+
1320
+ Get all tokens, DEX, and bridges metadata.
1321
+
1322
+ Args:
1323
+ blockchains (Optional[List[models.Blockchain]]): The list of all accepted
1324
+ blockchains. An empty list
1325
+ means no filter is required
1326
+ Wire name ``blockchains``
1327
+ (query).
1328
+ blockchains_exclude (Optional[bool]): Defines the provided blockchains as
1329
+ the include/exclude list. Default is
1330
+ false (include) Wire name
1331
+ ``blockchainsExclude`` (query).
1332
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
1333
+ list means no filter is required Wire name
1334
+ ``swappers`` (query).
1335
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
1336
+ include/exclude list. Default is false
1337
+ (include) Wire name ``swappersExclude``
1338
+ (query).
1339
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
1340
+ swappers based on tag, empty list
1341
+ means no filter is required Wire name
1342
+ ``swapperGroups`` (query).
1343
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
1344
+ tags as the include/exclude list.
1345
+ Default is false (include) Wire
1346
+ name ``swappersGroupsExclude``
1347
+ (query).
1348
+ transaction_types (Optional[List[models.GenericTransactionType]]): Blockchain Type Wire
1349
+ name
1350
+ ``transactionTypes``
1351
+ (query).
1352
+ transaction_types_exclude (Optional[bool]): Defines the provided swappers'
1353
+ tags as the include/exclude
1354
+ list. Default is false (include)
1355
+ Wire name
1356
+ ``transactionTypesExclude``
1357
+ (query).
1358
+ exclude_non_populars (Optional[bool]): Exclude non popular tokens. Default
1359
+ is false (include) Wire name
1360
+ ``excludeNonPopulars`` (query).
1361
+
1362
+ Returns:
1363
+ ``Optional[models.BasicApiMetaResponse]`` — JSON response parsed into the
1364
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1365
+ empty body.
1366
+
1367
+ Examples:
1368
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1369
+ result = await client.metadata.meta()
1370
+ print(result)
1371
+ """
1372
+ url = f"/basic/meta"
1373
+ params: Dict[str, Any] = {}
1374
+ if blockchains is not None:
1375
+ params["blockchains"] = blockchains
1376
+ if blockchains_exclude is not None:
1377
+ params["blockchainsExclude"] = blockchains_exclude
1378
+ if swappers is not None:
1379
+ params["swappers"] = swappers
1380
+ if swappers_exclude is not None:
1381
+ params["swappersExclude"] = swappers_exclude
1382
+ if swapper_groups is not None:
1383
+ params["swapperGroups"] = swapper_groups
1384
+ if swappers_groups_exclude is not None:
1385
+ params["swappersGroupsExclude"] = swappers_groups_exclude
1386
+ if transaction_types is not None:
1387
+ params["transactionTypes"] = transaction_types
1388
+ if transaction_types_exclude is not None:
1389
+ params["transactionTypesExclude"] = transaction_types_exclude
1390
+ if exclude_non_populars is not None:
1391
+ params["excludeNonPopulars"] = exclude_non_populars
1392
+ req_headers: Dict[str, str] = {}
1393
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1394
+
1395
+ response = await self._root._client.request(
1396
+ "GET",
1397
+ url,
1398
+ params=params or None,
1399
+ headers=req_headers or None,
1400
+ )
1401
+ response.raise_for_status()
1402
+ if response.status_code in (204, 205) or not response.content:
1403
+ return None
1404
+ return models.BasicApiMetaResponse.model_validate(response.json())
1405
+
1406
+
1407
+ class AsyncRoutingOperations:
1408
+ """Operations with tag ``Routing``."""
1409
+
1410
+ def __init__(self, root: AsyncClient) -> None:
1411
+ self._root = root
1412
+
1413
+ async def get_connected_assets(
1414
+ self, from_: str
1415
+ ) -> Optional[models.ConnectedAssetsResponse]:
1416
+ """
1417
+ Connected Assets
1418
+
1419
+ Get all tokens which has route with single-step swap from intended asset. Empty
1420
+ `asset` list in response indicates all assets on that chain are connected
1421
+
1422
+ Args:
1423
+ from_ (str): The asset which is going to be swapped into other assets Wire
1424
+ name ``from`` (query).
1425
+
1426
+ Returns:
1427
+ ``Optional[models.ConnectedAssetsResponse]`` — JSON response parsed into the
1428
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1429
+ empty body.
1430
+
1431
+ Examples:
1432
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1433
+ result = await client.routing.get_connected_assets(from_="ETH.USDC--0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
1434
+ print(result)
1435
+ """
1436
+ url = f"/basic/connected-assets"
1437
+ params: Dict[str, Any] = {}
1438
+ params["from"] = from_
1439
+ req_headers: Dict[str, str] = {}
1440
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1441
+
1442
+ response = await self._root._client.request(
1443
+ "GET",
1444
+ url,
1445
+ params=params or None,
1446
+ headers=req_headers or None,
1447
+ )
1448
+ response.raise_for_status()
1449
+ if response.status_code in (204, 205) or not response.content:
1450
+ return None
1451
+ return models.ConnectedAssetsResponse.model_validate(response.json())
1452
+
1453
+ async def quote(
1454
+ self,
1455
+ from_: str,
1456
+ to: str,
1457
+ amount: int,
1458
+ slippage: Optional[float] = None,
1459
+ swappers: Optional[List[str]] = None,
1460
+ swappers_exclude: Optional[bool] = None,
1461
+ swapper_groups: Optional[List[str]] = None,
1462
+ swappers_groups_exclude: Optional[bool] = None,
1463
+ messaging_protocols: Optional[List[models.ParamMessagingProtocolsItem]] = None,
1464
+ im_message: Optional[str] = None,
1465
+ source_contract: Optional[str] = None,
1466
+ destination_contract: Optional[str] = None,
1467
+ contract_call: Optional[bool] = None,
1468
+ referrer_code: Optional[str] = None,
1469
+ referrer_fee: Optional[float] = None,
1470
+ avoid_native_fee: Optional[bool] = None,
1471
+ enable_centralized_swappers: Optional[bool] = None,
1472
+ header_x_rango_id: Optional[str] = None,
1473
+ ) -> Optional[models.BasicApiQuoteResponse]:
1474
+ """
1475
+ Quote (Get Best Route)
1476
+
1477
+ Get the best route for swapping X to Y via Rango Exchange routing protocol
1478
+
1479
+ Args:
1480
+ from_ (str): The asset X that user likes to swap Wire name ``from`` (query).
1481
+ to (str): The asset Y that user wants to swap X into that Wire name ``to``
1482
+ (query).
1483
+ amount (int): The machine-readable amount of asset X that is going to be
1484
+ swapped Wire name ``amount`` (query).
1485
+ slippage (Optional[float]): Amount of user's preferred slippage in percent.
1486
+ if you don't send it, it will assume 0.5%
1487
+ slippage Wire name ``slippage`` (query).
1488
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
1489
+ list means no filter is required Wire name
1490
+ ``swappers`` (query).
1491
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
1492
+ include/exclude list. Default is false
1493
+ (include) Wire name ``swappersExclude``
1494
+ (query).
1495
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
1496
+ swappers based on tag, empty list
1497
+ means no filter is required Wire name
1498
+ ``swapperGroups`` (query).
1499
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
1500
+ tags as the include/exclude list.
1501
+ Default is false (include) Wire
1502
+ name ``swappersGroupsExclude``
1503
+ (query).
1504
+ messaging_protocols (Optional[List[models.ParamMessagingProtocolsItem]]): Message protocols which
1505
+ will be used to call
1506
+ message before or after
1507
+ swap Wire name
1508
+ ``messagingProtocols``
1509
+ (query).
1510
+ im_message (Optional[str]): Message to call after or before swap transaction
1511
+ Wire name ``imMessage`` (query).
1512
+ source_contract (Optional[str]): Contract address which should be called
1513
+ before swap transaction Wire name
1514
+ ``sourceContract`` (query).
1515
+ destination_contract (Optional[str]): Contract address which should be
1516
+ called after swap transaction Wire
1517
+ name ``destinationContract`` (query).
1518
+ contract_call (Optional[bool]): set this parameter to `true` if you wants to
1519
+ send transactions through a contract Wire
1520
+ name ``contractCall`` (query).
1521
+ referrer_code (Optional[str]): Referrer code Wire name ``referrerCode``
1522
+ (query).
1523
+ referrer_fee (Optional[float]): Referrer fee in percent Wire name
1524
+ ``referrerFee`` (query).
1525
+ avoid_native_fee (Optional[bool]): When it is true, Swappers that have
1526
+ native tokens as fee must be excluded.
1527
+ example: when you call it from AA
1528
+ account. Wire name ``avoidNativeFee``
1529
+ (query).
1530
+ enable_centralized_swappers (Optional[bool]): Specify that centralized
1531
+ swappers must be included in
1532
+ swappers or not. Default is
1533
+ false (exclude) Wire name
1534
+ ``enableCentralizedSwappers``
1535
+ (query).
1536
+ header_x_rango_id (Optional[str]): A unique client generated Id, better use
1537
+ UUID Wire name ``X-Rango-Id`` (header).
1538
+
1539
+ Returns:
1540
+ ``Optional[models.BasicApiQuoteResponse]`` — JSON response parsed into the
1541
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1542
+ empty body.
1543
+
1544
+ Examples:
1545
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1546
+ result = await client.routing.quote(from_="BSC.BNB", to="AVAX_CCHAIN.USDT.E--0xc7198437980c041c805a1edcba50c1ce5db95118", amount=100000000000000000, slippage=8.5)
1547
+ print(result)
1548
+ """
1549
+ url = f"/basic/quote"
1550
+ params: Dict[str, Any] = {}
1551
+ params["from"] = from_
1552
+ params["to"] = to
1553
+ params["amount"] = amount
1554
+ if slippage is not None:
1555
+ params["slippage"] = slippage
1556
+ if swappers is not None:
1557
+ params["swappers"] = swappers
1558
+ if swappers_exclude is not None:
1559
+ params["swappersExclude"] = swappers_exclude
1560
+ if swapper_groups is not None:
1561
+ params["swapperGroups"] = swapper_groups
1562
+ if swappers_groups_exclude is not None:
1563
+ params["swappersGroupsExclude"] = swappers_groups_exclude
1564
+ if messaging_protocols is not None:
1565
+ params["messagingProtocols"] = messaging_protocols
1566
+ if im_message is not None:
1567
+ params["imMessage"] = im_message
1568
+ if source_contract is not None:
1569
+ params["sourceContract"] = source_contract
1570
+ if destination_contract is not None:
1571
+ params["destinationContract"] = destination_contract
1572
+ if contract_call is not None:
1573
+ params["contractCall"] = contract_call
1574
+ if referrer_code is not None:
1575
+ params["referrerCode"] = referrer_code
1576
+ if referrer_fee is not None:
1577
+ params["referrerFee"] = referrer_fee
1578
+ if avoid_native_fee is not None:
1579
+ params["avoidNativeFee"] = avoid_native_fee
1580
+ if enable_centralized_swappers is not None:
1581
+ params["enableCentralizedSwappers"] = enable_centralized_swappers
1582
+ req_headers: Dict[str, str] = {}
1583
+ if header_x_rango_id is not None:
1584
+ req_headers["X-Rango-Id"] = str(header_x_rango_id)
1585
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1586
+
1587
+ response = await self._root._client.request(
1588
+ "GET",
1589
+ url,
1590
+ params=params or None,
1591
+ headers=req_headers or None,
1592
+ )
1593
+ response.raise_for_status()
1594
+ if response.status_code in (204, 205) or not response.content:
1595
+ return None
1596
+ return models.BasicApiQuoteResponse.model_validate(response.json())
1597
+
1598
+
1599
+ class AsyncTransactionOperations:
1600
+ """Operations with tag ``Transaction``."""
1601
+
1602
+ def __init__(self, root: AsyncClient) -> None:
1603
+ self._root = root
1604
+
1605
+ async def is_approved(
1606
+ self, request_id: str, tx_id: str
1607
+ ) -> Optional[models.CheckApprovalResponse]:
1608
+ """
1609
+ Check Approval TX Status
1610
+
1611
+ When swap endpoint returns a non-null value for the approval transaction, and
1612
+ user signs that tx, you should periodically call this endpoint to see if the
1613
+ approval tx is completed. After a successful check, you could proceed with the
1614
+ main transaction.
1615
+
1616
+ Args:
1617
+ request_id (str): unique ID generated by quote endpoint Wire name
1618
+ ``requestId`` (query).
1619
+ tx_id (str): Approve transaction tx id Wire name ``txId`` (query).
1620
+
1621
+ Returns:
1622
+ ``Optional[models.CheckApprovalResponse]`` — JSON response parsed into the
1623
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1624
+ empty body.
1625
+
1626
+ Examples:
1627
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1628
+ result = await client.transaction.is_approved(request_id="b3a12c6d-86b8-4c21-97e4-809151dd4036", tx_id="0x7f17aaba51d1f24204cd8b02251001d3704add46d84840a5826b95ef49b8b74f")
1629
+ print(result)
1630
+ """
1631
+ url = f"/basic/is-approved"
1632
+ params: Dict[str, Any] = {}
1633
+ params["requestId"] = request_id
1634
+ params["txId"] = tx_id
1635
+ req_headers: Dict[str, str] = {}
1636
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1637
+
1638
+ response = await self._root._client.request(
1639
+ "GET",
1640
+ url,
1641
+ params=params or None,
1642
+ headers=req_headers or None,
1643
+ )
1644
+ response.raise_for_status()
1645
+ if response.status_code in (204, 205) or not response.content:
1646
+ return None
1647
+ return models.CheckApprovalResponse.model_validate(response.json())
1648
+
1649
+ async def report_tx(
1650
+ self, body: models.BasicApiReportTransactionRequest
1651
+ ) -> Optional[models.BasicApiReportTransactionResponse]:
1652
+ """
1653
+ Report Failed TX
1654
+
1655
+ Use it when the user rejects the transaction in wallet or the wallet fails to
1656
+ handle the transaction. Calling this endpoint is not required, but is useful for
1657
+ reporting and we recommend you to call it.Consider that transactions include
1658
+ Inbound tx, cannot be reported as failed or canceled!!
1659
+
1660
+ Args:
1661
+ body (models.BasicApiReportTransactionRequest): JSON request body.
1662
+
1663
+ Returns:
1664
+ ``Optional[models.BasicApiReportTransactionResponse]`` — JSON response
1665
+ parsed into the declared type when the body is non-empty; ``None`` for HTTP
1666
+ 204/205 or an empty body.
1667
+
1668
+ Examples:
1669
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1670
+ result = await client.transaction.report_tx(body=models.BasicApiReportTransactionRequest(request_id="688b308e-a06b-4a4e-a837-220d458b8642", event_type=models.BasicApiReportTransactionRequestEventType.USER_REJECT))
1671
+ print(result)
1672
+ """
1673
+ url = f"/basic/report-tx"
1674
+ params: Dict[str, Any] = {}
1675
+ req_headers: Dict[str, str] = {}
1676
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1677
+
1678
+ json_body: Any = None
1679
+ if body is not None:
1680
+ json_body = body.model_dump(
1681
+ mode="json",
1682
+ by_alias=True,
1683
+ exclude_none=True,
1684
+ )
1685
+ response = await self._root._client.request(
1686
+ "POST",
1687
+ url,
1688
+ params=params or None,
1689
+ headers=req_headers or None,
1690
+ json=json_body,
1691
+ )
1692
+ response.raise_for_status()
1693
+ if response.status_code in (204, 205) or not response.content:
1694
+ return None
1695
+ return models.BasicApiReportTransactionResponse.model_validate(response.json())
1696
+
1697
+ async def status(
1698
+ self, request_id: str, tx_id: str
1699
+ ) -> Optional[models.BasicApiStatusResponse]:
1700
+ """
1701
+ Check TX Status
1702
+
1703
+ Check if the user swapp has succeeded or not. When a user signs the swap
1704
+ transaction on his/her wallet, you should call this endpoint periodically to see
1705
+ the swap status.
1706
+
1707
+ Args:
1708
+ request_id (str): unique ID generated by quote endpoint Wire name
1709
+ ``requestId`` (query).
1710
+ tx_id (str): Last signed transaction's id Wire name ``txId`` (query).
1711
+
1712
+ Returns:
1713
+ ``Optional[models.BasicApiStatusResponse]`` — JSON response parsed into the
1714
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1715
+ empty body.
1716
+
1717
+ Examples:
1718
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1719
+ result = await client.transaction.status(request_id="b3a12c6d-86b8-4c21-97e4-809151dd4036", tx_id="0xfa88b705a5b4049adac7caff50c887d9600ef023ef1a937f8f8b6f44e90042b5")
1720
+ print(result)
1721
+ """
1722
+ url = f"/basic/status"
1723
+ params: Dict[str, Any] = {}
1724
+ params["requestId"] = request_id
1725
+ params["txId"] = tx_id
1726
+ req_headers: Dict[str, str] = {}
1727
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1728
+
1729
+ response = await self._root._client.request(
1730
+ "GET",
1731
+ url,
1732
+ params=params or None,
1733
+ headers=req_headers or None,
1734
+ )
1735
+ response.raise_for_status()
1736
+ if response.status_code in (204, 205) or not response.content:
1737
+ return None
1738
+ return models.BasicApiStatusResponse.model_validate(response.json())
1739
+
1740
+ async def swap(
1741
+ self,
1742
+ from_: str,
1743
+ to: str,
1744
+ amount: int,
1745
+ slippage: float,
1746
+ from_address: str,
1747
+ to_address: str,
1748
+ disable_estimate: Optional[bool] = None,
1749
+ swappers: Optional[List[str]] = None,
1750
+ swappers_exclude: Optional[bool] = None,
1751
+ swapper_groups: Optional[List[str]] = None,
1752
+ swappers_groups_exclude: Optional[bool] = None,
1753
+ messaging_protocols: Optional[List[models.ParamMessagingProtocolsItem]] = None,
1754
+ im_message: Optional[str] = None,
1755
+ source_contract: Optional[str] = None,
1756
+ destination_contract: Optional[str] = None,
1757
+ infinite_approve: Optional[bool] = None,
1758
+ contract_call: Optional[bool] = None,
1759
+ referrer_fee: Optional[float] = None,
1760
+ referrer_address: Optional[str] = None,
1761
+ referrer_code: Optional[str] = None,
1762
+ avoid_native_fee: Optional[bool] = None,
1763
+ enable_centralized_swappers: Optional[bool] = None,
1764
+ use_max_native_token_balance: Optional[bool] = None,
1765
+ header_x_rango_id: Optional[str] = None,
1766
+ ) -> Optional[models.BasicApiSwapResponse]:
1767
+ """
1768
+ Create TX (Swap)
1769
+
1770
+ Generating the transaction data for calling dex/bridge contract via Rango
1771
+ Exchange.
1772
+
1773
+ Args:
1774
+ from_ (str): The asset X that user likes to swap Wire name ``from`` (query).
1775
+ to (str): The asset Y that user wants to swap X into that Wire name ``to``
1776
+ (query).
1777
+ amount (int): The machine-readable amount of asset X that is going to be
1778
+ swapped Wire name ``amount`` (query).
1779
+ slippage (float): Amount of user's preferred slippage in percent Wire name
1780
+ ``slippage`` (query).
1781
+ from_address (str): User wallet address Wire name ``fromAddress`` (query).
1782
+ to_address (str): Destination wallet address Wire name ``toAddress``
1783
+ (query).
1784
+ disable_estimate (Optional[bool]): This field should be false when the
1785
+ client wants to preview the route to the
1786
+ user and true when the user accepts the
1787
+ swap. If it's true, the server will be
1788
+ much slower to respond but will check
1789
+ some prerequisites, including the balance
1790
+ of X and any required fees in the user's
1791
+ wallets. Wire name ``disableEstimate``
1792
+ (query).
1793
+ swappers (Optional[List[str]]): The list of all accepted swappers. An empty
1794
+ list means no filter is required. Wire name
1795
+ ``swappers`` (query).
1796
+ swappers_exclude (Optional[bool]): Defines the provided swappers as the
1797
+ include/exclude list. Default is false
1798
+ (include) Wire name ``swappersExclude``
1799
+ (query).
1800
+ swapper_groups (Optional[List[str]]): The list of all included/excluded
1801
+ swappers based on tag, empty list
1802
+ means no filter is required Wire name
1803
+ ``swapperGroups`` (query).
1804
+ swappers_groups_exclude (Optional[bool]): Defines the provided swappers'
1805
+ tags as the include/exclude list.
1806
+ Default is false (include) Wire
1807
+ name ``swappersGroupsExclude``
1808
+ (query).
1809
+ messaging_protocols (Optional[List[models.ParamMessagingProtocolsItem]]): Message protocols which
1810
+ will be used to call
1811
+ message before or after
1812
+ swap Wire name
1813
+ ``messagingProtocols``
1814
+ (query).
1815
+ im_message (Optional[str]): Message to call after or before swap transaction
1816
+ Wire name ``imMessage`` (query).
1817
+ source_contract (Optional[str]): Contract address which should be called
1818
+ before swap transaction Wire name
1819
+ ``sourceContract`` (query).
1820
+ destination_contract (Optional[str]): Contract address which should be
1821
+ called after swap transaction Wire
1822
+ name ``destinationContract`` (query).
1823
+ infinite_approve (Optional[bool]): Use this parameter if you want infinite
1824
+ approve from user Wire name
1825
+ ``infiniteApprove`` (query).
1826
+ contract_call (Optional[bool]): set this parameter to `true` if you wants to
1827
+ send transactions through a contract Wire
1828
+ name ``contractCall`` (query).
1829
+ referrer_fee (Optional[float]): Referrer fee in percent Wire name
1830
+ ``referrerFee`` (query).
1831
+ referrer_address (Optional[str]): Referrer wallet address Wire name
1832
+ ``referrerAddress`` (query).
1833
+ referrer_code (Optional[str]): Referrer code Wire name ``referrerCode``
1834
+ (query).
1835
+ avoid_native_fee (Optional[bool]): When it is true, Swappers that have
1836
+ native tokens as fee must be excluded.
1837
+ example: when you call it from AA
1838
+ account. Wire name ``avoidNativeFee``
1839
+ (query).
1840
+ enable_centralized_swappers (Optional[bool]): Specify that centralized
1841
+ swappers must be included in
1842
+ swappers or not. Default is
1843
+ false (exclude) Wire name
1844
+ ``enableCentralizedSwappers``
1845
+ (query).
1846
+ use_max_native_token_balance (Optional[bool]): Forces transaction creation
1847
+ by subtracting fees from
1848
+ input if balance is
1849
+ insufficient. Wire name
1850
+ ``useMaxNativeTokenBalance``
1851
+ (query).
1852
+ header_x_rango_id (Optional[str]): A unique client generated Id, better use
1853
+ UUID Wire name ``X-Rango-Id`` (header).
1854
+
1855
+ Returns:
1856
+ ``Optional[models.BasicApiSwapResponse]`` — JSON response parsed into the
1857
+ declared type when the body is non-empty; ``None`` for HTTP 204/205 or an
1858
+ empty body.
1859
+
1860
+ Examples:
1861
+ async with AsyncClient(api_key='c6381a79-2817-4602-83bf-6a641a409e32') as client:
1862
+ result = await client.transaction.swap(from_="BSC.BNB", to="AVAX_CCHAIN.USDT.E--0xc7198437980c041c805a1edcba50c1ce5db95118", amount=100000000000000000, slippage=8.5, from_address="0x9F8cCdaFCc39F3c7D6EBf637c9151673CBc36b88", to_address="0x6f33bb1763eebead07cf8815a62fcd7b30311fa3", disable_estimate=False, infinite_approve=False, referrer_fee=0.3, referrer_address="0x6f33bb1763eebead07cf8815a62fcd7b30311fa3")
1863
+ print(result)
1864
+ """
1865
+ url = f"/basic/swap"
1866
+ params: Dict[str, Any] = {}
1867
+ params["from"] = from_
1868
+ params["to"] = to
1869
+ params["amount"] = amount
1870
+ params["slippage"] = slippage
1871
+ params["fromAddress"] = from_address
1872
+ params["toAddress"] = to_address
1873
+ if disable_estimate is not None:
1874
+ params["disableEstimate"] = disable_estimate
1875
+ if swappers is not None:
1876
+ params["swappers"] = swappers
1877
+ if swappers_exclude is not None:
1878
+ params["swappersExclude"] = swappers_exclude
1879
+ if swapper_groups is not None:
1880
+ params["swapperGroups"] = swapper_groups
1881
+ if swappers_groups_exclude is not None:
1882
+ params["swappersGroupsExclude"] = swappers_groups_exclude
1883
+ if messaging_protocols is not None:
1884
+ params["messagingProtocols"] = messaging_protocols
1885
+ if im_message is not None:
1886
+ params["imMessage"] = im_message
1887
+ if source_contract is not None:
1888
+ params["sourceContract"] = source_contract
1889
+ if destination_contract is not None:
1890
+ params["destinationContract"] = destination_contract
1891
+ if infinite_approve is not None:
1892
+ params["infiniteApprove"] = infinite_approve
1893
+ if contract_call is not None:
1894
+ params["contractCall"] = contract_call
1895
+ if referrer_fee is not None:
1896
+ params["referrerFee"] = referrer_fee
1897
+ if referrer_address is not None:
1898
+ params["referrerAddress"] = referrer_address
1899
+ if referrer_code is not None:
1900
+ params["referrerCode"] = referrer_code
1901
+ if avoid_native_fee is not None:
1902
+ params["avoidNativeFee"] = avoid_native_fee
1903
+ if enable_centralized_swappers is not None:
1904
+ params["enableCentralizedSwappers"] = enable_centralized_swappers
1905
+ if use_max_native_token_balance is not None:
1906
+ params["useMaxNativeTokenBalance"] = use_max_native_token_balance
1907
+ req_headers: Dict[str, str] = {}
1908
+ if header_x_rango_id is not None:
1909
+ req_headers["X-Rango-Id"] = str(header_x_rango_id)
1910
+ self._root._apply_security(["apiKey"], params, req_headers, None)
1911
+
1912
+ response = await self._root._client.request(
1913
+ "GET",
1914
+ url,
1915
+ params=params or None,
1916
+ headers=req_headers or None,
1917
+ )
1918
+ response.raise_for_status()
1919
+ if response.status_code in (204, 205) or not response.content:
1920
+ return None
1921
+ return models.BasicApiSwapResponse.model_validate(response.json())
1922
+
1923
+
1924
+ class AsyncClient:
1925
+ """
1926
+ Simple and Easy to use APIs for Rango Aggregation protocols for dApps and Wallets
1927
+ for single step cross-chain and on-chain swaps using the best route and all the
1928
+ available on-chain liquidity across all blockchain networks.
1929
+
1930
+ Pass ``log_http_debug=True`` and configure logging for this module (e.g.
1931
+ ``logging.getLogger(__name__).setLevel(logging.DEBUG)`` on ``…client``) to emit each
1932
+ HTTP request and response at DEBUG, including headers and bodies. This may log
1933
+ credentials—use only in trusted environments.
1934
+
1935
+ Optional ``proxy`` is forwarded to the underlying ``httpx`` client (a proxy URL
1936
+ string or ``httpx.URL``).
1937
+
1938
+ Security credentials may be passed as constructor keyword arguments or read from
1939
+ environment variables (see the README); constructor values take precedence when both
1940
+ are set.
1941
+ """
1942
+
1943
+ def __init__(
1944
+ self,
1945
+ base_url: Optional[str] = None,
1946
+ *,
1947
+ api_key: Optional[str] = None,
1948
+ headers: Optional[Dict[str, str]] = None,
1949
+ timeout: float = 30.0,
1950
+ proxy: Optional[Union[str, httpx.URL]] = None,
1951
+ log_http_debug: bool = False,
1952
+ ) -> None:
1953
+ _resolved = base_url if base_url is not None else DEFAULT_SERVER_URL
1954
+ if not _resolved:
1955
+ raise ValueError(
1956
+ "No base URL: pass base_url=… or define servers in the OpenAPI document.",
1957
+ )
1958
+ self._base_url = _resolved.rstrip("/")
1959
+ self._headers = dict(headers or {})
1960
+ self._proxy = proxy
1961
+ self._sec_apiKey = _security_value_from_kw_or_env(
1962
+ api_key,
1963
+ "RANGO_BASIC_API_KEY",
1964
+ )
1965
+ if not self._sec_apiKey:
1966
+ raise ValueError(
1967
+ "OpenAPI security scheme "
1968
+ + "apiKey"
1969
+ + ": pass keyword argument "
1970
+ + "api_key"
1971
+ + ", or set environment variable "
1972
+ + "RANGO_BASIC_API_KEY"
1973
+ + "."
1974
+ )
1975
+
1976
+ _ahooks: Optional[Dict[str, List[Any]]] = (
1977
+ _async_http_debug_event_hooks() if log_http_debug else None
1978
+ )
1979
+ self._client = httpx.AsyncClient(
1980
+ base_url=self._base_url,
1981
+ headers=self._headers,
1982
+ timeout=timeout,
1983
+ proxy=self._proxy,
1984
+ event_hooks=_ahooks,
1985
+ )
1986
+ self.balance = AsyncBalanceOperations(self)
1987
+ self.metadata = AsyncMetadataOperations(self)
1988
+ self.routing = AsyncRoutingOperations(self)
1989
+ self.transaction = AsyncTransactionOperations(self)
1990
+
1991
+ def _apply_security(
1992
+ self,
1993
+ operation_scheme_keys: List[str],
1994
+ params: Dict[str, Any],
1995
+ headers: Dict[str, str],
1996
+ cookies: Optional[Dict[str, str]],
1997
+ ) -> None:
1998
+ if "apiKey" in operation_scheme_keys and self._sec_apiKey is not None:
1999
+ params["apiKey"] = self._sec_apiKey
2000
+
2001
+ async def aclose(self) -> None:
2002
+ await self._client.aclose()
2003
+
2004
+ async def __aenter__(self) -> "AsyncClient":
2005
+ return self
2006
+
2007
+ async def __aexit__(self, *args: object) -> None:
2008
+ await self.aclose()