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) =>TransactionPreviewAPI;exporttypeFullPreviewOptions=TransactionPreviewOptions&TransactionPreviewInitOptions;exporttypeTransactionPreviewAPI={/** * 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:string;params?: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=string;exporttypei18nOptions=Record<Locale,i18n>;exporttypei18n=typeof en;exporttypeDeviceNotBrowser={type:null;os:null;browser:null;};exporttypeTransactionForSim=SimulationTransaction&{data?:string;};exportinterfaceSimulationTransaction{from:string;to:string;value:number;gas:number;input:string;// Either Type 1 Gas (gasPrice) or Type 2 Gas (maxPriorityFeePerGas & maxFeePerGas)// must be included in the payloadgasPrice?:number;maxPriorityFeePerGas?:number;maxFeePerGas?:number;}exporttypeMultiSimOutput={id?:string;contractCall:ContractCall[];error?:any;gasUsed:number[];internalTransactions:InternalTransaction[][];netBalanceChanges:NetBalanceChange[][];network:Network;simDetails:SimDetails;serverVersion:string;system:System;status:Status;simulatedBlockNumber:number;transactions:InternalTransaction[];};exportinterfaceContractCall{contractType?:string;contractAddress?:string;contractAlias?:string;methodName:string;params:Record<string,unknown>;contractName?:string;contractDecimals?:number;decimalValue?:string;}exportinterfaceInternalTransaction{type:string;from:string;to:string;input:string;gas:number;gasUsed:number;value:string;contractCall:ContractCall;error?:string;errorReason?:string;}exportinterfaceNetBalanceChange{address:string;balanceChanges:BalanceChange[];}exportinterfaceBalanceChange{delta:string;asset:Asset;breakdown:BreakDown[];}exportinterfaceAsset{type:string;symbol:string;contractAddress:string;}exportinterfaceBreakDown{counterparty:string;amount:string;}exportinterfaceInternalTransaction{type:string;from:string;to:string;input:string;gas:number;gasUsed:number;value:string;contractCall: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:number;e2eMs:number;performanceProfile:any;}