wayfinder-paths 0.1.13__py3-none-any.whl → 0.1.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wayfinder-paths might be problematic. Click here for more details.
- wayfinder_paths/adapters/balance_adapter/README.md +13 -14
- wayfinder_paths/adapters/balance_adapter/adapter.py +73 -32
- wayfinder_paths/adapters/balance_adapter/test_adapter.py +123 -0
- wayfinder_paths/adapters/brap_adapter/README.md +11 -16
- wayfinder_paths/adapters/brap_adapter/adapter.py +144 -78
- wayfinder_paths/adapters/brap_adapter/examples.json +63 -52
- wayfinder_paths/adapters/brap_adapter/test_adapter.py +127 -65
- wayfinder_paths/adapters/hyperlend_adapter/adapter.py +30 -14
- wayfinder_paths/adapters/hyperlend_adapter/test_adapter.py +121 -67
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter.py +6 -6
- wayfinder_paths/adapters/hyperliquid_adapter/test_adapter_live.py +12 -12
- wayfinder_paths/adapters/ledger_adapter/test_adapter.py +6 -6
- wayfinder_paths/adapters/moonwell_adapter/adapter.py +332 -9
- wayfinder_paths/adapters/moonwell_adapter/test_adapter.py +13 -13
- wayfinder_paths/adapters/pool_adapter/README.md +9 -10
- wayfinder_paths/adapters/pool_adapter/adapter.py +9 -10
- wayfinder_paths/adapters/pool_adapter/test_adapter.py +2 -2
- wayfinder_paths/adapters/token_adapter/README.md +2 -14
- wayfinder_paths/adapters/token_adapter/adapter.py +16 -10
- wayfinder_paths/adapters/token_adapter/examples.json +4 -8
- wayfinder_paths/adapters/token_adapter/test_adapter.py +9 -7
- wayfinder_paths/core/clients/BRAPClient.py +102 -61
- wayfinder_paths/core/clients/ClientManager.py +1 -68
- wayfinder_paths/core/clients/HyperlendClient.py +125 -64
- wayfinder_paths/core/clients/LedgerClient.py +1 -4
- wayfinder_paths/core/clients/PoolClient.py +122 -48
- wayfinder_paths/core/clients/TokenClient.py +91 -36
- wayfinder_paths/core/clients/WalletClient.py +26 -56
- wayfinder_paths/core/clients/WayfinderClient.py +28 -160
- wayfinder_paths/core/clients/__init__.py +0 -2
- wayfinder_paths/core/clients/protocols.py +35 -46
- wayfinder_paths/core/clients/sdk_example.py +37 -22
- wayfinder_paths/core/constants/erc20_abi.py +0 -11
- wayfinder_paths/core/engine/StrategyJob.py +10 -56
- wayfinder_paths/core/services/base.py +1 -0
- wayfinder_paths/core/services/local_evm_txn.py +25 -9
- wayfinder_paths/core/services/local_token_txn.py +2 -6
- wayfinder_paths/core/services/test_local_evm_txn.py +145 -0
- wayfinder_paths/core/strategies/Strategy.py +16 -4
- wayfinder_paths/core/utils/evm_helpers.py +2 -9
- wayfinder_paths/policies/erc20.py +1 -1
- wayfinder_paths/run_strategy.py +13 -19
- wayfinder_paths/strategies/basis_trading_strategy/strategy.py +77 -11
- wayfinder_paths/strategies/basis_trading_strategy/test_strategy.py +6 -6
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/strategy.py +107 -23
- wayfinder_paths/strategies/hyperlend_stable_yield_strategy/test_strategy.py +54 -9
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/README.md +6 -5
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/strategy.py +2246 -1279
- wayfinder_paths/strategies/moonwell_wsteth_loop_strategy/test_strategy.py +276 -109
- wayfinder_paths/strategies/stablecoin_yield_strategy/README.md +1 -1
- wayfinder_paths/strategies/stablecoin_yield_strategy/strategy.py +153 -56
- wayfinder_paths/strategies/stablecoin_yield_strategy/test_strategy.py +16 -12
- wayfinder_paths/templates/adapter/README.md +1 -1
- wayfinder_paths/templates/strategy/README.md +3 -3
- wayfinder_paths/templates/strategy/test_strategy.py +3 -2
- {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/METADATA +14 -49
- {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/RECORD +59 -60
- wayfinder_paths/abis/generic/erc20.json +0 -383
- wayfinder_paths/core/clients/AuthClient.py +0 -83
- {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/LICENSE +0 -0
- {wayfinder_paths-0.1.13.dist-info → wayfinder_paths-0.1.15.dist-info}/WHEEL +0 -0
|
@@ -8,7 +8,10 @@ from wayfinder_paths.adapters.ledger_adapter.adapter import LedgerAdapter
|
|
|
8
8
|
from wayfinder_paths.adapters.token_adapter.adapter import TokenAdapter
|
|
9
9
|
from wayfinder_paths.core.adapters.BaseAdapter import BaseAdapter
|
|
10
10
|
from wayfinder_paths.core.adapters.models import SWAP
|
|
11
|
-
from wayfinder_paths.core.clients.BRAPClient import
|
|
11
|
+
from wayfinder_paths.core.clients.BRAPClient import (
|
|
12
|
+
BRAPClient,
|
|
13
|
+
BRAPQuoteResponse,
|
|
14
|
+
)
|
|
12
15
|
from wayfinder_paths.core.clients.LedgerClient import TransactionRecord
|
|
13
16
|
from wayfinder_paths.core.clients.TokenClient import TokenClient
|
|
14
17
|
from wayfinder_paths.core.constants import DEFAULT_SLIPPAGE, ZERO_ADDRESS
|
|
@@ -61,7 +64,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
61
64
|
amount: str,
|
|
62
65
|
slippage: float | None = None,
|
|
63
66
|
wayfinder_fee: float | None = None,
|
|
64
|
-
) -> tuple[bool,
|
|
67
|
+
) -> tuple[bool, BRAPQuoteResponse | str]:
|
|
65
68
|
"""
|
|
66
69
|
Get a quote for a cross-chain swap operation.
|
|
67
70
|
|
|
@@ -77,19 +80,16 @@ class BRAPAdapter(BaseAdapter):
|
|
|
77
80
|
wayfinder_fee: Wayfinder fee (optional)
|
|
78
81
|
|
|
79
82
|
Returns:
|
|
80
|
-
Tuple of (success, data) where data is quote
|
|
83
|
+
Tuple of (success, data) where data is quote response or error message
|
|
81
84
|
"""
|
|
82
85
|
try:
|
|
83
86
|
data = await self.brap_client.get_quote(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
amount1=amount,
|
|
91
|
-
slippage=slippage,
|
|
92
|
-
wayfinder_fee=wayfinder_fee,
|
|
87
|
+
from_token=from_token_address,
|
|
88
|
+
to_token=to_token_address,
|
|
89
|
+
from_chain=from_chain_id,
|
|
90
|
+
to_chain=to_chain_id,
|
|
91
|
+
from_wallet=from_address,
|
|
92
|
+
from_amount=amount,
|
|
93
93
|
)
|
|
94
94
|
return (True, data)
|
|
95
95
|
except Exception as e:
|
|
@@ -130,22 +130,28 @@ class BRAPAdapter(BaseAdapter):
|
|
|
130
130
|
"""
|
|
131
131
|
try:
|
|
132
132
|
data = await self.brap_client.get_quote(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
amount1=amount,
|
|
140
|
-
slippage=slippage,
|
|
141
|
-
wayfinder_fee=wayfinder_fee,
|
|
133
|
+
from_token=from_token_address,
|
|
134
|
+
to_token=to_token_address,
|
|
135
|
+
from_chain=from_chain_id,
|
|
136
|
+
to_chain=to_chain_id,
|
|
137
|
+
from_wallet=from_address,
|
|
138
|
+
from_amount=amount,
|
|
142
139
|
)
|
|
143
140
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
"
|
|
148
|
-
|
|
141
|
+
raw_quotes = data.get("quotes")
|
|
142
|
+
if isinstance(raw_quotes, list):
|
|
143
|
+
all_quotes = raw_quotes
|
|
144
|
+
best_quote = data.get("best_quote") or data.get("best_route")
|
|
145
|
+
else:
|
|
146
|
+
quotes_container = raw_quotes or {}
|
|
147
|
+
all_quotes = quotes_container.get(
|
|
148
|
+
"all_quotes", []
|
|
149
|
+
) or quotes_container.get("quotes", [])
|
|
150
|
+
best_quote = (
|
|
151
|
+
quotes_container.get("best_quote")
|
|
152
|
+
or data.get("best_quote")
|
|
153
|
+
or data.get("best_route")
|
|
154
|
+
)
|
|
149
155
|
|
|
150
156
|
# If preferred providers specified, select by provider preference
|
|
151
157
|
if preferred_providers and all_quotes:
|
|
@@ -156,13 +162,6 @@ class BRAPAdapter(BaseAdapter):
|
|
|
156
162
|
return (True, selected_quote)
|
|
157
163
|
# Fall through to best_quote if no preferred provider found
|
|
158
164
|
|
|
159
|
-
# Extract best quote from response - check nested quotes first, then top level
|
|
160
|
-
best_quote = (
|
|
161
|
-
quotes_container.get("best_quote")
|
|
162
|
-
or data.get("best_quote")
|
|
163
|
-
or data.get("best_route")
|
|
164
|
-
)
|
|
165
|
-
|
|
166
165
|
if not best_quote:
|
|
167
166
|
return (False, "No quotes available")
|
|
168
167
|
|
|
@@ -253,8 +252,8 @@ class BRAPAdapter(BaseAdapter):
|
|
|
253
252
|
to_token_address=to_token_address,
|
|
254
253
|
from_chain_id=from_chain_id,
|
|
255
254
|
to_chain_id=to_chain_id,
|
|
256
|
-
from_address="0x0000000000000000000000000000000000000000",
|
|
257
|
-
to_address="0x0000000000000000000000000000000000000000",
|
|
255
|
+
from_address="0x0000000000000000000000000000000000000000",
|
|
256
|
+
to_address="0x0000000000000000000000000000000000000000",
|
|
258
257
|
amount=amount,
|
|
259
258
|
slippage=slippage,
|
|
260
259
|
)
|
|
@@ -262,22 +261,22 @@ class BRAPAdapter(BaseAdapter):
|
|
|
262
261
|
if not success:
|
|
263
262
|
return (False, quote_data)
|
|
264
263
|
|
|
265
|
-
|
|
266
|
-
best_quote = quotes.get("best_quote")
|
|
264
|
+
best_quote = quote_data.get("best_quote")
|
|
267
265
|
|
|
268
266
|
if not best_quote:
|
|
269
267
|
return (False, "No quote available for fee calculation")
|
|
270
268
|
|
|
271
269
|
# Extract fee information
|
|
270
|
+
fee_estimate = best_quote.get("fee_estimate", {})
|
|
272
271
|
fees = {
|
|
273
272
|
"input_amount": best_quote.get("input_amount", 0),
|
|
274
273
|
"output_amount": best_quote.get("output_amount", 0),
|
|
275
|
-
"gas_fee": best_quote.get("
|
|
276
|
-
"bridge_fee":
|
|
277
|
-
"protocol_fee":
|
|
278
|
-
"total_fee":
|
|
279
|
-
"slippage":
|
|
280
|
-
"price_impact": best_quote.get("
|
|
274
|
+
"gas_fee": best_quote.get("gas_estimate") or 0,
|
|
275
|
+
"bridge_fee": 0,
|
|
276
|
+
"protocol_fee": fee_estimate.get("fee_total_usd", 0),
|
|
277
|
+
"total_fee": fee_estimate.get("fee_total_usd", 0),
|
|
278
|
+
"slippage": 0,
|
|
279
|
+
"price_impact": best_quote.get("quote", {}).get("priceImpact", 0),
|
|
281
280
|
}
|
|
282
281
|
|
|
283
282
|
return (True, fees)
|
|
@@ -310,19 +309,26 @@ class BRAPAdapter(BaseAdapter):
|
|
|
310
309
|
"""
|
|
311
310
|
try:
|
|
312
311
|
data = await self.brap_client.get_quote(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
amount1=amount,
|
|
320
|
-
slippage=slippage,
|
|
312
|
+
from_token=from_token_address,
|
|
313
|
+
to_token=to_token_address,
|
|
314
|
+
from_chain=from_chain_id,
|
|
315
|
+
to_chain=to_chain_id,
|
|
316
|
+
from_wallet="0x0000000000000000000000000000000000000000",
|
|
317
|
+
from_amount=amount,
|
|
321
318
|
)
|
|
322
319
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
320
|
+
raw_quotes = data.get("quotes")
|
|
321
|
+
if isinstance(raw_quotes, list):
|
|
322
|
+
all_quotes = raw_quotes
|
|
323
|
+
best_quote = data.get("best_quote") or data.get("best_route")
|
|
324
|
+
else:
|
|
325
|
+
quotes = raw_quotes or {}
|
|
326
|
+
all_quotes = quotes.get("all_quotes", []) or quotes.get("quotes", [])
|
|
327
|
+
best_quote = (
|
|
328
|
+
quotes.get("best_quote")
|
|
329
|
+
or data.get("best_quote")
|
|
330
|
+
or data.get("best_route")
|
|
331
|
+
)
|
|
326
332
|
|
|
327
333
|
if not all_quotes:
|
|
328
334
|
return (False, "No routes available")
|
|
@@ -339,7 +345,12 @@ class BRAPAdapter(BaseAdapter):
|
|
|
339
345
|
"route_analysis": {
|
|
340
346
|
"highest_output": sorted_quotes[0] if sorted_quotes else None,
|
|
341
347
|
"lowest_fees": (
|
|
342
|
-
min(
|
|
348
|
+
min(
|
|
349
|
+
all_quotes,
|
|
350
|
+
key=lambda x: float(
|
|
351
|
+
x.get("fee_estimate", {}).get("fee_total_usd", 0)
|
|
352
|
+
),
|
|
353
|
+
)
|
|
343
354
|
if all_quotes
|
|
344
355
|
else None
|
|
345
356
|
),
|
|
@@ -422,13 +433,40 @@ class BRAPAdapter(BaseAdapter):
|
|
|
422
433
|
chain = from_token.get("chain") or {}
|
|
423
434
|
chain_id = self._chain_id(chain)
|
|
424
435
|
|
|
425
|
-
|
|
426
|
-
|
|
436
|
+
calldata = quote.get("calldata") or {}
|
|
437
|
+
transaction = dict(calldata)
|
|
438
|
+
if not transaction or not transaction.get("data"):
|
|
427
439
|
return (False, "Quote missing calldata")
|
|
428
440
|
transaction["chainId"] = chain_id
|
|
441
|
+
# Always set the sender to the strategy wallet for broadcast.
|
|
442
|
+
# (Calldata may include either "from" or "from_address" depending on provider.)
|
|
429
443
|
transaction["from"] = to_checksum_address(from_address)
|
|
430
444
|
|
|
431
|
-
|
|
445
|
+
def _as_address(value: Any) -> str | None:
|
|
446
|
+
if not isinstance(value, str):
|
|
447
|
+
return None
|
|
448
|
+
v = value.strip()
|
|
449
|
+
if (
|
|
450
|
+
v.startswith("0x")
|
|
451
|
+
and len(v) == 42
|
|
452
|
+
and v.lower() != ZERO_ADDRESS.lower()
|
|
453
|
+
):
|
|
454
|
+
return v
|
|
455
|
+
return None
|
|
456
|
+
|
|
457
|
+
spender = (
|
|
458
|
+
_as_address(transaction.get("allowanceTarget"))
|
|
459
|
+
or _as_address(transaction.get("allowance_target"))
|
|
460
|
+
or _as_address(transaction.get("approvalAddress"))
|
|
461
|
+
or _as_address(transaction.get("approval_address"))
|
|
462
|
+
or _as_address(transaction.get("spender"))
|
|
463
|
+
or _as_address(quote.get("allowanceTarget"))
|
|
464
|
+
or _as_address(quote.get("allowance_target"))
|
|
465
|
+
or _as_address(quote.get("approvalAddress"))
|
|
466
|
+
or _as_address(quote.get("approval_address"))
|
|
467
|
+
or _as_address(quote.get("spender"))
|
|
468
|
+
or _as_address(transaction.get("to"))
|
|
469
|
+
)
|
|
432
470
|
approve_amount = (
|
|
433
471
|
quote.get("input_amount")
|
|
434
472
|
or quote.get("inputAmount")
|
|
@@ -455,13 +493,35 @@ class BRAPAdapter(BaseAdapter):
|
|
|
455
493
|
broadcast_success, broadcast_response = await self._broadcast_transaction(
|
|
456
494
|
transaction
|
|
457
495
|
)
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
496
|
+
# Log only key fields to avoid spamming raw HexBytes logs
|
|
497
|
+
if isinstance(broadcast_response, dict):
|
|
498
|
+
tx_hash_log = broadcast_response.get("tx_hash", "unknown")
|
|
499
|
+
block_log = broadcast_response.get("block_number", "unknown")
|
|
500
|
+
status_log = (
|
|
501
|
+
broadcast_response.get("receipt", {}).get("status", "unknown")
|
|
502
|
+
if isinstance(broadcast_response.get("receipt"), dict)
|
|
503
|
+
else "unknown"
|
|
504
|
+
)
|
|
505
|
+
self.logger.info(
|
|
506
|
+
f"Swap broadcast: success={broadcast_success}, tx={tx_hash_log}, block={block_log}, status={status_log}"
|
|
507
|
+
)
|
|
508
|
+
else:
|
|
509
|
+
self.logger.info(f"Swap broadcast: success={broadcast_success}")
|
|
462
510
|
if not broadcast_success:
|
|
463
511
|
return (False, broadcast_response)
|
|
464
512
|
|
|
513
|
+
tx_hash = None
|
|
514
|
+
block_number = None
|
|
515
|
+
confirmations = None
|
|
516
|
+
confirmed_block_number = None
|
|
517
|
+
if isinstance(broadcast_response, dict):
|
|
518
|
+
tx_hash = broadcast_response.get("tx_hash") or broadcast_response.get(
|
|
519
|
+
"transaction_hash"
|
|
520
|
+
)
|
|
521
|
+
block_number = broadcast_response.get("block_number")
|
|
522
|
+
confirmations = broadcast_response.get("confirmations")
|
|
523
|
+
confirmed_block_number = broadcast_response.get("confirmed_block_number")
|
|
524
|
+
|
|
465
525
|
# Record the swap operation in ledger - but don't let ledger errors fail the swap
|
|
466
526
|
# since the on-chain transaction already succeeded
|
|
467
527
|
try:
|
|
@@ -477,15 +537,20 @@ class BRAPAdapter(BaseAdapter):
|
|
|
477
537
|
self.logger.warning(
|
|
478
538
|
f"Ledger recording failed (swap succeeded on-chain): {e}"
|
|
479
539
|
)
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
540
|
+
ledger_record = {}
|
|
541
|
+
|
|
542
|
+
result_payload: dict[str, Any] = {
|
|
543
|
+
"from_amount": quote.get("input_amount"),
|
|
544
|
+
"to_amount": quote.get("output_amount"),
|
|
545
|
+
"tx_hash": tx_hash,
|
|
546
|
+
"block_number": block_number,
|
|
547
|
+
"confirmations": confirmations,
|
|
548
|
+
"confirmed_block_number": confirmed_block_number,
|
|
549
|
+
}
|
|
550
|
+
if isinstance(ledger_record, dict):
|
|
551
|
+
result_payload.update(ledger_record)
|
|
552
|
+
|
|
553
|
+
return (True, result_payload)
|
|
489
554
|
|
|
490
555
|
async def get_bridge_quote(
|
|
491
556
|
self,
|
|
@@ -516,8 +581,8 @@ class BRAPAdapter(BaseAdapter):
|
|
|
516
581
|
to_token_address=to_token_address,
|
|
517
582
|
from_chain_id=from_chain_id,
|
|
518
583
|
to_chain_id=to_chain_id,
|
|
519
|
-
from_address="0x0000000000000000000000000000000000000000",
|
|
520
|
-
to_address="0x0000000000000000000000000000000000000000",
|
|
584
|
+
from_address="0x0000000000000000000000000000000000000000",
|
|
585
|
+
to_address="0x0000000000000000000000000000000000000000",
|
|
521
586
|
amount=amount,
|
|
522
587
|
slippage=slippage,
|
|
523
588
|
)
|
|
@@ -634,14 +699,15 @@ class BRAPAdapter(BaseAdapter):
|
|
|
634
699
|
validation_errors.append(f"Swap not possible: {quote_data}")
|
|
635
700
|
return (False, {"valid": False, "errors": validation_errors})
|
|
636
701
|
|
|
702
|
+
best_quote = (
|
|
703
|
+
quote_data.get("best_quote", {}) if isinstance(quote_data, dict) else {}
|
|
704
|
+
)
|
|
637
705
|
return (
|
|
638
706
|
True,
|
|
639
707
|
{
|
|
640
708
|
"valid": True,
|
|
641
709
|
"quote_available": True,
|
|
642
|
-
"estimated_output":
|
|
643
|
-
.get("best_quote", {})
|
|
644
|
-
.get("output_amount", "0"),
|
|
710
|
+
"estimated_output": str(best_quote.get("output_amount", 0)),
|
|
645
711
|
},
|
|
646
712
|
)
|
|
647
713
|
except Exception as e:
|
|
@@ -695,7 +761,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
695
761
|
return await self._broadcast_transaction(approve_tx, confirmations=2)
|
|
696
762
|
|
|
697
763
|
async def _broadcast_transaction(
|
|
698
|
-
self, transaction: dict[str, Any], confirmations: int =
|
|
764
|
+
self, transaction: dict[str, Any], confirmations: int | None = None
|
|
699
765
|
) -> tuple[bool, Any]:
|
|
700
766
|
return await self.wallet_provider.broadcast_transaction(
|
|
701
767
|
transaction,
|
|
@@ -779,7 +845,7 @@ class BRAPAdapter(BaseAdapter):
|
|
|
779
845
|
|
|
780
846
|
def _chain_id(self, chain: Any) -> int:
|
|
781
847
|
if isinstance(chain, dict):
|
|
782
|
-
chain_id = chain.get("id")
|
|
848
|
+
chain_id = chain.get("id")
|
|
783
849
|
else:
|
|
784
850
|
chain_id = getattr(chain, "id", None)
|
|
785
851
|
if chain_id is None:
|
|
@@ -14,25 +14,37 @@
|
|
|
14
14
|
"output": {
|
|
15
15
|
"success": true,
|
|
16
16
|
"data": {
|
|
17
|
-
"quotes":
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"route": "Route 1",
|
|
32
|
-
"output_amount": "995000000000000000",
|
|
33
|
-
"total_fee": "8000000000000000"
|
|
17
|
+
"quotes": [
|
|
18
|
+
{
|
|
19
|
+
"provider": "enso",
|
|
20
|
+
"input_amount": 1000000000000000000,
|
|
21
|
+
"output_amount": 995000000000000000,
|
|
22
|
+
"fee_estimate": {
|
|
23
|
+
"fee_total_usd": 0.08,
|
|
24
|
+
"fee_breakdown": []
|
|
25
|
+
},
|
|
26
|
+
"calldata": {
|
|
27
|
+
"data": "0x",
|
|
28
|
+
"to": "0x",
|
|
29
|
+
"value": "0",
|
|
30
|
+
"chainId": 8453
|
|
34
31
|
}
|
|
35
|
-
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"best_quote": {
|
|
35
|
+
"provider": "enso",
|
|
36
|
+
"input_amount": 1000000000000000000,
|
|
37
|
+
"output_amount": 995000000000000000,
|
|
38
|
+
"fee_estimate": {
|
|
39
|
+
"fee_total_usd": 0.08,
|
|
40
|
+
"fee_breakdown": []
|
|
41
|
+
},
|
|
42
|
+
"calldata": {
|
|
43
|
+
"data": "0x",
|
|
44
|
+
"to": "0x",
|
|
45
|
+
"value": "0",
|
|
46
|
+
"chainId": 8453
|
|
47
|
+
}
|
|
36
48
|
}
|
|
37
49
|
}
|
|
38
50
|
}
|
|
@@ -52,15 +64,19 @@
|
|
|
52
64
|
"output": {
|
|
53
65
|
"success": true,
|
|
54
66
|
"data": {
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
67
|
+
"provider": "enso",
|
|
68
|
+
"input_amount": 1000000000000000000,
|
|
69
|
+
"output_amount": 995000000000000000,
|
|
70
|
+
"fee_estimate": {
|
|
71
|
+
"fee_total_usd": 0.08,
|
|
72
|
+
"fee_breakdown": []
|
|
73
|
+
},
|
|
74
|
+
"calldata": {
|
|
75
|
+
"data": "0x",
|
|
76
|
+
"to": "0x",
|
|
77
|
+
"value": "0",
|
|
78
|
+
"chainId": 8453
|
|
79
|
+
}
|
|
64
80
|
}
|
|
65
81
|
}
|
|
66
82
|
},
|
|
@@ -77,14 +93,14 @@
|
|
|
77
93
|
"output": {
|
|
78
94
|
"success": true,
|
|
79
95
|
"data": {
|
|
80
|
-
"input_amount":
|
|
81
|
-
"output_amount":
|
|
82
|
-
"gas_fee":
|
|
83
|
-
"bridge_fee":
|
|
84
|
-
"protocol_fee":
|
|
85
|
-
"total_fee":
|
|
86
|
-
"slippage": 0
|
|
87
|
-
"price_impact":
|
|
96
|
+
"input_amount": 1000000000000000000,
|
|
97
|
+
"output_amount": 995000000000000000,
|
|
98
|
+
"gas_fee": 567840,
|
|
99
|
+
"bridge_fee": 0,
|
|
100
|
+
"protocol_fee": 0.08,
|
|
101
|
+
"total_fee": 0.08,
|
|
102
|
+
"slippage": 0,
|
|
103
|
+
"price_impact": 6888
|
|
88
104
|
}
|
|
89
105
|
}
|
|
90
106
|
},
|
|
@@ -101,35 +117,30 @@
|
|
|
101
117
|
"output": {
|
|
102
118
|
"success": true,
|
|
103
119
|
"data": {
|
|
104
|
-
"total_routes":
|
|
120
|
+
"total_routes": 2,
|
|
105
121
|
"best_route": {
|
|
106
|
-
"
|
|
107
|
-
"output_amount":
|
|
108
|
-
"
|
|
122
|
+
"provider": "enso",
|
|
123
|
+
"output_amount": 995000000000000000,
|
|
124
|
+
"fee_estimate": { "fee_total_usd": 0.08, "fee_breakdown": [] }
|
|
109
125
|
},
|
|
110
126
|
"all_routes": [
|
|
111
127
|
{
|
|
112
|
-
"
|
|
113
|
-
"output_amount":
|
|
114
|
-
"
|
|
115
|
-
"estimated_time": 300
|
|
128
|
+
"provider": "enso",
|
|
129
|
+
"output_amount": 995000000000000000,
|
|
130
|
+
"fee_estimate": { "fee_total_usd": 0.08, "fee_breakdown": [] }
|
|
116
131
|
},
|
|
117
132
|
{
|
|
118
|
-
"
|
|
119
|
-
"output_amount":
|
|
120
|
-
"
|
|
121
|
-
"estimated_time": 180
|
|
133
|
+
"provider": "enso",
|
|
134
|
+
"output_amount": 992000000000000000,
|
|
135
|
+
"fee_estimate": { "fee_total_usd": 0.12, "fee_breakdown": [] }
|
|
122
136
|
}
|
|
123
137
|
],
|
|
124
138
|
"route_analysis": {
|
|
125
139
|
"highest_output": {
|
|
126
|
-
"output_amount":
|
|
140
|
+
"output_amount": 995000000000000000
|
|
127
141
|
},
|
|
128
142
|
"lowest_fees": {
|
|
129
|
-
"
|
|
130
|
-
},
|
|
131
|
-
"fastest": {
|
|
132
|
-
"estimated_time": 180
|
|
143
|
+
"fee_estimate": { "fee_total_usd": 0.08, "fee_breakdown": [] }
|
|
133
144
|
}
|
|
134
145
|
}
|
|
135
146
|
}
|