React - 使用 Wagmi 連接錢包並保持連線

依照 wagmi document 指示安裝好 package後,首先在 React 建立連線錢包按鈕的 Component:

import { useAccount, useConnect } from 'wagmi'
import { InjectedConnector } from 'wagmi/connectors/injected'
import React from 'react'
import { useDisconnect } from 'wagmi'

export default function ConnectButton() {
  const { address, isConnected } = useAccount()
  const { connect } = useConnect({
    connector: new InjectedConnector(),
  })

  const { disconnect } = useDisconnect()

  async function connectWallet() {
    try {
      connect()
      localStorage.setItem('isWalletConnected', true) 
      // 連接錢包後將 localStorage 的 isWalletConnected 欄位設定為 true
    } catch (ex) {
      console.log(ex)
    }
  }

  async function disconnectWallet() {
    try {
      disconnect()
      localStorage.setItem('isWalletConnected', false)
      // 解除連接錢包後將 localStorage 的 isWalletConnected 欄位設定為 false
    } catch (ex) {
      console.log(ex)
    }
  }

  if (isConnected) return( // 如果 isConnected == true 表示在連線狀態,再次點擊會斷開連接
    <div>
      <button  id='wallet_address' onClick={() => disconnectWallet()}>Connected to {address}</button>
    </div>
  )
  return(
    <div>
      <button id='personal_btn' onClick={() => connectWallet()}>Connect Wallet</button>
    </div>
  )
}

在需要連接錢包、保持連線的地方新增以下程式碼

import * as React from 'react';
import { useEffect } from "react";
import { InjectedConnector } from 'wagmi/connectors/injected'
import ConnectButton from "./component/connect";
import { useConnect  } from 'wagmi'

function Main() {
	const { connect } = useConnect({
    connector: new InjectedConnector(),
  })

	useEffect(() => { 
    // 每次進入頁面都檢查 localStorage 是否有已連線的資訊,沒有則自動連線錢包
		const connectWalletOnPageLoad = async () => {
			if (localStorage?.getItem('isWalletConnected') === 'true') {
				try {
					connect()
				} catch (ex) {
					console.log(ex)
				}
			}
		}

		connectWalletOnPageLoad()
	}, [])

	return(
		<div>
			<div><ConnectButton /></div> 
		</div>
	  );
};

export default Main;

Reference

Keep Wallet Connected on Page Refresh — Web3 Dev

Go - HTTP POST/GET request 筆記

我的 Go 版本:go version go1.20.1 darwin/amd64

GET

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {

    resp, err := http.Get("https://weippig.com/")

    if err != nil {
        log.Fatal(err)
    }

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(body))
}

POST

假設要發送 POST 請求給某個叫做 http://apple.com 的 url,並且使用 JSON 格式傳送字串 merchant_id 和 merchant_trade_no 以及數字 total_amount:

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "io/ioutil"
)

func main() {
    url := "http://apple.com"
    values := map[string]interface{}{
		"merchant_id":       "111",
		"merchant_trade_no": "123",
		"total_amount":      1,
	 }

    json_data, err := json.Marshal(values)

    if err != nil {
        log.Fatal(err)
    }

    resp, err := http.Post(url, "application/json",
        bytes.NewBuffer(json_data))

    if err != nil {
        log.Fatal(err)
    }

    body, error := ioutil.ReadAll(resp.Body)
    if error != nil {
      fmt.Println(error)
    }

    resp.Body.Close()

    fmt.Println(string(body))
}

Express + Swagger 學習記錄

Express 後端寫到一半,想弄個 swagger 來做測試,也可一目了然現在有什麼 api,對網路上的學習資源做了一些整理:

方法:使用 swagger-autogen

  1. 用下面指令安裝需要的 package
     npm install --save swagger-autogen swagger-ui-express
    
  2. 建立 swagger.js
     const swaggerAutogen = require('swagger-autogen')()
    
     const outputFile = './swagger_output.json'
     const endpointsFiles = ['./app.js'] 
    
     swaggerAutogen(outputFile, endpointsFiles)
    
  3. app.js 加入程式碼:
     const swaggerUi = require('swagger-ui-express')
     const swaggerFile = require('./swagger_output.json') 
    
     app.use('/api-doc', swaggerUi.serve, swaggerUi.setup(swaggerFile))
    
  4. 在終端機執行 swagger.js,自動產生 swagger_output.json
     node ./swagger.js
    
  5. 進入 http://localhost:3000/api-doc/ 就可以看到 swagger ui 了!

資料來源 使用 Swagger 自動生成 API 文件

Go - Export struct

在研究怎麼 Export struct 時,找到說 struct 名字要大寫,但改成大寫後卻出現下面的警告:

export struct field is unused

原來是 struct field 也要改成大寫,變成 exported fields!

Firebase 學習記錄

因為網路上的教學有些有點舊,所以整理了一篇 firebase 學習記錄。

  1. 建立專案,參考這篇
  2. 寫入資料(不覆蓋路徑下舊有的資料,但為了區別所以會自動產生一個亂數的key)
     function write(groupid, userid, username, message) {
       push(ref(db, '/group/'+ groupid), {
         userid: userid,
         username: username,
         message: message,
         timestamp: Date.now()
       })
     }
    
  3. 讀取資料,存入 itemList 後回傳
     function read(groupid) {
       const itemList = []
          
       onValue(ref(db, '/group/'+groupid), (snapshot) => {
         snapshot.forEach(function (snapshot) {
           var obj = snapshot.val();
           itemList.push(obj)
       })
       }, {
         onlyOnce: true
       });
    
       return itemList
     }
    
  4. 以覆蓋方式寫入資料(重置資料庫)
     function resetDB() {
       set(ref(db, '/group'), {});
     }
    

完整程式碼:

import { initializeApp } from "firebase/app";
import { getDatabase, ref, set, push, onValue} from "firebase/database";

const firebaseConfig = {
  apiKey: "你的 api key",
  authDomain: "你的 authDomain",
  databaseURL: "你的 db URL",
  projectId: "你的 projectId",
  storageBucket: "你的 storageBucket",
  messagingSenderId: "你的 messagingSenderId",
  appId: "你的 appId",
  measurementId: "你的 measurementId"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);

export function resetDB() {
  set(ref(db, '/group'), {});
}
export function write(groupid, userid, username, message) {
  push(ref(db, '/group/'+ groupid), {
    userid: userid,
    username: username,
    message: message,
    timestamp: Date.now()
  })
}

export function read(groupid) {
  const itemList = []
  
  onValue(ref(db, '/group/'+groupid), (snapshot) => {
    snapshot.forEach(function (snapshot) {
      var obj = snapshot.val();
      itemList.push(obj)
  })
  }, {
    onlyOnce: true
  });

  return itemList
}

Reference

Firebase doc