Arweave / NextJS Template

This template uses Arweave, Warp Contracts, NextJS, TailwindCSS, DaisyUI and uvu.

Get template here

Setup

You will need an Arweave wallet which you can get from arconnect or arweave. Save the wallet.json file and place it in the root of the project directory. MAKE SURE ITS ACKNOWLEDGED BY .gitignore.

To deploy a dApp or contract to mainnet this template uses Bundlr node2. Fund a Bundlr instance by running yarn fund <amount>. To use node1, change references in package.json to node1. Note - Funding can take up to 30 minutes to register funds.

Add a .env file and add the variable WARP, setting it to either local or mainnet depending on your use case.

Install your dependencies with yarn.

Gateways

To interact with Arweave and Warp Contracts you must initialize a gateway to connect to. The Arweave gateway added to this template connect to mainnet. The Warp-Contracts gateway is conditionally chosen based on your WARP variable. These are located in utils/index.js and are available to all pages by pulling in the MainContext.

At the top of a page file import the dependencies.

import { useContext } from 'react'
import { MainContext } from '../context'

Inside of your component, declare the arweave and warp variables set to the context.

const { arweave, warp } = useContext(MainContext)

Now you can use these variables globally to call functions provided by the arweave-js and warp-contracts SDK's.

Example: This will query the Arweave network for data using GraphQL:

await arweave.api.post(`graphql`, your_query)

This connects to specific Arweave smart contracts and reads its state:

const warp.contract("CONTRACT_ID").connect(jwk)
const { cachedValue } = await contract.setEvaluationOptions({
   allowBigInt: true
}).readState()

Find out more:
Arweave SDK
Warp Contracts SDK

Testing smart contract

In tests/index.mjs there is a basic test that will deploy the counter contract and check if the state clicks has incremented. This is a way to test contracts before deploying to mainnet and using them in dApps. Creating contracts and deploying to a local testnet is a good way to ensure the contracts do exactly as needed before deploying to mainnet.

Use yarn test to run tests.

  • Flow of the test:
    • Creating ArLocal testing environment inside test
    • Deploy contract to local
    • Checks contract state
    • Generate local wallet for contract interaction
    • Write contract interaction - clicks increments by 1
    • Asserts state update
    • Tears down ArLocal testing environment

Deploy smart contract

This template has a basic counter smart contract and deploy script built in. You can deploy to local testnet or mainnet. Once your tests have passed, the contract is ready to be deployed.

For local deployment, you must run npx arlocal to create a slim gateway environment. This is so you have somewhere to deploy your contracts in your local environment.

  • For Testnet:
    • In .env add WARP=local
    • Run ArLocal npx arlocal
    • Deploy yarn deploy-contract
  • For Mainnet
    • In .env add WARP=mainnet
    • Deploy yarn deploy-contract

Interact with smart contract

For basic interactions with smart contracts you need the warp object and contract ID. To better understand this, we will be using the test explained earlier.

In the test, once deployed you get a res object returned after deploying, which has a contractTxId. The contractTxId is used, along with your wallet jwk, to connect to the contract using Warp Contracts.

// connecting to contract
const contract = warp.contract(res.contractTxId).connect(wallet.jwk)

// updating state by 1
await contract.writeInteraction({
  function: 'click'
})
// reading contracts recent state
const secondCall = await contract.readState()

The return of secondCall should look similar to this:

SortKeyCacheResult {
  sortKey: '000000000003,0000000000000,06a6a95eed3d2700cc03c1d1f158a4a1182f4d5b15f95dea5817a9db8fbda8a2',
  cachedValue: EvalStateResult {
    state: { clicks: 2 },
    validity: {
      'hdvOXH9giingC8eRl-L_ogCytyDNIP8FYIkOXDc-oyA': true,
      '6cbdUvhjUxDPLo0yD-K596L_tuv88UQJPFy-f9AiPvY': true
    },
    errorMessages: {}
  }
}

This can be abstracted into a UI to allow users to interact with any given contract. The writeInteraction function will trigger a web wallet modal for the user to sign the transaction, updating the state of the contract on mainnet, giving us the ability to build dynamic and interactive apps powered by Arweave and smart contracts.

Deploy app

Once your dApp has a UI, has been tested and you have a funded Bundlr instance, it is ready to be deployed to the Permaweb (you can deploy using arkb, though Bundlr makes transactions cheaper, and free if files are under 100kb).

dApps deployed to Arweave do not support Server Side Rendering, so everything in your dApp must be built statically. Once everything is good to be deployed run yarn build to generate the static build. Once you see that you have an out directory in the root run yarn deploy to deploy it to the Permaweb. Your console will log a URL which is where your site is deployed to. It will look like this https://arweave.net/TX_ID. It can take up to 30 minutes to register the transaction, but usually it is quite fast.

With the site deployed you can now use the Tx ID to get an .arweave.dev Permapage. Find out more about that at Permapages

Note - If you have any images from outside URL's, add the URL to next.config.js like the Arweave one below.

//
images: {
  domains: ['arweave.net', 'YOURS_HERE'],
 },
//