Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

Next.jsでMetamaskを使用するDAppの優先ストレージ

DAOやDAPPなどのWeb3アプリケーションはますます人気が高まっています。 Web3の前提により、これらのプラットフォームは、ユーザーのIDを他のユーザーにプライベートに保ち、さらには自分自身に知られないようにしながら、ユーザーにより個人的でカスタマイズされたエクスペリエンスを提供することになっています。

このプロジェクトでは、このような場合のユーザーエクスペリエンスを向上させる方法を探ります。

ウォレットによる認証/IDチェック

多くのアプリケーションでは、ETHなどの暗号資産を管理するためにMetamaskのようなブロックチェーンウォレットが使用されます。このようなウォレットを使用すると、ユーザーはさまざまなチェーンでアカウントを作成できます。これらのアカウントは秘密鍵を使用して作成されますが、各アカウントにはそれらを表すパブリックアドレスがあります。

公開鍵は誰でも表示できますが、それに関連するトランザクションは所有者のみが管理できます。ウォレット接続は、そのようなアプリケーションに確実な認証メカニズムを提供します。

プロジェクト

このプロジェクトでは、Next.jsを使用して設定ストレージシステムを実装します。このシステムでは、ユーザーが提供されるインターフェイスをカスタマイズします。つまり、そのサイトに戻るたびに、意図したとおりにUIが表示されます。

さらに強力なアイデアは、企業のサブプラットフォームとクロスプラットフォーム間でユーザーインターフェイスを正規化することです。このように、ユーザーが他のサイトで設定した設定をサポートする特定のサイトに移動するたびに、同様のエクスペリエンスが得られます。

また、このプロジェクトを変更して、カスタマイズ用のパラメーターの数を変更することもできます。これにより、思いついた構造にプロジェクトを成形できます。

このサンプルプロジェクトでは、パラメータは2つだけです。つまり:

  • ウェブサイトのテーマ
  • ユーザーの挨拶の名前
はじめに

UpstashRedis環境変数を構成する

  • Upstashで無料のRedisデータベースを作成する
  • .env.local.exampleファイルを.env.localにコピーします(Gitでは無視されます):
  • UPSTASH_REDIS_REST_URLおよびUPSTASH_REDIS_REST_TOKENは、Upstashコンソールのデータベース詳細ページにあります。
依存関係

依存関係をインストールします:npm i @upstash/redis @metamask/detect-provider @mui/material @emotion/react @emotion/styled

api/store.jsを作成します ファイル

Redis SDKを構成し、ハンドラー関数をエクスポートします。

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

api/[accountAddress].jsを作成します ファイル

同様に、Redis SDKを構成し、ハンドラーをエクスポートします。

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

index.jsを構成します ファイル

プロジェクトの変数を設定します 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])

メタマスクの接続
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!')
    }
  }

しばらくしてから更新またはナビゲートしたときに接続を確認する
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")
    }
}

設定を行うには
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")
    }
}

設定を取得するには
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!")
    }
}

変数の状態を変更する

次の関数を入力フィールド/ボタンなどにバインドします。

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

上記の関数を使用してシンプルなUIを作成します

関連するMaterial-UI依存関係をインポートしたことを確認してください。

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

sampleComponent.jsxを作成します ディレクトリ内のcomponents

これは、Webインターフェイス、アプリケーションなどを表す主要なコンポーネントです。このコンポーネントは、システムがどのように機能するかを視覚化し、主な目標が提供します。ここで、パラメータを好きなように解析し、サンプルインターフェイスを作成します。

この場合、プロジェクトは次のように構成されます。


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

ワークフロー ユーザーはまだMetamask経由で接続されていません。デフォルトのテンプレート。

Next.jsでMetamaskを使用するDAppの優先ストレージ

ユーザーが初めてMetamask経由で接続しました。デフォルトのテンプレート。

Next.jsでMetamaskを使用するDAppの優先ストレージ

  • ユーザーは、プラットフォームに挨拶したときに表示したい名前を入力します。
  • ユーザーは、明るいテーマと暗いテーマのどちらかを選択します。

ユーザー設定が設定されます。今後は、提供されているプリファレンスインターフェイスをサポートする任意のプラットフォームで同じインターフェイスを表示できます。ユーザーがカスタマイズしたテンプレート。

Next.jsでMetamaskを使用するDAppの優先ストレージ

このコンポーネントは、ユーザーが設定した設定をテキスト形式で表示します。好きなように解析できます。

この簡単な例でわかるように、ユーザーに表示するコンポーネントをパラメーター化できます。デザインを改善し、パラメーターの数を増やすことで、いつでもこのプロジェクトに追加できます。ただし、基本的なロジックは同じままです。

最後の言葉

プロジェクトのデモを見るには、こちらを確認してください。

完成したプロジェクトを確認するには、プロジェクトのGithubリポジトリにアクセスしてください。

そこに、Vercel展開用のクイック展開ボタンが表示されます。プロジェクトを迅速にデプロイし、UpstashRedis統合を自動的に作成できます。

ご意見・ご感想をお待ちしております。ツイッターまたは不和で私たちに連絡することができます。


  1. UpstashRedisを使用したNetlifyグラフのグローバルキャッシュ

    昨日、NetlifyはNetlify Graphと呼ばれる新機能を発表しました。私の同僚は最近、写真の同様の欠落部分を強調し、Netlifyは解決に向けて良い一歩を踏み出しました。 基本的に、Netlify Graphは、開発者がWebアプリのGraphQL API呼び出しを構築するのに役立ちます。NetlifyDashboardでGraphQLリクエストを準備した後、シングルクリックでクライアントコードをプロジェクトに挿入できます。 Netlify関数をサードパーティサービスと一緒に使用することには欠点があります。クライアント側のリクエストは、最初にNetlifyバックエンド(関数)に送

  2. Next.jsに最適なデータベース

    Next.jsを使用すると、開発者はサーバー側レンダリング機能を備えたフルスタックアプリケーションを構築できます。 VercelとNetlifyは、サーバーレス関数を使用してバックエンドAPIを作成するのに役立ちます。次の質問は、Next.jsアプリの理想的なデータベースは何かということです。この投稿では、Next.jsコミュニティで人気のあるデータベースを確認します。それらがサーバーレスモデルにどのように適合するかについてコメントします。確認すべき2つのこと: サーバーレス価格設定:価格は従量制ですか?データベースが使用されていない場合でも、料金を支払う必要がありますか? サーバーレス接続