Skip to content

Commit 2a3abbf

Browse files
Feature/uniswap example (#1280)
* Remove broken uniswap widget * Use vercel adapter when ran in vercel * Finish up example * Remove unused deps * Update formatting * added explainer text * Revert faq change * lock sveltekit version Co-authored-by: Murat Akdeniz <[email protected]>
1 parent f20dfb6 commit 2a3abbf

File tree

11 files changed

+325
-278
lines changed

11 files changed

+325
-278
lines changed

.github/workflows/docs.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@ name: Deploy documentation to Pages
44
on:
55
# Runs on pushes targeting the default branch
66
push:
7-
87
branches: ["docs-main"]
98

10-
11-
12-
139
# Allows you to run this workflow manually from the Actions tab
1410
workflow_dispatch:
1511

docs/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
"format": "prettier --write --plugin-search-dir=. ."
1515
},
1616
"devDependencies": {
17-
"@iconify-json/ri": "^1.1.1",
17+
"@iconify-json/ri": "^1.1.3",
1818
"@playwright/test": "^1.22.2",
19-
"@sveltejs/kit": "next",
19+
"@sveltejs/adapter-static": "^1.0.0-next.39",
20+
"@sveltejs/adapter-vercel": "next",
21+
"@sveltejs/kit": "1.0.0-next.357",
2022
"@svelteness/kit-docs": "^0.22.12",
2123
"@tailwindcss/typography": "^0.5.2",
24+
"@types/react-dom": "^18.0.6",
2225
"@typescript-eslint/eslint-plugin": "^5.27.0",
2326
"@typescript-eslint/parser": "^5.27.0",
2427
"@vitebook/client": "^0.100.5",
@@ -40,8 +43,6 @@
4043
"svelte-preprocess": "^4.10.7",
4144
"tslib": "^2.3.1",
4245
"typescript": "^4.7.2",
43-
"@sveltejs/adapter-static": "^1.0.0-next.39",
44-
"@sveltejs/adapter-vercel": "next",
4546
"unplugin-icons": "^0.13.4"
4647
},
4748
"type": "module",
209 KB
Binary file not shown.
File renamed without changes.
File renamed without changes.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { default as ConnectWallet } from './ConnectWallet.svelte'
2-
export { default as ReactConnectWallet } from './ReactConnectWallet.md'
3-
export { default as SvelteConnectWallet } from './SvelteConnectWallet.md'
1+
export { default as ConnectWallet } from './connect-wallet/ConnectWallet.svelte'
2+
export { default as ReactConnectWallet } from './connect-wallet/ReactConnectWallet.md'
3+
export { default as SvelteConnectWallet } from './connect-wallet/SvelteConnectWallet.md'
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
<script>
2+
import { ConnectWallet, ReactConnectWallet, SvelteConnectWallet } from '$lib/components'
3+
4+
import uniswapExampleVideo from '$lib/assets/uniswap-example.mp4'
5+
6+
const frameworks = ['yarn', 'npm']
7+
</script>
8+
9+
# Uniswap Widget Example
10+
11+
This example will walk you through how to integrate `@web3-onboard` with the [Uniswap Widget](https://docs.uniswap.org/sdk/widgets/swap-widget)! Add this web3-onboard enabled uniswap widget to your site to provide users with token swap capabilities quickly.
12+
13+
## Step 1: Install
14+
15+
To start, we'll install the widgets library and the web3-onboard react library using npm or Yarn.
16+
17+
<Tabs values={frameworks}>
18+
<TabPanel value="yarn">
19+
20+
```bash copy
21+
yarn add @web3-onboard/react @web3-onboard/injected-wallets
22+
```
23+
24+
</TabPanel>
25+
<TabPanel value="npm">
26+
27+
```bash copy
28+
npm install @web3-onboard/react @web3-onboard/injected-wallets
29+
```
30+
31+
</TabPanel>
32+
</Tabs>
33+
34+
35+
36+
## Step 2: Import + Configure
37+
38+
Import the libraries and any wallets you would like to use. For this example, we are going to use the injected wallets module. You can easily add more wallet support to your dapp via our other wallet modules. Additionally, we'll setup web3-onboard to support 2 chains: Ethereum mainnet and Polygon mainnet.
39+
40+
We'll create a file called `web3-onboard.ts` and then export the initialized `web3-onboard` instance and use this throughout our dapp.
41+
42+
```ts title="web3-onboard.ts"|copy
43+
import { init } from '@web3-onboard/react'
44+
import injectedModule from '@web3-onboard/injected-wallets'
45+
46+
const INFURA_KEY = ''
47+
48+
const ethereumRopsten = {
49+
id: '0x3',
50+
token: 'rETH',
51+
label: 'Ethereum Ropsten',
52+
rpcUrl: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
53+
}
54+
55+
const polygonMainnet = {
56+
id: '0x89',
57+
token: 'MATIC',
58+
label: 'Polygon',
59+
rpcUrl: 'https://matic-mainnet.chainstacklabs.com',
60+
}
61+
62+
const chains = [ethereumRopsten, polygonMainnet]
63+
64+
const wallets = [injectedModule()]
65+
66+
const appMetadata = {
67+
name: 'Uniswap Widget Example',
68+
icon: '<svg>My App Icon</svg>',
69+
description:
70+
'Example showcasing how to integrate web3-onboard with uniswap widget.',
71+
recommendedInjectedWallets: [
72+
{ name: 'MetaMask', url: 'https://metamask.io' },
73+
{ name: 'Coinbase', url: 'https://wallet.coinbase.com/' },
74+
],
75+
}
76+
77+
// initialize and export Onboard
78+
export default init({
79+
wallets,
80+
chains,
81+
appMetadata,
82+
})
83+
```
84+
85+
## Step 3: Add the react hooks
86+
In our main `App` component we'll setup our Web3-Onboard react hooks. For this example we'll be using the `useConnectWallet` react hook. This will give us access to the currently connected wallets, as well as, methods for us to facilitate connecting and disconnecting a wallet.
87+
88+
```tsx title="App.tsx"|copy
89+
import { useState, useEffect } from 'react'
90+
91+
import { ethers } from 'ethers'
92+
import { useConnectWallet } from '@web3-onboard/react'
93+
94+
export default function App() {
95+
96+
const [{ wallet, connecting }, connect, disconnect] = useConnectWallet()
97+
const [provider, setProvider] = useState<ethers.providers.Web3Provider>()
98+
99+
// Once the wallet is connected the provider will be defined and we'll set the provider value
100+
// This provider will then be passed to the Uniswap component in the next step.
101+
useEffect(() => {
102+
if (wallet?.provider) {
103+
setProvider(new ethers.providers.Web3Provider(wallet.provider, 'any'))
104+
} else {
105+
// Reset the provider back to 'undefined' such that the
106+
// connect wallet option will reappear in the uniswap modal
107+
setProvider(undefined)
108+
}
109+
}, [wallet])
110+
111+
// The connect wallet function which will be based to the Uniswap component in the next step.
112+
const connectWallet = () => {
113+
connect()
114+
}
115+
116+
return (
117+
<main>
118+
<h1>Uniswap Swap Widget</h1>
119+
// Uniswap widget will go here
120+
</main>
121+
)
122+
}
123+
```
124+
125+
## Step 4: Add the Uniswap widget
126+
127+
To begin, we'll import the `SwapWidget` along with the corresponding fonts. We'll define a few constants that will be passed to the swap widget:
128+
129+
- The json rpc endpoint that will be used to provide trade quotes prior to the user connecting a wallet
130+
- The token list url used to provide a list of tokens for the user to select from
131+
- The Uniswap token address which will be used as the default selected token
132+
133+
To learn more about all of the `SwapWidget` props, check out [the api reference](https://docs.uniswap.org/sdk/widgets/swap-widget/api).
134+
135+
We will take the `connectWallet` function that we previously defined and pass it to the `onConnectWallet` prop on the `SwapWidget`. This will allow us to initiate the web3-onboard connect wallet modal once the user clicks the on the connect wallet button within the `SwapWidget`. Finally, we'll also pass the `provider` to the SwapWidget such that once the `provider` is defined, the `SwapWidget` will be able to use the wallet's provider to facilitate the swap.
136+
137+
```tsx title="App.tsx"|copy|{6-13,40-58}
138+
import { useState, useEffect } from 'react'
139+
140+
import { ethers } from 'ethers'
141+
import { useConnectWallet } from '@web3-onboard/react'
142+
143+
import { SwapWidget } from '@uniswap/widgets'
144+
import '@uniswap/widgets/fonts.css'
145+
146+
const JSON_RPC_URL = 'https://cloudflare-eth.com'
147+
// The url of the default uniswap token list. This list will be passed to the Uniswap component
148+
// and will appear by default in the token selector UI.
149+
const TOKEN_LIST = 'https://gateway.ipfs.io/ipns/tokens.uniswap.org'
150+
const UNI = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
151+
152+
export default function App() {
153+
154+
const [{ wallet, connecting }, connect, disconnect] = useConnectWallet()
155+
const [provider, setProvider] = useState<ethers.providers.Web3Provider>()
156+
157+
// Once the wallet is connected the provider will be defined and we'll set the provider value
158+
// This provider will then be passed to the Uniswap component below.
159+
useEffect(() => {
160+
if (wallet?.provider) {
161+
setProvider(new ethers.providers.Web3Provider(wallet.provider, 'any'))
162+
} else {
163+
// Reset the provider back to 'undefined' such that the
164+
// connect wallet option will reappear in the uniswap modal
165+
setProvider(undefined)
166+
}
167+
}, [wallet])
168+
169+
// The connect wallet function which will be based to the Uniswap component below.
170+
const connectWallet = () => {
171+
connect()
172+
}
173+
174+
return (
175+
<main>
176+
<h1>Uniswap Swap Widget</h1>
177+
<SwapWidget
178+
jsonRpcEndpoint={JSON_RPC_URL}
179+
// Specifies the set of tokens that appear by default in the token selector list.
180+
tokenList={TOKEN_LIST}
181+
// This is the provider that we receive from the user's connected wallet
182+
provider={provider}
183+
// When the Uniswap connect wallet button gets hit
184+
// the function gets called. We'll hook this up to
185+
// our connect wallet method from web3-onboard.
186+
onConnectWallet={connectWallet}
187+
// Address of the token to be selected by default in the
188+
// input field (e.g. USDC) for each network chain ID.
189+
defaultInputTokenAddress="NATIVE"
190+
// Default amount for the input field in this case 1 ETH
191+
defaultInputAmount="1"
192+
// Address of the token to be selected by default in the input field (e.g. USDC)
193+
// for each network chain ID.
194+
defaultOutputTokenAddress={UNI}
195+
/>
196+
</main>
197+
)
198+
}
199+
```
200+
201+
## Step 5: Wrap the context provider
202+
203+
Finally, we'll wrap our main App component with the `web3-onboard` context provider in order for us to access the `web3-onboard` instance throughout our app.
204+
205+
```js title="index.tsx"|copy|{8-9,13-15}
206+
import React from 'react'
207+
import ReactDOM from 'react-dom'
208+
import { Web3OnboardProvider } from '@web3-onboard/react'
209+
210+
import './index.css'
211+
import App from './App.tsx'
212+
213+
// Import the web3-onboard singleton
214+
import web3Onboard from './web3-onboard'
215+
216+
ReactDOM.render(
217+
<React.StrictMode>
218+
<Web3OnboardProvider web3Onboard={web3Onboard}>
219+
<App />
220+
</Web3OnboardProvider>
221+
</React.StrictMode>,
222+
document.getElementById('root')
223+
)
224+
```
225+
## See in action!
226+
227+
<video width="100%" height="240" style="border-radius: 0.375rem" controls>
228+
<source src={uniswapExampleVideo} type="video/mp4">
229+
Your browser does not support the video tag.
230+
</video>
231+
232+
## Live Example 🚀
233+
234+
Check out the live example on StackBlitz! StackBlitz will install and build the package in the below container
235+
236+
<iframe title="Uniswap + Web3-Onboard" src="https://stackblitz.com/edit/node-avakex?ctl=1&embed=1&hideExplorer=1&hideNavigation=1&view=preview"
237+
width="100%" height="500px" style="border-radius: 0.375rem" />

docs/svelte.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,27 @@ const config = {
1919
postcss: true
2020
})
2121
],
22+
2223
kit: {
2324
adapter: adapter(),
2425
prerender: {
2526
default: true,
2627
entries: ['*']
2728
},
2829
vite: {
30+
build: {
31+
rollupOptions: {
32+
external: [
33+
'@web3-react/core',
34+
'@web3-react/eip1193',
35+
'@web3-react/metamask',
36+
'@web3-react/network',
37+
'@web3-react/walletconnect',
38+
'@web3-react/types',
39+
'@web3-react/url'
40+
]
41+
}
42+
},
2943
resolve: {
3044
alias: {
3145
$fonts: resolve(process.cwd(), 'src/lib/fonts')

docs/tsconfig.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
"resolveJsonModule": true,
99
"skipLibCheck": true,
1010
"sourceMap": true,
11-
"strict": true
11+
"strict": true,
12+
"jsx": "react-jsx",
13+
"outDir": "build"
1214
},
1315
"include": ["src/**/*"],
14-
"exclude": ["node_modules", "./.svelte-kit"]
16+
"exclude": ["./.svelte-kit"]
1517
}

0 commit comments

Comments
 (0)