scaffold-aptos Scaffolding | Move dApp Extreme Beginner

This article will describe a scaffolding for an Aptos dApp created by NonceGeekDAO -- Scaffold-Aptos.

https://github.com/NonceGeek/scaffold-move

For example contracts used see:

https://github.com/NonceGeek/MoveDID

It has implications for the following projects:

https://github.com/Amovane/aptos-NFT-marketplace

The main technology stack of the project:Next.js,TailwindThe

0x00 Running the program

$ git clone https://github.com/NonceGeek/scaffold-move.git
$ cd scaffold-aptos & yarn
$ direnv allow # If using direnv
$ export [... .things in .envrc...] # If setting environment variables directly
$ yarn dev

0x01 Project structure

.
├── README.md
├── next-env.d.ts
├── next.config.js
├── node_modules
├── package.json
├── postcss.config.js
postcss.config.js
scripts
src
    ├── components /* important */ │ ├── AptosConnect.js
    │ ├── AptosConnect.tsx
    │ ├── ModalContext.tsx
    │ ├── NavBar.tsx
    │ ├── NavItem.tsx
    │ ├── TooltipSection.tsx
    │ └── WalletModal.tsx
    ├── config /* important */ │ └── constants.tsx
    │ └── constants.ts
    ├── hooks
    │ ├── index.ts
    │ ├── useOffers.ts
    │ └── useTokens.ts
    ├─ pages /* important */ │ ├─ _app.ts │ ├─ _app.ts │ ├─ _app.ts
    │ ├── _app.tsx
    │ ├── api
    │ ├── did_querier.tsx
    │ ├── endpoint.tsx
    │ └── index.tsx
    ├── styles
    │ ├── globals.css
    │ └── loading.css
    ├─ types
    │ ├── Offer.ts
    │ └─ index.ts
    └── utils
        ├─ aptos.ts
        ├── nftstorage.ts
        └─ supabase.ts
├─ tailwind.config.js
├── .envrc
├── tsconfig.json
└── yarn.lock

The three main folders we'll be focusing on arecomponents,config and pagesThe

0x02 Config - Environment Variable Management

Environment variables are written to the.envrcfile, it is recommended to pass thedirenvThis environment variable management tool performs environment variable management.

But directly in thebashIt is also possible to execute the command to set environment variables in the

export NEXT_PUBLIC_DAPP_ADDRESS=0x0c78cfc8cf31129444f22da3e527a48732f5b6e4e09ffbe82ffb900f84b22a17
export NEXT_PUBLIC_DAPP_NAME=DID
export NEXT_PUBLIC_MARKET_COIN_TYPE=0x1::aptos_coin::AptosCoin
export NEXT_PUBLIC_APTOS_NODE_URL=https://fullnode.testnet.aptoslabs.com/v1/
export NEXT_PUBLIC_APTOS_FAUCET_URL=https://faucet.devnet.aptoslabs.com/v1/
export NEXT_PUBLIC_APTOS_NETWORK=testnet

exist  constants.ts file, we convert the environment variable into a global variable with a command like this:

export const DAPP_NAME = process.env.NEXT_PUBLIC_DAPP_NAME!; // changed here.

If we want to add a new environment variable, we can follow suit. For example, add a URL that points to the browser:

export const NETWORK=process.env.NEXT_PUBLIC_APTOS_NETWORK!
export const MODULE_URL="https://explorer.aptoslabs.com/account/" + DAPP_ADDRESS + "/modules?network=" + NETWORK

0x03 Components - Page Components

The main set of components includes the following --

  • Wallet Connection Component: byAptosConnect.tsx,ModalContext.tsxandWalletModal.tsxIngredients.
  • Navigation Component: byNavBar.tsxandNavItem.tsxIngredients.

3.1 Wallet Connection Component

AptosConnect.tsx The source code for this is below:

import { useWallet } from "@manahippo/aptos-wallet-adapter" ;
import { useContext } from "react";
import { ModalContext } from ". /ModalContext"; import { useContext } from "react"; import { ModalContext } from ".
import { WalletModal } from ". /WalletModal";

