{"id":22051539,"url":"https://github.com/unboxed-software/solana-expo","last_synced_at":"2026-04-11T10:37:20.540Z","repository":{"id":207655767,"uuid":"719782802","full_name":"Unboxed-Software/solana-expo","owner":"Unboxed-Software","description":null,"archived":false,"fork":false,"pushed_at":"2023-11-16T22:22:44.000Z","size":194,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-28T21:34:20.238Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Unboxed-Software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-11-16T22:22:16.000Z","updated_at":"2023-11-16T22:22:48.000Z","dependencies_parsed_at":"2023-11-17T00:06:32.113Z","dependency_job_id":null,"html_url":"https://github.com/Unboxed-Software/solana-expo","commit_stats":null,"previous_names":["unboxed-software/solana-expo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unboxed-Software%2Fsolana-expo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unboxed-Software%2Fsolana-expo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unboxed-Software%2Fsolana-expo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unboxed-Software%2Fsolana-expo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Unboxed-Software","download_url":"https://codeload.github.com/Unboxed-Software/solana-expo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245121591,"owners_count":20564151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-30T15:09:32.061Z","updated_at":"2025-10-08T00:37:17.493Z","avatar_url":"https://github.com/Unboxed-Software.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Notes\n\n- Java version 11 (openjdk 11.0.20.1 2023-08-24)\n- https://developer.android.com/studio\n- if you’re running on a mac - you’ll need to run:\n    \n    ```bash\n    git clone https://github.com/Unboxed-Software/solana-mobile-counter.git\n    cd solana-mobile-counter\n    npm install\n    cd android/\n    chmod +x gradlew\n    cd ..\n    npm run android\n    ```\n    \n\n# Lesson\n\n---\ntitle: Basic React Native\nobjectives:\n- Explain the...\n- Explain how...\n- Use...\n---\n\n# TL;DR\n\n- …\n- ….\n- …\n\n# Overview\n\n## Topic\n\n### Subtopic\n\n## Conclusion\n\n# Demo\n\nToday we will be building a simple Android mobile counter dApp with React Native with Expo. The app will interact with the [Anchor counter program](https://www.soldev.app/course/intro-to-anchor-frontend) that we made in the [Intro to client-side Anchor development](https://www.soldev.app/course/intro-to-anchor-frontend) lesson. In the app we will be able to: see the current count, and increment it. All on devnet.\n\n### 1. Prerequisites\n\nReact Native allows us to write our applications like we’re used to on the web. To do this, React Native actually compiles down to languages that phones understand. On top of this, we will be using [Expo which is a set of tools and services](https://reactnative.dev/docs/environment-setup) built around React Native to make our lives easier. However, this means we have some setup to do.\n\n1. Android Studio\n    1. [Setup a React Native dev environment](https://reactnative.dev/docs/environment-setup?guide=native#creating-a-new-application). Go through the ***[entire article](https://reactnative.dev/docs/environment-setup?guide=native#creating-a-new-application)*** and accomplish the following for **************Android**************:\n        1. Install dependancies\n        2. Installing Android Studio\n        3. Configuring **ANDROID_HOME** environment variable \n        4. Create a new sample project (only for setting up the emulator)\n            1. If you run into an error `✖ Copying template`, add the `--npm` flag at the end\n            \n            ```bash\n            npx react-native@latest init AwesomeProject\n            ✔ Downloading template\n            ✖ Copying template\n            \n            npx react-native@latest init AwesomeProject --npm\n            ✔ Downloading template\n            ✔ Copying template\n            ```\n            \n        5. Run and compile the sample project on an emulator \n    2. Install the Solana fake wallet\n        1. Install the repo\n            \n            ```bash\n            git clone https://github.com/solana-mobile/mobile-wallet-adapter.git\n            ```\n            \n        2. In Android Studio, `Open project \u003e Navigate to the cloned directory \u003e Select mobile-wallet-adapter/android/build.gradle`\n        3. After Android Studio finishes loading the project, select `fakewallet` in the build/run configuration dropdown in the top right\n            \n            ![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/ec2a3cf6-83e2-40e2-9f09-a64e303f7a96/a7b704e7-60cb-45af-8bbd-0f4acd5587e4/Untitled.png)\n            \n2. Expo and EAS ( Expo Application Services )\n    1. [Create an account](https://expo.dev/signup)\n    2. Install the eas-cli \n        ```bash\n        npm install --global eas-cli\n        ```\n        \n\nLastly, if you run into Java versioning issues - you’ll want to be on Java version 11. To check what you’re currently running type `java --version` in your terminal.\n\n### 2. Create the App\n\n**Important!** Since the `@solana-mobile/mobile-wallet-adapter-protocol` package we will use includes native code, we cannot build and [run Expo normally](https://docs.solanamobile.com/react-native/expo#running-the-app). We’ll need to build it first, and then run our development client. You can do this locally, or use an Expo account to have them build it for you. We are going to build this locally, if you want expo to build it [follow the Solana Mobile’s guide](https://docs.solanamobile.com/react-native/expo#local-vs-eas-builds).\n\nLet’s create our app with the following:\n\n`npx create-expo-app -t expo-template-blank-typescript solana-expo`\n\nThen let’s make sure everything is setup properly by starting the default app and running it on our android emulator.\n\n`cd solana-expo` \n\n### 3. Install Dependancies\n\nWe’ll need to add in our Solana dependancies. Fortunately [Solana Mobile gives](https://docs.solanamobile.com/react-native/expo) us a really nice list of what packages we need and why we need them: \n\n- `@solana-mobile/mobile-wallet-adapter-protocol`: A React Native/Javascript API enabling interaction with MWA-compatible wallets.\n- `@solana-mobile/mobile-wallet-adapter-protocol-web3js`: A convenience wrapper to use common primitives from [@solana/web3.js](https://github.com/solana-labs/solana-web3.js) – such as `Transaction` and `Uint8Array`.\n- `@solana/web3.js`: Solana Web Library for interacting with Solana network through the [JSON RPC API](https://docs.solana.com/api/http).\n- `react-native-get-random-values` Secure random number generator polyfill for `web3.js` underlying Crypto library on React Native.\n- `buffer` Buffer polyfill also needed for `web3.js` on React Native.\n\nWe are also going to add three of our own `@project-serum/anchor` to allow us to interact with our counter program, and `assert`, `react-native-get-random-values` and  as a polyfill to allow our other package to do it’s thing.\n\n```bash\nnpm install \\\n  @solana/web3.js \\\n  @solana-mobile/mobile-wallet-adapter-protocol-web3js \\\n  @solana-mobile/mobile-wallet-adapter-protocol \\\n  react-native-get-random-values \\\n  buffer \\\n\t@project-serum/anchor \\\n\tassert\n```\n\nWe will be adding the appropriate polyfills to our `App.tsx` in a couple of steps. Polyfills actively replace node-native libraries to make them work anywhere Node is not running.  But in case you’re curious now. We will be adding:\n\nAt the very top of the file:\n\n`import 'react-native-get-random-values';`\n\nbelow all of the imports:\n\n`global.Buffer = require('buffer').Buffer;`\n\n### 4. Expo Dependancies\n\n```bash\nnpx expo install expo-image-picker\n```\n\nIn `app.json`:\n```json\n  \"expo\": {\n    // ....\n    \"plugins\": [\n      [\n        \"expo-image-picker\",\n        {\n          \"photosPermission\": \"Allows you to use images to create solana NFTs\"\n        }\n      ]\n    ],\n    // ....\n  }\n```\n\n***NOTE*** Every time you add in new dependancies you'll have to build and re-install the app. Anything visual or logic-based can be done in the hot-reloader\n\n### 4. First Build\n\nThen we'll need to login\n\n```bash\neas login\n```\n\nThen create a file called `eas.json` in the root of your directory, with the following inside.\n\n```bash\n{\n  \"cli\": {\n    \"version\": \"\u003e= 5.2.0\"\n  },\n  \"build\": {\n    \"development\": {\n      \"developmentClient\": true,\n      \"distribution\": \"internal\"\n    },\n    \"preview\": {\n      \"distribution\": \"internal\"\n    },\n    \"production\": {}\n  },\n  \"submit\": {\n    \"production\": {}\n  }\n}\n```\n\n\n\nThen build the project. You will choose `y` for every answer. This will take a while. When it is done, you will get an output of `build-XXXXXXXXXXX.apk`\n\n```bash\nnpx eas build --profile development --platform android --local\n```\n\nTake the resulting build file and ***drag it*** into your emulator.\n\nFinally run the following to build and deploy on your emulator:\n\n```bash\nnpx expo start --dev-client --android\n```\n\nThis should open and run the app in your Android emulator. If you run into problems, check to make sure you’ve accomplished everything in the Prerequisites section.\n\n**Note:** We are making everything from scratch today, however if you just want to start with Expo Go development with Solana, check out [Solana Mobile’s Expo template](https://docs.solanamobile.com/react-native/expo-dapp-template).\n\n\n### 5. Solana Items\n\nCreate two new folders `components` and `screens`\n\nAdd in two new files `components/AuthProvider.tsx` and `components/ConnectionProvider/tsx`:\n\nCreate new file in `screens/MainScreen.tsx`:\n\n```tsx\nimport {StatusBar, StyleSheet, View, Text} from 'react-native';\nimport React from 'react';\n\nconst mainScreenStyles = StyleSheet.create({\n  container: {\n    height: '100%',\n    width: '100%',\n    backgroundColor: 'lightgray',\n  },\n\n  incrementButtonContainer: {position: 'absolute', right: '5%', bottom: '3%'},\n  counterContainer: {\n    alignContent: 'center',\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n});\n\nexport function MainScreen() {\n  return (\n    \u003cView style={mainScreenStyles.container}\u003e\n      \u003cStatusBar barStyle=\"light-content\" backgroundColor=\"darkblue\" /\u003e\n      \u003cText\u003eSolana Expo App\u003c/Text\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\nChange `App.tsx`:\n```tsx\nimport 'react-native-get-random-values';\nimport { StatusBar } from 'expo-status-bar';\nimport { StyleSheet, Text, View } from 'react-native';\nimport { ConnectionProvider } from './components/ConnectionProvider';\nimport { AuthorizationProvider } from './components/AuthProvider';\nimport { clusterApiUrl } from '@solana/web3.js';\nimport { MainScreen } from './screens/MainScreen';\nglobal.Buffer = require('buffer').Buffer;\n\nexport default function App() {\n  // const cluster = \"localhost\" as any;\n  // const endpoint = 'http://10.0.2.2:8899';\n  const cluster = \"devnet\";\n  const endpoint = clusterApiUrl(cluster);\n\n  return (\n    \u003cConnectionProvider\n      endpoint={endpoint}\n      config={{ commitment: \"processed\" }}\n    \u003e\n      \u003cAuthorizationProvider cluster={cluster}\u003e\n        \u003cMainScreen/\u003e\n      \u003c/AuthorizationProvider\u003e\n    \u003c/ConnectionProvider\u003e\n  );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funboxed-software%2Fsolana-expo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funboxed-software%2Fsolana-expo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funboxed-software%2Fsolana-expo/lists"}