To use the Transaction Preview package with web3-onboard all a developer needs to do is initialize web3-onboard with their
Blocknative API key and pass in the module as shown below.
ts
Copied
Copy
import Onboard from'@web3-onboard/core'import injectedModule from'@web3-onboard/injected'import transactionPreviewModule from'@web3-onboard/transaction-preview'const injected =injectedModule()const transactionPreview =transactionPreviewModule(// Optional initialization object// {// Optional: Require balance change approval prior to sending transaction to wallet// Defaults to true// requireTransactionApproval?: false// i18n?: i18nOptions - Internationalization options// })const onboard =Onboard({ transactionPreview,apiKey:'xxx387fb-bxx1-4xxc-a0x3-9d37e426xxxx' wallets: [injected],chains: [{id:'0x1',token:'ETH',label:'Ethereum',rpcUrl:'https://mainnet.infura.io/v3/17c1e1500e384acfb6a72c5d2e67742e'} ]// ... other Onboard options})// Transaction code here using Ether.js or Web3.js or custom// The transaction will automatically be picked up and simulated with a UI displaying in the upper right corner
To use the Transaction Preview package without web3-onboard all a developer needs to do is:
Execute the entry function from the @web3-onboard/transaction-preview package and optional params
Run the returned init function with their
Blocknative API key, an initialized instance of their
Blocknative SDK and a containerElement string with the html ID of the target element to append the visualization to
Finally pass a transaction meant for a wallet provider (created using libraries like Ethers or Web3)
With the above steps a UI will be rendered with the balance changes and gas used.
ts
Copied
Copy
import transactionPreviewModule from'@web3-onboard/transaction-preview'const{init, previewTransaction}=transactionPreviewModule({// Optional: Require balance change approval prior to sending transaction to wallet// Defaults to true// requireTransactionApproval?: false// i18n?: i18nOptions - Internationalization options})awaitinit({/** * Blocknative API key (https://explorer.blocknative.com/account) */apiKey: string/** * Your Blocknative SDK instance * */sdk: SDK/** * Optional dom query string to mount UI to * */containerElement: string})// Transaction code here using Ether.js or Web3.js or construct your own transactionsconst simulate =asyncprovider=>{// if using ethers v6 this is:// ethersProvider = new ethers.BrowserProvider(wallet.provider, 'any')constethersProvider=newethers.providers.Web3Provider(provider,'any')constsigner=ethersProvider.getSigner()constaddressFrom='0xcxxxxxx11111999991111'// Uniswap V2constCONTRACT_ADDRESS='0x7a250d5630b4cf539739df2c5dacb4c659f2488d'consterc20_interface= ['function approve(address _spender, uint256 _value) public returns (bool success)','function transferFrom(address sender, address recipient, uint256 amount) external returns (bool)','function balanceOf(address owner) view returns (uint256)' ]constuniswapV2router_interface= ['function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)' ]constweth='0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'constoneInch='0x111111111117dc0aa78b770fa6a738034120c302'letswapTxDataletapproveTxDataconstswapContract=newethers.Contract(CONTRACT_ADDRESS,uniswapV2router_interface )consterc20_contract=newethers.Contract(oneInch,erc20_interface)constoneEther=ethers.BigNumber.from('9000000000000000000')approveTxData=awaiterc20_contract.populateTransaction.approve(CONTRACT_ADDRESS,oneEther )constamountOutMin=0constamountOutMinHex=ethers.BigNumber.from(amountOutMin).toHexString()constpath= [oneInch,weth]constdeadline=Math.floor(Date.now() /1000) +60*1// 1 minutes from the current Unix timeconstinputAmountHex=oneEther.toHexString()swapTxData=awaitswapContract.populateTransaction.swapExactTokensForETH(inputAmountHex,amountOutMinHex,path,addressFrom,deadline )constuniswapV2Router='0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'constpopApproveTransaction=awaitsigner.populateTransaction(approveTxData)constpopTransaction=awaitsigner.populateTransaction(swapTxData)consttransactions= [{...popApprovedTransaction, value:0},{...popTransaction, from:addressFrom, to:uniswapV2Router, value:0} ]awaitpreviewTransaction(transactions)}returnawaitpreviewTransaction(transactions)}const simData =simulate(ethereumProvider)console.log(simData)
exporttypeTransactionPreviewModule=(options:TransactionPreviewOptions)=>TransactionPreviewAPIexporttypeFullPreviewOptions=TransactionPreviewOptions&TransactionPreviewInitOptionsexporttypeTransactionPreviewAPI={/** * This Method accepts a standard EIP1193 provider * (such as an injected wallet from window.ethereum) * and it will be patched to allow for transaction previewing */patchProvider:(provider:PatchedEIP1193Provider)=>PatchedEIP1193Provider/** * This Method accepts: * apiKey: string - Blocknative API key (https://explorer.blocknative.com/) * sdk: instance of an initialized bnc-sdk (www.npmjs.com/package/bnc-sdk) * containerElement: string of an html id selector (e.g. "#my-html-el") */init:(initializationOptions:TransactionPreviewInitOptions)=>void/** * This method accepts a transaction meant for a wallet provider * (created using libraries like Ethers or Web3), * simulates the transaction and generates a corresponding UI and * return a response from the Blocknative Transaction Preview API. * Note: the package will need to initialized with the `init` * function prior to usage */previewTransaction:(transaction:TransactionForSim[])=>Promise<MultiSimOutput>}exporttypePatchedEIP1193Provider=EIP1193Provider&{simPatched:boolean}exportinterfaceProviderReq{method:stringparams?:Array<unknown>}exporttypeRequestOptions=Pick<TransactionPreviewInitOptions,'apiKey'>exporttypeTransactionPreviewInitOptions={/** * Blocknative API key (https://explorer.blocknative.com/account) */apiKey:string/** * Your Blocknative SDK instance (https://www.npmjs.com/package/bnc-sdk) * */sdk:SDK/** * Optional dom query string to mount UI to * */containerElement:string}exporttypeTransactionPreviewOptions={/** * Optional requirement for user to accept transaction balance changes * prior to sending the transaction to the wallet * Defaults to true * */requireTransactionApproval?:boolean/** * An optional internationalization object that defines the display * text for different locales. Can also be used to override the default text. * To override the default text, pass in a object for the en locale */i18n?:i18nOptions}exporttypeLocale=stringexporttypei18nOptions=Record<Locale,i18n>exporttypei18n=typeof enexporttypeDeviceNotBrowser={type:nullos:nullbrowser:null}exporttypeTransactionForSim=SimulationTransaction&{data?:string}exportinterfaceSimulationTransaction{from:stringto:stringvalue:numbergas:numberinput:string// Either Type 1 Gas (gasPrice) or Type 2 Gas (maxPriorityFeePerGas & maxFeePerGas)// must be included in the payloadgasPrice?:numbermaxPriorityFeePerGas?:numbermaxFeePerGas?:number}exporttypeMultiSimOutput={id?:stringcontractCall:ContractCall[]error?:anygasUsed:number[]internalTransactions:InternalTransaction[][]netBalanceChanges:NetBalanceChange[][]network:NetworksimDetails:SimDetailsserverVersion:stringsystem:Systemstatus:StatussimulatedBlockNumber:numbertransactions:InternalTransaction[]}exportinterfaceContractCall{contractType?:stringcontractAddress?:stringcontractAlias?:stringmethodName:stringparams:Record<string,unknown>contractName?:stringcontractDecimals?:numberdecimalValue?:string}exportinterfaceInternalTransaction{type:stringfrom:stringto:stringinput:stringgas:numbergasUsed:numbervalue:stringcontractCall:ContractCallerror?:stringerrorReason?:string}exportinterfaceNetBalanceChange{address:stringbalanceChanges:BalanceChange[]}exportinterfaceBalanceChange{delta:stringasset:Assetbreakdown:BreakDown[]}exportinterfaceAsset{type:stringsymbol:stringcontractAddress:string}exportinterfaceBreakDown{counterparty:stringamount:string}exportinterfaceInternalTransaction{type:stringfrom:stringto:stringinput:stringgas:numbergasUsed:numbervalue:stringcontractCall:ContractCall}exporttypeSystem='bitcoin'|'ethereum'exporttypeNetwork=|'main'|'testnet'|'ropsten'|'rinkeby'|'goerli'|'kovan'|'xdai'|'bsc-main'|'matic-main'|'fantom-main'|'matic-mumbai'|'local'exporttypeStatus=|'pending'|'confirmed'|'speedup'|'cancel'|'failed'|'dropped'|'simulated'exportinterfaceSimDetails{blockNumber:numbere2eMs:numberperformanceProfile:any}