Home

Blog

How to Integrate Brydge

How to Integrate Brydge

How to Integrate Brydge

How to Integrate Brydge

How to Integrate Brydge

January 30, 2023

January 30, 2023

January 30, 2023

January 30, 2023

Welcome

Hello and welcome to today’s tutorial on integrating with Brydge! If you don’t know too much about us yet, check out some resources here on who we are and what we do. If you do know about us and are thinking it’s time to integrate, this is the place for you!

Today I’ll be walking you through a step-by-step integration of our widget for three core use-cases, each of which you can integrate using our React component or our iFrame component. We’ll first start by setting up a demo application using NextJS and then working through the prerequisites for setting the widget using both methods of integration. We’ll start with the React component, which will be much more involved, however, may allow for some more custom use cases and then move on to the much easier iFrame integration, which is recommended for anyone getting started. Note that NextJS is by no means required to integrate, it’s just what I have chosen to use for today’s demo.

FYI—our CMS is terrible at formatting code. You can view a nice looking version of this tutorial on Medium here.

Let’s get going!

Code reference

All of the code that we cover today is available on GitHub.

Environment setup

Integration video

In terms of technical prerequisites, you will need to have Yarn and Node (v14.6.0+) installed on your machine, as well as a text editor (I’ll be using Visual Studio Code). I’ve linked to their download pages just in case you need to install any of them.

If you’re here today, it’s likely that you already have some kind of site ready to host the widget, so you can skip ahead to the next section, however, you may find it useful to follow along for the sake of context.

It’s important to keep in mind throughout this setup that I am only offering an example of how an application can be configured to handle a widget integration, however, this is by no means the only way to do so. You may already have many pieces of the setup already configured in your own way which are likely to work perfectly with our widget.

Let’s start by opening our terminals and finding a directory to work in. From here, run the following command to create a new NextJS app in the Typescript language:

yarn create next-app --typescript

We’ll be prompted to give the app a name. I’ve named mine brydge-demo. You can choose whatever you like for the rest of the options. I’ve chosen to include a src directory, so for the purposes of following along, it might be best for you to do the same.

Once the setup is complete, set the new project directory to be your working directory with cd brydge-demo (or whatever you named your project).

Next, let’s open up our new project directory in a text editor and explore some relevant files. Using my project setup, these are brydge-demo/package.json and brydge-demo/src/pages/index.tsx. The first, package.json will allow us to keep track of our app’s dependancies. You can see that for each entry under the dependancies field, we have a package name and a version. Something like this:

{

...

"dependencies": {

"package-name": "0.0.1", ...

}

}

