Computer >> Máy Tính >  >> Lập trình >> Redis

Bộ nhớ ưu tiên cho DApps sử dụng Metamask với Next.js

Các ứng dụng Web3 như DAO và DAPP ngày càng trở nên phổ biến hơn. Theo cơ sở của Web3, các nền tảng này được cho là cung cấp trải nghiệm cá nhân và tùy chỉnh hơn cho người dùng của họ trong khi vẫn giữ bí mật danh tính của họ cho những người khác hoặc thậm chí không biết đến chính họ.

Trong dự án này, chúng tôi khám phá cách chúng tôi có thể nâng cao trải nghiệm người dùng trong những trường hợp như vậy.

Xác thực / Kiểm tra danh tính thông qua ví

Đối với nhiều ứng dụng, ví blockchain như Metamask được sử dụng để quản lý tài sản tiền điện tử như ETH. Những ví như vậy cho phép người dùng tạo tài khoản trên các chuỗi khác nhau. Các tài khoản này được tạo bằng khóa cá nhân, tuy nhiên mỗi tài khoản có một địa chỉ công khai đại diện cho chúng.

Vì khóa công khai có thể được hiển thị bởi bất kỳ ai nhưng các giao dịch liên quan đến nó chỉ có thể được quản lý bởi chủ sở hữu. Kết nối ví cung cấp một cơ chế xác thực vững chắc cho các ứng dụng như vậy.

Dự án

Trong dự án này, chúng tôi sẽ triển khai hệ thống lưu trữ tùy chọn sử dụng Next.js, nơi người dùng tùy chỉnh giao diện được cung cấp cho họ. Có nghĩa là, bất cứ khi nào họ quay lại trang web đó, họ sẽ thấy giao diện người dùng như họ mong muốn.

Thậm chí nhiều ý tưởng mạnh mẽ hơn có thể là bình thường hóa giao diện người dùng trên các nền tảng phụ &đa nền tảng của các công ty. Bằng cách này, bất cứ khi nào người dùng điều hướng đến một trang web nhất định hỗ trợ các tùy chọn mà họ đặt trên các trang web khác, họ sẽ có trải nghiệm tương tự.

Ngoài ra, dự án này có thể được sửa đổi để thay đổi số lượng các tham số để tùy chỉnh, cho phép bạn biến nó thành cấu trúc theo ý bạn.

Đối với dự án mẫu này, chỉ có 2 tham số. Cụ thể:

  • Chủ đề của trang web
  • Tên chào mừng cho người dùng

Bắt đầu

Định cấu hình các biến môi trường của Upstash Redis

  • Tạo cơ sở dữ liệu Redis miễn phí tại Upstash
  • Sao chép tệp .env.local.example sang .env.local (sẽ bị Git bỏ qua):
  • Bạn có thể tìm thấy UPSTASH_REDIS_REST_URL và UPSTASH_REDIS_REST_TOKEN tại trang chi tiết cơ sở dữ liệu trong Upstash Console.

Phụ thuộc

Cài đặt phần phụ thuộc:npm i @upstash/redis @metamask/detect-provider @mui/material @emotion/react @emotion/styled

Tạo api/store.js tệp

Định cấu hình Redis SDK và xuất hàm xử lý.

api / store.js
import { Redis } from "@upstash/redis"
const redis = Redis.fromEnv()

export default async function handler(req, res) {
  const accountID = await JSON.parse(req.body).accountID
  const body = req.body
  const setResult = await redis.set(accountID, body);
  res.status(200).json({ result: setResult })
}

Tạo api/[accountAddress].js tệp

Tương tự, hãy định cấu hình Redis SDK và xuất trình xử lý.

api / [accountAddress] .js
import { Redis } from "@upstash/redis"
const redis = Redis.fromEnv()

export default async function handler(req, res) {
    const accountID = req.query.accountAddress
    const getResult = await redis.get(accountID)
    res.status(200).json({ result: getResult })
}

Định cấu hình index.js tệp

