This guide covers basic use cases and teaches you how to use our React Native SDK in your mobile app. For a more comprehensive guide of how to build your first dApp, check out our React Native starter tutorial.
To connect to a wallet, use the transact function from @solana-mobile/mobile-wallet-adapter-protocol-web3js.The transact method starts a session with a locally installed MWA-compatible wallet app. Within the callback, use
wallet to send requests for signing or sending transactions/messages.
TIPUse the transact function from @solana-mobile/mobile-wallet-adapter-protocol-web3js rather than @solana-mobile/mobile-wallet-adapter-protocol.The former provides convenient wrappers around common web3.js Solana types like Transaction while the latter provides base64 encoded byte payloads.
After starting a session with a wallet app with transact, you should first request authorization for your app with a call to authorize.When requesting authorization, include an App Identity to the request so users can recognize your app during the authorization flow.
name: The name of your app.
uri: The web URL associated with your app.
icon: A path to your app icon relative to the app uri above.
Once authorized with a wallet, the app can request the wallet to sign transactions, messages and send transactions via RPC. We’ll cover that in the next section.authorize returns an AuthorizationResult that contains:
accounts: An array of Accounts (a label and public key) from the wallet.
authToken: An authorization token that can be stored and re-used for requathorization on subsequent connections.
In practice, most wallet apps only support single account authorization, so there will be at most 1 item in accounts.
For subsequent connections to the wallet app, you can skip the authorization step by sending a reauthorize request
with a previously stored authToken. If still valid, reauthorize will bypass the need to explicitly grant authorization again.
import {transact} from '@solana-mobile/mobile-wallet-adapter-protocol-web3js';import {AuthorizeAPI, DeauthorizeAPI} from '@solana-mobile/mobile-wallet-adapter-protocol';export const APP_IDENTITY = { name: 'React Native dApp', uri: 'https://yourdapp.com' icon: "./favicon.ico",};// If we have one, retrieve an authToken from a previous authorization.const storedAuthToken = maybeGetStoredAuthToken(); // dummy placeholder functionawait transact(async (wallet: AuthorizeAPI & ReauthorizeAPI) => { // If we have a previously stored authToken, we can instead call `reauthorize`. const authorizationResult = await (storedAuthToken ? wallet.reauthorize({ auth_token: storedAuthToken, identity: APP_IDENTITY, }) : wallet.authorize({ cluster: 'devnet', identity: APP_IDENTITY, })); // Rest of transact code goes below...});
A dApp can revoke authorization or “disconnect” from a wallet by sending a deauthorize request.
This will invalidate the previously provided authToken from the wallet.
await transact(async (wallet) => { if (!previouslyStoredAuthToken) { return; } // Pass in the prior auth token to invalidate it. await wallet.deauthorize({ auth_token: previouslyStoredAuthToken });});
A client interacts with the Solana network by submitting a transaction to the cluster. Transactions
allow a client to invoke instructions of on-chain Programs.For a full explanation, see the core docs overview of a transaction.
Versioned Transactions
Tab Title
A versioned transaction is a new format for transactions required for use by clients.
We’ll create a VersionedTransaction from the @solana/web3.js library.As an example, we’ll be invoking the transfer instruction from the System Program.
The System Program is an example of a Solana Native Program.
import { Connection, PublicKey, TransactionInstruction, VersionedTransaction, TransactionMessage, SystemProgram,} from "@solana/web3.js";// Create a list of Program instructions to execute.const instructions = [ SystemProgram.transfer({ fromPubkey: fromPublicKey, toPubkey: toPublicKey, lamports: 1_000, }),];// Connect to an RPC endpoint and get the latest blockhash, to include in// the transaction.const connection = new Connection(clusterApiUrl("devnet"), "confirmed");const latestBlockhash = await connection.getLatestBlockhash();// Create the "message" of a transaction and compile to `V0Message` format.const txMessage = new TransactionMessage({ payerKey: fromPublicKey, recentBlockhash: latestBlockhash.blockhash, instructions,}).compileToV0Message();// Construct the Versioned Transaction passing in the message.const versionedTransaction = new VersionedTransaction(txMessage);
For backwards compatiblity, you can still construct legacy transactions with @solana/web3.js.
After a Transaction is signed by the appropriate accounts, it can be submitted to the Solana network via RPC.
import { transact } from "@solana-mobile/mobile-wallet-adapter-protocol-web3js";import { sendTransaction, clusterApiUrl, Connection, VersionedTransaction, confirmTransaction,} from "@solana/web3.js";const connection = new Connection(clusterApiUrl("devnet"), "confirmed");const signedTx: VersionedTransaction = await transact((wallet) => { /* ...signing code from above... */});// After sending, a transaction signature is returned.const txSignature = await connection.sendTransaction(signedTx);// Confirm the transaction was successful.const confirmationResult = await connection.confirmTransaction( txSignature, "confirmed");if (confirmationResult.value.err) { throw new Error(JSON.stringify(confirmationResult.value.err));} else { console.log("Transaction successfully submitted!");}
The result from sending a transaction is a base58 transaction signature (or transaction ID). This transaction signature can be used to uniquely identify your transaction
on the ledger.Using confirmTransaction, you can check that the transaction was confirmed by the network. For other commitment levels, read about Commitment Status.
An alternative option for submitting transactions is for the dApp to send a signAndSendTransactions MWA request to a wallet.This request sends an unsigned transaction to the wallet. If authorized, the wallet will then sign the transaction and send it to the network with its own implementation.
import { transact } from "@solana-mobile/mobile-wallet-adapter-protocol-web3js";import { sendTransaction, clusterApiUrl, Connection, VersionedTransaction, confirmTransaction,} from "@solana/web3.js";const connection = new Connection(clusterApiUrl("devnet"), "confirmed");const txSignature = await transact((wallet) => { /* ...transaction code from above... */ // Send the unsigned transaction, the wallet will sign and submit it to the network, // returning the transaction signature. const transactionSignatures = await wallet.signAndSendTransactions({ transactions: [versionedTransaction], }); return transactionSignatures[0];});// Confirm the transaction was successful.const confirmationResult = await connection.confirmTransaction( txSignature, "confirmed");if (confirmationResult.value.err) { throw new Error(JSON.stringify(confirmationResult.value.err));} else { console.log("Transaction successfully submitted!");}
Follow the First dApp Tutorial to learn how to use our starter dApp scaffold, create UI components, and record a public message on the Solana Blockchain.
See our collection of Sample Apps to reference a full React Native app.