In index.tsx, we’ll see a bunch of code that makes up the contents of the default landing page. Let’s head back to our terminal and run yarn dev . You should receive a console message similar to ready - started server on 0.0.0.0:3000, url: [<http://localhost:3000>](<http://localhost:3000/>). On your browser follow that link (I’ve linked it in the previous sentence) to open the app running on port 3000 of your localhost. You should see some default NextJS content. If you’re having any trouble, check out the video as it might provide some helpful visuals.

Next, head back into the text editor and we’ll take out all of that content and add a little bit of our own. Go ahead and replace all the existing code in index.tsx with the following snippet:

import Head from 'next/head'

import styles from '@/styles/Home.module.css'

export default function Home() {

return (

<>

<Head>

<title>brydge demo</title>

<meta name="description" content="Generated by create next app" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="icon" href="/favicon.ico" />

</Head>

<main className={styles.main}>

<div className={styles.description}>

<p> Integrate with &nbsp; <code className={styles.code}>Brydge</code> </p>

</div>

</main>

</>

)

}

Save that and head back over to localhost:3000 and we should see a blank page with the message: “Integrate with Brydge”.

Great work so far! We’ve now got a nice demo app setup and we can start integrating our widget. We’ll now look at the two ways of integration. I personally recommend that you skip right down to the iFrame component section and skip all the tricky bits of the React integration, however, if you feel like the React setup is right for you or you prefer to learn about both, hop right into the next section.

React component

Integration video

Now that we have our NextJS app set up, we can start getting it ready to host our React widget!

Remember that the setup that I am providing is not the only way to configure your app to host the React component. You may have your own, wallet handlers, providers, etc. all of which are likely to work with our widget.

Let’s get started with adding some dependancies. Open up package.json in the project root directory and add the following three dependancies:

{

...

"dependencies": {

"wagmi": "^0.6.6",

"@rainbow-me/rainbowkit": "^0.5.3",

"@brydge-network/widget": "3.1.3",

...

}

}

The first two, Wagmi and RainbowKit are going to help us connect to our users’ wallets so that the widget can interact with blockchains on their behalf. The third, is of course, the widget itself. That’s all we need to know for now but feel free to do some extra reading on any of these if you’d like.

Now we can head back to our terminal and run a yarn install (again in the project root directory), which will install the necessary artifacts of each dependancy in the node_modules directory. Feel free to browse the contents of these at any time for the sake of in-depth context.

Next, let’s open up the _app.tsx file in the src/pages directory. This file is used by NextJS to initialize the pages in our app. WE are going to override the default behaviour to facilitate connection to user wallets. You can read more about _app.tsx here.

We can do this by replacing the existing content with the following:

import '@/styles/globals.css'

import type { AppProps } from 'next/app'

import { chain, configureChains, createClient, WagmiConfig } from 'wagmi'

import { infuraProvider } from 'wagmi/providers/infura'

import { publicProvider } from 'wagmi/providers/public'

import { getDefaultWallets, RainbowKitProvider } from '@rainbow-me/rainbowkit'

const { chains, provider } = configureChains( [chain.mainnet, chain.polygon, chain.optimism, chain.arbitrum], [ infuraProvider({ apiKey: process.env.NEXT_PUBLIC_INFURA_KEY }), publicProvider(), ], )

const { connectors } = getDefaultWallets({ appName: 'Brydge', chains, }) const wagmiClient = createClient({ autoConnect: false, connectors, provider, })

export default function App({ Component, pageProps }: AppProps) {

return (

<WagmiConfig client={wagmiClient}>

<RainbowKitProvider chains={chains}>

<Component {...pageProps} />

</RainbowKitProvider>

</WagmiConfig>

)

}

Quite a bit to take in, but let’s look at the most important pieces. First we have:

const { chains, provider } = configureChains( [chain.mainnet, chain.polygon, chain.optimism, chain.arbitrum], [ infuraProvider({ apiKey: process.env.NEXT_PUBLIC_INFURA_KEY }), publicProvider(), ], )

This configureChains call is going to let us define what chains our user’s can connect to our widget with as well as the providers that we will use to facilitate blockchain interaction. Here, we have chosen to include Ethereum Mainnet, Polygon, Optimism, and Arbitrum. We also support Avalanche, with more supported chains coming soon! You can choose whichever chains best serve your use case. Additionally, we have chosen to use Infura as our provider as well as the Wagmi public provider. We can use multiple providers for the sake of redundancy or to include chains that are supported only by certain providers.

Note here that we need to have a public key for Infura or whichever provider we choose to use. You can get a free Infura key here. For the above code to work, create a .env file in the root directory of your project and add the following:

NEXT_PUBLIC_INFURA_KEY='YOURKEY'

We then pass the chains and provider objects to getDefaultWallets and createClient respectively for the creation of a Wagmi client that will manage the connection of our wallets.

Finally, we wrap our app’s content in a WagmiConfig object (using our Wagmi client) and a RainbowKitProvider object (using our chains):

return ( <WagmiConfig client={wagmiClient}> <RainbowKitProvider chains={chains}> <Component {...pageProps} /> </RainbowKitProvider> </WagmiConfig> )

Feel free to do some additional reading on any of the above functions here.

Now, we can move over to our landing page at src/pages/index.tsx (or wherever you prefer on your own site). We’ll start by adding some imports:

import { useRouter } from 'next/router'

import { useEffect, useState } from 'react'

import { BrydgeWidget } from '@brydge-network/widget'

import { useConnectModal } from '@rainbow-me/rainbowkit'

import { useAccount } from 'wagmi' import { Ethereum } from '@wagmi/core'

Feel free to look further into any of them if you’re interested.

Next, we’ll write a function that returns a provider that we can pass to our widget:

function useEthereumProvider() {

const [provider, setProvider] = useState<Ethereum>()

const { connector, isConnected } = useAccount() useEffect(() => {

if (isConnected) {

connector.getProvider().then((p) => { setProvider(p) })

} else {

setProvider(undefined)

}

}, [connector, isConnected]) return provider }

This provider object will allow the widget to interact with our blockchains.

Next, we define our jsonRpcEndpoints:

const jsonRpcEndpoints = {

1: `https://mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_KEY}`,

10: `https://optimism-mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_KEY}`,

137: `https://polygon-mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_KEY}`,

42161: `https://arbitrum-mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_INFURA_KEY}`,

}

This will determine the chains that our widget can interact with. Once again, we will need an Infura key defined in a .env file as demonstrated above.

Now, let’s add some functionality to our Home function, without modifying the return statement yet:

export default function Home() {

const router = useRouter()

const provider = useEthereumProvider()

const { openConnectModal } = useConnectModal()

const [isReady, setIsReady] = useState(false)

useEffect(() => {

if (router.isReady) { setIsReady(true) }

}, [router.isReady])

const content = isReady ? ( <BrydgeWidget jsonRpcEndpoints={jsonRpcEndpoints} provider={provider} onConnectWallet={openConnectModal} /> ) : ( <div className={styles.center}>Loading Brydge Widget...</div> )

return ( ...

A few things to note here. Firstly, we are using the NextJS router object (returned by useRouter) in tandem with the isReady flag and it’s setter, setIsReady to check if the router is ready to render our widget. This ensures that we do not pass the widget any harmful undefined props at the time of rendering. Additionally, we have our provider returned by our previously written function, as well as openConnectModel which is a hook that will provide a UI to connect a wallet upon clicking the widgets “Connect Wallet” button. Lastly, we define our content to be the widget object (receiving jsonRpcEndpoints, provider, and openConnectModal as props) if the router is ready, and a loading message otherwise.

Finally, let’s add this content to our return statement:

return ( <> <Head> <title>brydge demo</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main className={styles.main}> <div className={styles.description}> <p> Integrate with &nbsp; <code className={styles.code}>Brydge</code> </p> </div> <div>{content}</div> </main> </> )

Great! We’ve done all the necessary setup and can now head back to the terminal and run a yarn dev. Go ahead and checkout localhost:3000 where you should see a swap widget! Go ahead and connect your wallet or play around with the different swapping options. You can now continue to learn how to repeat the setup process for the iFrame component (I recommend this as it’s much simpler) or continue to the following sections to learn about different widget use cases and props.

If you had any trouble following along or ran into errors, check out the above video to watch me walk through the code.

iFrame component

Integration video

Starting where we left off just before beginning our React component integration, let’s get going with our iFrame component integration. If you’re not already familiar with iFrames, you can go ahead and do a little reading here. In short, this style of integration is going to allow you to nest the browsing context of our widget hosted by us on the Brydge website, while still allowing you to configure widget props to match your use case.

We can kick things off by opening up package.json in the root of our project directory. For the iFrame integration, we just need to add one dependancy so go ahead and add it under the dependancies field:

{

...

"dependencies": {

"@brydge-network/utils": "0.1.15", ...

}

}

This package is going to provide us with an encodeUrl function that will allow us to format a url with all our widget props to serve as the src tag of our iFrame.

We can head back over to the terminal and run a yarn install in our project’s root directory to download all the required dependancy artifacts into the node_modules directory.

Next, go ahead and open up the landing page of our app: src/pages/index.tsx (or of course, wherever you would like to host the widget in your own site).

First let’s import that encodeUrl function I mentioned:

import { encodeUrl } from '@brydge-network/utils'

Now, let’s put that to use and modify our Home function (or whichever function that you want to be rendering the widget):

export default function Home() {

const url = '<https://brydge.network/widget/>' + encodeUrl({})

return ( ...

Here we define a url constant, prefixed with the address at which the iFrame widget is hosted. For now, we’ll just pass encodeUrl an empty object.

Finally, let’s pop our iFrame into the return statement:

return ( <> <Head> <title>brydge demo</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main className={styles.main}> <div className={styles.description}> <p> Integrate with &nbsp; <code className={styles.code}>Brydge</code> </p> </div> <iframe height={500} width={500} src={url} /> </main> </> )

Note that you can play around with the iFrame attributes, including width, height and boarder. A full list is included here.

Awesome! Let’s go back to the terminal and run yarn dev which should start up our app on localhost:3000. We should now have a default swap widget on the landing page! Great work so far and keep reading to learn more about core use cases and prop customization.

If you had any trouble following along or ran into errors, check out the above video to watch me walk through the code.

LP mode

Integration video

Use case and props

As summarized in our integration docs, Liquidity Pool Deposit mode allows your users to deposit liquidity into any of your pools using any supported token on any of our supported chains.

To set up an LP mode widget we’re going to need to pass the widget two pieces of data:

  • widgetMode: LP_DEPOSIT, PURCHASE, or SWAP (set this to LP_DEPOSIT)

  • lpInfo: A data object defining the liquidity pool in which to deposit

    • lpChainId: The chain ID of the chain on which the pool resides

    • routerAddress: The contract address (on the chain with ID = lpChainId) of the liquidity pool’s router

    • currencyAAddress: The contract address (on the chain with ID = lpChainId) of the first currency participating in the liquidity pool (can be ‘NATIVE’ for the chain’s native token)

    • currencyBAddress: The contract address (on the chain with ID = lpChainId) of the second currency participating in the liquidity pool (can be ‘NATIVE’ for the chain’s native token)

    • tokenPairName: The name of your token pair (Ex: ‘TokenA-TokenB LP’)

Integration

For our demo, we’ll setup an integration with QuickSwap’s router on Polygon with USDC and MATIC as our token pair.

We can begin by adding our data points in the file that integrates our widget:

const widgetMode = 'LP_DEPOSIT'

const lpInfo = {

// Polygon

lpChainId: 137,

// QuickSwap Router

routerAddress: '0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff',

// USDC

currencyAAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',

// MATIC

currencyBAddress: 'NATIVE',

tokenPairName: 'USDC-MATIC LP', }

Now, simply pass these to the widget using whichever integration method you have chosen:

// React

<BrydgeWidget jsonRpcEndpoints={jsonRpcEndpoints} provider={provider} openConnectModal={openConnectModal} widgetMode={widgetMode} lpInfo={lpInfo} />

// iFrame

const url = '<https://brydge.network/widget/>' + encodeUrl({ widgetMode, lpInfo, })

Head back over to your application and you should have an LP mode widget ready to go!

For further prop customization proceed to the Additional props section.

Purchase mode

Integration video

Use case and props

Purchase mode allows your to execute arbitrary call data on chain to facilitate the transactions of NFTs or other blockchain artifacts. For additional info on the mode, check out our integration docs.

To configure the widget in purchase mode, you’ll need to provide these data points:

  • widgetMode: LP_DEPOSIT, PURCHASE, or SWAP (set this to PURCHASE)

  • destinationChainId: The chain ID of the chain on which the purchasable artifact resides

  • outputTokenAddress: The contract address (on the chain with ID = destinationChainId) of the token accepted for the purchase (can be set to ‘NATIVE’ for the chain’s native token)

  • price: The price (in units of the outputTokenAddress token) of the purchasable artifact

  • iCalls: A list of iCall objects of arbitrary length

    • Each iCall object requires the following:

      • _to: The contract address to be called by the iCall

      • _value: The amount of native token (if any) to be sent to _to

      • _calldata: The functions and function parameters to be called by the iCall

For more information on iCalls and how to encode them for your use case, refer to our integration docs.

One thing to note is that in many use cases, you may want to include the connected wallet’s address as the _to field or within the calldata field, however, if you are integrating with our iFrame component you may not have access to this address on your end. In this case, you can use the special placeholder address 0x0123456789abcdeffedcba9876543210deadbeef instead and we will handle the input of the wallet address on our end.

Integration

For this demo, we will simply use dummy iCalls and thus, our widget will not facilitate any purchases. We’ll set the accepted token to be Ether on the Ethereum Mainnet and the price to 1 ETH.

Let’s add our necessary data to the file that integrates our widget:

const widgetMode = 'PURCHASE'

// ETH on Mainnet

const outputTokenAddress = 'NATIVE'

// Ethereum Mainnet

const destinationChainId = 1

// 1 ETH

const price = 1

// Dummy calls

const iCalls = [ { _to: '0x0000000000000000000000000000000000000003', _value: 0, _calldata: '0x0000000000000000000000000000000000000001', }, ]

Now, simply pass these to the widget using whichever integration method you have chosen:

// React

<BrydgeWidget jsonRpcEndpoints={jsonRpcEndpoints} provider={provider} openConnectModal={openConnectModal} widgetMode={widgetMode} outputTokenAddress={outputTokenAddress} destinationChainId={destinationChainId} price={price} calls={iCalls} />

// iFrame

const url = '<https://brydge.network/widget/>' + encodeUrl({ widgetMode, outputTokenAddress, destinationChainId, price, iCalls, })

Head back over to your application and you should have a demo Purchase mode widget ready to go! Remember to configure the iCalls to your use case to facilitate purchases.

For further prop customization proceed to the Additional props section.

Swap mode

Integration video

Use case and props

Last but not least, we have Swap mode. This will allow your users to swap to and from any of our supported tokens on any supported chain! If you noticed earlier, the widgets we setup before passing any additional props are actually fully functional swap widgets that are ready to go without any further configuration.

If you happen to be some kind of stakeholder in a specific token and are hoping to encourage members of the community to hold said token, you can set the Swap widget’s default output using the following data:

  • widgetMode: LP_DEPOSIT, PURCHASE, or SWAP (set this to SWAP)

  • destinationChainId: The chain ID of the chain on which the purchasable artifact resides

  • outputTokenAddress: The contract address (on the chain with ID = destinationChainId) of the token accepted for the purchase (can be set to ‘NATIVE’ for the chain’s native token)

Integration

We can add this data to the file where our widget is living:

const widgetMode = 'SWAP'

// USDC on Polygon

const outputTokenAddress = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174'

// Polygon Network

const destinationChainId = 137

Now, simply pass these to the widget using whichever integration method you have chosen:

// React

<BrydgeWidget jsonRpcEndpoints={jsonRpcEndpoints} provider={provider} openConnectModal={openConnectModal} widgetMode={widgetMode} outputTokenAddress={outputTokenAddress} destinationChainId={destinationChainId} />

// iFrame

const url = '<https://brydge.network/widget/>' + encodeUrl({ widgetMode, outputTokenAddress, destinationChainId, })

Head back over to your application and you should have a custom Swap mode widget ready to go!

For further prop customization proceed to the Additional props section.

Additional props

In addition to the props discussed in the pervious sections, you can also include further props to adjust the widget’s theming and behaviour to best fit your use case! For a full list of these props check out our prop documentation.

Thank you for choosing Brydge

Thank you so much for following along today! I hope everything was straight forward, but if not, don’t hesitate to reach out to us with any questions or comments on Discord!

Make your dApp accessible to retail

Make your dApp accessible to retail

Make your dApp accessible to retail