From 22e4dbf3299bade2698743544652dba10e133fc6 Mon Sep 17 00:00:00 2001 From: Nathan Richards Date: Tue, 28 May 2024 19:35:44 +0200 Subject: [PATCH] refactor: start on cleaning up of examples --- examples/node/examples/bridge.ts | 14 +--- .../node/examples/klimaRetireExactCarbon.ts | 80 ++++--------------- examples/node/examples/multihop.ts | 64 ++++----------- examples/node/examples/polynomialDeposit.ts | 73 ++++------------- examples/node/examples/swap.ts | 14 +--- .../examples/utils/checkTokenAllowance.ts | 47 +++++++++++ .../utils/transformTxRequestToSendTxParams.ts | 30 +++++++ .../helpers/reportStepsExecutionToTerminal.ts | 13 +++ 8 files changed, 136 insertions(+), 199 deletions(-) create mode 100644 examples/node/examples/utils/checkTokenAllowance.ts create mode 100644 examples/node/examples/utils/transformTxRequestToSendTxParams.ts create mode 100644 examples/node/helpers/reportStepsExecutionToTerminal.ts diff --git a/examples/node/examples/bridge.ts b/examples/node/examples/bridge.ts index 80f773a8..3b4b0212 100644 --- a/examples/node/examples/bridge.ts +++ b/examples/node/examples/bridge.ts @@ -1,5 +1,4 @@ import * as lifiDataTypes from '@lifi/data-types' -import type { RouteExtended, Execution } from '@lifi/sdk' import { executeRoute, getRoutes, @@ -14,6 +13,7 @@ import { privateKeyToAccount } from 'viem/accounts' import { mainnet, arbitrum, optimism, polygon } from 'viem/chains' import 'dotenv/config' import { promptConfirm } from '../helpers/promptConfirm' +import { reportStepsExecutionToTerminal } from '../helpers/reportStepsExecutionToTerminal' const { findDefaultToken } = (lifiDataTypes as any).default @@ -83,17 +83,7 @@ async function run() { // here we are using the update route hook to report the execution steps to the terminal const executionOptions = { - updateRouteHook: (updatedRoute: RouteExtended) => { - const lastExecution = updatedRoute.steps.reduce( - (accum, step) => { - if (step.execution) { - return step.execution - } - }, - undefined as undefined | Execution - ) - console.info(lastExecution) - }, + updateRouteHook: reportStepsExecutionToTerminal, } await executeRoute(route, executionOptions) diff --git a/examples/node/examples/klimaRetireExactCarbon.ts b/examples/node/examples/klimaRetireExactCarbon.ts index 246b38dd..ae16befe 100644 --- a/examples/node/examples/klimaRetireExactCarbon.ts +++ b/examples/node/examples/klimaRetireExactCarbon.ts @@ -7,10 +7,8 @@ import { EVM, getContractCallsQuote, getStatus, - getTokenAllowance, - setTokenAllowance, } from '@lifi/sdk' -import type { Chain, Address, Hash } from 'viem' +import type { Chain, Address } from 'viem' import { parseAbi, encodeFunctionData, @@ -24,7 +22,8 @@ import { mainnet, arbitrum, optimism, polygon } from 'viem/chains' import { privateKeyToAccount } from 'viem/accounts' import 'dotenv/config' import { promptConfirm } from '../helpers/promptConfirm' -import { AddressZero } from './constants' +import { checkTokenAllowance } from './utils/checkTokenAllowance' +import { transformTxRequestToSendTxParams } from './utils/transformTxRequestToSendTxParams' const { findDefaultToken } = (lifiDataTypes as any).default @@ -33,7 +32,6 @@ const run = async () => { try { console.info('>> Initialize LiFi SDK') - const privateKey = process.env.PRIVATE_KEY as Address // NOTE: Here we are using the private key to get the account, @@ -89,7 +87,6 @@ const run = async () => { chain: polygon, transport: http(), }) - const sourceAmountDefaultRetirement = (await publicClient.readContract({ address: KLIMA_ETHEREUM_CONTRACT_POL, abi, @@ -100,14 +97,10 @@ const run = async () => { retireAmount, // uint256 retireAmount, ], })) as bigint - const usdcAmount = parseUnits( sourceAmountDefaultRetirement.toString(), USDCe_POL.decimals ).toString() - - console.log('>> usdcAmount', usdcAmount) - const retireTxData = encodeFunctionData({ abi, functionName: 'retireExactCarbonDefault', @@ -142,7 +135,6 @@ const run = async () => { }, ], } - console.info( '>> create ContractCallsQuoteRequest', contractCallsQuoteRequest @@ -151,74 +143,30 @@ const run = async () => { const contactCallsQuoteResponse = await getContractCallsQuote( contractCallsQuoteRequest ) - console.info('>> Quote received', contactCallsQuoteResponse) if (!(await promptConfirm('Execute Quote?'))) { return } - if (contactCallsQuoteResponse.action.fromToken.address !== AddressZero) { - const approval = await getTokenAllowance( - contactCallsQuoteResponse.action.fromToken, - account.address, - contactCallsQuoteResponse.estimate.approvalAddress - ) - - // set approval if needed - if ( - approval && - approval < BigInt(contactCallsQuoteResponse.action.fromAmount) - ) { - const txHash = await setTokenAllowance({ - walletClient: client, - spenderAddress: contactCallsQuoteResponse.estimate.approvalAddress, - token: contactCallsQuoteResponse.action.fromToken, - amount: BigInt(contactCallsQuoteResponse.action.fromAmount), - }) - - if (txHash) { - const transactionReceipt = await client.waitForTransactionReceipt({ - hash: txHash, - retryCount: 20, - retryDelay: ({ count }: { count: number; error: Error }) => - Math.min(~~(1 << count) * 200, 3000), - }) - - console.info( - `>> Set Token Allowance - transaction complete: amount: ${contactCallsQuoteResponse.action.fromToken} txHash: ${transactionReceipt.transactionHash}.` - ) - } - } - } + await checkTokenAllowance(contactCallsQuoteResponse, account, client) - const transactionRequest = - contactCallsQuoteResponse.transactionRequest || {} - - console.info('>> Execute transaction', transactionRequest) - - const hash = await client.sendTransaction({ - to: transactionRequest.to as Address, - account: client.account!, - data: transactionRequest.data as Hash, - value: transactionRequest.value - ? BigInt(transactionRequest.value) - : undefined, - gas: transactionRequest.gasLimit - ? BigInt(transactionRequest.gasLimit as string) - : undefined, - gasPrice: transactionRequest.gasPrice - ? BigInt(transactionRequest.gasPrice as string) - : undefined, - chain: null, - }) + console.info( + '>> Execute transaction', + contactCallsQuoteResponse.transactionRequest + ) + const hash = await client.sendTransaction( + transformTxRequestToSendTxParams( + client.account, + contactCallsQuoteResponse.transactionRequest + ) + ) console.info('>> Transaction sent', hash) const receipt = await client.waitForTransactionReceipt({ hash, }) - console.info('>> Transaction receipt', receipt) // wait for execution diff --git a/examples/node/examples/multihop.ts b/examples/node/examples/multihop.ts index 9083c487..91bd8211 100644 --- a/examples/node/examples/multihop.ts +++ b/examples/node/examples/multihop.ts @@ -22,6 +22,8 @@ import { privateKeyToAccount } from 'viem/accounts' import { AddressZero } from './constants' import 'dotenv/config' import { promptConfirm } from '../helpers/promptConfirm' +import { checkTokenAllowance } from './utils/checkTokenAllowance' +import { transformTxRequestToSendTxParams } from './utils/transformTxRequestToSendTxParams' const { findDefaultToken } = (lifiDataTypes as any).default @@ -128,60 +130,22 @@ const run = async () => { return } - if (contactCallsQuoteResponse.action.fromToken.address !== AddressZero) { - const approval = await getTokenAllowance( - contactCallsQuoteResponse.action.fromToken, - account.address, - contactCallsQuoteResponse.estimate.approvalAddress - ) - - // set approval if needed - if ( - approval && - approval < BigInt(contactCallsQuoteResponse.action.fromAmount) - ) { - const txHash = await setTokenAllowance({ - walletClient: client, - spenderAddress: contactCallsQuoteResponse.estimate.approvalAddress, - token: contactCallsQuoteResponse.action.fromToken, - amount: BigInt(contactCallsQuoteResponse.action.fromAmount), - }) - - if (txHash) { - const transactionReceipt = await client.waitForTransactionReceipt({ - hash: txHash, - retryCount: 20, - retryDelay: ({ count }: { count: number; error: Error }) => - Math.min(~~(1 << count) * 200, 3000), - }) - - console.info( - `>> Set Token Allowance - transaction complete: amount: ${contactCallsQuoteResponse.action.fromToken} txHash: ${transactionReceipt.transactionHash}.` - ) - } - } - } + await checkTokenAllowance(contactCallsQuoteResponse, account, client) const transactionRequest = contactCallsQuoteResponse.transactionRequest || {} - console.info('>> Execute transaction', transactionRequest) - - const hash = await client.sendTransaction({ - to: transactionRequest.to as Address, - account: client.account!, - value: transactionRequest.value - ? BigInt(transactionRequest.value) - : undefined, - data: transactionRequest.data as Hash, - gas: transactionRequest.gasLimit - ? BigInt(transactionRequest.gasLimit as string) - : undefined, - gasPrice: transactionRequest.gasPrice - ? BigInt(transactionRequest.gasPrice as string) - : undefined, - chain: null, - }) + console.info( + '>> Execute transaction', + contactCallsQuoteResponse.transactionRequest + ) + + const hash = await client.sendTransaction( + transformTxRequestToSendTxParams( + client.account, + contactCallsQuoteResponse.transactionRequest + ) + ) console.info('>> Transaction sent', hash) diff --git a/examples/node/examples/polynomialDeposit.ts b/examples/node/examples/polynomialDeposit.ts index 37c2cfa0..c27e7ce7 100644 --- a/examples/node/examples/polynomialDeposit.ts +++ b/examples/node/examples/polynomialDeposit.ts @@ -5,10 +5,8 @@ import { EVM, getContractCallsQuote, getStatus, - getTokenAllowance, - setTokenAllowance, } from '@lifi/sdk' -import type { Address, Chain, Hash } from 'viem' +import type { Address, Chain } from 'viem' import { createWalletClient, encodeFunctionData, @@ -22,6 +20,8 @@ import { mainnet, arbitrum, optimism, polygon } from 'viem/chains' import 'dotenv/config' import { promptConfirm } from '../helpers/promptConfirm' import { AddressZero } from './constants' +import { checkTokenAllowance } from './utils/checkTokenAllowance' +import { transformTxRequestToSendTxParams } from './utils/transformTxRequestToSendTxParams' const run = async () => { console.info('>> Starting Polynomial Demo: Deposit sETH on Optimism') @@ -99,7 +99,6 @@ const run = async () => { }, ], } - console.info( '>> create contract calls quote request', contractCallsQuoteRequest @@ -108,74 +107,30 @@ const run = async () => { const contactCallsQuoteResponse = await getContractCallsQuote( contractCallsQuoteRequest ) - console.info('>> Contract Calls Quote', contactCallsQuoteResponse) if (!(await promptConfirm('Execute Quote?'))) { return } - if (contactCallsQuoteResponse.action.fromToken.address !== AddressZero) { - const approval = await getTokenAllowance( - contactCallsQuoteResponse.action.fromToken, - account.address, - contactCallsQuoteResponse.estimate.approvalAddress - ) - - // set approval if needed - if ( - approval && - approval < BigInt(contactCallsQuoteResponse.action.fromAmount) - ) { - const txHash = await setTokenAllowance({ - walletClient: client, - spenderAddress: contactCallsQuoteResponse.estimate.approvalAddress, - token: contactCallsQuoteResponse.action.fromToken, - amount: BigInt(contactCallsQuoteResponse.action.fromAmount), - }) - - if (txHash) { - const transactionReceipt = await client.waitForTransactionReceipt({ - hash: txHash, - retryCount: 20, - retryDelay: ({ count }: { count: number; error: Error }) => - Math.min(~~(1 << count) * 200, 3000), - }) - - console.info( - `>> Set Token Allowance - transaction complete: amount: ${contactCallsQuoteResponse.action.fromToken} txHash: ${transactionReceipt.transactionHash}.` - ) - } - } - } + await checkTokenAllowance(contactCallsQuoteResponse, account, client) - const transactionRequest = - contactCallsQuoteResponse.transactionRequest || {} - - console.info('>> Execute transaction', transactionRequest) - - const hash = await client.sendTransaction({ - to: transactionRequest.to as Address, - account: client.account!, - value: transactionRequest.value - ? BigInt(transactionRequest.value as string) - : undefined, - data: transactionRequest.data as Hash, - gas: transactionRequest.gasLimit - ? BigInt(transactionRequest.gasLimit as string) - : undefined, - gasPrice: transactionRequest.gasPrice - ? BigInt(transactionRequest.gasPrice as string) - : undefined, - chain: null, - }) + console.info( + '>> Execute transaction', + contactCallsQuoteResponse.transactionRequest + ) + const hash = await client.sendTransaction( + transformTxRequestToSendTxParams( + client.account, + contactCallsQuoteResponse.transactionRequest + ) + ) console.info('>> Transaction sent', hash) const receipt = await client.waitForTransactionReceipt({ hash, }) - console.info('>> Transaction receipt', receipt) // wait for execution diff --git a/examples/node/examples/swap.ts b/examples/node/examples/swap.ts index d0593859..75a29377 100644 --- a/examples/node/examples/swap.ts +++ b/examples/node/examples/swap.ts @@ -1,5 +1,4 @@ import * as lifiDataTypes from '@lifi/data-types' -import type { RouteExtended, Execution } from '@lifi/sdk' import { createConfig, EVM, @@ -14,6 +13,7 @@ import { privateKeyToAccount } from 'viem/accounts' import { optimism } from 'viem/chains' import { promptConfirm } from '../helpers/promptConfirm' import 'dotenv/config' +import { reportStepsExecutionToTerminal } from '../helpers/reportStepsExecutionToTerminal' const dataTypes = (lifiDataTypes as any).default @@ -74,17 +74,7 @@ async function run() { // here we are using the update route hook to report the execution steps to the terminal const executionOptions = { - updateRouteHook: (updatedRoute: RouteExtended) => { - const lastExecution = updatedRoute.steps.reduce( - (accum, step) => { - if (step.execution) { - return step.execution - } - }, - undefined as undefined | Execution - ) - console.info(lastExecution) - }, + updateRouteHook: reportStepsExecutionToTerminal, } await executeRoute(route, executionOptions) diff --git a/examples/node/examples/utils/checkTokenAllowance.ts b/examples/node/examples/utils/checkTokenAllowance.ts new file mode 100644 index 00000000..cb9c67f4 --- /dev/null +++ b/examples/node/examples/utils/checkTokenAllowance.ts @@ -0,0 +1,47 @@ +import type { LiFiStep } from '@lifi/sdk' +import { getTokenAllowance, setTokenAllowance } from '@lifi/sdk' +import type { PrivateKeyAccount, PublicClient, WalletClient } from 'viem' +import { AddressZero } from '../constants' + +export const checkTokenAllowance = async ( + contactCallsQuoteResponse: LiFiStep, + account: PrivateKeyAccount, + client: WalletClient +) => { + if (contactCallsQuoteResponse.action.fromToken.address !== AddressZero) { + const approval = await getTokenAllowance( + contactCallsQuoteResponse.action.fromToken, + account.address, + contactCallsQuoteResponse.estimate.approvalAddress + ) + + // set approval if needed + if ( + approval && + approval < BigInt(contactCallsQuoteResponse.action.fromAmount) + ) { + const txHash = await setTokenAllowance({ + walletClient: client, + spenderAddress: contactCallsQuoteResponse.estimate.approvalAddress, + token: contactCallsQuoteResponse.action.fromToken, + amount: BigInt(contactCallsQuoteResponse.action.fromAmount), + }) + + if (txHash) { + // client needs to be extended with public actions to have waitForTransactionReceipt function + // there is currently no native type in viem for this so here we use WalletClient & PublicClient + const transactionReceipt = await ( + client as WalletClient & PublicClient + ).waitForTransactionReceipt({ + hash: txHash, + retryCount: 20, + retryDelay: ({ count }: { count: number; error: Error }) => + Math.min(~~(1 << count) * 200, 3000), + }) + console.info( + `>> Set Token Allowance - amount: ${contactCallsQuoteResponse.action.fromToken} txHash: ${transactionReceipt.transactionHash}.` + ) + } + } + } +} diff --git a/examples/node/examples/utils/transformTxRequestToSendTxParams.ts b/examples/node/examples/utils/transformTxRequestToSendTxParams.ts new file mode 100644 index 00000000..298c958f --- /dev/null +++ b/examples/node/examples/utils/transformTxRequestToSendTxParams.ts @@ -0,0 +1,30 @@ +import { TransactionRequest } from '@lifi/sdk' +import { + type Address, + type Hash, + PrivateKeyAccount, + SendTransactionParameters, +} from 'viem' + +export const transformTxRequestToSendTxParams = ( + account: PrivateKeyAccount, + txRequest?: TransactionRequest +): SendTransactionParameters => { + if (!txRequest) { + throw new Error( + 'transformTxRequestToSendTx: A transaction request was not provided' + ) + } + + return { + to: txRequest.to as Address, + account, + data: txRequest.data as Hash, + value: txRequest.value ? BigInt(txRequest.value) : undefined, + gas: txRequest.gasLimit ? BigInt(txRequest.gasLimit as string) : undefined, + gasPrice: txRequest.gasPrice + ? BigInt(txRequest.gasPrice as string) + : undefined, + chain: null, + } +} diff --git a/examples/node/helpers/reportStepsExecutionToTerminal.ts b/examples/node/helpers/reportStepsExecutionToTerminal.ts new file mode 100644 index 00000000..fba5518e --- /dev/null +++ b/examples/node/helpers/reportStepsExecutionToTerminal.ts @@ -0,0 +1,13 @@ +import type { Execution, RouteExtended } from '@lifi/sdk' + +export const reportStepsExecutionToTerminal = (updatedRoute: RouteExtended) => { + const lastExecution = updatedRoute.steps.reduce( + (accum, step) => { + if (step.execution) { + return step.execution + } + }, + undefined as undefined | Execution + ) + console.info(lastExecution) +}