# Get started with Wallet Provider [Wallet Provider](https://github.com/terra-money/wallet-provider) makes it easy to build Terra Station (browser extension and mobile) functionality into your React application. It contains custom hooks that drastically simplify common tasks like connecting a wallet and triggering transactions. This guide will cover how to set up a React app, integrate Wallet Provider, check the balance of the connected account, and call a token swap. If you want to integrate Terra Station into an existing react app you can skip past the `Project Setup` section. ::: {admonition} Just want to dive in? :class: tip Check out the getting started section for the premade templates [in Github](https://github.com/terra-money/wallet-provider/). ::: If you're using a frontend framework other than React you'll need to use [Wallet Controller](https://www.npmjs.com/package/@terra-money/wallet-controller) instead. Controller provides the sub-structure of Provider. You can see an example of how Wallet Controller works in the [Vue.js template example](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/vue). ## Prerequisites - [Terra Station Chrome extension](../../../learn/terra-station/download/terra-station-extension.md) - Node.js version 16+ - [NPM](https://www.npmjs.com/) ## 1. Project Setup 1. To get started, you'll need some basic React scaffolding. To generate this, run the following in your terminal: ```sh npx create-react-app my-terra-app cd my-terra-app ``` 2. Then, install the `@terra-money/wallet-provider` package: ```sh npm install @terra-money/wallet-provider ``` ## 2. Wrap your app in `WalletProvider` Next, you'll wrap your `App` with `` to give all your components access to useful data, hooks, and utilities. You'll also need to pass in information about Terra networks, such as the mainnet or chainId, into the provider via `getChainOptions`. 1. Navigate to your `Index.js` in a code editor and replace the code with the following: ```js import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { getChainOptions, WalletProvider } from '@terra-money/wallet-provider'; getChainOptions().then((chainOptions) => { ReactDOM.render( , document.getElementById('root'), ); }); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); ``` 2. Start the application to make sure it works: ```sh npm start ``` Your browser should open to `http://localhost:3000/`, and you should see the react logo with a black background and some text. :::{Dropdown} Getting `polyfill` errors? To solve these errors, can downgrade `react-scripts`: `4.0.3` in your `package.json` and reinstall your dependencies as a quick fix: 1. Navigate to `my-terra-app` in your terminal and run the following: ```sh npm install react-scripts@4.0.3 ``` 2. Reinstall your dependencies: ```sh npm install ``` 3. Restart your app: ```sh npm start ``` Alternatively, you can configure your webpack to include the necessary fallbacks. Here's an [example](https://github.com/terra-money/wallet-provider/blob/main/templates/create-react-app/config-overrides.js) that uses [react-app-rewired](https://www.npmjs.com/package/react-app-rewired). ::: 3. Create a new directory called `components` in the `source` directory. This directory will house components to trigger different actions from our connected wallet. ## 3. Put `useWallet` to work Now that `App.js` has inherited the context of `WalletProvider`, you can start putting your imports to work. You'll use the multi-purpose `useWallet` hook to connect your terra station extension to your web browser. 1. Create a new file in the `components` directory called `Connect.js`. 2. Populate the `Connect.js` file with the following: ```js import { useWallet, WalletStatus } from '@terra-money/wallet-provider'; import React from 'react'; export default function Connect() { const { status, network, wallets, availableConnectTypes, connect, disconnect, } = useWallet(); return ( <> {JSON.stringify({ status, network, wallets }, null, 2 )} {status === WalletStatus.WALLET_NOT_CONNECTED && ( <> {availableConnectTypes.map((connectType) => ( ))} )} {status === WalletStatus.WALLET_CONNECTED && ( )} ); } ``` 3. Open `App.js` in your code editor and replace the code with the following: ```js import './App.css'; import Connect from './components/Connect'; function App() { return (
); } export default App; ``` 4. Refresh your browser. There should be some new text and buttons in your browser. 5. Make sure your Terra Station extension is connected to a wallet. Click **Connect EXTENSION**, and the app will connect to your wallet. The `status`, `network`, and `wallets` properties in your browser provide useful information about the state of the Terra wallet. Before connecting, the `status` variable is `WALLET_NOT_CONNECTED`, and upon connection the status becomes `WALLET_CONNECTED`. In addition, the `wallets` array now has one entry with the `connectType` and `terraAddress` you used to connect. You should be able to see these changes in real-time. ## 4. Querying a wallet balance It's common for an app to show the connected user's UST balance. To achieve this you'll need two hooks. The first is `useLCDClient`. An `LCDClient` is essentially a REST-based adapter for the Terra blockchain. You can use it to query an account balance. The second is `useConnectedWallet`, which tells you if a wallet is connected, and if so, basic information about that wallet such as its address. Note that if your wallet is empty you won't see any tokens. 1. Create a file in your `Components` folder named `Query.js`. 2. Populate `Query.js` with the following: ```js import { useConnectedWallet, useLCDClient } from '@terra-money/wallet-provider'; import React, { useEffect, useState } from 'react'; export default function Query() { const lcd = useLCDClient(); // LCD stands for Light Client Daemon const connectedWallet = useConnectedWallet(); const [balance, setBalance] = useState(null); useEffect(() => { if (connectedWallet) { lcd.bank.balance(connectedWallet.walletAddress).then(([coins]) => { setBalance(coins.toString()); }); } else { setBalance(null); } }, [connectedWallet, lcd]); // useEffect is called when these variables change return (
{balance &&

{balance}

} {!connectedWallet &&

Wallet not connected!

}
); } ``` 3. Open `App.js` in your code editor and add `import Query from './components/Query'` to line 3, and ` ` to line 11. The whole file should look like the following: ```js import './App.css'; import Connect from './components/Connect'; import Query from './components/Query' function App() { return (
); } export default App; ``` 4. Refresh your browser. Your wallet balance will appear in micro-denominations. Multiply by $10^6$ for an accurate balance. ## 5. Sending a transaction WalletProvider also helps create and send transactions to the Terra network. You'll also need `Terra.js` to help generate the sample transaction: ```sh npm install @terra-money/terra.js ``` Before broadcasting this example transaction, ensure you're on the Terra testnet. To change networks click the gear icon in your Terra station and select `testnet`. You can request tesnet funds from the [faucet](https://faucet.terra.money/). You'll receive luna which can be swapped for UST within the Station extension. A UST transfer transaction needs a fee and a message containing the sender address, recipient address, and send amount (in this case 1 UST). Once the message is constructed, the `post` method on `connectedWallet` broadcasts it to the network. :::{admonition} What happens if something goes wrong? :class: note Wallet provider also supplies useful error types. This example will handle the `UserDenied` error case. You can find other cases to handle [on Github](https://github.com/terra-money/wallet-provider/blob/4e601c2dece7bec92c9ce95991d2314220a2c954/packages/src/%40terra-money/wallet-controller/exception/mapExtensionTxError.ts#L23). ::: 1. Create a file in your `Components` folder named `Tx.js`. 2. Populate `Tx.js` with the following: ```js import { Fee, MsgSend } from '@terra-money/terra.js'; import { useConnectedWallet, UserDenied } from '@terra-money/wallet-provider'; import React, { useCallback, useState } from 'react'; const TEST_TO_ADDRESS = 'terra12hnhh5vtyg5juqnzm43970nh4fw42pt27nw9g9'; export default function Tx() { const [txResult, setTxResult] = useState(null); const [txError, setTxError] = useState(null); const connectedWallet = useConnectedWallet(); const testTx = useCallback(async () => { if (!connectedWallet) { return; } if (connectedWallet.network.chainID.startsWith('columbus')) { alert(`Please only execute this example on Testnet`); return; } try { const transactionMsg = { fee: new Fee(1000000, '200000uusd'), msgs: [ new MsgSend(connectedWallet.walletAddress, TEST_TO_ADDRESS, { uusd: 1000000, }), ], } const tx = await connectedWallet.post(transactionMsg); setTxResult(tx); } catch (error) { if (error instanceof UserDenied) { setTxError('User Denied'); } else { setTxError( 'Unknown Error: ' + (error instanceof Error ? error.message : String(error)), ); } } }, [connectedWallet]); return ( <> {connectedWallet?.availablePost && !txResult && !txError && ( )} {txResult && <>{JSON.stringify(txResult, null, 2)}} {txError &&
{txError}
} {connectedWallet && !connectedWallet.availablePost && (

This connection does not support post()

)} ); } ``` :::{note} Because all coins are denominated in micro-units, you will need to multiply any coins by $10^6$ . For example, 1000000 uusd = 1 UST. ::: 3. Open `App.js` in your code editor and add `import Tx from './components/Tx'` to line 4, and ` ` to line 12. The whole file should look like the following: ```js import './App.css'; import Connect from './components/Connect'; import Query from './components/Query'; import Tx from './components/Tx'; function App() { return (
); } export default App; ``` 4. Refresh your browser. You'll see a new **Send** button. Click the button to send your transaction. Your station extension will ask you to confirm the transaction. That's all! You can find more examples of `WalletProvider` capabilities in the following example templates: - [Wallet Provider + Create-React-App](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/create-react-app) - [Wallet Provider + Next.js](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/next) - [Wallet Provider + Vite.js](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/vite) - [Wallet Controller + Lit](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/lit) - [Wallet Controller + Vue.js](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/vue) - [Wallet Controller + Svelte](https://githubbox.com/terra-money/wallet-provider/tree/main/templates/svelte)