From 63de043337e23bc0abc79f400063f3a39550c43f Mon Sep 17 00:00:00 2001 From: LewisB Date: Mon, 12 Jun 2023 16:58:10 +0200 Subject: [PATCH 01/10] fix: add missing transaction names --- packages/sdk-v2/src/sdk/claim/react.ts | 2 +- packages/sdk-v2/src/sdk/microbridge/react.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/sdk-v2/src/sdk/claim/react.ts b/packages/sdk-v2/src/sdk/claim/react.ts index 999a361a..90cfdb04 100644 --- a/packages/sdk-v2/src/sdk/claim/react.ts +++ b/packages/sdk-v2/src/sdk/claim/react.ts @@ -42,7 +42,7 @@ export const useClaim = (refresh: QueryParams["refresh"] = "never") => { const ubi = useGetContract("UBIScheme", true, "claim", chainId) as UBIScheme; const identity = useGetContract("Identity", true, "claim", chainId) as IIdentity; - const claimCall = useContractFunctionWithDefaultGasFees(ubi, "claim"); + const claimCall = useContractFunctionWithDefaultGasFees(ubi, "claim", { transactionName: "Claimed Daily UBI" }); const results = useCalls( [ diff --git a/packages/sdk-v2/src/sdk/microbridge/react.ts b/packages/sdk-v2/src/sdk/microbridge/react.ts index 48cebf4c..85bb18c5 100644 --- a/packages/sdk-v2/src/sdk/microbridge/react.ts +++ b/packages/sdk-v2/src/sdk/microbridge/react.ts @@ -4,7 +4,7 @@ import TokenBridgeABI from "@gooddollar/bridge-contracts/artifacts/contracts/bri import bridgeContracts from "@gooddollar/bridge-contracts/release/deployment.json"; import { TokenBridge } from "@gooddollar/bridge-contracts/typechain-types"; import { IGoodDollar } from "@gooddollar/goodprotocol/types"; -import { TransactionStatus, useCalls, useEthers, useLogs } from "@usedapp/core"; +import { ChainId, TransactionStatus, useCalls, useEthers, useLogs } from "@usedapp/core"; import { BigNumber, Contract, ethers } from "ethers"; import { first, groupBy, mapValues } from "lodash"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; @@ -109,7 +109,9 @@ export const useBridge = (withRelay = false) => { const [selfRelayStatus, setSelfRelay] = useState | undefined>(); // const bridgeTo = useContractFunction(bridgeContract, "bridgeTo", {}); - const transferAndCall = useContractFunctionWithDefaultGasFees(g$Contract, "transferAndCall"); + const transferAndCall = useContractFunctionWithDefaultGasFees(g$Contract, "transferAndCall", { + transactionName: "BridgeTransfer" + }); const bridgeRequestId = (transferAndCall.state?.receipt?.logs || []) .filter(log => log.address === bridgeContract.address) .map(log => bridgeContract.interface.parseLog(log))?.[0]?.args?.id; @@ -280,6 +282,7 @@ export const useRelayTx = () => { export const useBridgeHistory = () => { const bridgeContracts = useGetBridgeContracts(); const refresh = useRefreshOrNever(12); + const fuseChainId = 122 as ChainId; const fuseOut = useLogs( { contract: bridgeContracts[122] as TokenBridge, @@ -287,7 +290,7 @@ export const useBridgeHistory = () => { args: [] }, { - chainId: 122, + chainId: fuseChainId, fromBlock: -2e5, refresh } @@ -300,7 +303,7 @@ export const useBridgeHistory = () => { args: [] }, { - chainId: 122, + chainId: fuseChainId, fromBlock: -2e5, refresh } From 3996dd2a4bd1ed282ce597690ec43bd9e8a3bd95 Mon Sep 17 00:00:00 2001 From: LewisB Date: Wed, 14 Jun 2023 10:03:06 +0200 Subject: [PATCH 02/10] chore: re-arrange file structure --- .../src/core/layout/ActionHeader.tsx | 2 +- packages/good-design/src/core/web3/index.ts | 3 +- .../src/core/web3/{ => modals}/KimaModal.tsx | 6 +-- .../src/core/web3/modals/SignTxModal.tsx | 54 +++++++++++++++++++ .../web3/{ => modals}/SwitchChainModal.tsx | 7 ++- .../good-design/src/core/web3/modals/index.ts | 3 ++ .../bridge/MicroBridgeController.stories.tsx | 4 +- 7 files changed, 67 insertions(+), 12 deletions(-) rename packages/good-design/src/core/web3/{ => modals}/KimaModal.tsx (90%) create mode 100644 packages/good-design/src/core/web3/modals/SignTxModal.tsx rename packages/good-design/src/core/web3/{ => modals}/SwitchChainModal.tsx (89%) create mode 100644 packages/good-design/src/core/web3/modals/index.ts diff --git a/packages/good-design/src/core/layout/ActionHeader.tsx b/packages/good-design/src/core/layout/ActionHeader.tsx index 35911f70..8cecf9a9 100644 --- a/packages/good-design/src/core/layout/ActionHeader.tsx +++ b/packages/good-design/src/core/layout/ActionHeader.tsx @@ -4,7 +4,7 @@ import { Title } from "./"; interface ActionHeaderProps { textColor: any; - /** text to complete the 'To complete this action, ...' sentence */ + /** text to complete the 'To complete this action, ...' copy */ actionText: string; } diff --git a/packages/good-design/src/core/web3/index.ts b/packages/good-design/src/core/web3/index.ts index a677f99e..6958e930 100644 --- a/packages/good-design/src/core/web3/index.ts +++ b/packages/good-design/src/core/web3/index.ts @@ -1,4 +1,3 @@ export * from "./WalletAndChainGuard"; -export * from "./SwitchChainModal"; +export * from "./modals"; export * from "./ExplorerLink"; -export * from "./KimaModal"; diff --git a/packages/good-design/src/core/web3/KimaModal.tsx b/packages/good-design/src/core/web3/modals/KimaModal.tsx similarity index 90% rename from packages/good-design/src/core/web3/KimaModal.tsx rename to packages/good-design/src/core/web3/modals/KimaModal.tsx index b844c2c6..aa87c171 100644 --- a/packages/good-design/src/core/web3/KimaModal.tsx +++ b/packages/good-design/src/core/web3/modals/KimaModal.tsx @@ -1,8 +1,8 @@ import React, { useEffect } from "react"; -import { useModal } from "../../hooks/useModal"; +import { useModal } from "../../../hooks/useModal"; import { Box, Text } from "native-base"; -import { LearnButton } from "../buttons"; -import { Title } from "../layout"; +import { LearnButton } from "../../buttons"; +import { Title } from "../../layout"; type BridgeNetworks = { origin: string; diff --git a/packages/good-design/src/core/web3/modals/SignTxModal.tsx b/packages/good-design/src/core/web3/modals/SignTxModal.tsx new file mode 100644 index 00000000..14486aeb --- /dev/null +++ b/packages/good-design/src/core/web3/modals/SignTxModal.tsx @@ -0,0 +1,54 @@ +import { useColorModeValue } from "native-base"; +import React, { useEffect, useState } from "react"; +import { useConfig } from "@usedapp/core"; +import { useSwitchNetwork } from "@gooddollar/web3sdk-v2"; +import { find } from "lodash"; +import { useModal } from "../../../hooks/useModal"; +import { ActionHeader } from "../../layout"; +import { LearnButton } from "../../buttons"; + +export interface SignTxProps { + children?: any; +} + +/** + * A modal to wrap your component or page with and show a modal re-active to switchChain requests + * it assumes you have already wrapped your app with the Web3Provider out of the @gooddollar/sdk-v2 package + * @param {boolean} switching indicating if there is a pending switch request triggered + * @param children + * @returns JSX.Element + */ +export const SignTxModal = ({ children }: SignTxProps) => { + const config = useConfig(); + const [requestedChain, setRequestedChain] = useState(0); + const { setOnSwitchNetwork } = useSwitchNetwork(); + const textColor = useColorModeValue("goodGrey.500", "white"); + + const { Modal, showModal, hideModal } = useModal(); + + useEffect(() => { + if (setOnSwitchNetwork) { + setOnSwitchNetwork(() => async (chainId: number, afterSwitch: any) => { + if (afterSwitch) { + hideModal(); + } else { + setRequestedChain(chainId); + showModal(); + } + }); + } + }, [setOnSwitchNetwork]); + + const networkName = find(config.networks, _ => _.chainId === requestedChain)?.chainName; + + return ( + + } + body={} + closeText="x" + /> + {children} + + ); +}; diff --git a/packages/good-design/src/core/web3/SwitchChainModal.tsx b/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx similarity index 89% rename from packages/good-design/src/core/web3/SwitchChainModal.tsx rename to packages/good-design/src/core/web3/modals/SwitchChainModal.tsx index 3c7914a8..4086d4d5 100644 --- a/packages/good-design/src/core/web3/SwitchChainModal.tsx +++ b/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx @@ -3,9 +3,9 @@ import React, { useEffect, useState } from "react"; import { useConfig } from "@usedapp/core"; import { useSwitchNetwork } from "@gooddollar/web3sdk-v2"; import { find } from "lodash"; -import { useModal } from "../../hooks/useModal"; -import { ActionHeader } from "../layout"; -import { LearnButton } from "../buttons"; +import { useModal } from "../../../hooks/useModal"; +import { ActionHeader } from "../../layout"; +import { LearnButton } from "../../buttons"; export interface SwitchChainProps { children?: any; @@ -37,7 +37,6 @@ export const SwitchChainModal = ({ children }: SwitchChainProps) => { } }); } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [setOnSwitchNetwork]); const networkName = find(config.networks, _ => _.chainId === requestedChain)?.chainName; diff --git a/packages/good-design/src/core/web3/modals/index.ts b/packages/good-design/src/core/web3/modals/index.ts new file mode 100644 index 00000000..04793e33 --- /dev/null +++ b/packages/good-design/src/core/web3/modals/index.ts @@ -0,0 +1,3 @@ +export * from "./SwitchChainModal"; +export * from "./SignTxModal"; +export * from "./KimaModal"; diff --git a/packages/good-design/src/stories/apps/bridge/MicroBridgeController.stories.tsx b/packages/good-design/src/stories/apps/bridge/MicroBridgeController.stories.tsx index 378a4448..98a93da6 100644 --- a/packages/good-design/src/stories/apps/bridge/MicroBridgeController.stories.tsx +++ b/packages/good-design/src/stories/apps/bridge/MicroBridgeController.stories.tsx @@ -2,13 +2,13 @@ import { WalletAndChainGuard } from "../../../core/web3/WalletAndChainGuard"; import React from "react"; import { MicroBridgeController } from "../../../apps/bridge/MicroBridgeController"; import { W3Wrapper } from "../../W3Wrapper"; -import { SwitchChainModal } from "../../../core/web3/SwitchChainModal"; +import { SwitchChainModal } from "../../../core/web3/modals/SwitchChainModal"; export default { title: "Apps/MicroBridgeController", component: MicroBridgeController, decorators: [ - (Story:any) => ( + (Story: any) => ( From bd526d9fdb5eb2c584cf41f79c4489f05e5b759a Mon Sep 17 00:00:00 2001 From: LewisB Date: Wed, 14 Jun 2023 10:15:26 +0200 Subject: [PATCH 03/10] set up basic sign tx modal --- .../src/core/web3/modals/SignTxModal.tsx | 36 ++++++------------- .../src/core/web3/modals/SwitchChainModal.tsx | 1 - 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/packages/good-design/src/core/web3/modals/SignTxModal.tsx b/packages/good-design/src/core/web3/modals/SignTxModal.tsx index 14486aeb..f3025088 100644 --- a/packages/good-design/src/core/web3/modals/SignTxModal.tsx +++ b/packages/good-design/src/core/web3/modals/SignTxModal.tsx @@ -1,8 +1,5 @@ import { useColorModeValue } from "native-base"; -import React, { useEffect, useState } from "react"; -import { useConfig } from "@usedapp/core"; -import { useSwitchNetwork } from "@gooddollar/web3sdk-v2"; -import { find } from "lodash"; +import React from "react"; import { useModal } from "../../../hooks/useModal"; import { ActionHeader } from "../../layout"; import { LearnButton } from "../../buttons"; @@ -12,40 +9,27 @@ export interface SignTxProps { } /** - * A modal to wrap your component or page with and show a modal re-active to switchChain requests + * A modal to wrap your component or page with and show a modal re-active to calls from usedapp's useContractFunction * it assumes you have already wrapped your app with the Web3Provider out of the @gooddollar/sdk-v2 package - * @param {boolean} switching indicating if there is a pending switch request triggered * @param children * @returns JSX.Element */ export const SignTxModal = ({ children }: SignTxProps) => { - const config = useConfig(); - const [requestedChain, setRequestedChain] = useState(0); - const { setOnSwitchNetwork } = useSwitchNetwork(); const textColor = useColorModeValue("goodGrey.500", "white"); - const { Modal, showModal, hideModal } = useModal(); + const { + Modal + //showModal, + //hideModal + } = useModal(); - useEffect(() => { - if (setOnSwitchNetwork) { - setOnSwitchNetwork(() => async (chainId: number, afterSwitch: any) => { - if (afterSwitch) { - hideModal(); - } else { - setRequestedChain(chainId); - showModal(); - } - }); - } - }, [setOnSwitchNetwork]); - - const networkName = find(config.networks, _ => _.chainId === requestedChain)?.chainName; + // todo: add trigger to show modal on any useDapp contract function execution return ( } - body={} + header={} + body={} closeText="x" /> {children} diff --git a/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx b/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx index 4086d4d5..8041c6ea 100644 --- a/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx +++ b/packages/good-design/src/core/web3/modals/SwitchChainModal.tsx @@ -14,7 +14,6 @@ export interface SwitchChainProps { /** * A modal to wrap your component or page with and show a modal re-active to switchChain requests * it assumes you have already wrapped your app with the Web3Provider out of the @gooddollar/sdk-v2 package - * @param {boolean} switching indicating if there is a pending switch request triggered * @param children * @returns JSX.Element */ From fc1d2c959b11b5ddab2f32547790dba6adf52db0 Mon Sep 17 00:00:00 2001 From: LewisB Date: Wed, 14 Jun 2023 10:30:06 +0200 Subject: [PATCH 04/10] (sdk-v2): enable pending sig notificaiton --- packages/sdk-v2/src/sdk/base/hooks/useGasFees.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sdk-v2/src/sdk/base/hooks/useGasFees.ts b/packages/sdk-v2/src/sdk/base/hooks/useGasFees.ts index 72339e4b..80204854 100644 --- a/packages/sdk-v2/src/sdk/base/hooks/useGasFees.ts +++ b/packages/sdk-v2/src/sdk/base/hooks/useGasFees.ts @@ -30,8 +30,9 @@ export const useGasFees = () => { export function useContractFunctionWithDefaultGasFees>( contract: T | Falsy, functionName: FN, - options?: TransactionOptions + customOptions?: TransactionOptions ) { + const options = { enablePendingSignatureNotification: true, ...customOptions }; const { send, ...rest } = useContractFunction(contract, functionName, options); const gasFees = useGasFees(); const newSend = useCallback( From e69cb4401294a3ae002a975de3944722bd4bf2c0 Mon Sep 17 00:00:00 2001 From: LewisB Date: Thu, 15 Jun 2023 15:00:49 +0200 Subject: [PATCH 05/10] wip: story example for sign modal and tracking notifications --- .eslintrc.cjs | 3 +- .../good-design/src/stories/W3Wrapper.tsx | 5 +- .../stories/core/web3/SignTxModal.stories.tsx | 115 ++++++++++++++++++ .../stories/hooks/useTestContractFunction.tsx | 38 ++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx create mode 100644 packages/good-design/src/stories/hooks/useTestContractFunction.tsx diff --git a/.eslintrc.cjs b/.eslintrc.cjs index b5f2bd78..5bc45c70 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -32,7 +32,8 @@ module.exports = { "@typescript-eslint/no-unnecessary-type-assertion": "off", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-misused-promises": "off", - "react-hooks-addons/no-unused-deps": ["warn", { effectComment: "used" }] + "react-hooks-addons/no-unused-deps": ["warn", { effectComment: "used" }], + "@typescript-eslint/no-unused-vars": ["warn", { vars: "local", args: "after-used", ignoreRestSiblings: true }] }, globals: { JSX: true, diff --git a/packages/good-design/src/stories/W3Wrapper.tsx b/packages/good-design/src/stories/W3Wrapper.tsx index 23524828..49d3815f 100644 --- a/packages/good-design/src/stories/W3Wrapper.tsx +++ b/packages/good-design/src/stories/W3Wrapper.tsx @@ -19,6 +19,9 @@ const config: Config = { readOnlyUrls: { 122: "https://rpc.fuse.io", 42220: "https://forno.celo.org" + }, + notifications: { + expirationPeriod: 0 } }; @@ -30,7 +33,7 @@ export const W3Wrapper = ({ children, withMetaMask, env = "fuse" }: PageProps) = if (!withMetaMask) { const rpc = new ethers.providers.JsonRpcProvider("https://rpc.fuse.io"); - + rpc.getSigner = () => w as any; setProvider(rpc); } diff --git a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx new file mode 100644 index 00000000..2eba5a5f --- /dev/null +++ b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx @@ -0,0 +1,115 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { SignTxModal } from "../../../core"; +import { W3Wrapper } from "../../W3Wrapper"; +import BaseButton from "../../../core/buttons/BaseButton"; +import { Box, Button, VStack, Center } from "native-base"; +import { useNotifications, useEthers } from "@usedapp/core"; +import { ethers } from "ethers"; +import { JsonRpcSigner } from "@ethersproject/providers"; +import useTestContractFunction from "../../hooks/useTestContractFunction"; + +const SignTxModalExample = () => { + const { notifications } = useNotifications(); + const [signer, setSigner] = useState(undefined); + const { send, transferState } = useTestContractFunction({ signer }); + const { activateBrowserWallet, library, account } = useEthers(); + const [connected, setConnected] = useState(false); + + const connect = useCallback(async () => { + await (activateBrowserWallet as any)(); + setConnected(true); + }, []); + + useEffect(() => { + if (library && !signer && account) { + console.log("library -->", { library, account }); + const signer = (library as ethers.providers.JsonRpcProvider)?.getSigner(); + console.log("signer set -->", { addr: signer.getAddress() }); + setSigner(signer); + } + }, [library, connected]); + + useEffect(() => { + console.log("signer -->", { signer }); + }, [signer]); + + const sign = useCallback(async () => { + if (signer) { + const signedMessage = await signer.signMessage("Test"); + console.log("signedMessage -->", { signedMessage }); + } + }, [signer]); + + useEffect(() => { + console.log("notifications -->", { notifications, transferState }); + }, [notifications, transferState]); + + return ( + + + {!connected ? ( + + ) : ( + <> + + + + )} + + + {notifications.map(notification => { + if ("transaction" in notification) + return ( + +
id: {notification.id}
+
type: {notification.type}
+
transactionName: {notification.transactionName}
+
submittedAt: {notification.submittedAt}
+
+ ); + })} +
+
+ ); +}; + +export default { + title: "Core/Web3/SignTxModal", + component: SignTxModalExample, + decorators: [ + (Story: any) => ( + + + + ) + ], + argTypes: {} +}; + +export const SignTxModalStory = { + args: {} +}; diff --git a/packages/good-design/src/stories/hooks/useTestContractFunction.tsx b/packages/good-design/src/stories/hooks/useTestContractFunction.tsx new file mode 100644 index 00000000..ff513af7 --- /dev/null +++ b/packages/good-design/src/stories/hooks/useTestContractFunction.tsx @@ -0,0 +1,38 @@ +import React, { useCallback, useState } from "react"; +import { useEthers } from "@usedapp/core"; +import { ethers, Contract } from "ethers"; +import { JsonRpcSigner } from "@ethersproject/providers"; +import { useContractFunctionWithDefaultGasFees } from "@gooddollar/web3sdk-v2"; +import Contracts from "@gooddollar/goodprotocol/releases/deployment.json"; +// import { +// IGoodDollar, +// } from "@gooddollar/goodprotocol/types"; +import GoodDollarABI from "@gooddollar/goodprotocol/artifacts/abis/IGoodDollar.min.json"; + +interface CustomProps { + signer?: JsonRpcSigner; +} + +const useTestContractFunction = (params: CustomProps) => { + const { signer } = params; + const { account } = useEthers(); + const gdContract = new Contract(Contracts["fuse"].GoodDollar, GoodDollarABI.abi, signer) as any; + + const { state: transferState, send: sendTransfer } = useContractFunctionWithDefaultGasFees( + gdContract, + "transferAndCall", + { + transactionName: "SelfTransfer" + } + ); + + const send = useCallback(async () => { + const callData = ethers.constants.HashZero; + const sendTen = await sendTransfer(account, "10000", callData); + console.log("sending 10.... -->", { sendTen }); + }, [account, sendTransfer, signer]); + + return { send, transferState }; +}; + +export default useTestContractFunction; From 6905fe7c38a8b626d303151dc3fc5e2e4a99fa1e Mon Sep 17 00:00:00 2001 From: LewisB Date: Fri, 16 Jun 2023 06:14:27 +0200 Subject: [PATCH 06/10] cleanup signtxmodal story --- packages/good-design/package.json | 2 +- .../stories/core/web3/SignTxModal.stories.tsx | 58 +++++++++---------- .../stories/hooks/useTestContractFunction.tsx | 3 +- yarn.lock | 4 +- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/packages/good-design/package.json b/packages/good-design/package.json index af968c20..23564150 100644 --- a/packages/good-design/package.json +++ b/packages/good-design/package.json @@ -27,7 +27,6 @@ "@babel/preset-react": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.18.9", - "@gooddollar/web3sdk-v2": "latest", "@storybook/addon-actions": "^6.5.12", "@storybook/addon-essentials": "^6.5.12", "@storybook/addon-links": "^6.5.12", @@ -74,6 +73,7 @@ "@babel/core": "^7.18.10", "@babel/runtime": "^7.18.9", "@gooddollar/goodprotocol": "^2.0.3", + "@gooddollar/web3sdk-v2": "workspace:^", "@lingui/macro": "^3.14.0", "@lingui/react": "^3.14.0", "@magiklabs/react-sdk": "^1.0.8", diff --git a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx index 2eba5a5f..e2c0f2d4 100644 --- a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx +++ b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { SignTxModal } from "../../../core"; import { W3Wrapper } from "../../W3Wrapper"; import BaseButton from "../../../core/buttons/BaseButton"; -import { Box, Button, VStack, Center } from "native-base"; +import { Box, Button, HStack, Center } from "native-base"; import { useNotifications, useEthers } from "@usedapp/core"; import { ethers } from "ethers"; import { JsonRpcSigner } from "@ethersproject/providers"; @@ -22,24 +22,11 @@ const SignTxModalExample = () => { useEffect(() => { if (library && !signer && account) { - console.log("library -->", { library, account }); const signer = (library as ethers.providers.JsonRpcProvider)?.getSigner(); - console.log("signer set -->", { addr: signer.getAddress() }); setSigner(signer); } }, [library, connected]); - useEffect(() => { - console.log("signer -->", { signer }); - }, [signer]); - - const sign = useCallback(async () => { - if (signer) { - const signedMessage = await signer.signMessage("Test"); - console.log("signedMessage -->", { signedMessage }); - } - }, [signer]); - useEffect(() => { console.log("notifications -->", { notifications, transferState }); }, [notifications, transferState]); @@ -50,7 +37,7 @@ const SignTxModalExample = () => { {!connected ? ( { ) : ( <> - { {notifications.map(notification => { if ("transaction" in notification) return ( - -
id: {notification.id}
-
type: {notification.type}
-
transactionName: {notification.transactionName}
-
submittedAt: {notification.submittedAt}
-
+ +
+ id: {notification.id}{" "} +
+
+ type: {notification.type}{" "} +
+
+ transactionName: {notification.transactionName}{" "} +
+
+ submittedAt: {notification.submittedAt}{" "} +
+
); })} diff --git a/packages/good-design/src/stories/hooks/useTestContractFunction.tsx b/packages/good-design/src/stories/hooks/useTestContractFunction.tsx index ff513af7..584acba7 100644 --- a/packages/good-design/src/stories/hooks/useTestContractFunction.tsx +++ b/packages/good-design/src/stories/hooks/useTestContractFunction.tsx @@ -28,8 +28,7 @@ const useTestContractFunction = (params: CustomProps) => { const send = useCallback(async () => { const callData = ethers.constants.HashZero; - const sendTen = await sendTransfer(account, "10000", callData); - console.log("sending 10.... -->", { sendTen }); + await sendTransfer(account, "10000", callData); }, [account, sendTransfer, signer]); return { send, transferState }; diff --git a/yarn.lock b/yarn.lock index fd9bf64c..01a2cf1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3255,7 +3255,7 @@ __metadata: "@babel/preset-typescript": ^7.16.0 "@babel/runtime": ^7.18.9 "@gooddollar/goodprotocol": ^2.0.3 - "@gooddollar/web3sdk-v2": latest + "@gooddollar/web3sdk-v2": "workspace:^" "@lingui/macro": ^3.14.0 "@lingui/react": ^3.14.0 "@magiklabs/react-sdk": ^1.0.8 @@ -3438,7 +3438,7 @@ __metadata: languageName: node linkType: hard -"@gooddollar/web3sdk-v2@workspace:packages/sdk-v2": +"@gooddollar/web3sdk-v2@workspace:^, @gooddollar/web3sdk-v2@workspace:packages/sdk-v2": version: 0.0.0-use.local resolution: "@gooddollar/web3sdk-v2@workspace:packages/sdk-v2" dependencies: From 94c174caec9a8bec19b1f35bc629f1b248a5589b Mon Sep 17 00:00:00 2001 From: LewisB Date: Fri, 16 Jun 2023 06:49:42 +0200 Subject: [PATCH 07/10] fix: also include pendingSignature --- .../src/stories/core/web3/SignTxModal.stories.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx index e2c0f2d4..c2cf57f8 100644 --- a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx +++ b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { SignTxModal } from "../../../core"; import { W3Wrapper } from "../../W3Wrapper"; import BaseButton from "../../../core/buttons/BaseButton"; -import { Box, Button, HStack, Center } from "native-base"; +import { Box, HStack, Center, Heading } from "native-base"; import { useNotifications, useEthers } from "@usedapp/core"; import { ethers } from "ethers"; import { JsonRpcSigner } from "@ethersproject/providers"; @@ -58,10 +58,14 @@ const SignTxModalExample = () => { )} - + {notifications.map(notification => { - if ("transaction" in notification) - return ( + // this first if check is needed because of a weird type inference + if (notification.type === "walletConnected") return; + else notification.type.includes("transaction"); + return ( + + Notifications { submittedAt: {notification.submittedAt}{" "} - ); + + ); })} From de25ca20a52ad62cf90abecd7f7d3c4f5b4c7ac7 Mon Sep 17 00:00:00 2001 From: LewisB Date: Fri, 16 Jun 2023 07:03:21 +0200 Subject: [PATCH 08/10] show signtx modal on pendingSignature --- .../src/core/web3/modals/SignTxModal.tsx | 20 ++++--- .../stories/core/web3/SignTxModal.stories.tsx | 56 +++++++++---------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/packages/good-design/src/core/web3/modals/SignTxModal.tsx b/packages/good-design/src/core/web3/modals/SignTxModal.tsx index f3025088..425c2fb8 100644 --- a/packages/good-design/src/core/web3/modals/SignTxModal.tsx +++ b/packages/good-design/src/core/web3/modals/SignTxModal.tsx @@ -1,5 +1,6 @@ +import React, { useEffect } from "react"; import { useColorModeValue } from "native-base"; -import React from "react"; +import { useNotifications } from "@usedapp/core"; import { useModal } from "../../../hooks/useModal"; import { ActionHeader } from "../../layout"; import { LearnButton } from "../../buttons"; @@ -15,20 +16,23 @@ export interface SignTxProps { * @returns JSX.Element */ export const SignTxModal = ({ children }: SignTxProps) => { + const { notifications } = useNotifications(); const textColor = useColorModeValue("goodGrey.500", "white"); - const { - Modal - //showModal, - //hideModal - } = useModal(); + const { Modal, showModal, hideModal } = useModal(); - // todo: add trigger to show modal on any useDapp contract function execution + useEffect(() => { + if (notifications.length > 0 && notifications[0].type === "transactionPendingSignature") { + showModal(); + } else { + hideModal(); + } + }, [notifications]); return ( } + header={} body={} closeText="x" /> diff --git a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx index c2cf57f8..12293083 100644 --- a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx +++ b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx @@ -62,34 +62,34 @@ const SignTxModalExample = () => { {notifications.map(notification => { // this first if check is needed because of a weird type inference if (notification.type === "walletConnected") return; - else notification.type.includes("transaction"); - return ( - - Notifications - -
- id: {notification.id}{" "} -
-
- type: {notification.type}{" "} -
-
- transactionName: {notification.transactionName}{" "} -
-
- submittedAt: {notification.submittedAt}{" "} -
-
-
- ); + else if (notification.type.includes("transaction")) + return ( + + Notifications + +
+ id: {notification.id}{" "} +
+
+ type: {notification.type}{" "} +
+
+ transactionName: {notification.transactionName}{" "} +
+
+ submittedAt: {notification.submittedAt}{" "} +
+
+
+ ); })}
From a87963ebde3ddf07ddbdf3610f8356fef981e78e Mon Sep 17 00:00:00 2001 From: LewisB Date: Fri, 16 Jun 2023 09:04:47 +0200 Subject: [PATCH 09/10] add: trigger toast or run callback from signtx modal --- .../src/core/web3/modals/SignTxModal.tsx | 67 ++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/packages/good-design/src/core/web3/modals/SignTxModal.tsx b/packages/good-design/src/core/web3/modals/SignTxModal.tsx index 425c2fb8..687080b7 100644 --- a/packages/good-design/src/core/web3/modals/SignTxModal.tsx +++ b/packages/good-design/src/core/web3/modals/SignTxModal.tsx @@ -1,13 +1,44 @@ import React, { useEffect } from "react"; -import { useColorModeValue } from "native-base"; +import { Box, Heading, useColorModeValue, useToast, Text } from "native-base"; import { useNotifications } from "@usedapp/core"; +import type { TransactionReceipt, TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider"; import { useModal } from "../../../hooks/useModal"; import { ActionHeader } from "../../layout"; import { LearnButton } from "../../buttons"; -export interface SignTxProps { +// usedapp type definitions without walletConnected +type NotificationPayload = { submittedAt: number } & ( + | { type: "transactionPendingSignature"; transactionName?: string; transactionRequest?: TransactionRequest } + | { type: "transactionStarted"; transaction: TransactionResponse; transactionName?: string } + | { + type: "transactionSucceed"; + transaction: TransactionResponse; + receipt: TransactionReceipt; + transactionName?: string; + originalTransaction?: TransactionResponse; + } + | { + type: "transactionFailed"; + transaction: TransactionResponse; + receipt: TransactionReceipt; + transactionName?: string; + originalTransaction?: TransactionResponse; + } +); + +export type Notification = { id: string } & NotificationPayload; + +//todo: add proper (customizable) styles +const SimpleTxToast = ({ title, desc }: { title: string; desc: string }) => ( + + {title} + txName: {desc} + +); + +export type SignTxProps = { children?: any; -} +} & ({ withToast: boolean; onSubmitted?: never } | { withToast?: never; onSubmitted: () => void }); /** * A modal to wrap your component or page with and show a modal re-active to calls from usedapp's useContractFunction @@ -15,17 +46,37 @@ export interface SignTxProps { * @param children * @returns JSX.Element */ -export const SignTxModal = ({ children }: SignTxProps) => { +export const SignTxModal = ({ children, withToast, onSubmitted }: SignTxProps) => { + const doWithToast = withToast; const { notifications } = useNotifications(); + const toast = useToast(); const textColor = useColorModeValue("goodGrey.500", "white"); const { Modal, showModal, hideModal } = useModal(); useEffect(() => { - if (notifications.length > 0 && notifications[0].type === "transactionPendingSignature") { - showModal(); - } else { - hideModal(); + const localNotif = notifications as Notification[]; + if (localNotif[0]?.type.includes("transaction")) { + const { type, transactionName = "" } = localNotif[0]; + switch (type) { + case "transactionPendingSignature": + showModal(); + break; + case "transactionStarted": + hideModal(); + if (doWithToast) { + toast.show({ + render: () => , + placement: "top-right" + }); + } else if (onSubmitted) { + onSubmitted(); + } + break; + default: + hideModal(); + break; + } } }, [notifications]); From 526e9026c103373faa698518c62fc117cc2b56f6 Mon Sep 17 00:00:00 2001 From: LewisB Date: Fri, 16 Jun 2023 09:17:25 +0200 Subject: [PATCH 10/10] chore: cleanup --- .../src/core/web3/modals/SignTxModal.tsx | 13 ++++++++----- .../src/stories/core/web3/SignTxModal.stories.tsx | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/good-design/src/core/web3/modals/SignTxModal.tsx b/packages/good-design/src/core/web3/modals/SignTxModal.tsx index 687080b7..71698ba8 100644 --- a/packages/good-design/src/core/web3/modals/SignTxModal.tsx +++ b/packages/good-design/src/core/web3/modals/SignTxModal.tsx @@ -38,15 +38,18 @@ const SimpleTxToast = ({ title, desc }: { title: string; desc: string }) => ( export type SignTxProps = { children?: any; -} & ({ withToast: boolean; onSubmitted?: never } | { withToast?: never; onSubmitted: () => void }); +} & ({ withToast: boolean; onSubmit?: never } | { withToast?: never; onSubmit: () => void }); /** - * A modal to wrap your component or page with and show a modal re-active to calls from usedapp's useContractFunction + * A modal to wrap your component or page with and show a modal re-active to a + * pending signature for a usedapp useContractFunction call * it assumes you have already wrapped your app with the Web3Provider out of the @gooddollar/sdk-v2 package * @param children + * @param withToast - if true, will show a simple toast + * @param onSubmitted - if withToast false, provide a callback to handle what happens after tx is submitted * @returns JSX.Element */ -export const SignTxModal = ({ children, withToast, onSubmitted }: SignTxProps) => { +export const SignTxModal = ({ children, withToast, onSubmit }: SignTxProps) => { const doWithToast = withToast; const { notifications } = useNotifications(); const toast = useToast(); @@ -69,8 +72,8 @@ export const SignTxModal = ({ children, withToast, onSubmitted }: SignTxProps) = render: () => , placement: "top-right" }); - } else if (onSubmitted) { - onSubmitted(); + } else { + onSubmit?.(); } break; default: diff --git a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx index 12293083..21e92176 100644 --- a/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx +++ b/packages/good-design/src/stories/core/web3/SignTxModal.stories.tsx @@ -32,7 +32,7 @@ const SignTxModalExample = () => { }, [notifications, transferState]); return ( - + {!connected ? (