Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/providers/evm/privyAlchemyEvmProviderAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
toHex,
TypedDataDefinition,
type Address,
type Call,
type Chain,
type Hex,
type Log,
Expand All @@ -24,6 +23,7 @@ import {
} from "viem/actions";
import { createEvmNetworkContext, EVM_MAINNET_CHAINS } from "../../core/chains.js";
import type {
EvmCall,
GetLogsParams,
IEvmProviderAdapter,
ReadContractParams,
Expand Down Expand Up @@ -451,20 +451,25 @@ export class PrivyAlchemyEvmProviderAdapter implements IEvmProviderAdapter {
return `0x${hex}`;
}

async sendTransaction(chainId: number, call: Call): Promise<Address> {
async sendTransaction(chainId: number, call: EvmCall): Promise<Address> {
const { walletClient } = this.getClients(chainId);
return walletClient.sendTransaction({
account: walletClient.account!,
chain: walletClient.chain,
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<Address | Address[]> {
const { smartWalletClient } = this.getClients(chainId);
const suffix = this.builderCodeSuffix;
Expand All @@ -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: {
Expand Down
7 changes: 4 additions & 3 deletions src/providers/evm/viemProviderAdapter.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -26,11 +27,11 @@ export class ViemProviderAdapter implements IEvmProviderAdapter {
return createEvmNetworkContext(chainId);
}

async sendTransaction(_chainId: number, _call: Call): Promise<Address> {
async sendTransaction(_chainId: number, _call: EvmCall): Promise<Address> {
throw new Error("sendTransaction() not implemented. Override in subclass.");
}

async sendCalls(_chainId: number, _calls: Call[]): Promise<Address | Address[]> {
async sendCalls(_chainId: number, _calls: EvmCall[]): Promise<Address | Address[]> {
throw new Error("sendCalls() not implemented. Override in subclass.");
}

Expand Down
17 changes: 15 additions & 2 deletions src/providers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<unknown, { gas?: bigint }>;

export type SolanaInstructionLike = {
programId: string;
keys: Array<{ pubkey: string; isSigner: boolean; isWritable: boolean }>;
Expand Down Expand Up @@ -31,8 +44,8 @@ export type GetLogsParams = {

export interface IEvmProviderAdapter extends IProviderAdapter {
getAddress(): Promise<Address>;
sendTransaction(chainId: number, call: Call): Promise<Address>;
sendCalls(chainId: number, calls: Call[]): Promise<Address | Address[]>;
sendTransaction(chainId: number, call: EvmCall): Promise<Address>;
sendCalls(chainId: number, calls: EvmCall[]): Promise<Address | Address[]>;
getTransactionReceipt(
chainId: number,
hash: Address
Expand Down