# Getting started

The following document explains how to get started with the Teller Widget, as well as the available customization options.&#x20;

We recommend using the following build configurations/environments for your react apps

1. Vite&#x20;
2. next.js
3. `create-react-app` (although this one is highly unrecommended)

There are additional steps required for the last 2 environments that are outlined at the bottom of this page.

## Installing the widget

### Required packages

```bash
 @tanstack/react-query
 alchemy-sdk
 graphql
 graphql-request
 react
 react-dom
 @teller-protocol/v2-contracts
```

Using either yarn or npm, to install the widget, run the following commands

```bash
yarn add @teller-protocol/teller-widget @tanstack/react-query alchemy-sdk graphql graphql-request react react-dom @teller-protocol/v2-contracts
```

```bash
npm install --save @teller-protocol/teller-widget @tanstack/react-query alchemy-sdk graphql graphql-request react react-dom @teller-protocol/v2-contracts
```

Please note that your app must be running React 18.2.0 or higher, and must have the packages in [#required-packages](#required-packages "mention") and that subgraph studio api key is required for the widget to function properly.

## Using the widget

To use the widget, import it from the package

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget subgraphApiKey="xxx" />;
};
```

The widget will work without any additional props or setup required. It will pickup the user's connected wallet and display all available loans for the user's wallet tokens.&#x20;

To generate a subgraph api key from The Graph, used in prop `subgraphApiKey`, follow the steps [here](https://docs.teller.org/teller-widget/generating-subgraph-studio-api-key).

## Customizing the widget

The following elements of the widget are customizable

* `buttonLabel`: The label in the button to trigger the widget
* `whitelistedTokens`: Additional tokens to always display
* `showOnlyWhiteListedTokens`: Toggle to show only the tokens defined in `whitelistedTokens`
* `buttonColorPrimary`: #hex background color styling to the main button
* `buttonTextColorPrimary`: #hex text color styling to the main button
* `buttonClassName`: a css class to add to the main button
* `isBareButton`: a boolean that removes all the standard styling and keeps the button to bare minimum for much easier customization
* `referralFee`: Loan fee %, to be sent to a referral address
* `referralAddress`: The address to receive the referral fee
* `welcomeScreenLogo`: Logo (as a URL) displayed on the widget's welcome screen
* `welcomeScreenTitle`: Bold, header text on the widget's welcome screen
* `welcomeScreenParagraph`: Body, paragraph text on the widget's welcome screen

### buttonLabel

You can customize the label that appears in the button once you add it to the your app.&#x20;

By default the label is `Cash Advance`, this can be changed to any string like so

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonLabel="Get a loan now!" />;
};
```

### whitelistedTokens

By default, the widget shows available offers for the tokens in the user's wallet.&#x20;

By passing in an object organized by chain id, you can customize this list so the tokens in the list *always* show up in the available loan opportunities. If the token is not found in the user's wallet, the widget will default to a value of 1 for the respective token.&#x20;

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

// Object organized by chain id
const whitelistedTokens = {
  // polygon
  [137]: [ 
    "0x61299774020da444af134c82fa83e3810b309991",
    "0x692ac1e363ae34b6b489148152b12e2785a3d8d6",
  ],
  // mainnet
  [1]: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],
};

const App = () => {
  return <TellerWidget whitelistedTokens={whitelistedTokens} />;
};
```

### showOnlyWhiteListedTokens

If you want  to *only* show the tokens in the above list, set this prop to true. Please note that for this prop to work, `whitelistedTokens` must be present as well.&#x20;

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const whitelistedTokens = {
  [137]: [
    "0x61299774020da444af134c82fa83e3810b309991",
    "0x692ac1e363ae34b6b489148152b12e2785a3d8d6",
  ],
  [1]: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],
};

const App = () => {
  return <TellerWidget whitelistedTokens={whitelistedTokens} showOnlyWhiteListedTokens />;
};
```

