Learn how to build native mobile apps using blockchain functionality
@nexis-network-mobile/mobile-wallet-adapter-protocol
and
@nexis-network-mobile/mobile-wallet-adapter-protocol-web3js
window
object of your webpage. This gives
your site access to them. Mobile wallets, however, are native applications on a
mobile operating system. There’s no way to surface functions from one native
application to another. The Mobile Wallet Adapter exists to enable any app,
written in any language, to connect to a native wallet app.
We’ll dig into the specifics of the Mobile Wallet Adapter in a
later lesson, but it effectively opens
a WebSocket between applications to facilitate communication. That way a
separate app can provide the wallet app with the transaction to be signed and
sent, and the wallet app can respond with appropriate status updates.
<div>
, <p>
, and <img>
you’ll be using <View>
, <Text>
, and <Image>
.onClick
, you’ll use onPress
and
other gestures.ios
and android
directories contain platform-specific information.
Additionally, there are config files like Gemfile
and metro.config.js
.
Generally, leave all configurations alone and just worry about writing your
code, the starting point for which will be in App.tsx
.transact
function, which we’ll talk
about soon.
useConnection
hook to grab the Connection
object. Using
that, you can get account info. Since reading is free, we don’t need to actually
connect to the wallet.
solana-wallet://
scheme.
transact
function:
Web3MobileWallet
object. You can then use
this to send transactions to the wallet. Again, when you want to access the
wallet, it has to be through the function transact
function’s callback.
transact
callback. The flow is as
follows:
transact
which will have a callback
of async (wallet: Web3MobileWallet) => {...}
.wallet.authorize
or
wallet.reauthorize
method depending on the state of the wallet.wallet.signTransactions
or sign and send with
wallet.signAndSendTransactions
.“built on blockchain technology that issue or allow the exchange of cryptocurrencies or NFTs.”
transact
callback. Remember to look at our other lessons if you need a
refresher on Nexis Native Chain development more broadly.
✖ Copying template
, add the --npm
flag
at the end
Open project > Navigate to the cloned directory > Select mobile-wallet-adapter/android
fakewallet
in
the build/run configuration dropdown in the top right
Logcat
. Now that your fake wallet is
running on the emulator, go to View -> Tool Windows -> Logcat
. This will
open up a console logging out what’s happening with fake wallet.
java --version
in your
terminal.
Connection
object to interact with Nexis Native Chain (ConnectionProvider.tsx
)ProgramProvider.tsx
)AuthProvider.tsx
)CounterView.tsx
)CounterButton.tsx
)counter
.
Let’s make sure everything is set up properly by starting the default app and
running it on our Android emulator.
@nexis-network-mobile/mobile-wallet-adapter-protocol
: A React Native/Javascript API
enabling interaction with MWA-compatible wallets@nexis-network-mobile/mobile-wallet-adapter-protocol-web3js
: A convenience wrapper
to use common primitives
from @nexis-network/web3.js, such
as Transaction
and Uint8Array
@nexis-network/web3.js
: Nexis Native Chain Web Library for interacting with the Nexis Native Chain network
through the JSON RPC APIreact-native-get-random-values
Secure random number generator polyfill
for web3.js
underlying Crypto library on React Nativebuffer
: Buffer polyfill; also needed for web3.js
on React Native@coral-xyz/anchor
: The Anchor TS client.assert
: A polyfill that lets Anchor do its thing.text-encoding-polyfill
: A polyfill needed to create the Program
objectcomponents
and within it, a file called ConnectionProvider.tsx
. This
provider will wrap the entire application and make our Connection
object
available throughout. Hopefully, you’re noticing a pattern: this is identical to
the React patterns we’ve used throughout the course.
WalletProvider
that we’re used to in web
apps. However, since we’re using Android and its natively installed wallets, the
flow to connect and utilize them is a bit different. Most notably, we need to
follow the MWA protocol.
We do this by providing the following in our AuthProvider
:
accounts
: If the user has multiple wallets, different accounts are
maintained in this array of Accounts.selectedAccount
: The current selected account for the transaction.authorizeSession(wallet)
: Authorizes (or reauthorizes, if token is expired)
the wallet
for the user and returns an account which will act as the
selected account for the session. The wallet
variable is from the callback
of the transact
function you call independently anytime you want to interact
with a wallet.deauthorizeSession(wallet)
: Deauthorizes the wallet
.onChangeAccount
: Acts as a handler when selectedAccount
is changed.getPublicKeyFromAddress(base64Address)
: Creates a new Public Key object from
the Base64 address given from the wallet
objectgetAuthorizationFromAuthResult
: Handles the authorization result, extracts
relevant data from the result, and returns the Authorization
context objectuseAuthorization
hook.
Since this provider is the same across virtually all apps, we’re going to give
you the full implementation that you can copy/paste. We’ll dig into the details
of MWA in a future lesson.
Create the file AuthProvider.tsx
in the components
and paste in the
following:
models
, then
create a new file anchor-counter.ts
. Paste the contents of the
Anchor Counter IDL into this
new file.
Next, create the file ProgramProvider.tsx
inside of components
. Inside we’ll
create the program provider to surface our program and the counter PDA:
App.tsx
with the following changes:
ConnectionProvider
, then AuthorizationProvider
,
and finally ProgramProvider
ConnectionProvider
AuthorizationProvider
<View>
with <MainScreen />
, a screen we’ll
build in the next stepscreens
and a new file called MainScreen.tsx
inside of it. In this file, we
are only structuring the screen to display two yet-to-be-created components:
CounterView
and CounterButton
.
Additionally, in this file, we’re introducing React Native’s StyleSheet
. This
is another difference from regular React. Don’t worry, it behaves very similarly
to CSS.
In screens/MainScreen.tsx
paste the following:
CounterView
is the first of our two program-specific files.
CounterView
’s only job is to fetch and listen for updates on our Counter
account. Since we’re only listening here, we don’t have to do anything
MWA-related. It should look identical to a web application. We’ll use our
Connection
object to listen for the programAddress
specified in
ProgramProvider.tsx
. When the account is changed, we update the UI.
In components/CounterView.tsx
paste the following:
CounterButton
. This floating action
button will do the following in a new function incrementCounter
:
transact
to get access to a mobile walletauthorizeSession
from the useAuthorization
hookincrement
transactionsignAndSendTransactions
to have the wallet sign and send the
transactionCounterButton.tsx
and paste in the following:
CounterButton
→ Make sure you have Nexis Native Chain
wallet installed ( like the fake wallet we installed in Prerequisites )increment
→ This is likely due
to you reaching a Devnet airdrop rate limit. Take out the airdrop section in
CounterButton
and manually send some Devnet sol to your wallet’s address
(printed in the console)main
branch of the repository.
decrement
function on our program. This
instruction already exists on the program and its IDL, so you simply need to
write client code to call it.
After you give it a try on your own, feel free to take a look at the
solution code on the solution
branch.