Skip to content

Commit

Permalink
Add "Your first dapp" tutorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharydenton authored and aptos-bot committed May 10, 2022
1 parent 544f3a1 commit 4a05974
Show file tree
Hide file tree
Showing 9 changed files with 585 additions and 137 deletions.
470 changes: 470 additions & 0 deletions developer-docs-site/docs/tutorials/first-dapp.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "dappsite",
"name": "first-dapp",
"version": "0.1.0",
"private": true,
"dependencies": {
Expand All @@ -8,9 +8,9 @@
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.0",
"@types/node": "^16.11.33",
"@types/react": "^18.0.8",
"@types/react": "^18.0.9",
"@types/react-dom": "^18.0.3",
"aptos": "0.0.18",
"aptos": "^0.0.20",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
Expand Down Expand Up @@ -40,8 +40,5 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"prettier": "^2.6.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>dapp-example</title>
<title>first-dapp</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
a,
input,
textarea {
display: block;
}

textarea {
border: 0;
min-height: 50vh;
outline: 0;
padding: 0;
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,91 @@
import * as React from "react";
import { DappSite } from "./DappSite";
import React from "react";
import "./App.css";

import { Types, AptosClient } from "aptos";

const client = new AptosClient("https://fullnode.devnet.aptoslabs.com");

/** Convert string to hex-encoded utf-8 bytes. */
function stringToHex(text: string) {
const encoder = new TextEncoder();
const encoded = encoder.encode(text);
return Array.from(encoded, (i) => i.toString(16).padStart(2, "0")).join("");
}

function App() {
const aptos = (window as any).aptos;
const location = window.location;
// Retrieve aptos.account on initial render and store it.
const urlAddress = window.location.pathname.slice(1).toLowerCase();
const isEditable = !urlAddress;
const [address, setAddress] = React.useState<string | null>(null);
React.useEffect(() => {
if (urlAddress) {
setAddress(urlAddress);
} else {
window.aptos.account().then(setAddress);
}
}, [urlAddress]);

const [userAddress, setUserAddress] = React.useState<string | null>(null);
// Check for the module; show publish instructions if not present.
const [modules, setModules] = React.useState<Types.MoveModule[]>([]);
React.useEffect(() => {
if (!aptos) return;
aptos.account().then((account: string) => {
setUserAddress(account);
if (!address) setAddress(account);
});
}, [aptos]);
if (!address) return;
client.getAccountModules(address).then(setModules);
}, [address]);

const [address, setAddress] = React.useState<string | null>(null);
const hasModule = modules.some((m) => m.abi?.name === "Message");
const publishInstructions = (
<pre>
Run this command to publish the module:
<br />
aptos move publish --package-dir /path/to/hello_blockchain/
--named-addresses HelloBlockchain={address}
</pre>
);

// Call set_message with the textarea value on submit.
const ref = React.createRef<HTMLTextAreaElement>();
const [isSaving, setIsSaving] = React.useState(false);
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!ref.current) return;

const message = ref.current.value;
const transaction = {
type: "script_function_payload",
function: `${address}::Message::set_message`,
arguments: [stringToHex(message)],
type_arguments: [],
};

try {
setIsSaving(true);
await window.aptos.signAndSubmitTransaction(transaction);
} finally {
setIsSaving(false);
}
};

// Get the message from account resources.
const [resources, setResources] = React.useState<Types.AccountResource[]>([]);
React.useEffect(() => {
setAddress(location.pathname.slice(1).toLowerCase());
}, [location.pathname]);
if (!address) return;
client.getAccountResources(address).then(setResources);
}, [address]);
const resourceType = `${address}::Message::MessageHolder`;
const resource = resources.find((r) => r.type === resourceType);
const data = resource?.data as { message: string } | undefined;
const message = data?.message;

return (
<div className="App">
{address != null ? (
<DappSite userAddress={userAddress} address={address} />
{hasModule ? (
<form onSubmit={handleSubmit}>
<textarea ref={ref} defaultValue={message} readOnly={!isEditable} />
{isEditable && <input disabled={isSaving} type="submit" />}
{isEditable && <a href={address!}>Get public URL</a>}
</form>
) : (
<p>Loading...</p>
publishInstructions
)}
</div>
);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
pre, textarea, code {
body {
margin: 0;
font-size: 20px;
font-family: ui-monospace,
Menlo, Monaco,
"Cascadia Mono", "Segoe UI Mono",
"Roboto Mono",
"Oxygen Mono",
"Ubuntu Monospace",
"Source Code Pro",
"Fira Mono",
"Droid Sans Mono",
"Courier New", monospace;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

textarea {
border: 0;
width: 100%;
min-height: 50vh;
outline: 0;
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";

// Wait until DOMContentLoaded so that window.aptos is initialized.
document.addEventListener("DOMContentLoaded", () => {
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
declare global {
interface Window {
aptos: any;
}
}

const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);

window.addEventListener("load", () => {
root.render(
<React.StrictMode>
<App />
Expand Down

This file was deleted.

0 comments on commit 4a05974

Please sign in to comment.