### buttonColorPrimary

For simple css styling, the primary button's background color can be changed by passing in this prop. The input must be in hex format, including the #, ie #FFFFFF

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonColorPrimary="#HEX" />;
};
```

### buttonTextColorPrimary

Also for simple css styling, the primary button's text color can be changed by passing in this prop. The input must be in hex format, including the #, ie #FFFFFF

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonTextColorPrimary="#HEX" />;
};
```

### buttonClassName

To facilitate styling of the button, and make it easier to match your app's styles, a `buttonClassName` prop is available to add a custom css class to the button.&#x20;

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonClassName="custom-button" />;
};
```

### isBareButton

By setting `isBareButton` to true, all the styling of the button is reset to the browser's default styling to make it easier to override the styling of the button.

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonClassName="custom-button" isBareButton />;
};
```

### whitelistedChains

An optional `array` to show desired chains. By default, the widget shows all chains. Available chains:

* 1 (Ethereum),
* 137 (Polygon)
* 42161 (Arbitrum)
* 8453 (Base)

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget whitelistedChains={[1,137]} />;
};
```

### referralFee

Referral fee %, in basis points. For example, 100 = 1%, max 500 = 5%. Note, referral fee on rollover loans is capped at 5% of the original loan repayment.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget referralFee={100} />;
};
```

### referralAddress

Recipient wallet address to receive referral fee.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget referralAddress={"0x..."} />;
};
```

### welcomeScreenLogo

Logo (as a URL) displayed on the widget's welcome screen. Image types .png, .jpg, .jpeg, .svg.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenLogo={"https://img-url.png"} />;
};
```

### welcomeScreenTitle

Bold, header text on the widget's welcome screen.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenTitle={"DeFi's cash advance"} />;
};
```

### welcomeScreenParagraph

Body, paragraph text on the widget's welcome screen.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenParagraph={"Time-based loans, up to thirty days, with no margin-call liquidations."} />;
};
```

## Different environment configurations

### next.js

please add the following to your `next.config.js`

```javascript
webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        fs: false,
        worker_threads: false,
        module: false,
      };
    }

    return config;
  },
```

### create-react-app

For CRA based environments, multiple steps are required&#x20;

1. Install the following packages

```bash
assert browserify-zlib buffer crypto crypto-browserify encoding fs https-browserify os-browserify path-browserify pino-pretty process react-app-rewired stream-browserify stream-http url vm-browserify
```

2. Modify the start scripts in `package.json` to use `react-app-rewired` instead of `react-scripts`

```json
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
```

3. Add a `config-overrides.js` file to the top of the project directory with the following

```javascript
const webpack = require("webpack");
module.exports = function override(config, env) {
  config.resolve.fallback = {
    url: require.resolve("url"),
    fs: false,
    assert: require.resolve("assert"),
    crypto: require.resolve("crypto-browserify"),
    http: require.resolve("stream-http"),
    https: require.resolve("https-browserify"),
    os: require.resolve("os-browserify/browser"),
    stream: require.resolve("stream-browserify"),
    path: require.resolve("path-browserify"),
    zlib: require.resolve("browserify-zlib"),
    vm: require.resolve("vm-browserify"),
    worker_threads: false,
    module: false,
    process: require.resolve("process/browser"),
  };
  config.plugins.push(
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    })
  );

  return config;
};
```

*Please note that the following message may appear once the project has been built*

<figure><img src="https://235952736-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F50IvFxALM8CkQEDqGRgY%2Fuploads%2FYvH0ggQRSvOMRS94HkIq%2FIMG_9009.jpg?alt=media&#x26;token=ae757fb9-8504-449f-870d-c24b363e600e" alt=""><figcaption></figcaption></figure>

*This message can safely be ignored, as this only happens in dev environments. You can either close it by clicking on the x on the top right or by refreshing the page. This message won't appear in production environments*