Đặt các biến của bạn cho dự án

index.js
const [accountAddress, setAccountAddress] = useState(null)
const [themePreference, setThemePreference] = useState("light")
const [greetingMessage, setGreetingMessage] = useState("Anonymous Person")
const [userSettings, setUserSettings] = useState(null)

// Check if connection already established. If so, fetch the data.
useEffect(() => {
    checkConnection()
    getPreferences()
}, [accountAddress])

Đang kết nối Metamask

async function connect() {
    const provider = await detectEthereumProvider()
    console.log("provider:", provider)

    if (provider) {
      console.log('Ethereum successfully detected!')
      provider.request({ method: "eth_requestAccounts" }).then((accounts) => {
        if (!accountAddress) {
          setAccountAddress(accounts[0])
        }
      }).catch((err) => console.log(err))
      console.log("window.ethereum:", window.ethereum)
      getPreferences()
    } else {
      alert('Please install MetaMask!')
    }
  }

Kiểm tra Kết nối khi được làm mới hoặc điều hướng sau một thời gian

async function checkConnection() {
    const provider = await detectEthereumProvider()
    if (provider) {
      provider
        .request({ method: 'eth_accounts' })
        .then(accounts => {
          setAccountAddress(accounts[0])
        })
        .catch(console.log)
    } else {
      console.log("Not connected, window.ethereum not found")
    }
}

Để đặt tùy chọn

async function setPreferences(themePreference, greetingMessage) {
    if (accountAddress) {
      const res = await fetch(`/api/store`, {
        method: "POST",
        body: JSON.stringify({
          accountID: accountAddress,
          themePreference: themePreference,
          greetingMessage: greetingMessage,
        })
      })
      const data = await res.json()
    }
    else {
      alert("No account address detected")
    }
}

Để nhận tùy chọn

async function getPreferences(e) {
    if (accountAddress) {
      console.log("Fetching user preferences...")
      const res = await fetch(`/api/${accountAddress}`, { method: "GET" })
      const data = await res.json()

      setUserSettings(data.result)
      if (data.result) {
        setThemePreference(data.result.themePreference)
        setGreetingMessage(data.result.greetingMessage)
      }
    }
    else {
      console.log("No account connected yet!")
    }
}

Thay đổi trạng thái của các biến

Liên kết các chức năng sau với các trường / nút đầu vào, v.v.

async function handleDarkMode(e) {
    console.log("themePreference:", themePreference)
    const newPreference = themePreference == "light" ? "dark" : "light"
    setThemePreference(newPreference)
    await setPreferences(newPreference, greetingMessage)
    await getPreferences()
}

async function takeGreetingMessage(e) {
    // submit with enter/return key
    if (e.keyCode == 13) {
        const message = e.target.value
        setGreetingMessage(message)
        console.log(message)
        await setPreferences(themePreference, message)
        await getPreferences()
        e.target.value = ""
    }
}

Tạo giao diện người dùng đơn giản bằng cách sử dụng các chức năng trên

Đảm bảo rằng bạn đã nhập các phần phụ thuộc Material-UI có liên quan.

return (
    <div className={styles.container}>

      <h2>Web3 Preferences Holder</h2>
      <Button variant="contained" onClick={connect}>Connect Metamask</Button>
      <p>
        Lets you keep user preferences on cross-websites
      </p>
      <br />
      <p>For example, take a greeter message from user.</p>
      <TextField label="Call me..." variant="outlined" size="small" onKeyDown={takeGreetingMessage} />
      <br />
      <br />

      <Button onClick={handleDarkMode} variant="contained" size="small" style={{ backgroundColor: "#3D3B3B" }} > Switch Dark Mode </Button>

      <p>Sample Component/Page:</p>
      <Showcase userSettings={userSettings} />

    </div>
)

Tạo sampleComponent.jsx trong một thư mục components

