紀錄使用Wagmi套件來取得Ens上的資料。 及串接friend.sol智能合約來加入好友及顯示好友卡片
要取得ENS上的名稱,可以快速透過Wagmi的useEnsName來取得Ens的名稱,條件是要透過使用useAccount的回傳值來取得錢包地址,再將地址帶入useEnsName。
1 2 3 4 5 6 7 const useEns = () => { const { address } = useAccount(); const { data, isError, isLoading } = useEnsName({ address : address, }); if (isError) return console .log(Error ); };
只是Wagmi他沒有原生的用Wagmi來拿到 ENS text record 的方法, 而回到底層Ethers要取得ENS text record的方式,還是都得透過Provider來取得ENS上的資料,而Wagmi的底層一樣是Ethers,所以還是要定義變數 provider = useProvider(),再透過 provider去取得所有ENS text Record資料(範例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { useProvider, useAccount, useEnsName } from "wagmi" ;const useEns = () => { const [retEnsData,setRetEnsData] = useState({}) const { address } = useAccount(); const { data, isError, isLoading } = useEnsName({ address : address, }); const provider = useProvider(); if (isError) return console .log(Error ); }; export default useEns;
隨後先新增一非同步function,來使用provider的getResolver(解析器),可以透過console.log來得知,provider.getResolver()回傳內容
1 2 3 4 async function setEnsData (ensName: string ) { const resolver = await provider.getResolver(ensName); console .log('resolver:' ,resolver); }
新增useEffect來console.log看看useEnsName及provider.getResolver()回傳什麼內容
useEnsName回傳為錢包地址的ENS的名稱,provider.getResolver()則回傳一物件,包含: {provider: AlchemyProvider(物件), name: ‘edhal.eth’, address: ‘0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41’, _resolvedAddress: undefined}
確定resolver帶入參數ensName,可以取得provider的資料後 便可以開始透過resolover來取得ENS資料並存入變數,最後在setRetEnsDat中帶入物件,把所有變數存入
最後透過 console.log(retEnsData) 便可以看到存入retEnsData的所有ENS資料
回到index.tsx檔中引入hooks
1 import useEnsData from "../hooks/useEns" ;
並且宣告變數useEnsData,暫時手動把地址或Ens網域帶入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const [domainName, setDomainName] = useState("" );const [finalDomainName, setFinalDomainName] = useState(domainName);const [currentAddr, setCurrentAddr] = useState(undefined );const [isConnect, setIsConnect] = useState(false );const ensData: ensDataType = useEnsData(currentAddr, finalDomainName);const { connect, connectors, error, isLoading, pendingConnector, isSuccess } = useConnect(); useEffect(() => { if (isSuccess) { setCurrentAddr("0x08C5E50244FC58bc15Bf07BDAbb67453e624CB17" ); setFinalDomainName("edhal.ens" ); } }, [isSuccess]);
若有_ensName就可以帶入setEnsData來宣告變數resolver = provider.getResolver(ensName),若確定可以取得解析器,則可以再透過解析器取得ENS資料。 各項ENS資料的取得方式不太一樣大部分為使用resolver.getText 只有ethAddress是provider.resolveName(ensName) Avatar為resolver.getAvatar() avatarUrl為 avatar?.url
最後將範本components中的Card複製到我們的components下,將Card置入index.tsx中,並把ensData資料帶入。
1 2 3 4 <main className={styles.main}> <ConnectButton /> <Card cardData ={ensData} cardBgColor ={ "#cdcdcd "} colors ={[]} > </Card > </main>
成功取得ensData並置入卡片中
開始設計新增好友功能,以及好友清單… 透過智能合約addFriends.sol,來製作相關功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 pragma solidity ^0.8 .2 ; contract Friends { mapping(address => address[]) public myFriends; mapping(address => address[]) public friendRequests; function sendFriendRequest (address newFriend ) external { require (newFriend != msg.sender, "Cannot send friend request to yourself!" ); friendRequests[newFriend].push(msg.sender); } function acceptFriendRequest (uint256 index ) external { address newFriend = friendRequests[msg.sender][index]; require (newFriend != address(0 ), "No such friend request" ); myFriends[msg.sender].push(newFriend); myFriends[newFriend].push(msg.sender); delete friendRequests[msg.sender][index]; } function friendsCount (address addr ) external view returns (uint256 len ) { return myFriends[addr].length; } function friendRequestsCount (address addr ) external view returns (uint256 len ) { return friendRequests[addr].length; } }
先製作好友數,好友數可以透過friendCount這個function來取得
1 2 3 4 function friendsCount (address addr ) external view returns (uint256 len ) { return myFriends[addr].length; }
使用Wagimi 的 useContractRead 來讀取智能合約上的函數-friendsCount
1 2 3 4 5 6 7 const { data, isError, isLoading } = useContractRead({ address : "0x0d522A759cd763e763f2758a813F4620b15a6190" , abi : addFriendsAbi, functionName : "friendsCount" , args : [address], chainId : 5 , });
這時候透過console.log(data)來檢查後,發線回傳的值為Hex值,必須要轉譯才能成為十進位數字,透過ethers.js官方文件內搜尋到如何轉譯
1 2 3 console .log(ethers.utils.hexDataLength(data))