Skip to content

Commit

Permalink
feat: replace wallet and public clients with base client (#215)
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov authored Aug 22, 2024
1 parent 41c8d1e commit 76122c6
Show file tree
Hide file tree
Showing 18 changed files with 158 additions and 176 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lifi/sdk",
"version": "3.1.5",
"version": "3.2.0-alpha.1",
"description": "LI.FI Any-to-Any Cross-Chain-Swap SDK",
"keywords": [
"bridge",
Expand Down
4 changes: 2 additions & 2 deletions src/core/EVM/EVM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export function EVM(options?: EVMProviderOptions): EVMProvider {
options: StepExecutorOptions
): Promise<EVMStepExecutor> {
if (!_options.getWalletClient) {
throw new Error(`getWalletClient is not provided.`)
throw new Error(`Client is not provided.`)
}

const walletClient = await _options.getWalletClient()

const executor = new EVMStepExecutor({
walletClient,
client: walletClient,
multisig: _options.multisig,
routeId: options.routeId,
executionOptions: {
Expand Down
79 changes: 33 additions & 46 deletions src/core/EVM/EVMStepExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ import type {
FullStatusData,
Process,
} from '@lifi/types'
import type {
Hash,
PublicClient,
SendTransactionParameters,
WalletClient,
} from 'viem'
import { publicActions } from 'viem'
import type { Client, Hash, SendTransactionParameters } from 'viem'
import { getAddresses, sendTransaction } from 'viem/actions'
import { config } from '../../config.js'
import { LiFiErrorCode } from '../../errors/constants.js'
import { TransactionError, ValidationError } from '../../errors/errors.js'
Expand Down Expand Up @@ -37,40 +32,40 @@ import { getMaxPriorityFeePerGas } from './utils.js'
import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'

export interface EVMStepExecutorOptions extends StepExecutorOptions {
walletClient: WalletClient
client: Client
multisig?: MultisigConfig
}

export class EVMStepExecutor extends BaseStepExecutor {
private walletClient: WalletClient
private client: Client
private multisig?: MultisigConfig

constructor(options: EVMStepExecutorOptions) {
super(options)
this.walletClient = options.walletClient
this.client = options.client
this.multisig = options.multisig
}

// Ensure that we are using the right chain and wallet when executing transactions.
checkWalletClient = async (
checkClient = async (
step: LiFiStepExtended,
process?: Process
): Promise<WalletClient | undefined> => {
const updatedWalletClient = await switchChain(
this.walletClient,
): Promise<Client | undefined> => {
const updatedClient = await switchChain(
this.client,
this.statusManager,
step,
this.allowUserInteraction,
this.executionOptions?.switchChainHook
)
if (updatedWalletClient) {
this.walletClient = updatedWalletClient
if (updatedClient) {
this.client = updatedClient
}

// Prevent execution of the quote by wallet different from the one which requested the quote
let accountAddress = this.walletClient.account?.address
let accountAddress = this.client.account?.address
if (!accountAddress) {
const accountAddresses = await this.walletClient.getAddresses()
const accountAddresses = await getAddresses(this.client)
accountAddress = accountAddresses?.[0]
}
if (accountAddress !== step.action.fromAddress) {
Expand Down Expand Up @@ -100,7 +95,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
process
)
}
return updatedWalletClient
return updatedClient
}

executeStep = async (step: LiFiStepExtended): Promise<LiFiStepExtended> => {
Expand All @@ -116,13 +111,13 @@ export class EVMStepExecutor extends BaseStepExecutor {
// All changes are already done from the source chain
// Return the step
if (recievingChainProcess?.substatus !== 'WAIT_DESTINATION_TRANSACTION') {
const updatedWalletClient = await this.checkWalletClient(step)
if (!updatedWalletClient) {
const updatedClient = await this.checkClient(step)
if (!updatedClient) {
return step
}
}

const isMultisigWalletClient = !!this.multisig?.isMultisigWalletClient
const isMultisigClient = !!this.multisig?.isMultisigClient
const multisigBatchTransactions: MultisigTransaction[] = []

const shouldBatchTransactions =
Expand All @@ -144,13 +139,13 @@ export class EVMStepExecutor extends BaseStepExecutor {
const checkForAllowance =
!existingProcess?.txHash &&
!isZeroAddress(step.action.fromToken.address) &&
(shouldBatchTransactions || !isMultisigWalletClient)
(shouldBatchTransactions || !isMultisigClient)

if (checkForAllowance) {
const data = await checkAllowance(
this.client,
fromChain,
step,
this.walletClient,
this.statusManager,
this.executionOptions,
this.allowUserInteraction,
Expand Down Expand Up @@ -180,7 +175,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
)

try {
if (isMultisigWalletClient && multisigProcess) {
if (isMultisigClient && multisigProcess) {
const multisigTxHash = multisigProcess.multisigTxHash as Hash
if (!multisigTxHash) {
throw new ValidationError(
Expand All @@ -200,11 +195,8 @@ export class EVMStepExecutor extends BaseStepExecutor {
let txHash: Hash
if (process.txHash) {
// Make sure that the chain is still correct
const updatedWalletClient = await this.checkWalletClient(
step,
process
)
if (!updatedWalletClient) {
const updatedClient = await this.checkClient(step, process)
if (!updatedClient) {
return step
}

Expand All @@ -218,7 +210,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
)

// Check balance
await checkBalance(this.walletClient.account!.address, step)
await checkBalance(this.client.account!.address, step)

// Create new transaction
if (!step.transactionRequest) {
Expand Down Expand Up @@ -246,11 +238,8 @@ export class EVMStepExecutor extends BaseStepExecutor {

// STEP 3: Send the transaction
// Make sure that the chain is still correct
const updatedWalletClient = await this.checkWalletClient(
step,
process
)
if (!updatedWalletClient) {
const updatedClient = await this.checkClient(step, process)
if (!updatedClient) {
return step
}

Expand Down Expand Up @@ -281,10 +270,8 @@ export class EVMStepExecutor extends BaseStepExecutor {
// ? BigInt(step.transactionRequest.maxFeePerGas as string)
// : undefined,
maxPriorityFeePerGas:
this.walletClient.account?.type === 'local'
? await getMaxPriorityFeePerGas(
this.walletClient.extend(publicActions) as PublicClient
)
this.client.account?.type === 'local'
? await getMaxPriorityFeePerGas(this.client)
: step.transactionRequest.maxPriorityFeePerGas
? BigInt(step.transactionRequest.maxPriorityFeePerGas)
: undefined,
Expand Down Expand Up @@ -322,9 +309,9 @@ export class EVMStepExecutor extends BaseStepExecutor {
)
}
} else {
txHash = await this.walletClient.sendTransaction({
txHash = await sendTransaction(this.client, {
to: transactionRequest.to,
account: this.walletClient.account!,
account: this.client.account!,
data: transactionRequest.data,
value: transactionRequest.value,
gas: transactionRequest.gas,
Expand All @@ -336,7 +323,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
}

// STEP 4: Wait for the transaction
if (isMultisigWalletClient) {
if (isMultisigClient) {
process = this.statusManager.updateProcess(
step,
process.type,
Expand All @@ -359,7 +346,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
}

const transactionReceipt = await waitForTransactionReceipt({
walletClient: this.walletClient,
client: this.client,
chainId: fromChain.id,
txHash,
onReplaced: (response) => {
Expand All @@ -372,7 +359,7 @@ export class EVMStepExecutor extends BaseStepExecutor {

// if it's multisig wallet client and the process is in ACTION_REQUIRED
// then signatures are still needed
if (isMultisigWalletClient && process.status === 'ACTION_REQUIRED') {
if (isMultisigClient && process.status === 'ACTION_REQUIRED') {
await updateMultisigRouteProcess(
transactionReceipt?.transactionHash || txHash,
step,
Expand All @@ -386,7 +373,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
// Update pending process if the transaction hash from the receipt is different.
// This might happen if the transaction was replaced.
if (
!isMultisigWalletClient &&
!isMultisigClient &&
transactionReceipt?.transactionHash &&
transactionReceipt.transactionHash !== txHash
) {
Expand Down
18 changes: 9 additions & 9 deletions src/core/EVM/checkAllowance.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Chain, LiFiStep, Process, ProcessType } from '@lifi/types'
import type { Address, Hash, WalletClient } from 'viem'
import type { Address, Client, Hash } from 'viem'
import type { StatusManager } from '../StatusManager.js'
import type { ExecutionOptions } from '../types.js'
import { getAllowance } from './getAllowance.js'
Expand All @@ -8,9 +8,9 @@ import { setAllowance } from './setAllowance.js'
import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'

export const checkAllowance = async (
client: Client,
chain: Chain,
step: LiFiStep,
walletClient: WalletClient,
statusManager: StatusManager,
settings?: ExecutionOptions,
allowUserInteraction = false,
Expand All @@ -26,7 +26,7 @@ export const checkAllowance = async (
try {
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
await waitForApprovalTransaction(
walletClient,
client,
allowanceProcess.txHash! as Address,
allowanceProcess.type,
step,
Expand All @@ -43,7 +43,7 @@ export const checkAllowance = async (
const approved = await getAllowance(
chain.id,
step.action.fromToken.address,
walletClient.account!.address,
client.account!.address,
step.estimate.approvalAddress
)

Expand All @@ -56,7 +56,7 @@ export const checkAllowance = async (

if (shouldBatchTransactions) {
const approveTxHash = await setAllowance(
walletClient,
client,
step.action.fromToken.address,
step.estimate.approvalAddress,
fromAmount,
Expand All @@ -74,13 +74,13 @@ export const checkAllowance = async (
}

const approveTxHash = await setAllowance(
walletClient,
client,
step.action.fromToken.address,
step.estimate.approvalAddress,
fromAmount
)
await waitForApprovalTransaction(
walletClient,
client,
approveTxHash,
allowanceProcess.type,
step,
Expand Down Expand Up @@ -114,7 +114,7 @@ export const checkAllowance = async (
}

const waitForApprovalTransaction = async (
walletClient: WalletClient,
client: Client,
txHash: Hash,
processType: ProcessType,
step: LiFiStep,
Expand All @@ -127,7 +127,7 @@ const waitForApprovalTransaction = async (
})

const transactionReceipt = await waitForTransactionReceipt({
walletClient,
client: client,
chainId: chain.id,
txHash: txHash,
onReplaced(response) {
Expand Down
20 changes: 8 additions & 12 deletions src/core/EVM/getAllowance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { BaseToken, ChainId } from '@lifi/types'
import type { Address } from 'viem'
import { getContract } from 'viem'
import { multicall, readContract } from 'viem/actions'
import { isNativeTokenAddress } from '../../utils/utils.js'
import { allowanceAbi } from './abi.js'
import { getPublicClient } from './publicClient.js'
Expand All @@ -18,17 +18,13 @@ export const getAllowance = async (
spenderAddress: string
): Promise<bigint> => {
const client = await getPublicClient(chainId)
const contract = getContract({
address: tokenAddress as Address,
abi: allowanceAbi,
client: client,
})

try {
const approved = (await contract.read.allowance([
ownerAddress,
spenderAddress,
])) as bigint
const approved = (await readContract(client, {
address: tokenAddress as Address,
abi: allowanceAbi,
functionName: 'allowance',
args: [ownerAddress, spenderAddress],
})) as bigint
return approved
} catch (e) {
return 0n
Expand Down Expand Up @@ -57,7 +53,7 @@ export const getAllowanceMulticall = async (
args: [ownerAddress, token.spenderAddress],
}))

const results = await client.multicall({
const results = await multicall(client, {
contracts,
multicallAddress: multicallAddress as Address,
})
Expand Down
4 changes: 2 additions & 2 deletions src/core/EVM/getENSAddress.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ChainId } from '@lifi/types'
import { normalize } from 'viem/ens'
import { getEnsAddress, normalize } from 'viem/ens'
import { getPublicClient } from './publicClient.js'

export const getENSAddress = async (
name: string
): Promise<string | undefined> => {
try {
const client = await getPublicClient(ChainId.ETH)
const address = await client.getEnsAddress({
const address = await getEnsAddress(client, {
name: normalize(name),
})
return address as string | undefined
Expand Down
Loading

0 comments on commit 76122c6

Please sign in to comment.