diff --git a/src/providers/evm/privyAlchemyEvmProviderAdapter.ts b/src/providers/evm/privyAlchemyEvmProviderAdapter.ts index 440b780..d494c5d 100644 --- a/src/providers/evm/privyAlchemyEvmProviderAdapter.ts +++ b/src/providers/evm/privyAlchemyEvmProviderAdapter.ts @@ -7,7 +7,6 @@ import { toHex, TypedDataDefinition, type Address, - type Call, type Chain, type Hex, type Log, @@ -24,6 +23,7 @@ import { } from "viem/actions"; import { createEvmNetworkContext, EVM_MAINNET_CHAINS } from "../../core/chains.js"; import type { + EvmCall, GetLogsParams, IEvmProviderAdapter, ReadContractParams, @@ -451,7 +451,7 @@ export class PrivyAlchemyEvmProviderAdapter implements IEvmProviderAdapter { return `0x${hex}`; } - async sendTransaction(chainId: number, call: Call): Promise
{ + async sendTransaction(chainId: number, call: EvmCall): Promise { const { walletClient } = this.getClients(chainId); return walletClient.sendTransaction({ account: walletClient.account!, @@ -459,12 +459,17 @@ export class PrivyAlchemyEvmProviderAdapter implements IEvmProviderAdapter { to: call.to, data: call.data, value: call.value, + // Forward an explicit gas limit when the caller supplies one. + // Avoids the bundler's default estimate running too tight on + // complex routes (e.g. LiFi multi-hop with FeeCollector + + // DEX legs), which we've seen revert at ~95% gas utilization. + ...(call.gas !== undefined ? { gas: call.gas } : {}), }); } async sendCalls( chainId: number, - _calls: Call[] + _calls: EvmCall[] ): Promise { const { smartWalletClient } = this.getClients(chainId); const suffix = this.builderCodeSuffix; @@ -477,6 +482,10 @@ export class PrivyAlchemyEvmProviderAdapter implements IEvmProviderAdapter { ? appendBuilderCodeData(call.data ?? "0x", suffix) : call.data ?? "0x", ...(value !== 0n ? { value } : {}), + // Per-call gas hint, forwarded to the bundler so it doesn't + // underestimate. Best-effort: if the smart wallet client + // ignores the field, behavior is unchanged. + ...(call.gas !== undefined ? { gas: call.gas } : {}), }; }), capabilities: { diff --git a/src/providers/evm/viemProviderAdapter.ts b/src/providers/evm/viemProviderAdapter.ts index db52e04..0ef55ee 100644 --- a/src/providers/evm/viemProviderAdapter.ts +++ b/src/providers/evm/viemProviderAdapter.ts @@ -1,7 +1,8 @@ -import type { Address, Call, Log, TransactionReceipt } from "viem"; +import type { Address, Log, TransactionReceipt } from "viem"; import { createEvmNetworkContext } from "../../core/chains.js"; import type { + EvmCall, GetLogsParams, IEvmProviderAdapter, ReadContractParams, @@ -26,11 +27,11 @@ export class ViemProviderAdapter implements IEvmProviderAdapter { return createEvmNetworkContext(chainId); } - async sendTransaction(_chainId: number, _call: Call): Promise { + async sendTransaction(_chainId: number, _call: EvmCall): Promise { throw new Error("sendTransaction() not implemented. Override in subclass."); } - async sendCalls(_chainId: number, _calls: Call[]): Promise { + async sendCalls(_chainId: number, _calls: EvmCall[]): Promise { throw new Error("sendCalls() not implemented. Override in subclass."); } diff --git a/src/providers/types.ts b/src/providers/types.ts index cba4c49..0d54842 100644 --- a/src/providers/types.ts +++ b/src/providers/types.ts @@ -2,6 +2,19 @@ import type { Address, Call, Log, TransactionReceipt } from "viem"; import type { NetworkContext, SolanaCluster } from "../core/chains.js"; +/** + * Call shape accepted by sendTransaction / sendCalls. Extends viem's Call + * with an optional `gas` field so callers can override the wallet's + * gas-limit estimate (useful when an aggregator like LiFi already + * supplies a padded recommended gas limit and the bundler's default + * estimate runs too tight). + * + * Pass-through is best-effort: implementations forward `gas` to the + * underlying viem/Alchemy client. If a particular backend ignores it, + * the bundler falls back to its own estimate (current behaviour). + */ +export type EvmCall = Call