SvelteとMoralisによるWEB 3


このアプリの目的は、あなたがeMetum財布でMetamaskを使用してログインすることができますし、プロファイルを作成するウェブサイトを作成することです.これはあなたのアプリケーションの出発点として使用できるようにSvelteとMoralisを使用する方法の十分なカバーする必要があります.

なぜsvelte(と反応しない)


Svelte HTMLとCSSを愛する人々のためのJavaScriptフレームワークです.JavaScript内のすべてを移動する反応は、物事を不必要に複雑にする、再基本的なことを行う方法を学ぶことを強制します.Svelteは理解しやすく、コードが少なく、JavaScriptの拡張のような感じがします.

モリス


Moralis また、複数のチェーンで動作する単純なAPIを提供するサービスです.認証、データベース、ストレージ、クラウド機能は、あなたが箱から出るものの一部です.同じ場所にすべてを持つことは物事をより速く設定し、開発する.

プロジェクトの設定


端末に直接ジャンプして、新しいSvelteKit プロジェクト
$ npm init svelte@next web3-starter
$ cd web3-starter
$ npx svelte-add tailwindcss
$ npm install
$ npm run dev -- --open
  • NPMがインストールされていない場合read this .
  • 追加Tailwind もちろん任意ですが、私はそれを使用してお楽しみください.私は物事を簡単に保つためにスタイルに集中しません.
  • モリスを加える


    Moralisでアカウントを作成し、サーバーを作成する必要があります.サーバーの詳細を.env.development プロジェクトのルートでファイルします.
    VITE_PUBLIC_MORALIS_APP_ID="paste your app id here"
    VITE_PUBLIC_MORALIS_SERVER_URL="paste your server url here"
    
    端末でサーバを停止するctrl + c それから、$ npm run dev これらの変数を拾う.
    その後、あなたの頭にmoralisスクリプトを追加app.html .
      <!-- Moralis -->
      <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
      <script src="https://unpkg.com/moralis/dist/moralis.js"></script>
    
    Moralisを設定するには__layout.svelte . 私たちは私たちを得るために機能を追加します.env 変数と開始モリスは、初期のレイアウトがマウントされて(ロードされた)ときに、この関数を呼び出すし、一度moralisが開始した後、アプリケーションの残りの部分をロードします.
    <script>
      import "../app.css";
      import { onMount } from 'svelte';
    
      let moralisStarted = false; // track if started
    
      function configureMoralis() {
        // Get Env variables
        const serverUrl = import.meta.env.VITE_PUBLIC_MORALIS_SERVER_URL;
        const appId = import.meta.env.VITE_PUBLIC_MORALIS_APP_ID;
        // Start Moralis
        Moralis.start({ serverUrl, appId });
        // Let the app know it's started
        moralisStarted = true;
      }
    
      // Call configuration function when mounted
      onMount(() => {
        configureMoralis();
      });
    </script>
    
    <!-- If started, page content is loaded in this slot -->
    {#if moralisStarted}
      <slot />
    {/if}
    

    スベートストアの利用


    Svelte店は、アプリケーションの複数の領域からのアクセスに必要な情報を保存するために使用されます.
    私たちはcurrentUser ストアは、我々のアプリにログインしている現在のユーザーの追跡する.
    Moralisのユーザテーブルに関する情報は、プライバシーとセキュリティ上の理由でユーザー自身がアクセスすることができます.したがって、パブリックユーザーの詳細を追加し、それを追跡するためにストアを使用して我々のデータベースにパブリックプロファイルのテーブルを作成します.
    // new file: /src/lib/stores.js
    
    import { writable } from "svelte/store";
    
    export const currentUser = writable('loading');
    export const currentProfile = writable('loading');
    
    これらは多くのように見えないが、彼らは超強力です.我々はこれらの店をインポートすることができますし、我々のアプリケーションの任意の部分での値にアクセスする$ ストア名の前に$currentUser ), この方法では、値が変更されると自動的にUIを更新します.
    私は両方の値を持つストアを初期化しています'loading' したがって、データが見つからなかったか、まだデータがロードされるのを待っているならば、我々は知っています.

    財布で署名する


    私たちのサインインボタンを作成する時間/src/lib/ButtonSignIn.svelte
    <script>
      import { currentUser, currentProfile } from "$lib/stores";
    
      // Sign in function
      async function handleSignIn() {
        if ($currentUser) return;
    
        // Authenticate with MetaMask (Moralis API)
        const user = await Moralis.authenticate({
          signingMessage: "Sign in with Ethereum"
        });
    
        // Update value of current user store
        $currentUser = user;
      }
    
      // Sign out function
      async function handleSignOut() {
        await Moralis.User.logOut();
        $currentUser = null;
        $currentProfile = null;
      }
    </script>
    
    <!-- Still waiting for user data -->
    {#if $currentUser == 'loading'}
      <p>Loading user…</p>
    
    <!-- User is logged in, check for profile -->
    {:else if $currentUser}
    
      <!-- profile still loading -->
      {#if $currentProfile == 'loading'}
        <p>Loading profile…</p>
    
      <!-- has a profile -->
      {:else if $currentProfile}
        <p>User is {$currentProfile.get("username")}</p>
        <button on:click={handleSignOut}>Sign out</button>
    
      <!-- no profile found -->
      {:else}
        <p>Create profile (To do…)</p>
      {/if}
    
    <!-- User is logged out, show Sign in button-->
    {:else}
      <button on:click={handleSignIn}>
        Sign in with MetaMask
      </button>
    {/if}
    
    ここでは、複数の状態をカバーしています.まず、現在のユーザを探して、そのユーザーのプロファイルを探します.我々両方があるならば、すべてはすばらしいです、そして、ユーザーは完全にログインされます.
    しかし、我々は積載で動けないです.私たちはまだ、現在のユーザであるMoralisに頼む必要があります.これはすべてのページで起こる必要がありますので、それは行く必要があります__layout.svelte .
    <script>
      import "../app.css";
      import { onMount } from 'svelte';
    
      // Import stores
      import { currentUser, currentProfile } from "$lib/stores";
    
      // Import our sign in button
      import ButtonSignIn from "$lib/ButtonSignIn.svelte";
    
      let moralisStarted = false;
    
      // Get user when moralisStarted changes
      $: if (moralisStarted) getCurrentUser();
    
      // Get profile when value of $currentUser changes
      $: if ($currentUser) getCurrentProfile();
    
      async function configureMoralis() {...}
    
      // Check Moralis for current user
      async function getCurrentUser() {
        let user = Moralis.User.current();
        $currentUser = user;
        $currentProfile = 'loading';
      }
    
      // Check Moralis for current profile
      async function getCurrentProfile() {
        if ($currentUser == 'loading') return; // Ignore if still loading
    
        // Get Current Profile ID from Current User
        let id = $currentUser?.get("currentProfile")?.id;
        if (id) {
    
          // Get Profile from Moralis and update store
          const query = new Moralis.Query("Profile");
          $currentProfile = await query.get(id); // Profile or null
    
        } else {
          $currentProfile = null; // No profile created yet
        }
      }
    
      ...
    </script>
    
    {#if moralisStarted}
    
      <!-- Add sign in to top of the page -->
      <ButtonSignIn />
      <hr />
    
      <!-- Content for index.svelte and other pages will load here -->
      <slot />
    
    {/if}
    
    The $: を示すreactive statement Svelteで.それは、コードの一部が値を変更するたびに実行されることを意味します.

    プロファイルの作成


    ここで署名をした後にプロファイルを作成させる必要があります.では、新しいファイルでフォームを作成しましょう/src/lib/ProfileCreate.svelte .
    <script>
      import { currentUser, currentProfile } from "$lib/stores";
    
      // Any data we want in our profile
      let profileData = {
        username: "",
        bio: ""
      };
    
      async function handleCreateProfile() {
    
        // Get reference to Profile object from Moralis
        const Profile = Moralis.Object.extend("Profile");
    
        // Create a new profile object
        let profile = new Profile();
    
        // Add data to profile object
        profile.set("username", profileData.username.toLowerCase());
        profile.set("bio", bio);
        profile.set("user", $currentUser);
    
        // Save profile in Moralis
        await profile.save();
    
        // Update profile store
        $currentProfile = profile;
    
        // Save current profile on currentUser in Moralis
        $currentUser.set("currentProfile", profile);
        await $currentUser.save();
      }
    </script>
    
    <p>
      Welcome, {$currentUser.get("ethAddress")}. <br />
      Please create a profile.
    </p>
    <p>
      <input type="text"
        bind:value={profileData.username}
        placeholder="Username"
      />
    </p>
    <p>
      <textarea
        bind:value={profileData.username}
        placeholder="Bio (optional)"
      />
    </p>
    <p>
      <button
        on:click={handleCreateProfile}
        disabled={!profileData.username}
      >
        Create profile
      </button>
    </p>
    
    入力に対するsvelteのデータバインドはprofileData 変数は常に余分な作業なしでユーザが入力したものと同期します.また、ユーザーがいくつかのユーザー名を追加するまで、ボタンを無効にしている.

    プロフィール作成


    Buttonsigninコンポーネントに戻ると、プロファイルが作成されたときにプロファイルの作成フォームが表示されます.
    <script>
      import { currentUser, currentProfile } from "$lib/stores";
    
      // Import profile create form
      import ProfileCreate from "$lib/ProfileCreate.svelte";
    
      ...
    </script>
    
    {#if $currentUser == 'loading'}
      ...
    
    {:else if $currentUser}
    
      {#if $currentProfile == 'loading'}
        ...
    
      {:else if $currentProfile}
        ...
    
      <!-- no profile found -->
      {:else}
    
        <!-- show create profile form -->
        <ProfileCreate />
    
      {/if}
    
    {:else}
      ...
    {/if}
    
    
    これはすでに多くの機能を追加するために使用できる概念の多くをカバーしています.新しいテーブルを追加し、データのコピーを読むには、プロファイルのためにした.あなたのアプリケーション間のデータにアクセスするには、新しいストアを作成します.
    他の詳細についてはsvelteとmoralisドキュメントをチェックしてください.
    何かが不明だった場合は、コメントを残して、質問、またはあなたが構築しようとしているものと私はこの記事にパート2を追加することができます.私がここで、または、私が新しい記事を掲示するとき、見るために、あとに続いてください.👋