Your First Dapp
In this tutorial, you will learn how to build a dapp on the Aptos blockchain. A dapp usually consists of a user interface written in JavaScript, which interacts with one or more Move modules.
For this tutorial, we will use the Move module HelloBlockchain
described in Your First Move Module and focus on building the user interface.
We will use:
The end result is a dapp that lets users publish and share snippets of text on the Aptos blockchain.
FULL SOURCE CODE
The full source code for this tutorial is being updated. Meanwhile, the older one is available here.
Prerequisites
Aptos Wallet
Before starting this tutorial, install the Aptos Wallet extension.
After you install it:
Open the Wallet and click Create a new wallet. Then click Create account to create an Aptos Account.
Copy the private key. You will need it to set up the Aptos CLI in the next section.
TIP
Ensure that your account has sufficient funds to perform transactions by clicking the Faucet button.
Aptos CLI
Install the Aptos CLI.
Run
aptos init
, and when it asks for your private key, paste the private key from the Aptos Wallet that you copied earlier. This will initialize the Aptos CLI to use the same account as used by the Aptos Wallet.Run
aptos account list
to verify that it is working.
Step 1: Set up a single page app
We will now set up the frontend user interface for our dapp. We will use create-react-app
to set up the app in this tutorial, but neither React nor create-react-app
are required. You can use your preferred JavaScript framework.
You will now have a basic React app running in your browser.
Step 2: Integrate the Aptos Wallet Web3 API
The Aptos Wallet provides a Web3 API for dapps at window.aptos
. You can see how it works by opening up the browser console and running await window.aptos.account()
. It will print out the address corresponding to the account you set up in the Aptos Wallet.
Next we will update our app to use this API to display the Wallet account's address.
Wait until window.aptos
is defined
window.aptos
is definedThe first step when integrating with the window.aptos
API is to delay rendering the application until the window.onload
event has fired.
Open up src/index.tsx
and change the following code snippet:
to this:
This change will ensure that the window.aptos
API has been initialized by the time we render the app (if we render too early, the Wallet extension may not have had a chance to initialize the API yet and thus window.aptos
will be undefined
).
(Optional) TypeScript setup for window.aptos
window.aptos
If you are using TypeScript, you may also want to inform the compiler of the existence of the window.aptos
API. Add the following to src/index.tsx
:
This lets us use the window.aptos
API without having to do (window as any).aptos
.
Display window.aptos.account()
in the app
window.aptos.account()
in the appOur app is now ready to use the window.aptos
API. We will change src/App.tsx
to retrieve the value of window.aptos.account()
(the wallet account) on initial render, store it in state, and then display it:
Refresh the page and you will see your account address.
Add some CSS
Next, replace the contents of src/App.css
:
Step 3: Use the SDK to get data from the blockchain
The Wallet is now integrated with our dapp. Next, we will integrate the Aptos SDK to get data from the blockchain. We will use the Aptos SDK to retrieve information about our account and display that information on the page.
First, add the SDK to the project's dependencies:
You will now see "aptos": "^0.0.20"
(or similar) in your package.json
.
Create an AptosClient
AptosClient
Now we can import the SDK and create an AptosClient
to interact with the blockchain (technically it interacts with the REST API, which interacts with the blockchain).
As our wallet account is on devnet, we will set up the AptosClient
to interact with devnet as well. Add the following to src/App.tsx
:
Now, in addition to displaying the account address, the app will also display the account's sequence_number
. This sequence_number
represents the next transaction sequence number to prevent replay attacks of transactions. You will see this number increasing as you make transactions with the account.
Step 4: Publish a Move module
Our dapp is now set up to read from the blockchain. The next step is to write to the blockchain. To do so, we will publish a Move module to our account.
The Move module provides a location for this data to be stored. Specifically, we will use the HelloBlockchain
module from Your First Move Module, which provides a resource called MessageHolder
that holds a string (called message
).
Publish the HelloBlockchain
module with the Aptos CLI
HelloBlockchain
module with the Aptos CLIWe will use the Aptos CLI to compile and publish the HelloBlockchain
module.
Download the
hello_blockchain
package.Next, use the
aptos move publish
command (replacing/path/to/hello_blockchain/
and<address>
):
For example:
The --named-addresses
replaces the named address HelloBlockchain
in HelloBlockchain.move
with the specified address. For example, if we specify --named-addresses HelloBlockchain=0x5af503b5c379bd69f46184304975e1ef1fa57f422dd193cdad67dc139d532481
, then the following:
becomes:
This makes it possible to publish the module for the given account (in this case our wallet account, 0x5af503b5c379bd69f46184304975e1ef1fa57f422dd193cdad67dc139d532481
).
Assuming that your account has enough funds to execute the transaction, you can now publish the HelloBlockchain
module in your account. If you refresh the app, you will see that the account sequence number has increased from 0 to 1.
You can also verify that the module was published by going to the Aptos Explorer and looking up your account. If you scroll down to the Account Modules section, you should see something like the following:
Make a note of "name": "Message"
, we will use it in the next section.
Add module publishing instructions to the dapp
As a convenience to the users, we can have the app display the aptos move publish
command if the module does not exist. To do so, we will use the Aptos SDK to retrieve the account modules and look for one where module.abi.name
equals "Message"
(i.e., the "name": "Message"
we saw in the Aptos Explorer).
Update src/App.tsx
:
New users will be able to use this command to create a page for their account.
Step 5: Write a message on the blockchain
Now that the module has been published, we are ready to use it to write a message on the blockchain. For this step we will use the set_message
function exposed by the module.
A transaction that calls the set_message
function
set_message
functionThe signature for set_message
looks like this:
To call this function, we need to use the window.aptos
API provided by the wallet to submit a transaction. Specifically, we will create a entry_function_payload
transaction that looks like this:
There is no need to provide the account: signer
argument. Aptos provides it automatically.
However, we do need to specify the message_bytes
argument: this is the "<hex encoded utf-8 message>"
in the transaction. We need a way to convert a JS string to this format. We can do so by using TextEncoder
to convert to utf-8 bytes and then a one-liner to hex encode the bytes.
Add this function to src/App.tsx
:
Using this function, our transaction payload becomes:
Now that we understand how to use a transaction to call the set_message
function, next we call this function from our app using window.aptos.signAndSubmitTransaction()
.
We will add:
A
<textarea>
where the user can input a message, andA
<button>
that calls theset_message
function with the contents of the<textarea>
.
Update src/App.tsx
:
To test it:
Type something in the
<textarea>
and submit the form.Find your account in the Aptos Explorer and you will now see a
MessageHolder
resource under Account Resources with themessage
you wrote.
If you don't see it, try a shorter message. Long messages may cause the transaction to fail because longer messages take more gas.
Step 6: Display the message in the dapp
Now that the MessageHolder
resource has been created, we can use the Aptos SDK to retrieve it and display the message.
Get the wallet account's message
To retrieve the message, we will:
First use
AptosClient.getAccountResources()
function to fetch the account's resources and store them in state.Then we will look for one whose
type
isMessageHolder
. The full type is$address::message::MessageHolder
as it is part of the$address::message
module.In our example it is:
We will use this for the initial value of the
<textarea>
.
Update src/App.tsx
:
To test it:
Refresh the page and you will see the message you wrote earlier.
Change the text, submit the form, and refresh the page again. You will see that the contents have been updated with your new message.
This confirms that you are reading and writing messages on the Aptos blockchain.
Display messages from other accounts
So far, we have built a "single-player" dapp where you can read and write a message on your own account. Next, we will make it possible for other people to read messages, including people who do not have the Aptos Wallet installed.
We will set it up so that going to the URL /<account address>
displays the message stored at <account address>
(if it exists).
If the app is loaded at
/<account address>
, we will also disable editing.If editing is enabled, we will show a "Get public URL" link so you can share your message.
Update src/App.tsx
:
That concludes this tutorial.
Supporting documentation
Last updated