export function AptosConnect() {
  const { account } = useWallet(); const { modalState, setModal(); const { modalState, setModal()
  const { modalState, setModalState } = useContext(ModalContext);

  return (
    
      {account?.address ? (
        

useContext:

receives a context object (React.createContext ) and returns the current value of the context. The current context value is returned by the closest component in the hierarchy. <MyContext. (used form a nominal expression) value prop Decision.

https://zh-hans.reactjs.org/docs/hooks-reference.html#usecontext

So after clicking on theConnect Walletbutton will call thescaffold-aptos/src/pages/_app.tsxhit the nail on the headProvider::

...
return (
    <walletprovider wallets="{wallets}" autoconnect="{false}">
      <ModalContext.Provider value={modals}>
        <div classname="px-8">
          <navbar />
          <component {...pageprops} classname="bg-base-300" />
        </div>
      </ModalContext.Provider>
    </walletprovider>
  );
...

pass (a bill or inspection etc)useMemoWe can adjust the wallets we can log into, and naturally we can refer to Adapter's writeup to support new wallets.

const wallets = useMemo(
  () => [
  new AptosWalletAdapter(),
  new MartianWalletAdapter(),
  new PontemWalletAdapter(),
  
  ]
  []
).

3.2 Navigation components

NavBar.tsxThe source code is below:

import Image from "next/image" ;
import { NavItem } from ". /NavItem"; import { AptosConnect } from ".
import { AptosConnect } from ". /AptosConnect"; import { AptosConnect } from ".
import {
  MODULE_URL
} from ".. /config/constants";

export function NavBar() {
  return (
    <nav classname="navbar py-4 px-4 bg-base-100">
      <div classname="flex-1">
        <a href="http://movedid.build" target="_blank">
          <image src="/logo.png" width="{64}" height="{64}" alt="logo" />
        </a>
        <ul classname="menu menu-horizontal p-0 ml-5">
          <navitem href="/" title="AddrAggregatorManager" />
          <navitem href="/endpoint" title="EndpointManager" />
          <navitem href="/did_querier" title="DIDQuerier" />
          <li classname="font-sans font-semibold text-lg">
            <a href="https://github.com/NonceGeek/MoveDID/" target="_blank">Source Code</a>
            <a href="/en/{MODULE_URL}/" target="_blank">Contract on Explorer</a>
          </li>
        </ul>
      </div>
      <aptosconnect />
    </nav>
  );

pass (a bill or inspection etc)NavBarWe can set the URL in the navigation bar.

If it is an outbound link, you can use it as shown in the code, using the

  • tag to mark it.

    It is important to note that inNextframework, pages are routed according to thepagesautomatically generated from the files added in the

    ...
        ├── pages /* important */
        │ ├── _app.tsx
        │ ├── api
        │ ├── did_querier.tsx
        │ ├── endpoint.tsx
        │ └── index.tsx
    ...

    0x04 Pages and Chain Interaction

    We are based onindex.tsxmodule as an example. The function points involved in this module are summarized below:

    • Page Related:
      • Getting a value from an input box
      • Returns the value to the page
    • Chain interaction correlation:
      • Get the full amount of resources under an account from the chain (Resources)
      • Getting a specific resource under an account from the chain
      • Calling a method in a module (contract)

    4.1 Page Related Logic

    The lazier way of handling this is used here, through a one-timeuseStateGroups all incoming values on the page into theformInputDown.

    
      const [formInput, updateFormInput] = useState<{
        description: string;
        resource_path: string;
        
        addr: string; addr_description: string; addr_type: number; addr_description
        addr_description: string; addr_description: string; addr_description: string; addr: string
        chains: Array;
    
      }>({
        description: "",
        resource_path: "",
        addr_type: 1,
        addr: "",
        addr_description: "",
        chains: [],
      }).

    Then just assign the value in Input or any other type of component:

    updateFormInput({ . .formInput, chains: JSON.parse(e.target.value) })
      }
    />

    Get the variable at the time of use with the following code:

    const { description, resource_path, addr_type, addr, addr_description, chains } = formInput;

    The method of passing the value into the page is shown in the following code:

    <p>{JSON.stringify(resource)}</p>
    

    4.2 Chain interaction logic

    (1) Access to all resources

    By calling the aptosClient wrapped method with the following code, we can get all the resources:

    import {
      DAPP_ADDRESS,
      APTOS_FAUCET_URL,
      APTOS_NODE_URL
    } from "... /config/constants".
    import {
      WalletClient
    } from "@martiandao/aptos-web3-bip44.js";
    const { account, signAndSubmitTransaction } = useWallet();
    const client = new WalletClient(APTOS_NODE_URL, APTOS_FAUCET_URL);
    async function get_resources() {
      client.aptosClient.getAccountResources(account!.address!.toString()).then(value =>
    // do something to value!
    );
    }

    (2) Getting resources based on resource path addresses

    import { MoveResource } from "@martiandao/aptos-web3-bip44.js/dist/generated";
    const [resource, setResource] = React.useState();
    async function get_did_resource() {
      client.aptosClient.getAccountResource(account!.address!.toString(), DAPP_ADDRESS + "::addr_aggregator::AddrAggregator").then(
        setResource
      );
    }

    setResource After that, we can pass theresourcevariable provides access to this resource.

    (3) Calling contract methods

    Take the Add Address method in MoveDID as an example:

    async function create_addr() {
      await signAndSubmitTransaction(
        add_addr(), { gas_unit_price: 100 }
        { gas_unit_price: 100 }
      );
    }
    ...
    function add_addr() {
      const { description, resource_path, addr_type, addr, addr_description, chains } = formInput; }
      return {
      type: "entry_function_payload",
      function: DAPP_ADDRESS + "::addr_aggregator::add_addr",
      type_arguments: [],
      arguments: [
          addr_type,
          addr,
          chains,
          addr_description, [], arguments: [ addr_type, addr, chains, addr_description
        ]
      }
    }

    with respect totype_argumentsandargumentsSee here for an explanation of this:

    https://aptos.dev/guides/interacting-with-the-aptos-blockchain/

    When using this method, the browser wallet plugin is called to initiate the transaction:

    The above content are reproduced from the Internet, does not represent the position of AptosNews, is not investment advice, investment risk, the market need to be cautious, in case of infringement, please contact the administrator to delete.

  • Like (0)
    Donate WeChat Sweep WeChat Sweep Alipay Sweep Alipay Sweep
    Previous July 21, 2023
    Next July 21, 2023

    Related posts

    Leave a Reply

    Please Login to Comment
    WeChat Sweep
    Baidu Sweep

    Subscribe to AptosNews

    Subscribe to AptosNews to stay on top of Aptos.


    This will close in 25 seconds

    This site has no investment advice, Investment risk, Enter the market with caution.