| from typing import TypedDict, Any |
| import asyncio |
| from phi.tools import Toolkit |
| from phi.utils.log import logger |
| from src.libs.rpc_client import rpc_call |
|
|
| |
| class WalletParams(TypedDict): |
| userEmail: str |
| chain: str |
| testnet: bool |
| gasless: bool |
|
|
| |
| class TokenParams(TypedDict): |
| chainId: int |
| address: str |
| decimals: int |
| symbol: str |
| name: str |
|
|
| class CrossChainSwapTools(Toolkit): |
| def __init__(self): |
| super().__init__(name="cross_chain_swap_tools") |
|
|
| |
| self.register(self.cross_chain_swap) |
| self.register(self.get_bridge_chains) |
| self.register(self.get_cross_chain_swap_token_list) |
|
|
| def cross_chain_swap( |
| self, |
| chainId: int, |
| amountLD: str, |
| recipient: str, |
| user_email: str, |
| tokenIn: str, |
| tokenOut: str, |
| chain: str = "base", |
| ) -> str: |
| """ |
| Performs a cross-chain token swap. this is a sensitive function, show a preview and allow user to give final permission to execute function |
| |
| Parameters: |
| - chainId (int): The ID of the chain. |
| - amountLD (str): The amount to be swapped, in lowest denomination (e.g., wei for ETH). |
| - recipient (str): The recipient address. |
| - user_email (str): The email of the user for whom the wallet is being fetched and used to sign the transaction. get enail from user toolkit |
| - tokenIn (TokenParams): The input token parameters as structured from: get_cross_chain_swap_token_list. stringify object |
| - tokenOut (TokenParams): The output token parameters as structured from: get_cross_chain_swap_token_list. stringify object |
| - chain (str): The EVM chain for which the wallet is being fetched and used to execute this transaction. use chain base as default |
| |
| Returns: |
| - str: A string representation of the response from the RPC call. |
| |
| Raises: |
| None |
| |
| Note: |
| This method uses `asyncio.run()` to run the asynchronous RPC call. |
| """ |
| logger.info(f"Performing cross-chain swap on chain {chainId} for recipient {recipient}") |
|
|
| params = { |
| 'chainId': chainId, |
| 'amountLD': amountLD, |
| 'recipient': recipient, |
| 'wallet': { |
| "userEmail": user_email, |
| "chain": chain, |
| "testnet": True, |
| "gasless": True, |
| "connected": True |
| }, |
| 'tokenIn': tokenIn, |
| 'tokenOut': tokenOut, |
| } |
| response = asyncio.run(rpc_call(method_name="crossChainSwap", params=params)) |
| return self._format_response(response) |
|
|
| def get_bridge_chains(self, chainId: int) -> str: |
| """ |
| Fetches the list of supported bridge chains. |
| |
| Parameters: |
| - chainId (int): The ID of the chain. Supported values: |
| - 1: Ethereum |
| - 10: Optimism |
| - 56: BNB Chain |
| - 100: Gnosis Chain |
| - 137: Polygon |
| - 324: zkSync Era |
| - 1088: Metis |
| - 8453: Base |
| - 42161: Arbitrum |
| - 43114: Avalanche |
| """ |
| logger.info(f"Fetching supported bridge chains for chain ID {chainId}") |
|
|
| params = {'chainId': chainId} |
| response = asyncio.run(rpc_call(method_name="getBridgeChains", params=params)) |
| return self._format_response(response) |
|
|
| def get_cross_chain_swap_token_list(self, chainId: int) -> str: |
| """ |
| Fetches the list of supported cross-chain swap tokens on the specified chainId. always call before executing |
| cross_chain_swap to get accurate tokenIn and tokenOut data |
| |
| Parameters: |
| - chainId (int): The ID of the chain. |
| |
| Returns: |
| - str: A string representation of the response from the RPC call containing the list of cryptocurrency tokens, |
| each with details about their source token and the corresponding destination |
| tokens on different blockchain networks. |
| |
| Raises: |
| None |
| |
| Note: |
| This method uses `asyncio.run()` to run the asynchronous RPC call. |
| present data in proper nice readable format |
| """ |
| logger.info(f"Fetching cross-chain swap token list for chain ID {chainId}") |
|
|
| params = {'chainId': chainId} |
| response = asyncio.run(rpc_call(method_name="getCrossChainSwapTokenList", params=params)) |
| return self._format_response(response) |
|
|
| def _format_response(self, response: dict) -> str: |
| """ |
| Formats the response from the RPC call into a readable string. |
| |
| Parameters: |
| - response (dict): The response from the RPC call. |
| |
| Returns: |
| - str: A formatted string representation of the response. |
| """ |
| if 'error' in response: |
| logger.error(f"RPC call failed with error: {response['error']}") |
| return f"Error: {response['error']}" |
| return f"Response: {response}" |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|