Đây là thành phần chính đại diện cho giao diện web, ứng dụng của bạn, v.v. Thành phần này sẽ trực quan hóa cách hệ thống hoạt động và mục tiêu chính cung cấp. Tại đây, phân tích cú pháp các tham số theo cách bạn thích và tạo giao diện mẫu của bạn.

Trong trường hợp này, dự án được định cấu hình như sau:


import React from "react";
import { useState} from 'react'

import { ThemeProvider, createTheme } from '@mui/material/styles'
import { orange, grey } from '@mui/material/colors'

const lightTheme = createTheme({
  palette: {
    primary: {
      main: grey[400],
    },
  }
})

const darkTheme = createTheme({
  palette: {
    primary: {
      main: orange[400],
    },
  }
})

export default function Showcase(parameters) {

  const userSettings = parameters.userSettings
  const [theme, setTheme] = useState("light")
  const [greetingMessage, setGreetingMessage] = useState("Anonymous Person")

  const items = []
  if (userSettings) {

    const obj = userSettings[0]

    for (const key in userSettings) {
      items.push(<li key={key}> {key}: {userSettings[key]} </li>)
    }

    if (userSettings["themePreference"] != theme) {
      setTheme(userSettings["themePreference"] == "light" ? "light" : "dark")
    }

    if (!greetingMessage || userSettings["greetingMessage"] != greetingMessage) {
      if (userSettings["greetingMessage"]) {
        setGreetingMessage(userSettings["greetingMessage"])
      }
      else {
        setGreetingMessage("not the same message")
      }
    }
  }

  return (
    <div>
      <div style={{
        padding: 10,
        margin: 10,
        backgroundColor: theme == "light" ? "grey" : "orange",
        border: "solid",
        borderWidth: "30px",
        borderColor: theme == "light" ? "#B2B2B2" : "black"
      }}>
        <ThemeProvider
          theme={theme == "light" ? lightTheme : darkTheme}
        >

          <h2>Hi, {greetingMessage}!</h2>
          <p>User and their preferences:</p>
          {items}

        </ThemeProvider>

      </div>
    </div>
  );
}

Quy trình làm việc

Người dùng chưa được kết nối qua Metamask. Mẫu mặc định.

Bộ nhớ ưu tiên cho DApps sử dụng Metamask với Next.js

Người dùng đã kết nối qua Metamask lần đầu tiên. Mẫu mặc định.

Bộ nhớ ưu tiên cho DApps sử dụng Metamask với Next.js

  • Người dùng nhập tên mà họ muốn nhìn thấy khi được chào đón đến nền tảng.
  • Người dùng chọn giữa các chủ đề, cụ thể là sáng và tối.

Tùy chọn người dùng được thiết lập. Từ bây giờ, giao diện tương tự có thể được hiển thị trên bất kỳ nền tảng nào hỗ trợ giao diện tùy chọn được cung cấp. Mẫu do người dùng tùy chỉnh.

Bộ nhớ ưu tiên cho DApps sử dụng Metamask với Next.js

Thành phần hiển thị các tùy chọn do người dùng thiết lập ở định dạng văn bản, bạn có thể phân tích cú pháp chúng theo cách bạn muốn.

Như bạn có thể thấy trong ví dụ đơn giản này, bạn có thể tham số hóa bất kỳ thành phần nào mà bạn hiển thị cho người dùng. Bạn luôn có thể thêm vào dự án này bằng cách cải tiến thiết kế và tăng số lượng tham số; tuy nhiên logic cơ bản vẫn như cũ.

Lời cuối cùng

Để xem bản demo của dự án, hãy xem tại đây.

Để xem dự án đã hoàn thành, hãy truy cập Github Repo của dự án.

Ở đó, bạn sẽ thấy một nút triển khai nhanh để triển khai Vercel; cho phép bạn triển khai dự án nhanh chóng, tự động tạo tích hợp Upstash Redis.

Chúng tôi rất mong được nghe ý kiến ​​và suy nghĩ của bạn. Bạn có thể liên hệ với chúng tôi qua twitter hoặc disord.