Skip to content

Commit

Permalink
Merge pull request #1523 from blocknative/release/2.20.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamj1232 authored Feb 11, 2023
2 parents c441386 + c3e50bf commit f5dde45
Show file tree
Hide file tree
Showing 59 changed files with 6,462 additions and 1,984 deletions.
18 changes: 18 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,12 @@ jobs:
working_directory: ~/web3-onboard-monorepo/packages/phantom
steps:
- node-build-steps
build-xdefi:
docker:
- image: cimg/node:16.13.1
working_directory: ~/web3-onboard-monorepo/packages/xdefi
steps:
- node-build-steps

# Build staging/Alpha releases
build-staging-core:
Expand Down Expand Up @@ -551,6 +557,12 @@ jobs:
working_directory: ~/web3-onboard-monorepo/packages/phantom
steps:
- node-staging-build-steps
build-staging-xdefi:
docker:
- image: cimg/node:16.13.1
working_directory: ~/web3-onboard-monorepo/packages/xdefi
steps:
- node-staging-build-steps

workflows:
version: 2
Expand Down Expand Up @@ -747,3 +759,9 @@ workflows:
<<: *deploy_production_filters
- build-staging-phantom:
<<: *deploy_staging_filters
xdefi:
jobs:
- build-xdefi:
<<: *deploy_production_filters
- build-staging-xdefi:
<<: *deploy_staging_filters
Binary file added assets/transaction-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/src/lib/assets/transaction-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 22 additions & 8 deletions docs/src/lib/components/ThemeCustomizer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
let wallets$
const themes = ['system', 'default', 'light', 'dark', 'custom']
let selectedTheme = 'custom'
let selectedTheme = 'system'
let webURL = ''
let iframeUsed = false
Expand All @@ -30,13 +30,23 @@
const addURLToIFrame = () => {
if (!webURL || !isValidUrl(webURL)) {
alert('Invaled URL entered')
alert('Invalid URL entered')
return
}
iframeUsed = true
document.querySelector('#iframe_underlay').setAttribute('src', webURL)
hideDirections = true
onboard.connectWallet()
fetch(webURL)
.then(() => {
iframeUsed = true
document.querySelector('#iframe_underlay').setAttribute('src', webURL)
hideDirections = true
!onboard && getOnboard()
onboard.connectWallet()
})
.catch(() => {
alert(
'The website entered cannot be displayed within an iframe. Please try a different URL. See the browser console for more information.'
)
})
}
const resetPage = () => {
Expand All @@ -47,6 +57,10 @@
uploaded_image = undefined
webURL = ''
resetTheme()
closeOnboard()
}
const closeOnboard = () => {
const onboardCloseBtnVisible = document
?.querySelector('body > onboard-v2')
?.shadowRoot?.querySelector('.close-button')
Expand Down Expand Up @@ -266,9 +280,9 @@
placeholder="Enter your Website URL"
bind:value={webURL}
/>
<button on:click={addURLToIFrame}>Preview On Your Website</button>
<button type="submit">Preview On Your Website</button>
<button
on:click={resetPage}
on:click={() => resetPage()}
type="button"
disabled={iframeUsed || !!uploaded_image ? false : true}>Reset</button
>
Expand Down
51 changes: 20 additions & 31 deletions docs/src/routes/docs/[...3]modules/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ type ConnectModalOptions = {
* Defaults to false
*/
disableClose?: boolean
/**If set to true, the last connected wallet will store in local storage.
* Then on init, onboard will try to reconnect to that wallet with
* no modals displayed
*/
autoConnectLastWallet?: boolean // defaults to false
}
```
Expand Down Expand Up @@ -482,40 +487,16 @@ connectWallet()

### Auto Selecting a Wallet

A common UX pattern is to remember the wallet(s) that a user has previously connected by storing them in localStorage and then automatically selecting them for the user next time they visit your app.
You could enable this in your app by first syncing the `wallets` array to localStorage:
A common UX pattern is to remember the last wallet that a user has previously connected by storing it in localStorage and then automatically selecting them for the user next time they visit your app.
You can enable this in your app by using the `autoConnectLastWallet` parameter when initializing and Onboard will take care of it:

```javascript
const walletsSub = onboard.state.select('wallets')
const { unsubscribe } = walletsSub.subscribe((wallets) => {
const connectedWallets = wallets.map(({ label }) => label)
window.localStorage.setItem('connectedWallets', JSON.stringify(connectedWallets))
const onboard = Onboard({
// ... other options
connect: {
autoConnectLastWallet: true
}
})

// Don't forget to unsubscribe when your app or component un mounts to prevent memory leaks
// unsubscribe()
```

Now that you have the most recent wallets connected saved in local storage, you can auto select those wallet(s) when your app loads:

```javascript
const previouslyConnectedWallets = JSON.parse(window.localStorage.getItem('connectedWallets'))

if (previouslyConnectedWallets) {
// Connect the most recently connected wallet (first in the array)
await onboard.connectWallet({ autoSelect: previouslyConnectedWallets[0] })

// You can also auto connect "silently" and disable all onboard modals to avoid them flashing on page load
await onboard.connectWallet({
autoSelect: { label: previouslyConnectedWallets[0], disableModals: true }
})

// OR - loop through and initiate connection for all previously connected wallets
// note: This UX might not be great as the user may need to login to each wallet one after the other
// for (walletLabel in previouslyConnectedWallets) {
// await onboard.connectWallet({ autoSelect: walletLabel })
// }
}
```

## Disconnecting a Wallet
Expand Down Expand Up @@ -1318,3 +1299,11 @@ build: {
standalone: true,
}
```

### Next.js

:::admonition type=note

If you are seeing an error during builds when dynamically importing Web3Onboard in a NextJS v13 project, try upgrading to to the Canary beta release of NextJS where this issue is fixed.

:::
137 changes: 131 additions & 6 deletions docs/src/routes/docs/[...3]modules/transaction-preview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<script>
import previewGif from '$lib/assets/transaction-preview.gif'
import previewImg from '$lib/assets/transaction-preview.png'
Expand Down Expand Up @@ -73,24 +72,146 @@ const onboard = Onboard({
// The transaction will automatically be picked up and simulated with a UI displaying in the upper right corner
```

### Standalone Usage


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](https://onboard.blocknative.com/docs/overview/introduction#optional-use-an-api-key-to-fetch-real-time-transaction-data-balances-gas), an initialized instance of their [Blocknative SDK](https://www.npmjs.com/package/bnc-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.
```typescript
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
})
await init({
/**
* 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 transactions
const simulate = async provider => {
const ethersProvider = new ethers.providers.Web3Provider(provider, 'any')

const signer = ethersProvider.getSigner()
const addressFrom = '0xcxxxxxx11111999991111'

// Uniswap V2
const CONTRACT_ADDRESS = '0x7a250d5630b4cf539739df2c5dacb4c659f2488d'
const erc20_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)'
]

const uniswapV2router_interface = [
'function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'
]

const weth = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
const oneInch = '0x111111111117dc0aa78b770fa6a738034120c302'
let swapTxData
let approveTxData
const swapContract = new ethers.Contract(
CONTRACT_ADDRESS,
uniswapV2router_interface
)
const erc20_contract = new ethers.Contract(oneInch, erc20_interface)
const oneEther = ethers.BigNumber.from('9000000000000000000')
approveTxData = await erc20_contract.populateTransaction.approve(
CONTRACT_ADDRESS,
oneEther
)

const amountOutMin = 0
const amountOutMinHex = ethers.BigNumber.from(amountOutMin).toHexString()

const path = [oneInch, weth]
const deadline = Math.floor(Date.now() / 1000) + 60 * 1 // 1 minutes from the current Unix time

const inputAmountHex = oneEther.toHexString()

swapTxData = await swapContract.populateTransaction.swapExactTokensForETH(
inputAmountHex,
amountOutMinHex,
path,
addressFrom,
deadline
)
const uniswapV2Router = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'

const popApproveTransaction = await signer.populateTransaction(approveTxData)
const popTransaction = await signer.populateTransaction(swapTxData)
const transactions = [
{ ...popApprovedTransaction, value: 0 },
{
...popTransaction,
from: addressFrom,
to: uniswapV2Router,
value: 0
}
]
await previewTransaction(transactions)
}

return await previewTransaction(transactions)
}

const simData = simulate(ethereumProvider)
console.log(simData)
```

### Options & Types

```typescript
export type TransactionPreviewModule = (options: TransactionPreviewOptions) => TransactionPreviewAPI

export type FullPreviewOptions = TransactionPreviewOptions &
TransactionPreviewInitOptions

export type TransactionPreviewAPI = {
/**
* Pass this method a standard EIP1193 provider
* 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

/**
* Pass this method a standard EIP1193 provider
* (such as an injected wallet from window.ethereum)
* and it will be patched to allow for transaction previewing
* 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>
}

export type PatchedEIP1193Provider = EIP1193Provider & { simPatched: boolean }
Expand All @@ -108,7 +229,7 @@ export type TransactionPreviewInitOptions = {
*/
apiKey: string
/**
* Your Blocknative SDK instance
* Your Blocknative SDK instance (https://www.npmjs.com/package/bnc-sdk)
* */
sdk: SDK
/**
Expand Down Expand Up @@ -178,6 +299,7 @@ export type MultiSimOutput = {
export interface ContractCall {
contractType?: string
contractAddress?: string
contractAlias?: string
methodName: string
params: Record<string, unknown>
contractName?: string
Expand All @@ -194,6 +316,8 @@ export interface InternalTransaction {
gasUsed: number
value: string
contractCall: ContractCall
error?: string
errorReason?: string
}

export interface NetBalanceChange {
Expand Down Expand Up @@ -261,4 +385,5 @@ export interface SimDetails {
```

## Build Environments

For build env configurations and setups please see the Build Env section [here](/docs/modules/core#build-environments)
1 change: 1 addition & 0 deletions docs/src/routes/docs/[...4]wallets/injected.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ const injected = injectedModule({
- Frontier - _Desktop & Mobile_
- Rainbow - _Desktop & Mobile_
- DeFiWallet - _Desktop & Mobile_
- ApexWallet - _Desktop_

## Build Environments

Expand Down
Loading

1 comment on commit f5dde45

@vercel
Copy link

@vercel vercel bot commented on f5dde45 Feb 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.