From a1482129aae1144cfe413b5543134bdb482d676e Mon Sep 17 00:00:00 2001 From: Ray Huang Date: Thu, 20 Jul 2023 11:32:36 +0800 Subject: [PATCH 1/4] fix --- .husky/commit-msg | 4 - .husky/post-merge | 4 - .husky/pre-commit | 4 - package-lock.json | 86 ++++++--- package.json | 2 +- src/components/CreateCoinRaffle.jsx | 241 +++++++++++-------------- src/components/PreviousCoinRaffles.tsx | 108 +++-------- src/lib/hooks/useCoins.ts | 25 +++ src/lib/hooks/useGetTx.ts | 56 ++++++ src/lib/moveCallCreateCoinRaffle.jsx | 2 +- src/lib/updateCoinMetadatas.tsx | 8 +- src/lib/utils/getAllCoins.ts | 41 +++++ src/lib/utils/getRaffle.ts | 49 +++++ src/lib/utils/utils.ts | 12 ++ src/pages/_app.tsx | 13 +- src/pages/coinRaffle.tsx | 30 ++- src/pages/index.tsx | 47 ++--- yarn.lock | 33 +++- 18 files changed, 453 insertions(+), 312 deletions(-) delete mode 100755 .husky/commit-msg delete mode 100755 .husky/post-merge delete mode 100755 .husky/pre-commit create mode 100644 src/lib/hooks/useCoins.ts create mode 100644 src/lib/hooks/useGetTx.ts create mode 100644 src/lib/utils/getAllCoins.ts create mode 100644 src/lib/utils/getRaffle.ts create mode 100644 src/lib/utils/utils.ts diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100755 index 0bd658f..0000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx --no-install commitlint --edit "$1" diff --git a/.husky/post-merge b/.husky/post-merge deleted file mode 100755 index f53e03a..0000000 --- a/.husky/post-merge +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -yarn diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index c37466e..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx lint-staged \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0902e72..a3e7557 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@mysten/sui.js": "^0.37.1", "@mysten/wallet-kit": "^0.4.12", + "@tanstack/react-query": "^4.29.25", "clsx": "^1.2.1", "dotenv": "^16.3.1", "flowbite": "^1.7.0", @@ -37,7 +38,6 @@ "eslint-config-prettier": "^8.8.0", "eslint-plugin-simple-import-sort": "^7.0.0", "eslint-plugin-unused-imports": "^2.0.0", - "husky": "^7.0.4", "jest": "^27.5.1", "lint-staged": "^12.5.0", "next-router-mock": "^0.7.5", @@ -3630,6 +3630,41 @@ "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" } }, + "node_modules/@tanstack/query-core": { + "version": "4.29.25", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.25.tgz", + "integrity": "sha512-DI4y4VC6Uw4wlTpOocEXDky69xeOScME1ezLKsj+hOk7DguC9fkqXtp6Hn39BVb9y0b5IBrY67q6kIX623Zj4Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.25", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.25.tgz", + "integrity": "sha512-c1+Ezu+XboYrdAMdusK2fTdRqXPMgPAnyoTrzHOZQqr8Hqz6PNvV9DSKl8agUo6nXX4np7fdWabIprt+838dLg==", + "dependencies": { + "@tanstack/query-core": "4.29.25", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@testing-library/dom": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", @@ -7154,21 +7189,6 @@ "node": ">=10.17.0" } }, - "node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -11625,6 +11645,14 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -14466,6 +14494,20 @@ "mini-svg-data-uri": "^1.2.3" } }, + "@tanstack/query-core": { + "version": "4.29.25", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.25.tgz", + "integrity": "sha512-DI4y4VC6Uw4wlTpOocEXDky69xeOScME1ezLKsj+hOk7DguC9fkqXtp6Hn39BVb9y0b5IBrY67q6kIX623Zj4Q==" + }, + "@tanstack/react-query": { + "version": "4.29.25", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.25.tgz", + "integrity": "sha512-c1+Ezu+XboYrdAMdusK2fTdRqXPMgPAnyoTrzHOZQqr8Hqz6PNvV9DSKl8agUo6nXX4np7fdWabIprt+838dLg==", + "requires": { + "@tanstack/query-core": "4.29.25", + "use-sync-external-store": "^1.2.0" + } + }, "@testing-library/dom": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", @@ -17091,12 +17133,6 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -20323,6 +20359,12 @@ "punycode": "^2.1.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 9c9be61..acb83df 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dependencies": { "@mysten/sui.js": "^0.37.1", "@mysten/wallet-kit": "^0.4.12", + "@tanstack/react-query": "^4.29.25", "clsx": "^1.2.1", "dotenv": "^16.3.1", "flowbite": "^1.7.0", @@ -47,7 +48,6 @@ "eslint-config-prettier": "^8.8.0", "eslint-plugin-simple-import-sort": "^7.0.0", "eslint-plugin-unused-imports": "^2.0.0", - "husky": "^7.0.4", "jest": "^27.5.1", "lint-staged": "^12.5.0", "next-router-mock": "^0.7.5", diff --git a/src/components/CreateCoinRaffle.jsx b/src/components/CreateCoinRaffle.jsx index 989051b..82ed83f 100644 --- a/src/components/CreateCoinRaffle.jsx +++ b/src/components/CreateCoinRaffle.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useWalletKit } from '@mysten/wallet-kit'; import getSuiProvider from '../lib/getSuiProvider'; import { moveCallCreateCoinRaffle } from '../lib/moveCallCreateCoinRaffle'; @@ -8,17 +8,25 @@ import { CoinMetadatas } from '../lib/config'; import { updateCoinMetadatas } from '@/lib/updateCoinMetadatas'; import RingAnimation from './RingAnimation'; import { sleep } from '../lib/sleep.jsx'; +import useCoins from '../lib/hooks/useCoins'; +import useGetTx from '../lib/hooks/useGetTx'; export default function CreateCoinRaffle() { - let walletKit = useWalletKit(); - + const walletKit = useWalletKit(); + const { currentAccount } = walletKit; + const { coins, refetchCoins, loadingCoins } = useCoins(); + const { getRaffleObjId } = useGetTx(); + console.log('coins:', coins); + const [raffleName, setRaffleName] = useState('My Raffle'); + const [prizeBalance, setPrizeBalance] = useState(0); + const [winnerCount, setWinnerCount] = useState(1); + const [addresses, setAddresses] = useState( + '0x3d1037246147d652b463ff8815acaf034091d21bf2cfa996fab41d36c96ba099\n0x04d626ce8938318165fab01491095329aee67fd017a4a17fe2c981b8a9a569cc\n0x388a0e160cb67dbac3a182f1fadd31612a78fc271916db4b2f7d99d2c9ca2c72' + ); const [startRaffleDigest, setStartRaffleDigest] = useState(''); const [currentRaffleObjId, setCurrentRaffleObjId] = useState(''); const [currentRaffleFields, setCurrentRaffleFields] = useState({}); const [txRunning, setTxRunning] = useState(false); - const [userCoinsList, setUserCoinsList] = useState([]); - const [gettedUserCoinsList, setGettedUserCoinsList] = useState(false); - const [coinMetadataReady, setCoinMetadataReady] = useState(false); const [currentCoinInfo, setCurrentCoinInfo] = useState({ iconUrl: null, coinType: '0x2::sui::SUI', @@ -26,77 +34,49 @@ export default function CreateCoinRaffle() { symbol: 'SUI', }); - // TODO: ray: - if (!gettedUserCoinsList && walletKit && walletKit.currentAccount) { - let run = async () => { - setGettedUserCoinsList(true); - window.walletKit = walletKit; - - let network = walletKit.currentAccount.chains[0].split('sui:')[1]; - let provider = getSuiProvider(network); - let userCoins = []; - let nextCursor = ''; - let res; - do { - res = await provider.getAllCoins({ - owner: walletKit.currentAccount.address, - nextCursor, - }); - userCoins = userCoins.concat(res.data); - nextCursor = res.nextCursor; - } while (res.hasNextPage); - let coinSum = {}; - userCoins.forEach((coin) => { - if (coinSum[coin.coinType]) { - coinSum[coin.coinType].balance += Number(coin.balance); - } else { - coinSum[coin.coinType] = { - type: coin.coinType, - balance: Number(coin.balance), - }; - } - }); - setUserCoinsList(Array.from(Object.values(coinSum))); - await updateCoinMetadatas(Array.from(Object.keys(coinSum)), walletKit); - setCoinMetadataReady(true); - - // todo: may have next cursor + useEffect(() => { + if (currentAccount && startRaffleDigest) { + const raffleObjId = getRaffleObjId(startRaffleDigest); + setCurrentRaffleObjId(raffleObjId); + } + return () => { + setStartRaffleDigest(''); }; - run(); - } + }, [walletKit, startRaffleDigest]); // TODO: ray: 需要 getRaffleFields 只發生一次就夠了,但要等 walletKit Ready,且 currentRaffleObjId 有值,且 currentRaffleFields 為空 - const [gettingRaffleFieldsById, setGettingRaffleFieldsById] = useState(false); - if ( - currentRaffleObjId && - !gettingRaffleFieldsById && - !currentRaffleFields.id && - walletKit && - walletKit.currentAccount - ) { - let run = async () => { - setGettingRaffleFieldsById(true); - console.log('run:'); - let raffleFields = await getRaffleFields({ - walletKit, - raffleObjId: currentRaffleObjId, - }); - setCurrentRaffleFields(raffleFields); - console.log('raffleFields:', raffleFields); - setRaffleName(raffleFields.name); - setWinnerCount(raffleFields.winner_count); - await updateCoinMetadatas([raffleFields.coin_type], walletKit); - setPrizeBalance( - raffleFields.balance / - 10 ** CoinMetadatas[raffleFields.coin_type].decimals - ); // - setAddresses( - raffleFields.participants.join('\n') + raffleFields.winners.join('\n') - ); - setGettingRaffleFieldsById(false); - }; - run(); - } + // const [gettingRaffleFieldsById, setGettingRaffleFieldsById] = useState(false); + // if ( + // currentRaffleObjId && + // !gettingRaffleFieldsById && + // !currentRaffleFields.id && + // walletKit && + // walletKit.currentAccount + // ) { + // let run = async () => { + // setGettingRaffleFieldsById(true); + // console.log('run:'); + // let raffleFields = await getRaffleFields({ + // walletKit, + // raffleObjId: currentRaffleObjId, + // }); + // setCurrentRaffleFields(raffleFields); + // console.log('raffleFields:', raffleFields); + // setRaffleName(raffleFields.name); + // setWinnerCount(raffleFields.winner_count); + // await updateCoinMetadatas([raffleFields.coin_type], walletKit); + // setPrizeBalance( + // raffleFields.balance / + // 10 ** CoinMetadatas[raffleFields.coin_type].decimals + // ); // + // setAddresses( + // raffleFields.participants.join('\n') + raffleFields.winners.join('\n') + // ); + // setGettingRaffleFieldsById(false); + // }; + // run(); + // } + // TODO: ray: 需要 getTransactionBlock 只發生一次就夠了,但要等 walletKit Ready 且 startRaffleDigest 有值且 currentRaffleObjId 為空 const [gettingRaffleIdByDigest, setGettingRaffleIdByDigest] = useState(false); if ( @@ -133,31 +113,21 @@ export default function CreateCoinRaffle() { }; run(); } - // raffle name Handeler - let raffleNameDefault = ''; - const [raffleName, setRaffleName] = useState(raffleNameDefault); + const handleRaffleNameChange = (event) => { setRaffleName(event.target.value); }; - // prizeBlance Handeler - let prizeBalanceDefault = 0; - const [prizeBalance, setPrizeBalance] = useState(prizeBalanceDefault); const handlePrizeBalanceChange = (event) => { setPrizeBalance(event.target.value); }; - // winnerCount Handeler - let winnerCountDefault = 1; - const [winnerCount, setWinnerCount] = useState(winnerCountDefault); const handleWinnerCountChange = (event) => { setWinnerCount(event.target.value); }; - // addresses Handeler - const [addresses, setAddresses] = useState( - '0x3d1037246147d652b463ff8815acaf034091d21bf2cfa996fab41d36c96ba099\n0x04d626ce8938318165fab01491095329aee67fd017a4a17fe2c981b8a9a569cc\n0x388a0e160cb67dbac3a182f1fadd31612a78fc271916db4b2f7d99d2c9ca2c72' - ); + const handleAddressesChange = (event) => { setAddresses(event.target.value); }; + const handleSettleRaffle = async (event) => { setTxRunning(true); let result = await moveCallSettleCoinRaffle({ @@ -173,9 +143,10 @@ export default function CreateCoinRaffle() { ); } }; + const handleStartRaffle = async (event) => { - let _winnerCount = Number(winnerCount) || 1; - let _prizeBalance = prizeBalance || prizeBalanceDefault; + let _winnerCount = winnerCount; + let _prizeBalance = prizeBalance; let _addresses = addresses.split('\n'); let coin_type = currentCoinInfo.coinType; setTxRunning(true); @@ -197,10 +168,6 @@ export default function CreateCoinRaffle() { coin_type, }); console.log('resData:', resData); - - let network = walletKit.currentAccount.chains[0].split('sui:')[1]; - let provider = getSuiProvider(network); - setStartRaffleDigest(resData.digest); }; @@ -286,49 +253,51 @@ export default function CreateCoinRaffle() { className='py-2 text-sm text-gray-700 dark:text-gray-200' aria-labelledby='coinSelectDropdownButton' > - {userCoinsList.map((coin, index) => { - if (coinMetadataReady && CoinMetadatas[coin.type]) { - let icon = () => { - if (CoinMetadatas[coin.type].iconUrl) { - return ( - - ); - } else { - return <>; - } - }; - let handleOnClick = () => { - setCurrentCoinInfo({ - coinType: coin.type, - ...CoinMetadatas[coin.type], - }); - let a = document - .getElementById('coinSelectDropdownButton') - .click(); - }; - return ( -
  • - -
  • - ); - } else { - return <>; - } - })} + {coins && + coins.map((coin, index) => { + if (CoinMetadatas[coin.type]) { + let icon = () => { + if (CoinMetadatas[coin.type].iconUrl) { + return ( + + ); + } else { + return <>; + } + }; + let handleOnClick = () => { + setCurrentCoinInfo({ + coinType: coin.type, + ...CoinMetadatas[coin.type], + }); + let a = document + .getElementById('coinSelectDropdownButton') + .click(); + }; + return ( +
  • + +
  • + ); + } else { + return
    ; + } + })}