Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Lưu trữ tùy chọn người dùng trong ứng dụng Web3: Giải pháp Next.js hỗ trợ Metamask

Các ứng dụng Web3 như DAO và DApp ngày càng phổ biến. Theo tiền đề của Web3, các nền tảng này nên cung cấp trải nghiệm cá nhân hóa và tùy chỉnh hơn cho người dùng trong khi vẫn giữ danh tính riêng tư đối với người khác hoặc ngay cả chính họ.

Trong dự án này, chúng ta khám phá cách nâng cao trải nghiệm người dùng cho các trường hợp như vậy.

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

Đối với nhiều ứng dụng, ví blockchain như Metamask được dùng để quản lý tài sản crypto như ETH. Các ví nà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 với khóa riêng, 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 ai đó hiển thị 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. Việc kết nối ví cung cấp 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 ta sẽ triển khai một 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ọ. Nghĩa là, mỗi khi họ quay lại trang web đó, họ sẽ thấy UI như họ muốn.

Ý tưởng mạnh mẽ hơn có thể là chuẩn hóa giao diện người dùng trên các nền tảng con & chéo của các công ty. Cách này, khi người dùng điều hướng đến một trang web hỗ trợ các tùy chọn họ đã đặt trên các trang 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 tham số tùy chỉnh, cho phép bạn đúc nó thành bất kỳ cấu trúc nào bạn nghĩ ra.

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

  • Chủ đề (theme) của trang web
  • Tên chào hỏi cho người dùng

Bắt đầu

Cấu hình biến môi trường Upstash Redis

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

Phụ thuộc

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

Tạo file api/store.js

Cấu hình Redis SDK và xuất hàm handler.

// 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 file api/[accountAddress].js

Tương tự, cấu hình Redis SDK và xuất handler.

// 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
    })
}

Cấu hình file index.js

Đặt biế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)
// Kiểm tra nếu kết nối đã thiết lập. Nếu vậy, lấy dữ liệu.
useEffect(() => {
    checkConnection()
    getPreferences()
}, [accountAddress])

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 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")
    }
}

Để lấy 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 biến

Gán các hàm sau cho các trường input/nút bấm, 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 với phím enter/return
    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 UI đơn giản sử dụng các hàm trên

Đảm bảo bạn đã import các phụ thuộc Material-UI liên quan.

return (
    

Web3 Preferences Holder

Lets you keep user preferences on cross-websites


For example, take a greeter message from user.



Sample Component/Page:

)

Tạo sampleComponent.jsx trong 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ác tham số theo ý thích và tạo giao diện mẫu của bạn.

Trong trường hợp này, dự án được 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(
  • {key}: {userSettings[key]}
  • ) } 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 (

    Hi, {greetingMessage}!

    User and their preferences:

    {items}
    ); }

    Quy trình làm việc

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

    Lưu trữ tùy chọn người dùng trong ứng dụng Web3: Giải pháp Next.js hỗ trợ Metamask

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

    Lưu trữ tùy chọn người dùng trong ứng dụng Web3: Giải pháp Next.js hỗ trợ Metamask

    • Người dùng nhập tên họ muốn thấy khi được chào đón trê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ờ, cùng giao diện có thể 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 tùy chỉnh bởi người dùng.

    Lưu trữ tùy chọn người dùng trong ứng dụng Web3: Giải pháp Next.js hỗ trợ Metamask

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

    Như bạn 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 hiển thị cho người dùng. Bạn luôn có thể cải tiến dự án này bằng cách cải thiện thiết kế và tăng số lượng tham số; tuy nhiên logic cơ bản vẫn giữ nguyên.

    Lời kết

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

    Để xem dự án hoàn chỉnh, vào GitHub Repo của dự án.

    Ở đó, bạn sẽ thấy nút triển khai nhanh cho 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 mong chờ nghe ý tưởng và suy nghĩ của bạn. Bạn có thể liên hệ qua twitter hoặc discord.