diff --git a/src/wallet/adapters/lifi/lifi_adapter.py b/src/wallet/adapters/lifi/lifi_adapter.py index 24d9e39..f5559f2 100644 --- a/src/wallet/adapters/lifi/lifi_adapter.py +++ b/src/wallet/adapters/lifi/lifi_adapter.py @@ -77,8 +77,9 @@ def get_quote( "fromToken": token_in["address"], "toToken": token_out["address"], "fromAmount": amount_base_units, - "fromAddress": self._wallet._account.address, + "fromAddress": self._wallet._wallet_address, "slippage": 0.5, # 0.5% slippage default + "order": "CHEAPEST", } try: @@ -109,25 +110,7 @@ async def swap(self, quote: Dict[str, Any]) -> AsyncGenerator[Dict[str, Any], No Yields: Dict containing status updates about the swap progress """ - transaction_request = { - "data": quote["transactionRequest"]["data"], - "to": quote["transactionRequest"]["to"], - "value": quote["transactionRequest"]["value"], - "chainId": quote["transactionRequest"]["chainId"], - "maxFeePerGas": hex(int(quote["estimate"]["gasCosts"][0]["price"])), - "maxPriorityFeePerGas": hex( - int(float(quote["estimate"]["gasCosts"][0]["price"]) * 0.1) - ), - "gas": hex(int(quote["estimate"]["gasCosts"][0]["estimate"])), - "type": "0x2", - "nonce": await self._wallet._web3.eth.get_transaction_count( - self._wallet._wallet_address - ), - } - - response = await self._wallet.sign_transaction( - transaction_request, gas_estimate=False - ) + response = await self._wallet.send_transaction(quote["transactionRequest"]) tx_hash = response.get("data", {}).get("hash") if not tx_hash: diff --git a/src/wallet/wallet.py b/src/wallet/wallet.py index c7a6af3..9ee97a9 100644 --- a/src/wallet/wallet.py +++ b/src/wallet/wallet.py @@ -145,7 +145,6 @@ async def get_balances(self) -> Dict[str, Any]: Returns: Dict[str, Any]: Combined ETH and token balances """ - raise WalletError("Not implemented") # Get ETH balance try: eth_balance_wei = await self._web3.eth.get_balance(self._wallet_address) @@ -159,21 +158,22 @@ def get_tracked_tokens(self) -> List[str]: """Returns list of tracked token addresses""" return list(self._tracked_tokens) - async def sign_transaction( - self, transaction: Dict[str, Any], gas_estimate: bool = True + async def _make_privy_request( + self, + method: str, + transaction: Dict[str, Any], + additional_body_params: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: """ - Sign and send a transaction using Privy's wallet API. + Make a request to Privy's wallet API. Args: + method (str): RPC method to execute (e.g., 'eth_sendTransaction', 'eth_signTransaction') transaction (Dict[str, Any]): Transaction parameters - gas_estimate (bool): Whether to estimate gas if not provided + additional_body_params (Optional[Dict[str, Any]]): Additional parameters for request body Returns: - Dict[str, Any]: Transaction response from Privy API - - Raises: - WalletError: If the API request fails + Dict[str, Any]: Response from Privy API """ url = f"https://api.privy.io/v1/wallets/{self._wallet_id}/rpc" @@ -185,24 +185,20 @@ async def sign_transaction( "PRIVY_APP_ID and PRIVY_APP_SECRET environment variables must be set" ) - auth_string = f"{privy_app_id}:{privy_app_secret}" - basic_auth = base64.b64encode(auth_string.encode()).decode() - - # Add chain_id if not present if "chain_id" not in transaction: transaction["chain_id"] = self._chain_id - # Estimate gas if needed and not provided - if gas_estimate and "gas" not in transaction: - gas = await self._web3.eth.estimate_gas(transaction) - transaction["gas"] = hex(gas) + auth_string = f"{privy_app_id}:{privy_app_secret}" + basic_auth = base64.b64encode(auth_string.encode()).decode() body = { - "method": "eth_sendTransaction", - "caip2": f"eip155:{self._chain_id}", + "method": method, "params": {"transaction": transaction}, } + if additional_body_params: + body.update(additional_body_params) + headers = self._privy_signer.get_auth_headers(url=url, body=body, method="POST") headers.update( { @@ -218,3 +214,40 @@ async def sign_transaction( raise WalletError(f"API request failed: {error_text}") return await response.json() + + async def send_transaction( + self, transaction: Dict[str, Any], gas_estimate: bool = True + ) -> Dict[str, Any]: + """ + Sign and send a transaction using Privy's wallet API. + + Args: + transaction (Dict[str, Any]): Transaction parameters + gas_estimate (bool): Whether to estimate gas if not provided + + Returns: + Dict[str, Any]: Transaction response from Privy API + """ + if gas_estimate and "gas" not in transaction: + gas = await self._web3.eth.estimate_gas(transaction) + transaction["gas"] = hex(gas) + + return await self._make_privy_request( + method="eth_sendTransaction", + transaction=transaction, + additional_body_params={"caip2": f"eip155:{self._chain_id}"}, + ) + + async def sign_transaction(self, transaction: Dict[str, Any]) -> Dict[str, Any]: + """ + Sign a transaction using Privy's wallet API without broadcasting it. + + Args: + transaction (Dict[str, Any]): Transaction parameters to sign + + Returns: + Dict[str, Any]: Contains the signed transaction and encoding format + """ + return await self._make_privy_request( + method="eth_signTransaction", transaction=transaction + ) diff --git a/src/wallet/wallet_types.py b/src/wallet/wallet_types.py index 88306d2..85dfb7e 100644 --- a/src/wallet/wallet_types.py +++ b/src/wallet/wallet_types.py @@ -8,11 +8,14 @@ class WalletInstance: _web3: Web3Type - _account: AccountType - _wallet_id: str + _wallet_address: str _chain_id: int async def sign_transaction(self, transaction: Dict[str, Any]) -> Dict[str, Any]: + """Sign transaction""" + pass + + async def send_transaction(self, transaction: Dict[str, Any]) -> Dict[str, Any]: """Sign and send transaction""" pass