# Setting Up your NEAR Environment ## Setting Up Connection to NEAR Let's create a file `src/utils.js` in that file we will first define our Network Configuration First we want to define our imports. ```javascript= import { connect, Contract, keyStores, WalletConnection } from "near-api-js"; ``` Next you want to define your Contract Account Name ```javascript= const CONTRACT_NAME = process.env.CONTRACT_NAME || "activate-miami.blockhead.testnet"; ``` ```javascript= let config = { // testnet, mainnet, localnet -> near workspaces, kurtosis networkId: "testnet", keyStore: new keyStores.BrowserLocalStorageKeyStore(), nodeUrl: "https://rpc.testnet.near.org", contractName: CONTRACT_NAME, walletUrl: "https://wallet.testnet.near.org", helperUrl: "https://helper.testnet.near.org", explorerUrl: "https://explorer.testnet.near.org", }; ``` To connect to NEAR we will be using the `useEffect` React Hook, and populate it with the following ```javascript= export const connectToNEAR = async () => { // establishes connection to NEAR const near = await connect( config ); // Creates a walletConnection Instance to interact with your wallet window.walletConnection = new WalletConnection(near); // Retreives a String of the name of the current account that is signed in window.accountId = window.walletConnection.getAccountId(); // creates a contract object instance to interact with the smart contract window.Contract = await new Contract( window.walletConnection.account(), config.contractName, { viewMethods: ["get_status"], changeMethods: ["set_status"], } ); }; ``` This will allow us to define our keystore (which is set to the browser storage), and establish a connection to the NEAR wallet Afterwards we will simply define our login and logout buttons ```javascript= export function logout() { window.walletConnection.signOut(); // reload page window.location.replace(window.location.origin + window.location.pathname); } export function login() { // Allow the current app to make calls to the specified contract on the // user's behalf. // This works by creating a new access key for the user's account and storing // the private key in localStorage. window.walletConnection.requestSignIn(config.contractName); } ``` Now head to `index.js` and import these newly created methods with the following. ```javascript= import { connectToNEAR } from "./utils"; ``` Now we will want to call this method before we mount our application ```javascript= connectToNEAR().then(() => { root.render( <React.StrictMode> <App /> </React.StrictMode> ); }); ``` >Note React Issue with Webpack... ``` BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it. If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }' - install 'buffer' If you don't want to include a polyfill, you can use an empty module like this: resolve.fallback: { "buffer": false } ``` Workaround until react fixes this issue.. In the `package.json` file downgrade react scripts from 5.0.1 to 4.0.3 ```javascript= "dependencies":{ ..., "react-scripts": "4.0.3", ... } ``` ## Integrating Methods ### NEAR-API-JS Methods | Name | Desctiption | | ----- | ------------------------------------------------------- | | Login | Creates Full or FunctionCall Access Key for Application | |Logout| Logs user out of DApp| Set conditional statements in Navbar to login or logout of an application `src/App.js` Add the following to your list of imports in `App.js` ```javascript= import { login, logout } from "./utils"; ``` Add the conditional statement that checks the login status of the application. If the user is not logged in then call the `login` function, if they are logged in then called the `logout` function in the `onClick` logic for the login button in the Navbar `src/App.js` ```javascript= <Nav> //Code of interest <Nav.Link onClick={window.walletConnection.isSignedIn() ? logout : login} > {console.log(window.accountId)} {window.walletConnection.isSignedIn() ? window.accountId : "Login"} </Nav.Link> </Nav> ``` ## Writing the Smart Contract Refer to [This Document](https://hackmd.io/RI6JZ0jZRPqK_DRjpkK2aw?both) with this corresponding [presentation](https://docs.google.com/presentation/d/1vJIPBG9DHHdfViKhTPYPDQSqckW9DGiLM5z-YhO2Waw/edit#slide=id.p) ![](https://i.imgur.com/w40suAZ.png) ### Smart Contract Method | Name | Description | | ----------- | --------------------------------- | | get_message | Retreives messsage from NEAR Blockchain as a String | | set_message | Stores message in NEAR Blockchain | Within the `function App()` component's body where you have the state variables, add a `useEffect` that reads the latest message from the blockchain to display the last message entered by the user. Using this react hook called `useEffect` we can run this async function that will allow us to check the blockchain for a message once the app component gets mounted ```javascript= useEffect(() => { const getMessage = async () => { changeUserMessage( await window.Contract.get_message({ account_id: window.accountId }) ); }; getMessage(); }, []); ``` This async submit method will be used to save a message onto the blockchain. Once that is done an alert will prompt the user to refresh the page ```javascript= const submit = async (e) => { e.preventDefault(); changeButtonDisable(true); await window.Contract.set_message({ message: messageRef.current.value }); alert("please refresh page"); }; ``` Once you have created this, go down to where the Submit button is created in the app and uncomment out the `onClick` property Before: ```javascript= <Button disabled={buttonDisable} // onClick={submit} variant='primary' type='submit' > Submit </Button> ``` After: ```javascript= <Button disabled={buttonDisable} onClick={submit} variant='primary' type='submit' > Submit </Button> ``` ## Now Try out Your Application! ``` yarn && yarn start ``` ## Learning Resources [Near University](https://www.near.university/) [Blockheads](https://www.youtube.com/watch?v=Rt_cmIq12lo) [Discord](near.chat)