diff --git a/packages/sdk-provider-ethereum/src/EthereumStepExecutor.ts b/packages/sdk-provider-ethereum/src/EthereumStepExecutor.ts index 39e6b36c..fc5ea1c3 100644 --- a/packages/sdk-provider-ethereum/src/EthereumStepExecutor.ts +++ b/packages/sdk-provider-ethereum/src/EthereumStepExecutor.ts @@ -4,7 +4,6 @@ import { type ExtendedChain, getRelayerQuote, getStepTransaction, - isTokenMessageSigningAllowed, LiFiErrorCode, type LiFiStep, type LiFiStepExtended, @@ -227,6 +226,7 @@ export class EthereumStepExecutor extends BaseStepExecutor { private prepareUpdatedStep = async ( client: SDKClient, + viemClient: Client, step: LiFiStepExtended, signedTypedData?: SignedTypedData[] ) => { @@ -285,6 +285,7 @@ export class EthereumStepExecutor extends BaseStepExecutor { let transactionRequest: TransactionParameters | undefined if (step.transactionRequest) { transactionRequest = { + chainId: step.transactionRequest.chainId, to: step.transactionRequest.to, from: step.transactionRequest.from, data: step.transactionRequest.data, @@ -301,8 +302,8 @@ export class EthereumStepExecutor extends BaseStepExecutor { // ? BigInt(step.transactionRequest.maxFeePerGas as string) // : undefined, maxPriorityFeePerGas: - this.client.account?.type === 'local' - ? await getMaxPriorityFeePerGas(client, this.client) + viemClient.account?.type === 'local' + ? await getMaxPriorityFeePerGas(client, viemClient) : step.transactionRequest.maxPriorityFeePerGas ? BigInt(step.transactionRequest.maxPriorityFeePerGas) : undefined, @@ -432,10 +433,7 @@ export class EthereumStepExecutor extends BaseStepExecutor { // Check if message signing is disabled - useful for smart contract wallets // We also disable message signing for custom steps const disableMessageSigning = - this.executionOptions?.disableMessageSigning || - step.type !== 'lifi' || - // We disable message signing for tokens with '₮' symbol - !isTokenMessageSigningAllowed(step.action.fromToken) + this.executionOptions?.disableMessageSigning || step.type !== 'lifi' // Check if chain has Permit2 contract deployed. Permit2 should not be available for atomic batch. const permit2Supported = @@ -534,9 +532,20 @@ export class EthereumStepExecutor extends BaseStepExecutor { await checkBalance(client, this.client.account!.address, step) + // Make sure that the client and chain is still correct + const updatedClient = await this.checkClient(step, process) + if (!updatedClient) { + return step + } + // Try to prepare a new transaction request and update the step with typed data let { transactionRequest, isRelayerTransaction } = - await this.prepareUpdatedStep(client, step, signedTypedData) + await this.prepareUpdatedStep( + client, + updatedClient, + step, + signedTypedData + ) process = this.statusManager.updateProcess( step, diff --git a/packages/sdk/src/core/utils.ts b/packages/sdk/src/core/utils.ts index 6caa284a..66a83740 100644 --- a/packages/sdk/src/core/utils.ts +++ b/packages/sdk/src/core/utils.ts @@ -1,4 +1,4 @@ -import type { ChainId, ExtendedChain, LiFiStep, Token } from '@lifi/types' +import type { ChainId, ExtendedChain, LiFiStep } from '@lifi/types' import type { RPCUrls } from '../types/core.js' // Standard threshold for destination amount difference (0.5%) @@ -57,15 +57,3 @@ export function getRpcUrlsFromChains( } return result } - -/** - * Checks whether a given token is eligible for message signing. - * Tokens with '₮' symbol in their name are disallowed, - * since such tokens may have non-standard signing requirements or compatibility issues with hardware wallets. - * - * @param token - The token object to check. - * @returns true if the token is allowed for message signing, false otherwise. - */ -export const isTokenMessageSigningAllowed = (token: Token): boolean => { - return !token.name?.includes('₮') && !token.symbol?.includes('₮') -} diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index b6c83082..680155a0 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -37,7 +37,6 @@ export { } from './core/execution.js' export { StatusManager } from './core/StatusManager.js' export { stepComparison } from './core/stepComparison.js' -export { isTokenMessageSigningAllowed } from './core/utils.js' export { waitForDestinationChainTransaction } from './core/waitForDestinationChainTransaction.js' export { BaseError } from './errors/baseError.js' export type { ErrorCode } from './errors/constants.js' @@ -66,6 +65,7 @@ export type { Process, ProcessStatus, ProcessType, + RequestInterceptor, RouteExecutionData, RouteExecutionDataDictionary, RouteExecutionDictionary, diff --git a/packages/sdk/src/types/core.ts b/packages/sdk/src/types/core.ts index 9d81a917..9ed7f3cd 100644 --- a/packages/sdk/src/types/core.ts +++ b/packages/sdk/src/types/core.ts @@ -14,6 +14,11 @@ import type { TokenAmount, } from '@lifi/types' import type { Client } from 'viem' +import type { ExtendedRequestInit } from './request.js' + +export type RequestInterceptor = ( + request: ExtendedRequestInit +) => ExtendedRequestInit | Promise export interface SDKBaseConfig { apiKey?: string @@ -27,6 +32,8 @@ export interface SDKBaseConfig { widgetVersion?: string debug: boolean preloadChains?: boolean + chainsRefetchInterval?: number + requestInterceptor?: RequestInterceptor } export interface SDKConfig extends Partial> { diff --git a/packages/sdk/src/utils/request.ts b/packages/sdk/src/utils/request.ts index 559c653d..53144fe9 100644 --- a/packages/sdk/src/utils/request.ts +++ b/packages/sdk/src/utils/request.ts @@ -24,7 +24,8 @@ export const request = async ( retries: requestSettings.retries, } ): Promise => { - const { userId, integrator, widgetVersion, apiKey } = config + const { userId, integrator, widgetVersion, apiKey, requestInterceptor } = + config if (!integrator) { throw new SDKError( @@ -71,6 +72,10 @@ export const request = async ( 'x-lifi-integrator': integrator, } + if (requestInterceptor) { + options = await requestInterceptor(options) + } + const response: Response = await fetch( url, stripExtendRequestInitProperties(options) @@ -82,12 +87,10 @@ export const request = async ( return await response.json() } catch (error) { - if (options.retries > 0 && (error as HTTPError).status === 500) { + const retries = options.retries ?? 0 + if (retries > 0 && (error as HTTPError).status === 500) { await sleep(500) - return request(config, url, { - ...options, - retries: options.retries - 1, - }) + return request(config, url, { ...options, retries: retries - 1 }) } await (error as HTTPError).buildAdditionalDetails?.()