From b289c7f16c253879ec4e5b0fdbfa4af8facb567e Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 09:53:49 +0200 Subject: [PATCH 001/179] Create ledger live manifest template Based on the template we want to build the ledger live manifest based on the `mainnet`, `testnet` and `development`config. In config we set the correct id, name and url. --- dapp/config/development.json | 5 +++ dapp/config/mainnet.json | 5 +++ dapp/config/testnet.json | 5 +++ dapp/ledger-manifest-development.json | 31 ------------------- ...net.json => ledger-manifest-template.json} | 8 ++--- dapp/package.json | 6 +++- pnpm-lock.yaml | 4 ++- 7 files changed, 27 insertions(+), 37 deletions(-) create mode 100644 dapp/config/development.json create mode 100644 dapp/config/mainnet.json create mode 100644 dapp/config/testnet.json delete mode 100644 dapp/ledger-manifest-development.json rename dapp/{ledger-manifest-testnet.json => ledger-manifest-template.json} (81%) diff --git a/dapp/config/development.json b/dapp/config/development.json new file mode 100644 index 000000000..c53925a4c --- /dev/null +++ b/dapp/config/development.json @@ -0,0 +1,5 @@ +{ + "id": "dev", + "name": "Acre [dev]", + "url": "http://localhost:5173/" +} diff --git a/dapp/config/mainnet.json b/dapp/config/mainnet.json new file mode 100644 index 000000000..828c70373 --- /dev/null +++ b/dapp/config/mainnet.json @@ -0,0 +1,5 @@ +{ + "id": "mainnet", + "name": "Acre", + "url": "https://stake.acre.fi/" +} diff --git a/dapp/config/testnet.json b/dapp/config/testnet.json new file mode 100644 index 000000000..4c9b26c58 --- /dev/null +++ b/dapp/config/testnet.json @@ -0,0 +1,5 @@ +{ + "id": "testnet", + "name": "Acre [testnet]", + "url": "https://dapp.test.acre.fi/" +} diff --git a/dapp/ledger-manifest-development.json b/dapp/ledger-manifest-development.json deleted file mode 100644 index c387832f7..000000000 --- a/dapp/ledger-manifest-development.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "id": "acre-dev", - "name": "Acre [dev]", - "url": "http://localhost:5173/", - "homepageUrl": "http://localhost:5173/", - "icon": "http://localhost:5173/acre.svg", - "platforms": "desktop", - "apiVersion": "^2.0.0", - "manifestVersion": "2", - "branch": "stable", - "categories": ["staking"], - "currencies": ["bitcoin", "bitcoin_testnet"], - "content": { - "shortDescription": { - "en": "Bitcoin Liquid Staking" - }, - "description": { - "en": "Bitcoin Liquid Staking" - } - }, - "permissions": [ - "account.request", - "account.list", - "message.sign", - "transaction.sign", - "transaction.signAndBroadcast", - "bitcoin.getXPub" - ], - "domains": ["http://*"], - "type": "walletApp" -} diff --git a/dapp/ledger-manifest-testnet.json b/dapp/ledger-manifest-template.json similarity index 81% rename from dapp/ledger-manifest-testnet.json rename to dapp/ledger-manifest-template.json index c0b17490f..21111c229 100644 --- a/dapp/ledger-manifest-testnet.json +++ b/dapp/ledger-manifest-template.json @@ -1,9 +1,9 @@ { - "id": "acre-test", - "name": "Acre [test]", - "url": "https://dapp.test.acre.fi/", + "id": "acre-{{id}}", + "name": "{{name}}", + "url": "{{{url}}}", "homepageUrl": "https:/acre.fi/", - "icon": "https://dapp.test.acre.fi/acre.svg", + "icon": "{{{url}}}acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", diff --git a/dapp/package.json b/dapp/package.json index 222cf1a82..5885e659e 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -13,7 +13,10 @@ "lint:js:fix": "eslint . --fix", "lint:config": "prettier -c '**/*.@(json|yaml|toml)'", "lint:config:fix": "prettier -w '**/*.@(json|yaml|toml)'", - "test": "vitest" + "test": "vitest", + "prepare:dev": "mustache config/development.json ledger-manifest-template.json > ledger-manifest-development.json", + "prepare:testnet": "mustache config/testnet.json ledger-manifest-template.json > ledger-manifest-testnet.json", + "prepare:mainnet": "mustache config/mainnet.json ledger-manifest-template.json > ledger-manifest-mainnet.json" }, "dependencies": { "@acre-btc/sdk": "workspace:*", @@ -34,6 +37,7 @@ "ethers": "^6.10.0", "formik": "^2.4.5", "framer-motion": "^10.16.5", + "mustache": "^4.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-number-format": "^5.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b15d4587..5f3bd462b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,6 +77,9 @@ importers: framer-motion: specifier: ^10.16.5 version: 10.18.0(react-dom@18.3.1)(react@18.3.1) + mustache: + specifier: ^4.2.0 + version: 4.2.0 react: specifier: ^18.2.0 version: 18.3.1 @@ -16703,7 +16706,6 @@ packages: /mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true - dev: true /nan@2.20.0: resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} From 5a8a5f5af4a777b89cff79cc43c23f9bd2c2b6e5 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 09:55:42 +0200 Subject: [PATCH 002/179] Store the ledger live manifest for all env --- dapp/ledger-manifest-development.json | 31 +++++++++++++++++++++++++++ dapp/ledger-manifest-mainnet.json | 31 +++++++++++++++++++++++++++ dapp/ledger-manifest-testnet.json | 31 +++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 dapp/ledger-manifest-development.json create mode 100644 dapp/ledger-manifest-mainnet.json create mode 100644 dapp/ledger-manifest-testnet.json diff --git a/dapp/ledger-manifest-development.json b/dapp/ledger-manifest-development.json new file mode 100644 index 000000000..3d841d182 --- /dev/null +++ b/dapp/ledger-manifest-development.json @@ -0,0 +1,31 @@ +{ + "id": "acre-dev", + "name": "Acre [dev]", + "url": "http://localhost:5173/", + "homepageUrl": "https:/acre.fi/", + "icon": "http://localhost:5173/acre.svg", + "platforms": "desktop", + "apiVersion": "^2.0.0", + "manifestVersion": "2", + "branch": "stable", + "categories": ["staking"], + "currencies": ["bitcoin", "bitcoin_testnet"], + "content": { + "shortDescription": { + "en": "Bitcoin Liquid Staking" + }, + "description": { + "en": "Bitcoin Liquid Staking" + } + }, + "permissions": [ + "account.request", + "account.list", + "message.sign", + "transaction.sign", + "transaction.signAndBroadcast", + "bitcoin.getXPub" + ], + "domains": ["http://*"], + "type": "walletApp" +} diff --git a/dapp/ledger-manifest-mainnet.json b/dapp/ledger-manifest-mainnet.json new file mode 100644 index 000000000..b385230ad --- /dev/null +++ b/dapp/ledger-manifest-mainnet.json @@ -0,0 +1,31 @@ +{ + "id": "acre-mainnet", + "name": "Acre", + "url": "https://stake.acre.fi/", + "homepageUrl": "https:/acre.fi/", + "icon": "https://stake.acre.fi/acre.svg", + "platforms": "desktop", + "apiVersion": "^2.0.0", + "manifestVersion": "2", + "branch": "stable", + "categories": ["staking"], + "currencies": ["bitcoin", "bitcoin_testnet"], + "content": { + "shortDescription": { + "en": "Bitcoin Liquid Staking" + }, + "description": { + "en": "Bitcoin Liquid Staking" + } + }, + "permissions": [ + "account.request", + "account.list", + "message.sign", + "transaction.sign", + "transaction.signAndBroadcast", + "bitcoin.getXPub" + ], + "domains": ["http://*"], + "type": "walletApp" +} diff --git a/dapp/ledger-manifest-testnet.json b/dapp/ledger-manifest-testnet.json new file mode 100644 index 000000000..6d47022fa --- /dev/null +++ b/dapp/ledger-manifest-testnet.json @@ -0,0 +1,31 @@ +{ + "id": "acre-testnet", + "name": "Acre [testnet]", + "url": "https://dapp.test.acre.fi/", + "homepageUrl": "https:/acre.fi/", + "icon": "https://dapp.test.acre.fi/acre.svg", + "platforms": "desktop", + "apiVersion": "^2.0.0", + "manifestVersion": "2", + "branch": "stable", + "categories": ["staking"], + "currencies": ["bitcoin", "bitcoin_testnet"], + "content": { + "shortDescription": { + "en": "Bitcoin Liquid Staking" + }, + "description": { + "en": "Bitcoin Liquid Staking" + } + }, + "permissions": [ + "account.request", + "account.list", + "message.sign", + "transaction.sign", + "transaction.signAndBroadcast", + "bitcoin.getXPub" + ], + "domains": ["http://*"], + "type": "walletApp" +} From 1a792e09e8bdea84bf8c80872497fcdb3e6775d4 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 10:10:51 +0200 Subject: [PATCH 003/179] Add a special parameter for Ledger Live mode --- dapp/ledger-manifest-development.json | 2 +- dapp/ledger-manifest-mainnet.json | 2 +- dapp/ledger-manifest-template.json | 2 +- dapp/ledger-manifest-testnet.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dapp/ledger-manifest-development.json b/dapp/ledger-manifest-development.json index 3d841d182..87c37697d 100644 --- a/dapp/ledger-manifest-development.json +++ b/dapp/ledger-manifest-development.json @@ -1,7 +1,7 @@ { "id": "acre-dev", "name": "Acre [dev]", - "url": "http://localhost:5173/", + "url": "http://localhost:5173/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", "icon": "http://localhost:5173/acre.svg", "platforms": "desktop", diff --git a/dapp/ledger-manifest-mainnet.json b/dapp/ledger-manifest-mainnet.json index b385230ad..957caba81 100644 --- a/dapp/ledger-manifest-mainnet.json +++ b/dapp/ledger-manifest-mainnet.json @@ -1,7 +1,7 @@ { "id": "acre-mainnet", "name": "Acre", - "url": "https://stake.acre.fi/", + "url": "https://stake.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", "icon": "https://stake.acre.fi/acre.svg", "platforms": "desktop", diff --git a/dapp/ledger-manifest-template.json b/dapp/ledger-manifest-template.json index 21111c229..1b8051887 100644 --- a/dapp/ledger-manifest-template.json +++ b/dapp/ledger-manifest-template.json @@ -1,7 +1,7 @@ { "id": "acre-{{id}}", "name": "{{name}}", - "url": "{{{url}}}", + "url": "{{{url}}}?embed=ledger-live", "homepageUrl": "https:/acre.fi/", "icon": "{{{url}}}acre.svg", "platforms": "desktop", diff --git a/dapp/ledger-manifest-testnet.json b/dapp/ledger-manifest-testnet.json index 6d47022fa..d63282bf2 100644 --- a/dapp/ledger-manifest-testnet.json +++ b/dapp/ledger-manifest-testnet.json @@ -1,7 +1,7 @@ { "id": "acre-testnet", "name": "Acre [testnet]", - "url": "https://dapp.test.acre.fi/", + "url": "https://dapp.test.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", "icon": "https://dapp.test.acre.fi/acre.svg", "platforms": "desktop", From 968c6b6fb2523b23bdc0726b4bca4e07a55da5fa Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 10:15:26 +0200 Subject: [PATCH 004/179] Add script for generating all manifest files for ledger live --- dapp/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dapp/package.json b/dapp/package.json index 5885e659e..7aaba4f7d 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -16,7 +16,8 @@ "test": "vitest", "prepare:dev": "mustache config/development.json ledger-manifest-template.json > ledger-manifest-development.json", "prepare:testnet": "mustache config/testnet.json ledger-manifest-template.json > ledger-manifest-testnet.json", - "prepare:mainnet": "mustache config/mainnet.json ledger-manifest-template.json > ledger-manifest-mainnet.json" + "prepare:mainnet": "mustache config/mainnet.json ledger-manifest-template.json > ledger-manifest-mainnet.json", + "prepare:all-env": "pnpm prepare:dev && pnpm prepare:testnet && pnpm prepare:mainnet" }, "dependencies": { "@acre-btc/sdk": "workspace:*", From 2b579989984943c28281e262d3ac7a473ba82027 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 11:41:12 +0200 Subject: [PATCH 005/179] Create a special hook to check if the dApp is embedded --- dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useDetectEmbed.ts | 10 ++++++++++ dapp/src/hooks/useInitApp.ts | 2 ++ dapp/src/hooks/useIsEmbed.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 dapp/src/hooks/useDetectEmbed.ts create mode 100644 dapp/src/hooks/useIsEmbed.ts diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index b055549d0..b0cadfd73 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -34,3 +34,4 @@ export { default as useLocalStorage } from "./useLocalStorage" export { default as useDetectReferral } from "./useDetectReferral" export { default as useReferral } from "./useReferral" export { default as useMats } from "./useMats" +export { default as useIsEmbed } from "./useIsEmbed" diff --git a/dapp/src/hooks/useDetectEmbed.ts b/dapp/src/hooks/useDetectEmbed.ts new file mode 100644 index 000000000..967581e61 --- /dev/null +++ b/dapp/src/hooks/useDetectEmbed.ts @@ -0,0 +1,10 @@ +import { useEffect } from "react" +import useIsEmbed from "./useIsEmbed" + +export default function useDetectEmbed() { + const { enableIsEmbed } = useIsEmbed() + + useEffect(() => { + enableIsEmbed() + }, [enableIsEmbed]) +} diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index 42c21151f..109749a17 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -3,6 +3,7 @@ import { useAccountsChangedUnisat } from "./orangeKit/useAccountsChangedUnisat" import { useDisconnectOKX } from "./orangeKit/useDisconnectOKX" import { useInitDataFromSdk, useInitializeAcreSdk } from "./sdk" import { useSentry } from "./sentry" +import useDetectEmbed from "./useDetectEmbed" import useDetectReferral from "./useDetectReferral" import { useDisconnectWallet } from "./useDisconnectWallet" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" @@ -11,6 +12,7 @@ export function useInitApp() { // TODO: Let's uncomment when dark mode is ready // useDetectThemeMode() useSentry() + useDetectEmbed() useDetectReferral() useInitializeAcreSdk() useInitDataFromSdk() diff --git a/dapp/src/hooks/useIsEmbed.ts b/dapp/src/hooks/useIsEmbed.ts new file mode 100644 index 000000000..b54ce996b --- /dev/null +++ b/dapp/src/hooks/useIsEmbed.ts @@ -0,0 +1,27 @@ +import { useCallback } from "react" +import useLocalStorage from "./useLocalStorage" + +export default function useIsEmbed() { + const [isEmbed, setIsEmbed] = useLocalStorage( + "isEmbed", + undefined, + ) + + const enableIsEmbed = useCallback(() => { + const params = new URLSearchParams(window.location.search) + + if (params.get("embed")) { + setIsEmbed(true) + } + }, [setIsEmbed]) + + const disableIsEmbed = useCallback(() => { + setIsEmbed(false) + }, [setIsEmbed]) + + return { + enableIsEmbed, + disableIsEmbed, + isEmbed, + } +} From 91ef51010143b210afe84442915e9312671787df Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 20 Aug 2024 11:49:38 +0200 Subject: [PATCH 006/179] Set a referral for the embedded dApp --- dapp/src/hooks/useReferral.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index 26a3f53a7..719cc760e 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -4,6 +4,7 @@ import { MODAL_TYPES } from "#/types" import { referralProgram } from "#/utils" import useLocalStorage from "./useLocalStorage" import { useModal } from "./useModal" +import useIsEmbed from "./useIsEmbed" type UseReferralReturn = { referral: number | null @@ -17,10 +18,17 @@ export default function useReferral(): UseReferralReturn { env.REFERRAL, ) const { openModal } = useModal() + const { isEmbed } = useIsEmbed() const detectReferral = useCallback(() => { const param = referralProgram.getReferralFromURL() + if (isEmbed) { + // TODO: Set correct referral for embedded dApp + setReferral(0) + return + } + if (param === null) { setReferral(env.REFERRAL) return @@ -38,7 +46,7 @@ export default function useReferral(): UseReferralReturn { closeOnEsc: false, }) } - }, [openModal, setReferral]) + }, [isEmbed, openModal, setReferral]) const resetReferral = useCallback(() => { setReferral(env.REFERRAL) From 910e7d84bfda6468703def643f59f3a2ff1443e3 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 11:23:29 +0200 Subject: [PATCH 007/179] Create a helper function - `getURLParam` --- dapp/src/hooks/useDetectThemeMode.ts | 5 +++-- dapp/src/hooks/useIsEmbed.ts | 6 +++--- dapp/src/router/path.ts | 2 ++ dapp/src/utils/referralProgram.ts | 7 +++---- dapp/src/utils/router.ts | 7 ++++++- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/dapp/src/hooks/useDetectThemeMode.ts b/dapp/src/hooks/useDetectThemeMode.ts index b581e6820..7e11a51c9 100644 --- a/dapp/src/hooks/useDetectThemeMode.ts +++ b/dapp/src/hooks/useDetectThemeMode.ts @@ -1,12 +1,13 @@ import { useEffect } from "react" import { useColorMode } from "@chakra-ui/react" +import { router } from "#/utils" +import { SEARCH_PARAMS_NAMES } from "#/router/path" export function useDetectThemeMode(): string | null { const { colorMode, toggleColorMode } = useColorMode() // The ledger live passes the theme mode via url. // Let's detect the theme set by the user and toggle the color mode - const params = new URLSearchParams(window.location.search) - const themeMode = params.get("theme") + const themeMode = router.getURLParam(SEARCH_PARAMS_NAMES.themeMode) useEffect(() => { if ( diff --git a/dapp/src/hooks/useIsEmbed.ts b/dapp/src/hooks/useIsEmbed.ts index b54ce996b..46f5a69a2 100644 --- a/dapp/src/hooks/useIsEmbed.ts +++ b/dapp/src/hooks/useIsEmbed.ts @@ -1,4 +1,6 @@ import { useCallback } from "react" +import { router } from "#/utils" +import { SEARCH_PARAMS_NAMES } from "#/router/path" import useLocalStorage from "./useLocalStorage" export default function useIsEmbed() { @@ -8,9 +10,7 @@ export default function useIsEmbed() { ) const enableIsEmbed = useCallback(() => { - const params = new URLSearchParams(window.location.search) - - if (params.get("embed")) { + if (router.getURLParam(SEARCH_PARAMS_NAMES.embed)) { setIsEmbed(true) } }, [setIsEmbed]) diff --git a/dapp/src/router/path.ts b/dapp/src/router/path.ts index 619f102eb..ce48928bf 100644 --- a/dapp/src/router/path.ts +++ b/dapp/src/router/path.ts @@ -1,5 +1,7 @@ export const SEARCH_PARAMS_NAMES = { referral: "ref", + embed: "embed", + themeMode: "theme", } export const routerPath = { diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index b66eac663..126648157 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -1,4 +1,5 @@ import { SEARCH_PARAMS_NAMES } from "#/router/path" +import router from "./router" const MAX_UINT16 = 65535 @@ -7,10 +8,8 @@ const isValidReferral = (value: number) => { return isInteger && value >= 0 && value <= MAX_UINT16 } -const getReferralFromURL = () => { - const params = new URLSearchParams(window.location.search) - return params.get(SEARCH_PARAMS_NAMES.referral) -} +const getReferralFromURL = () => + router.getURLParam(SEARCH_PARAMS_NAMES.referral) export default { isValidReferral, diff --git a/dapp/src/utils/router.ts b/dapp/src/utils/router.ts index f523a3c85..9e71fd531 100644 --- a/dapp/src/utils/router.ts +++ b/dapp/src/utils/router.ts @@ -3,4 +3,9 @@ import { isString } from "./type-check" const getURLPath = (to: To) => (isString(to) ? to : to.pathname) -export default { getURLPath } +const getURLParam = (paramName: string) => { + const params = new URLSearchParams(window.location.search) + return params.get(paramName) +} + +export default { getURLPath, getURLParam } From e2339a2cc5294cc00f4214f108bc66f893f76dc0 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 11:33:22 +0200 Subject: [PATCH 008/179] Use only needed connectors when the app is embed --- dapp/src/wagmiConfig.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 29623f0d6..c7a16af5e 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -6,9 +6,12 @@ import { getOrangeKitXverseConnector, } from "@orangekit/react" import { env } from "./constants" +import { router } from "./utils" +import { SEARCH_PARAMS_NAMES } from "./router/path" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id +const IsEmbed = router.getURLParam(SEARCH_PARAMS_NAMES.embed) const chains: [Chain, ...Chain[]] = isTestnet ? [sepolia] : [mainnet] const connectorConfig = { @@ -25,10 +28,18 @@ const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) -const connectors = [ +const embedConnectors = [orangeKitXverseConnector()] +const defaultConnectors = [ orangeKitOKXConnector(), orangeKitUnisatConnector(), orangeKitXverseConnector(), +] + +const connectors = [ + ...(IsEmbed + ? // TODO: Use correct connector + embedConnectors + : defaultConnectors), ] as unknown as CreateConnectorFn[] const wagmiConfig = createConfig({ From b780c3fc4e45853e465ed6f591fa0bad2063019c Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 13:51:48 +0200 Subject: [PATCH 009/179] Call account selection action when app is embedded dApp --- dapp/src/components/ConnectWalletModal/index.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dapp/src/components/ConnectWalletModal/index.tsx b/dapp/src/components/ConnectWalletModal/index.tsx index bac59c3d6..6ebecc466 100644 --- a/dapp/src/components/ConnectWalletModal/index.tsx +++ b/dapp/src/components/ConnectWalletModal/index.tsx @@ -1,6 +1,6 @@ -import React, { useState } from "react" +import React, { useEffect, useState } from "react" import { ModalBody, ModalHeader, ModalCloseButton } from "@chakra-ui/react" -import { useConnectors, useWalletConnectionError } from "#/hooks" +import { useConnectors, useIsEmbed, useWalletConnectionError } from "#/hooks" import { OrangeKitConnector, BaseModalProps, OnSuccessCallback } from "#/types" import { wallets } from "#/constants" import withBaseModal from "../ModalRoot/withBaseModal" @@ -13,6 +13,7 @@ export function ConnectWalletModalBase({ }: { onSuccess?: OnSuccessCallback } & BaseModalProps) { + const { isEmbed } = useIsEmbed() const connectors = useConnectors() const enabledConnectors = connectors.map((connector) => ({ ...connector, @@ -27,12 +28,18 @@ export function ConnectWalletModalBase({ setSelectedConnectorId(connector.id) } + useEffect(() => { + if (!isEmbed) return + + setSelectedConnectorId(enabledConnectors[0].id) + }, [enabledConnectors, isEmbed]) + return ( <> {withCloseButton && ( resetConnectionError()} /> )} - Select your wallet + {`Select your ${isEmbed ? "account" : "wallet"}`} From 109d71cc1fbe729c7bd1d2d952948e4164716df8 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 14:08:44 +0200 Subject: [PATCH 010/179] Define basic information about a ledger wallet --- dapp/src/constants/wallets.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dapp/src/constants/wallets.ts b/dapp/src/constants/wallets.ts index 935c7b7bf..39bde7482 100644 --- a/dapp/src/constants/wallets.ts +++ b/dapp/src/constants/wallets.ts @@ -31,15 +31,24 @@ const XVERSE: WalletInfo = { }, } +const LEDGER: WalletInfo = { + id: "orangekit-ledger", + downloadUrls: { + desktop: "https://www.ledger.com/ledger-live", + }, +} + const SUPPORTED_WALLET_IDS = [ UNISAT.id, ...(featureFlags.OKX_WALLET_ENABLED ? [OKX.id] : []), ...(featureFlags.XVERSE_WALLET_ENABLED ? [XVERSE.id] : []), + LEDGER.id, ] export default { UNISAT, OKX, XVERSE, + LEDGER, SUPPORTED_WALLET_IDS, } From 678d151ba454cf4defc38787de58049be01cbfcc Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 14:27:08 +0200 Subject: [PATCH 011/179] Update texts when app is embedded dApp --- .../components/ConnectWalletModal/ConnectWalletButton.tsx | 4 +++- dapp/src/components/Header/ConnectWallet.tsx | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index a323181eb..e11caf8f0 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState } from "react" import { CONNECTION_ERRORS, ONE_SEC_IN_MILLISECONDS } from "#/constants" import { useAppDispatch, + useIsEmbed, useModal, useSignMessageAndCreateSession, useWallet, @@ -54,6 +55,7 @@ export default function ConnectWalletButton({ connector, onSuccess, }: ConnectWalletButtonProps) { + const { isEmbed } = useIsEmbed() const { address, isConnected, @@ -226,7 +228,7 @@ export default function ConnectWalletButton({ - Connect wallet + {`Connect ${isEmbed ? "account" : "wallet"}`} ) } From 128cc2900979ad6227c63774193f0c5c890dd573 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 20 Sep 2024 15:21:06 +0200 Subject: [PATCH 012/179] Error handling for ledger live app --- .../ActiveStakingStep/DepositBTCModal.tsx | 7 +++++-- .../ActiveUnstakingStep/SignMessageModal.tsx | 12 ++++++++++-- dapp/src/types/index.ts | 1 + dapp/src/types/ledgerLive.ts | 5 +++++ dapp/src/utils/index.ts | 1 + dapp/src/utils/ledgerLive.ts | 18 ++++++++++++++++++ 6 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 dapp/src/types/ledgerLive.ts create mode 100644 dapp/src/utils/ledgerLive.ts diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 6a9472487..98c563dbe 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -9,7 +9,7 @@ import { useStakeFlowContext, useVerifyDepositAddress, } from "#/hooks" -import { eip1193, logPromiseFailure } from "#/utils" +import { eip1193, ledgerLive, logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" import { Highlight, ModalCloseButton } from "@chakra-ui/react" import { TextMd } from "#/components/shared/Typography" @@ -53,7 +53,10 @@ export default function DepositBTCModal() { const onDepositBTCError = useCallback( (error: unknown) => { - if (eip1193.didUserRejectRequest(error)) { + if ( + eip1193.didUserRejectRequest(error) || + ledgerLive.didUserRejectRequest(error) + ) { handlePause() } else { onError(error) diff --git a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx index 03f7d84a7..4de884847 100644 --- a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx @@ -10,7 +10,12 @@ import { } from "#/hooks" import { ACTION_FLOW_TYPES, PROCESS_STATUSES } from "#/types" import { Button, ModalCloseButton } from "@chakra-ui/react" -import { dateToUnixTimestamp, eip1193, logPromiseFailure } from "#/utils" +import { + dateToUnixTimestamp, + eip1193, + ledgerLive, + logPromiseFailure, +} from "#/utils" import { setStatus } from "#/store/action-flow" import { useInitializeWithdraw } from "#/acre-react/hooks" import { queryKeysFactory } from "#/constants" @@ -106,7 +111,10 @@ export default function SignMessageModal() { (error: unknown) => { if (!sessionIdToPromise[sessionId.current].shouldOpenErrorModal) return - if (eip1193.didUserRejectRequest(error)) { + if ( + eip1193.didUserRejectRequest(error) || + ledgerLive.didUserRejectRequest(error) + ) { handlePause() } else { onSignMessageError() diff --git a/dapp/src/types/index.ts b/dapp/src/types/index.ts index 5411acd06..dc4d8a4a9 100644 --- a/dapp/src/types/index.ts +++ b/dapp/src/types/index.ts @@ -14,3 +14,4 @@ export * from "./eip1193" export * from "./error" export * from "./status" export * from "./orangekit" +export * from "./ledgerLive" diff --git a/dapp/src/types/ledgerLive.ts b/dapp/src/types/ledgerLive.ts new file mode 100644 index 000000000..6cd4aea65 --- /dev/null +++ b/dapp/src/types/ledgerLive.ts @@ -0,0 +1,5 @@ +export type LedgerLiveError = { + message?: string + name?: string + stack?: string +} diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index ba68a6887..c73ba1b20 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -18,3 +18,4 @@ export { default as referralProgram } from "./referralProgram" export { default as mezoPortalAPI } from "./mezoPortalApi" export { default as router } from "./router" export { default as acreApi } from "./acre-api" +export { default as ledgerLive } from "./ledgerLive" diff --git a/dapp/src/utils/ledgerLive.ts b/dapp/src/utils/ledgerLive.ts new file mode 100644 index 000000000..2c1f859bc --- /dev/null +++ b/dapp/src/utils/ledgerLive.ts @@ -0,0 +1,18 @@ +import { LedgerLiveError } from "#/types" +import { isObject, isString } from "./type-check" + +function isLedgerLiveError(arg: unknown): arg is LedgerLiveError { + return isObject(arg) && arg.name === "Error" && isString(arg.message) +} +function didUserRejectRequest(error: unknown): boolean { + return !!( + isLedgerLiveError(error) && + error.message && + error.message.includes("Signature interrupted by user") + ) +} + +export default { + isLedgerLiveError, + didUserRejectRequest, +} From 195ad047230335236251c734e7bdefba2040490c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 24 Sep 2024 15:20:45 +0200 Subject: [PATCH 013/179] Add Ledger Live connector --- dapp/package.json | 2 +- .../components/ConnectWalletModal/index.tsx | 4 +- dapp/src/constants/wallets.ts | 2 +- dapp/src/wagmiConfig.ts | 5 +- pnpm-lock.yaml | 69 +++++++++++-------- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index cf1bb4c33..372d30a62 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.30", + "@orangekit/react": "1.0.0-beta.32-dev.0", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/components/ConnectWalletModal/index.tsx b/dapp/src/components/ConnectWalletModal/index.tsx index 6ebecc466..cf1def645 100644 --- a/dapp/src/components/ConnectWalletModal/index.tsx +++ b/dapp/src/components/ConnectWalletModal/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react" import { ModalBody, ModalHeader, ModalCloseButton } from "@chakra-ui/react" import { useConnectors, useIsEmbed, useWalletConnectionError } from "#/hooks" import { OrangeKitConnector, BaseModalProps, OnSuccessCallback } from "#/types" -import { wallets } from "#/constants" +// import { wallets } from "#/constants" import withBaseModal from "../ModalRoot/withBaseModal" import ConnectWalletButton from "./ConnectWalletButton" import ConnectWalletErrorAlert from "./ConnectWalletErrorAlert" @@ -17,7 +17,7 @@ export function ConnectWalletModalBase({ const connectors = useConnectors() const enabledConnectors = connectors.map((connector) => ({ ...connector, - isDisabled: !wallets.SUPPORTED_WALLET_IDS.includes(connector.id), + isDisabled: false, })) const [selectedConnectorId, setSelectedConnectorId] = useState() diff --git a/dapp/src/constants/wallets.ts b/dapp/src/constants/wallets.ts index 39bde7482..30f7b3264 100644 --- a/dapp/src/constants/wallets.ts +++ b/dapp/src/constants/wallets.ts @@ -32,7 +32,7 @@ const XVERSE: WalletInfo = { } const LEDGER: WalletInfo = { - id: "orangekit-ledger", + id: "orangekit-ledger-live", downloadUrls: { desktop: "https://www.ledger.com/ledger-live", }, diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index c7a16af5e..302ec30b5 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -4,6 +4,7 @@ import { getOrangeKitUnisatConnector, getOrangeKitOKXConnector, getOrangeKitXverseConnector, + getOrangeKitLedgerLiveConnector, } from "@orangekit/react" import { env } from "./constants" import { router } from "./utils" @@ -27,8 +28,10 @@ const transports = chains.reduce( const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) +const orangeKitLedgerLiveConnector = + getOrangeKitLedgerLiveConnector(connectorConfig) -const embedConnectors = [orangeKitXverseConnector()] +const embedConnectors = [orangeKitLedgerLiveConnector()] const defaultConnectors = [ orangeKitOKXConnector(), orangeKitUnisatConnector(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6645a2bbc..d8d626b92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.30 - version: 1.0.0-beta.30(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5)(valibot@0.33.2) + specifier: 1.0.0-beta.32-dev.0 + version: 1.0.0-beta.32-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -4715,6 +4715,23 @@ packages: bignumber.js: 9.1.2 dev: false + /@ledgerhq/wallet-api-client@1.5.10: + resolution: {integrity: sha512-cSTdNKBjlzium1tRS2+Q8Ev6T8MM0v8WtOF34+I/+GfkcerA9wR6l4ISGWP9fPneur3r+uGF1k4Y5LPbMN5pdw==} + dependencies: + '@ledgerhq/hw-transport': 6.30.6 + '@ledgerhq/wallet-api-core': 1.11.0 + bignumber.js: 9.1.2 + dev: false + + /@ledgerhq/wallet-api-core@1.11.0: + resolution: {integrity: sha512-QB4Inky3HadsB246CMH4t+KWvJ6qLu/M2nDuUZZ5e27XMAVDe/XI2CzndYmRq8rjW8pCfytGdQrdH9aVcBK6Kg==} + dependencies: + '@ledgerhq/errors': 6.16.4 + bignumber.js: 9.1.2 + uuid: 9.0.1 + zod: 3.23.8 + dev: false + /@ledgerhq/wallet-api-core@1.6.0: resolution: {integrity: sha512-nVPN3yu5+5pbhfFYh0iKmij5U7KVKZfpDkusXbj4yKvueKY8ZXU1wgvw1rDhgxlqu+s7JTA50MX56doyhm46Qg==} dependencies: @@ -5754,14 +5771,16 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.30(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5)(valibot@0.33.2): - resolution: {integrity: sha512-hH5rRTDy0rDuVvgZKb53/fiQHHMjUlOL0pufMbv4fuy0AzrnNHu4ohFEJCyANpiL/FppdBZiFa/paqv+9obotg==} + /@orangekit/react@1.0.0-beta.32-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-3yllsWIjqEmgOEYIHiazv4sYDsb3KD1t9Ts8tOG0/By67e2r2yXDQ+ahq7gIJqVWj9qEeo6HMiUSq6ttZL90YA==} dependencies: + '@ledgerhq/wallet-api-client': 1.5.10 '@orangekit/sdk': 1.0.0-beta.16 '@rainbow-me/rainbowkit': 2.0.2(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(viem@2.8.16)(wagmi@2.5.12) + '@swan-bitcoin/xpub-lib': 0.1.5 ethers: 6.12.1 react: 18.3.1 - sats-connect: 2.5.0(typescript@5.4.5)(valibot@0.33.2) + sats-connect: 2.8.0(typescript@5.4.5) viem: 2.8.16(typescript@5.4.5) wagmi: 2.5.12(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(react@18.3.1)(typescript@5.4.5)(viem@2.8.16) transitivePeerDependencies: @@ -5792,7 +5811,6 @@ packages: - typescript - uWebSockets.js - utf-8-validate - - valibot - zod dev: false @@ -6787,12 +6805,10 @@ packages: engines: {node: '>=16'} dev: false - /@sats-connect/core@0.0.15(valibot@0.33.2): - resolution: {integrity: sha512-f+s+uM4BnjLs+I8AHp4Tf4GG8kMLGn44RalNZqlo/OkTeZj+llQEsMEwfKkIM8f45gA3jSWqmn4q/LsjMpWlVw==} - peerDependencies: - valibot: 0.33.2 + /@sats-connect/core@0.2.2: + resolution: {integrity: sha512-nl3zPnV1UBllYAniDfhM/oSFGQ2qy4cCg1YwxJZ+RQMwlTMrVh2f3lJ//dIIo9RgQPrtHpwrAaaWW0VpfqDQbg==} dependencies: - axios: 1.6.8 + axios: 1.7.4 bitcoin-address-validation: 2.2.3 buffer: 6.0.3 jsontokens: 4.0.1 @@ -6802,13 +6818,13 @@ packages: - debug dev: false - /@sats-connect/make-default-provider-config@0.0.5(@sats-connect/core@0.0.15)(typescript@5.4.5): + /@sats-connect/make-default-provider-config@0.0.5(@sats-connect/core@0.2.2)(typescript@5.4.5): resolution: {integrity: sha512-b/v4IeDEde5DqFOdMbMmf3B0t/lxlKnY04f3YIUWe1khOg3S6VdcK9Mqva+WUOsJHBTIA5b4hK7CqfMjx1Ic+w==} peerDependencies: '@sats-connect/core': '*' typescript: 5.4.4 dependencies: - '@sats-connect/core': 0.0.15(valibot@0.33.2) + '@sats-connect/core': 0.2.2 '@sats-connect/ui': 0.0.6 bowser: 2.11.0 typescript: 5.4.5 @@ -9423,35 +9439,35 @@ packages: - debug dev: false - /axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} + /axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} dependencies: follow-redirects: 1.15.6(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: false + dev: true - /axios@1.7.2: + /axios@1.7.2(debug@4.3.5): resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} dependencies: - follow-redirects: 1.15.6(debug@4.3.4) + follow-redirects: 1.15.6(debug@4.3.5) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: true - /axios@1.7.2(debug@4.3.5): - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + /axios@1.7.4: + resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} dependencies: - follow-redirects: 1.15.6(debug@4.3.5) + follow-redirects: 1.15.6(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: true + dev: false /axobject-query@3.2.1: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} @@ -18764,16 +18780,15 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sats-connect@2.5.0(typescript@5.4.5)(valibot@0.33.2): - resolution: {integrity: sha512-oyKQMH07dvXv/UCUlbHWoLsfycnDgsyipyaUovnFBsG85t1jF6wlXcGDPwiD8fIUmplDD6UmHlyAfCL8ai5b3w==} + /sats-connect@2.8.0(typescript@5.4.5): + resolution: {integrity: sha512-eYdpPoAXn6ud1hMZnQGowO1F0f9fS3jmE5Hq1F3VxXUbAvT2YmA72PBtG6QN/cdMuFZ5x1ce6I/fl270WSXqjw==} dependencies: - '@sats-connect/core': 0.0.15(valibot@0.33.2) - '@sats-connect/make-default-provider-config': 0.0.5(@sats-connect/core@0.0.15)(typescript@5.4.5) + '@sats-connect/core': 0.2.2 + '@sats-connect/make-default-provider-config': 0.0.5(@sats-connect/core@0.2.2)(typescript@5.4.5) '@sats-connect/ui': 0.0.6 transitivePeerDependencies: - debug - typescript - - valibot dev: false /sc-istanbul@0.4.6: From 043d623925b375be157dc85996fae0ce94ee9385 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 24 Sep 2024 19:42:47 +0200 Subject: [PATCH 014/179] Add ledger live manifest for testnet preview --- dapp/ledger-manifest-testnet-preview.json | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 dapp/ledger-manifest-testnet-preview.json diff --git a/dapp/ledger-manifest-testnet-preview.json b/dapp/ledger-manifest-testnet-preview.json new file mode 100644 index 000000000..4b66fd512 --- /dev/null +++ b/dapp/ledger-manifest-testnet-preview.json @@ -0,0 +1,31 @@ +{ + "id": "acre-testnet", + "name": "Acre [testnet - preview]", + "url": "https://deploy-preview-733--acre-dapp-testnet.netlify.app/?embed=ledger-live", + "homepageUrl": "https:/acre.fi/", + "icon": "https://deploy-preview-733--acre-dapp-testnet.netlify.app/acre.svg", + "platforms": "desktop", + "apiVersion": "^2.0.0", + "manifestVersion": "2", + "branch": "stable", + "categories": ["staking"], + "currencies": ["bitcoin", "bitcoin_testnet"], + "content": { + "shortDescription": { + "en": "Bitcoin Liquid Staking" + }, + "description": { + "en": "Bitcoin Liquid Staking" + } + }, + "permissions": [ + "account.request", + "account.list", + "message.sign", + "transaction.sign", + "transaction.signAndBroadcast", + "bitcoin.getXPub" + ], + "domains": ["http://*"], + "type": "walletApp" +} From dfd921b65c2fe05147fe64c9857de4dc167f2d86 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 25 Sep 2024 12:06:58 +0200 Subject: [PATCH 015/179] Update Ledger live manifest for testnet preview --- dapp/ledger-manifest-testnet-preview.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/ledger-manifest-testnet-preview.json b/dapp/ledger-manifest-testnet-preview.json index 4b66fd512..dd1aee77e 100644 --- a/dapp/ledger-manifest-testnet-preview.json +++ b/dapp/ledger-manifest-testnet-preview.json @@ -1,9 +1,9 @@ { "id": "acre-testnet", "name": "Acre [testnet - preview]", - "url": "https://deploy-preview-733--acre-dapp-testnet.netlify.app/?embed=ledger-live", + "url": "https://deploy-preview-708--acre-dapp-testnet.netlify.app/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", - "icon": "https://deploy-preview-733--acre-dapp-testnet.netlify.app/acre.svg", + "icon": "https://deploy-preview-708--acre-dapp-testnet.netlify.app/acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", From 7576045348b2f8534797e707336203b61ad19da2 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 25 Sep 2024 12:28:29 +0200 Subject: [PATCH 016/179] Update Ledger Live manifest We configured netlify branch deployments for this feature branch, so we can use `https://ledger-live-updates--acre-dapp-testnet.netlify.app/?embed=ledger-live` here. --- dapp/ledger-manifest-testnet-preview.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/ledger-manifest-testnet-preview.json b/dapp/ledger-manifest-testnet-preview.json index dd1aee77e..9464fe6fe 100644 --- a/dapp/ledger-manifest-testnet-preview.json +++ b/dapp/ledger-manifest-testnet-preview.json @@ -1,9 +1,9 @@ { "id": "acre-testnet", "name": "Acre [testnet - preview]", - "url": "https://deploy-preview-708--acre-dapp-testnet.netlify.app/?embed=ledger-live", + "url": "https://ledger-live-updates--acre-dapp-testnet.netlify.app/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", - "icon": "https://deploy-preview-708--acre-dapp-testnet.netlify.app/acre.svg", + "icon": "https://ledger-live-updates--acre-dapp-testnet.netlify.app/acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", From e32336eec604d9ea11b930ea8daf2ece45e4798c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 25 Sep 2024 14:11:27 +0200 Subject: [PATCH 017/179] Disable signature verification on login --- .../hooks/useSignMessageAndCreateSession.ts | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/dapp/src/hooks/useSignMessageAndCreateSession.ts b/dapp/src/hooks/useSignMessageAndCreateSession.ts index a59639595..dc75fef7b 100644 --- a/dapp/src/hooks/useSignMessageAndCreateSession.ts +++ b/dapp/src/hooks/useSignMessageAndCreateSession.ts @@ -1,5 +1,7 @@ import { OrangeKitConnector } from "#/types" +// eslint-disable-next-line @typescript-eslint/no-unused-vars import { acreApi, orangeKit } from "#/utils" +import { generateNonce } from "@orangekit/sign-in-with-wallet" import { useCallback } from "react" import { useSignMessage } from "wagmi" @@ -8,43 +10,41 @@ function useSignMessageAndCreateSession() { const signMessageAndCreateSession = useCallback( async (connectedConnector: OrangeKitConnector, btcAddress: string) => { - let session = await acreApi.getSession() - const hasSessionAddress = "address" in session - - const isSessionAddressEqual = hasSessionAddress - ? (session as { address: string }).address === btcAddress - : false - - if (hasSessionAddress && isSessionAddressEqual) { - return - } - - if (hasSessionAddress && !isSessionAddressEqual) { - // Delete session. - await acreApi.deleteSession() - // Ask for nonce to create new session. - session = await acreApi.getSession() - } - - if (!("nonce" in session)) { - throw new Error("Session nonce not available") - } - - const message = orangeKit.createSignInWithWalletMessage( - btcAddress, - session.nonce, - ) - + // const session = await acreApi.getSession() + // const hasSessionAddress = "address" in session + + // const isSessionAddressEqual = hasSessionAddress + // ? (session as { address: string }).address === btcAddress + // : false + + // if (hasSessionAddress && isSessionAddressEqual) { + // return + // } + + // if (hasSessionAddress && !isSessionAddressEqual) { + // // Delete session. + // await acreApi.deleteSession() + // // Ask for nonce to create new session. + // session = await acreApi.getSession() + // } + + // if (!("nonce" in session)) { + // throw new Error("Session nonce not available") + // } + const nonce = generateNonce() + const message = orangeKit.createSignInWithWalletMessage(btcAddress, nonce) + + // eslint-disable-next-line @typescript-eslint/no-unused-vars const signedMessage = await signMessageAsync({ message, connector: orangeKit.typeConversionToConnector(connectedConnector), }) - const publicKey = await connectedConnector - .getBitcoinProvider() - .getPublicKey() + // const publicKey = await connectedConnector + // .getBitcoinProvider() + // .getPublicKey() - await acreApi.createSession(message, signedMessage, publicKey) + // await acreApi.createSession(message, signedMessage, publicKey) }, [signMessageAsync], ) From b09fbebc9108893787dc97afd9392847a63aae29 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 27 Sep 2024 09:05:07 +0200 Subject: [PATCH 018/179] Trigger connection action for embed dApp The connection request should run right away when the user opens the modal window. --- .../ConnectWalletModal/ConnectWalletButton.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index f41eb8847..c1a525899 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from "react" +import React, { useCallback, useEffect, useRef, useState } from "react" import { CONNECTION_ERRORS, ONE_SEC_IN_MILLISECONDS } from "#/constants" import { useAppDispatch, @@ -68,6 +68,7 @@ export default function ConnectWalletButton({ useWalletConnectionError() const { closeModal } = useModal() const dispatch = useAppDispatch() + const isMounted = useRef(false) const [isLoading, setIsLoading] = useState(false) @@ -163,6 +164,13 @@ export default function ConnectWalletButton({ handleConnection() } + useEffect(() => { + if (!isMounted.current && isEmbed && isSelected) { + isMounted.current = true + handleConnection() + } + }, [handleConnection, isEmbed, isSelected]) + return ( Date: Fri, 27 Sep 2024 09:36:35 +0200 Subject: [PATCH 019/179] Triggering the connect wallet flow when application starts --- dapp/src/hooks/index.ts | 1 + .../src/hooks/useTriggerConnectWalletModal.ts | 22 +++++++++++++++++++ dapp/src/pages/DashboardPage/index.tsx | 4 +++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 dapp/src/hooks/useTriggerConnectWalletModal.ts diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 96f4c0205..d553204ab 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -34,3 +34,4 @@ export { default as useReferral } from "./useReferral" export { default as useMats } from "./useMats" export { default as useIsEmbed } from "./useIsEmbed" export { default as useSignMessageAndCreateSession } from "./useSignMessageAndCreateSession" +export { default as useTriggerConnectWalletModal } from "./useTriggerConnectWalletModal" diff --git a/dapp/src/hooks/useTriggerConnectWalletModal.ts b/dapp/src/hooks/useTriggerConnectWalletModal.ts new file mode 100644 index 000000000..644638ef0 --- /dev/null +++ b/dapp/src/hooks/useTriggerConnectWalletModal.ts @@ -0,0 +1,22 @@ +import { useEffect, useRef } from "react" +import { MODAL_TYPES } from "#/types" +import { useIsSignedMessage } from "./store/useIsSignedMessage" +import { useModal } from "./useModal" +import useIsEmbed from "./useIsEmbed" + +export default function useTriggerConnectWalletModal() { + const isSignedMessage = useIsSignedMessage() + const { isEmbed } = useIsEmbed() + const { openModal, closeModal } = useModal() + const isMounted = useRef(false) + + useEffect(() => { + if (!isMounted.current && isEmbed && !isSignedMessage) { + isMounted.current = true + openModal(MODAL_TYPES.CONNECT_WALLET, { + withCloseButton: false, + closeOnEsc: false, + }) + } + }, [closeModal, isEmbed, isSignedMessage, openModal]) +} diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index 811c9f212..cd083af23 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -1,5 +1,5 @@ import React from "react" -import { useMobileMode } from "#/hooks" +import { useMobileMode, useTriggerConnectWalletModal } from "#/hooks" import MobileModeBanner from "#/components/MobileModeBanner" import { featureFlags } from "#/constants" import DashboardCard from "./DashboardCard" @@ -13,6 +13,8 @@ import UsefulLinks from "./UsefulLinks" export default function DashboardPage() { const isMobileMode = useMobileMode() + useTriggerConnectWalletModal() + return isMobileMode ? ( ) : ( From c4e698f3376d661ff569b86ace36f272ab683957 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 27 Sep 2024 12:27:13 +0200 Subject: [PATCH 020/179] Cache the last used account in local storage --- dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useLastUsedBtcAddress.ts | 28 +++++++++++++++++++++++++ dapp/src/hooks/useWallet.ts | 9 ++++++-- dapp/src/wagmiConfig.ts | 5 +++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 dapp/src/hooks/useLastUsedBtcAddress.ts diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index d553204ab..bfd3f635d 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -35,3 +35,4 @@ export { default as useMats } from "./useMats" export { default as useIsEmbed } from "./useIsEmbed" export { default as useSignMessageAndCreateSession } from "./useSignMessageAndCreateSession" export { default as useTriggerConnectWalletModal } from "./useTriggerConnectWalletModal" +export { default as useLastUsedBtcAddress } from "./useLastUsedBtcAddress" diff --git a/dapp/src/hooks/useLastUsedBtcAddress.ts b/dapp/src/hooks/useLastUsedBtcAddress.ts new file mode 100644 index 000000000..cbe0b787a --- /dev/null +++ b/dapp/src/hooks/useLastUsedBtcAddress.ts @@ -0,0 +1,28 @@ +import { useCallback } from "react" +import useLocalStorage from "./useLocalStorage" + +export const LAST_USED_BTC_ADDRESS_KEY = "lastUsedBtcAddress" + +export default function useLastUsedBtcAddress() { + const [address, setAddress] = useLocalStorage( + LAST_USED_BTC_ADDRESS_KEY, + undefined, + ) + + const setAddressInLocalStorage = useCallback( + (btcAddress: string) => { + setAddress(btcAddress) + }, + [setAddress], + ) + + const removeAddressFromLocalStorage = useCallback(() => { + setAddress(undefined) + }, [setAddress]) + + return { + address, + setAddressInLocalStorage, + removeAddressFromLocalStorage, + } +} diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index 5d6c1da7e..2545a98d6 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -11,6 +11,7 @@ import { useConnector } from "./orangeKit/useConnector" import { useBitcoinProvider } from "./orangeKit/useBitcoinProvider" import useBitcoinBalance from "./orangeKit/useBitcoinBalance" import useResetWalletState from "./useResetWalletState" +import useLastUsedBtcAddress from "./useLastUsedBtcAddress" const { typeConversionToConnector, typeConversionToOrangeKitConnector } = orangeKit @@ -39,6 +40,8 @@ export function useWallet(): UseWalletReturn { const provider = useBitcoinProvider() const { data: balance } = useBitcoinBalance() const resetWalletState = useResetWalletState() + const { setAddressInLocalStorage, removeAddressFromLocalStorage } = + useLastUsedBtcAddress() const [address, setAddress] = useState(undefined) @@ -83,7 +86,8 @@ export function useWallet(): UseWalletReturn { const onDisconnect = useCallback(() => { disconnect() resetWalletState() - }, [disconnect, resetWalletState]) + removeAddressFromLocalStorage() + }, [disconnect, removeAddressFromLocalStorage, resetWalletState]) useEffect(() => { const fetchBitcoinAddress = async () => { @@ -91,13 +95,14 @@ export function useWallet(): UseWalletReturn { const btcAddress = await connector.getBitcoinAddress() setAddress(btcAddress) + setAddressInLocalStorage(btcAddress) } else { setAddress(undefined) } } logPromiseFailure(fetchBitcoinAddress()) - }, [connector, provider]) + }, [connector, provider, setAddressInLocalStorage]) return useMemo( () => ({ diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 302ec30b5..32896a65c 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -9,10 +9,15 @@ import { import { env } from "./constants" import { router } from "./utils" import { SEARCH_PARAMS_NAMES } from "./router/path" +import { LAST_USED_BTC_ADDRESS_KEY } from "./hooks/useLastUsedBtcAddress" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id const IsEmbed = router.getURLParam(SEARCH_PARAMS_NAMES.embed) +// TODO: Push address to connector +const lastUsedBtcAddress = localStorage.getItem(LAST_USED_BTC_ADDRESS_KEY) +// eslint-disable-next-line no-console +console.log("lastUsedBtcAddress=", lastUsedBtcAddress) const chains: [Chain, ...Chain[]] = isTestnet ? [sepolia] : [mainnet] const connectorConfig = { From b003ae27b88515ebb8d48dbc96c357d00ba38651 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Fri, 27 Sep 2024 16:07:31 +0200 Subject: [PATCH 021/179] Bump orangekit package to latest dev version To support "0-click connection" flow for the Ledger Live app. --- dapp/package.json | 2 +- dapp/src/wagmiConfig.ts | 14 +++--- pnpm-lock.yaml | 96 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 99 insertions(+), 13 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 372d30a62..3f6bb1596 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.32-dev.0", + "@orangekit/react": "1.0.0-beta.33-dev.0", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 32896a65c..52f74634c 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -14,10 +14,6 @@ import { LAST_USED_BTC_ADDRESS_KEY } from "./hooks/useLastUsedBtcAddress" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id const IsEmbed = router.getURLParam(SEARCH_PARAMS_NAMES.embed) -// TODO: Push address to connector -const lastUsedBtcAddress = localStorage.getItem(LAST_USED_BTC_ADDRESS_KEY) -// eslint-disable-next-line no-console -console.log("lastUsedBtcAddress=", lastUsedBtcAddress) const chains: [Chain, ...Chain[]] = isTestnet ? [sepolia] : [mainnet] const connectorConfig = { @@ -33,8 +29,14 @@ const transports = chains.reduce( const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) -const orangeKitLedgerLiveConnector = - getOrangeKitLedgerLiveConnector(connectorConfig) +const orangeKitLedgerLiveConnector = getOrangeKitLedgerLiveConnector({ + ...connectorConfig, + options: { + shouldConnectToFirstAccountByDefault: true, + tryToConnectToAddress: + localStorage.getItem(LAST_USED_BTC_ADDRESS_KEY) ?? undefined, + }, +}) const embedConnectors = [orangeKitLedgerLiveConnector()] const defaultConnectors = [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8d626b92..109c44f5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.32-dev.0 - version: 1.0.0-beta.32-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.0 + version: 1.0.0-beta.33-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -1908,6 +1908,13 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@bitcoin-js/tiny-secp256k1-asmjs@2.2.3: + resolution: {integrity: sha512-arFPdEZi9RIiaG76OZswTnAU0KfuiLwGw2VNfD66LKhzlbfOnX1o1WI/GI3qm9UbjG/0QOzZu/KmTNvL79x/DQ==} + engines: {node: '>=14.0.0'} + dependencies: + uint8array-tools: 0.0.7 + dev: false + /@bitcoinerlab/secp256k1@1.1.1: resolution: {integrity: sha512-uhjW51WfVLpnHN7+G0saDcM/k9IqcyTbZ+bDgLF3AX8V/a3KXSE9vn7UPBrcdU72tp0J4YPR7BHp2m7MLAZ/1Q==} dependencies: @@ -5771,13 +5778,12 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.32-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-3yllsWIjqEmgOEYIHiazv4sYDsb3KD1t9Ts8tOG0/By67e2r2yXDQ+ahq7gIJqVWj9qEeo6HMiUSq6ttZL90YA==} + /@orangekit/react@1.0.0-beta.33-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-qYF6nIBlDKUWcHhMUgoiLfGwJkg7qD07U6qfqf6W5AWaaV7RLDgPE4NZvYP4bIuQajBrzIv8FgPmVaCASO+poA==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 - '@orangekit/sdk': 1.0.0-beta.16 + '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) '@rainbow-me/rainbowkit': 2.0.2(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(viem@2.8.16)(wagmi@2.5.12) - '@swan-bitcoin/xpub-lib': 0.1.5 ethers: 6.12.1 react: 18.3.1 sats-connect: 2.8.0(typescript@5.4.5) @@ -5832,6 +5838,27 @@ packages: - utf-8-validate dev: false + /@orangekit/sdk@1.0.0-beta.18-dev.0(typescript@5.4.5): + resolution: {integrity: sha512-WGpBkoM0UIp++j6F6ql8vRUtyooZ3yV2hV5dtH5QtINHYPTSbo8dCBvDCPsSokrn1ev2bT1BTPpP+PXVGQuOzQ==} + dependencies: + '@bitcoin-js/tiny-secp256k1-asmjs': 2.2.3 + '@gelatonetwork/relay-sdk': 5.5.6 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@orangekit/contracts': 1.0.0-beta.3(ethers@6.12.1) + '@safe-global/protocol-kit': 3.1.1 + bip32: 5.0.0-rc.0(typescript@5.4.5) + bitcoinjs-lib: 6.1.5 + ethers: 6.12.1 + transitivePeerDependencies: + - bufferutil + - debug + - encoding + - supports-color + - typescript + - utf-8-validate + dev: false + /@orangekit/sign-in-with-wallet-parser@1.0.0-beta.6: resolution: {integrity: sha512-Yi6ohSJV4/Ovrq5c7jD+kPE8pZxLhWtFbZjKRwUW8JL60P/tcyT5o0etul0reqcY2iBlIo5aoC2Hh0noRGl86w==} dependencies: @@ -9620,6 +9647,10 @@ packages: resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} dev: false + /base-x@5.0.0: + resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} + dev: false + /base58-js@1.0.5: resolution: {integrity: sha512-LkkAPP8Zu+c0SVNRTRVDyMfKVORThX+rCViget00xdgLRrKkClCTz1T7cIrpr69ShwV5XJuuoZvMvJ43yURwkA==} engines: {node: '>= 8'} @@ -9736,6 +9767,19 @@ packages: wif: 2.0.6 dev: false + /bip32@5.0.0-rc.0(typescript@5.4.5): + resolution: {integrity: sha512-5hVFGrdCnF8GB1Lj2eEo4PRE7+jp+3xBLnfNjydivOkMvKmUKeJ9GG8uOy8prmWl3Oh154uzgfudR1FRkNBudA==} + engines: {node: '>=18.0.0'} + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.7 + uint8array-tools: 0.0.8 + valibot: 0.37.0(typescript@5.4.5) + wif: 5.0.0 + transitivePeerDependencies: + - typescript + dev: false + /bip39@3.0.2: resolution: {integrity: sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==} dependencies: @@ -10028,6 +10072,12 @@ packages: base-x: 4.0.0 dev: false + /bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + dependencies: + base-x: 5.0.0 + dev: false + /bs58check@2.1.2: resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} dependencies: @@ -10042,6 +10092,13 @@ packages: bs58: 5.0.0 dev: false + /bs58check@4.0.0: + resolution: {integrity: sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==} + dependencies: + '@noble/hashes': 1.4.0 + bs58: 6.0.0 + dev: false + /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -20279,6 +20336,16 @@ packages: dev: true optional: true + /uint8array-tools@0.0.7: + resolution: {integrity: sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==} + engines: {node: '>=14.0.0'} + dev: false + + /uint8array-tools@0.0.8: + resolution: {integrity: sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==} + engines: {node: '>=14.0.0'} + dev: false + /uint8arrays@3.1.0: resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} dependencies: @@ -20656,6 +20723,17 @@ packages: resolution: {integrity: sha512-ZpFWuI+bs5+PP66q4zVFn4e4t/s5jmMw5iPBZmGUoi8iQqXyU9YY/BLCAyk62Z/bNS8qdUNBEyx52952qdqW3w==} dev: false + /valibot@0.37.0(typescript@5.4.5): + resolution: {integrity: sha512-FQz52I8RXgFgOHym3XHYSREbNtkgSjF9prvMFH1nBsRyfL6SfCzoT1GuSDTlbsuPubM7/6Kbw0ZMQb8A+V+VsQ==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.4.5 + dev: false + /valid-url@1.0.9: resolution: {integrity: sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==} dev: false @@ -22281,6 +22359,12 @@ packages: bs58check: 2.1.2 dev: false + /wif@5.0.0: + resolution: {integrity: sha512-iFzrC/9ne740qFbNjTZ2FciSRJlHIXoxqk/Y5EnE08QOXu1WjJyCCswwDTYbohAOEnlCtLaAAQBhyaLRFh2hMA==} + dependencies: + bs58check: 4.0.0 + dev: false + /word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} From b8939114dd3ebe405a2a47beec3fcda34bf55b08 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Mon, 30 Sep 2024 11:26:12 +0200 Subject: [PATCH 022/179] Fix a bug of incorrect check for the `localStorage` item We use the `@rehooks/local-storage` library, which saves undefined as a string. Therefore, we need to check the value of "undefined". --- dapp/src/hooks/useLocalStorage.ts | 8 ++++++++ dapp/src/wagmiConfig.ts | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dapp/src/hooks/useLocalStorage.ts b/dapp/src/hooks/useLocalStorage.ts index 4eed2d95f..ed42703b5 100644 --- a/dapp/src/hooks/useLocalStorage.ts +++ b/dapp/src/hooks/useLocalStorage.ts @@ -1,5 +1,13 @@ import { useLocalStorage as useRehooksLocalStorage } from "@rehooks/local-storage" +export const getLocalStorageItem = (key: string): string | undefined => { + const value = localStorage.getItem(key) + if (value === "undefined" || value === "null" || value === null) + return undefined + + return value +} + export default function useLocalStorage(key: string, defaultValue: T) { return useRehooksLocalStorage(key, defaultValue) } diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 52f74634c..256083f34 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -10,6 +10,7 @@ import { env } from "./constants" import { router } from "./utils" import { SEARCH_PARAMS_NAMES } from "./router/path" import { LAST_USED_BTC_ADDRESS_KEY } from "./hooks/useLastUsedBtcAddress" +import { getLocalStorageItem } from "./hooks/useLocalStorage" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id @@ -33,8 +34,7 @@ const orangeKitLedgerLiveConnector = getOrangeKitLedgerLiveConnector({ ...connectorConfig, options: { shouldConnectToFirstAccountByDefault: true, - tryToConnectToAddress: - localStorage.getItem(LAST_USED_BTC_ADDRESS_KEY) ?? undefined, + tryToConnectToAddress: getLocalStorageItem(LAST_USED_BTC_ADDRESS_KEY), }, }) From 9aa13a0b0c97b7f2426f1672741def68fd23ee8b Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 30 Sep 2024 16:21:27 +0200 Subject: [PATCH 023/179] Bump `@orangekit/react` dependency To update the conection flow. --- dapp/package.json | 2 +- dapp/src/wagmiConfig.ts | 3 +-- pnpm-lock.yaml | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 3f6bb1596..819c417af 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.0", + "@orangekit/react": "1.0.0-beta.33-dev.1", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 256083f34..beef7ae17 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -33,8 +33,7 @@ const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) const orangeKitLedgerLiveConnector = getOrangeKitLedgerLiveConnector({ ...connectorConfig, options: { - shouldConnectToFirstAccountByDefault: true, - tryToConnectToAddress: getLocalStorageItem(LAST_USED_BTC_ADDRESS_KEY), + tryConnectToAddress: getLocalStorageItem(LAST_USED_BTC_ADDRESS_KEY), }, }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 109c44f5b..5b4134102 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.0 - version: 1.0.0-beta.33-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.1 + version: 1.0.0-beta.33-dev.1(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5778,8 +5778,8 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.0(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-qYF6nIBlDKUWcHhMUgoiLfGwJkg7qD07U6qfqf6W5AWaaV7RLDgPE4NZvYP4bIuQajBrzIv8FgPmVaCASO+poA==} + /@orangekit/react@1.0.0-beta.33-dev.1(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-VGmXLcetwNicpwDBvTlJtbLSk3BQed2ZxzGXZaSserGlRnOheMprN0kskAKDqXeKhUx3Is9ryJkzOwsgxXbNNA==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) From 9527153cf0cd937f5247d68e94cb28c1632b5145 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 1 Oct 2024 15:30:59 +0200 Subject: [PATCH 024/179] Improve error handling in connect wallet flow --- dapp/package.json | 2 +- dapp/src/hooks/orangeKit/useBitcoinProvider.ts | 3 ++- dapp/src/hooks/useWallet.ts | 1 + pnpm-lock.yaml | 8 ++++---- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 819c417af..6d2c6d597 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.1", + "@orangekit/react": "1.0.0-beta.33-dev.2", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/hooks/orangeKit/useBitcoinProvider.ts b/dapp/src/hooks/orangeKit/useBitcoinProvider.ts index 5b6cdaeaa..41e9bce37 100644 --- a/dapp/src/hooks/orangeKit/useBitcoinProvider.ts +++ b/dapp/src/hooks/orangeKit/useBitcoinProvider.ts @@ -8,7 +8,8 @@ export function useBitcoinProvider(): UseBitcoinProviderReturn { const connector = useConnector() return useMemo(() => { - if (!connector) return undefined + if (!connector || typeof connector.getBitcoinProvider !== "function") + return undefined return connector.getBitcoinProvider() }, [connector]) diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index 2545a98d6..108c9baa3 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -85,6 +85,7 @@ export function useWallet(): UseWalletReturn { const onDisconnect = useCallback(() => { disconnect() + setAddress(undefined) resetWalletState() removeAddressFromLocalStorage() }, [disconnect, removeAddressFromLocalStorage, resetWalletState]) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b4134102..56fbda366 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.1 - version: 1.0.0-beta.33-dev.1(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.2 + version: 1.0.0-beta.33-dev.2(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5778,8 +5778,8 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.1(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-VGmXLcetwNicpwDBvTlJtbLSk3BQed2ZxzGXZaSserGlRnOheMprN0kskAKDqXeKhUx3Is9ryJkzOwsgxXbNNA==} + /@orangekit/react@1.0.0-beta.33-dev.2(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-yAeaz2uuehbuSjYLlWHmH/x9MSfvjbd3egy3IsB5D+LMSR5vuIwPBvYkJzSRjYRKJW40Vkh7oeCx2HrDeQD2Tw==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) From 1fb905c06bc0e54b36cefe7d345d207b51b62b36 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 2 Oct 2024 07:41:13 +0200 Subject: [PATCH 025/179] Fix refetching data on reconnect --- dapp/src/hooks/useResetWalletState.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dapp/src/hooks/useResetWalletState.ts b/dapp/src/hooks/useResetWalletState.ts index 8d4c1bb2f..28d72030d 100644 --- a/dapp/src/hooks/useResetWalletState.ts +++ b/dapp/src/hooks/useResetWalletState.ts @@ -1,4 +1,4 @@ -import { useQueryClient } from "@tanstack/react-query" +import { QueryFilters, useQueryClient } from "@tanstack/react-query" import { useCallback } from "react" import { resetState } from "#/store/wallet" import { queryKeysFactory } from "#/constants" @@ -12,8 +12,10 @@ export default function useResetWalletState() { const dispatch = useAppDispatch() const resetQueries = useCallback(async () => { - queryClient.removeQueries({ queryKey: userKeys.all }) - await queryClient.resetQueries({ queryKey: userKeys.all }) + const filters: QueryFilters = { queryKey: userKeys.all, exact: true } + + queryClient.removeQueries(filters) + await queryClient.resetQueries(filters) }, [queryClient]) return useCallback(() => { From c2f723a2165e06c46aa0cf5556902feb40ae92c8 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 2 Oct 2024 08:01:26 +0200 Subject: [PATCH 026/179] Mock session mechanism in dapp We want the flow to be as close to the original as possible, so here we simulate the session mechanism. --- .../hooks/useSignMessageAndCreateSession.ts | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/dapp/src/hooks/useSignMessageAndCreateSession.ts b/dapp/src/hooks/useSignMessageAndCreateSession.ts index 8e67d9b76..ab1a81193 100644 --- a/dapp/src/hooks/useSignMessageAndCreateSession.ts +++ b/dapp/src/hooks/useSignMessageAndCreateSession.ts @@ -1,9 +1,13 @@ import { OrangeKitConnector } from "#/types" // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { acreApi, orangeKit } from "#/utils" +import { acreApi, getExpirationDate, orangeKit } from "#/utils" import { generateNonce } from "@orangekit/sign-in-with-wallet" import { useCallback } from "react" import { useSignMessage } from "wagmi" +import { ACRE_SESSION_EXPIRATION_TIME } from "#/constants" +import useLocalStorage from "./useLocalStorage" + +const initialSession = { address: "", sessionId: 0 } function useSignMessageAndCreateSession() { const { @@ -12,6 +16,16 @@ function useSignMessageAndCreateSession() { reset: resetMessageStatus, } = useSignMessage() + // TODO: Temporary solution to mock the session mechanism for Ledger Live App + // integration. To fully support the session mechanism exposed by Acre API + // backend we need sign message with "zero" address not fresh address. This is + // will be supported in future versions of Ledger Bitcoin App. + const [session, setSession] = useLocalStorage<{ + address: string + sessionId: number + }>("acre.session", initialSession) + const { address: sessionAddress, sessionId } = session + const signMessageAndCreateSession = useCallback( async (connectedConnector: OrangeKitConnector, btcAddress: string) => { // const session = await acreApi.getSession() @@ -35,6 +49,14 @@ function useSignMessageAndCreateSession() { // if (!("nonce" in session)) { // throw new Error("Session nonce not available") // } + if ( + new Date(sessionId).getTime() > Date.now() && + btcAddress === sessionAddress + ) { + // The session is valid no need to sign message. + return + } + const nonce = generateNonce() const message = orangeKit.createSignInWithWalletMessage(btcAddress, nonce) @@ -44,13 +66,18 @@ function useSignMessageAndCreateSession() { connector: orangeKit.typeConversionToConnector(connectedConnector), }) + const newSessionId = getExpirationDate( + ACRE_SESSION_EXPIRATION_TIME, + ).getTime() + setSession({ address: btcAddress, sessionId: newSessionId }) + // const publicKey = await connectedConnector // .getBitcoinProvider() // .getPublicKey() // await acreApi.createSession(message, signedMessage, publicKey) }, - [signMessageAsync], + [signMessageAsync, sessionAddress, sessionId, setSession], ) return { From f0ac21d32db080882b6e1c8130f4dba2c11d2299 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 2 Oct 2024 08:27:59 +0200 Subject: [PATCH 027/179] Bump `@orangekit/react` package --- dapp/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 6d2c6d597..62b096de5 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.2", + "@orangekit/react": "1.0.0-beta.33-dev.3", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 56fbda366..50c1c016e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.2 - version: 1.0.0-beta.33-dev.2(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.3 + version: 1.0.0-beta.33-dev.3(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5778,8 +5778,8 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.2(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-yAeaz2uuehbuSjYLlWHmH/x9MSfvjbd3egy3IsB5D+LMSR5vuIwPBvYkJzSRjYRKJW40Vkh7oeCx2HrDeQD2Tw==} + /@orangekit/react@1.0.0-beta.33-dev.3(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-oZ6kIF9rgoXqfxCN5akJ/wxp0wedc8X8l+pLcz+wqY5HGf/RTOqSMkH/lFLx38AFGVJGueMgwNz1nllFYfFsiA==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) From dc37b81a13076687478fcea6699512790469a495 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 3 Oct 2024 11:06:10 +0200 Subject: [PATCH 028/179] Handle Taprrot address validation correctly --- dapp/package.json | 2 +- .../components/ConnectWalletModal/ConnectWalletButton.tsx | 3 ++- pnpm-lock.yaml | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 62b096de5..09cf2f994 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.3", + "@orangekit/react": "1.0.0-beta.33-dev.4", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index c1a525899..5204cdc53 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -127,6 +127,8 @@ export default function ConnectWalletButton({ onError: (error: OrangeKitError) => { const errorData = orangeKit.parseOrangeKitConnectionError(error) setConnectionError(errorData) + if (connector.id === "orangekit-ledger-live") + logPromiseFailure(connector.disconnect()) }, }) }, [onConnect, connector, onSuccessConnection, setConnectionError]) @@ -148,7 +150,6 @@ export default function ConnectWalletButton({ const handleButtonClick = () => { // Do not trigger action again when wallet connection is in progress if (showStatuses) return - onDisconnect() resetConnectionError() resetMessageStatus() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 50c1c016e..d6220e857 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.3 - version: 1.0.0-beta.33-dev.3(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.4 + version: 1.0.0-beta.33-dev.4(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5778,8 +5778,8 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.3(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-oZ6kIF9rgoXqfxCN5akJ/wxp0wedc8X8l+pLcz+wqY5HGf/RTOqSMkH/lFLx38AFGVJGueMgwNz1nllFYfFsiA==} + /@orangekit/react@1.0.0-beta.33-dev.4(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-BrrylBjF9vM5szm+PdIcXDoj9vr+Ci3GoEW1idh4LCRIDxodBpB4CnAFpXZfhZsP0i3umEPO3IGwmPG+baR4Xg==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) From e50d86dbc3c5aa341698f21a58640f4db06f70aa Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 3 Oct 2024 13:26:18 +0200 Subject: [PATCH 029/179] Update `ConnectWalletButton` component Remove unnecessary disconnection in `onError` callback. After updating the `@orangekit/react` package to the latest version this is unnecessary. --- dapp/package.json | 2 +- .../ConnectWalletModal/ConnectWalletButton.tsx | 2 -- pnpm-lock.yaml | 14 +++++++------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 09cf2f994..742e1e655 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -24,7 +24,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.4", + "@orangekit/react": "1.0.0-beta.33-dev.5", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index 5204cdc53..b3307c506 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -127,8 +127,6 @@ export default function ConnectWalletButton({ onError: (error: OrangeKitError) => { const errorData = orangeKit.parseOrangeKitConnectionError(error) setConnectionError(errorData) - if (connector.id === "orangekit-ledger-live") - logPromiseFailure(connector.disconnect()) }, }) }, [onConnect, connector, onSuccessConnection, setConnectionError]) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6220e857..0cf67aa39 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.4 - version: 1.0.0-beta.33-dev.4(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.5 + version: 1.0.0-beta.33-dev.5(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5778,11 +5778,11 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.4(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-BrrylBjF9vM5szm+PdIcXDoj9vr+Ci3GoEW1idh4LCRIDxodBpB4CnAFpXZfhZsP0i3umEPO3IGwmPG+baR4Xg==} + /@orangekit/react@1.0.0-beta.33-dev.5(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-Vm2ArRbEpP+REm+aZgdsp648mvYzZ8/rVPjKmrJhvZi6erVGx0lpSM5p8vd42hmF402zUkg4Kwafh5ocpz5P0g==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 - '@orangekit/sdk': 1.0.0-beta.18-dev.0(typescript@5.4.5) + '@orangekit/sdk': 1.0.0-beta.18-dev.1(typescript@5.4.5) '@rainbow-me/rainbowkit': 2.0.2(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(viem@2.8.16)(wagmi@2.5.12) ethers: 6.12.1 react: 18.3.1 @@ -5838,8 +5838,8 @@ packages: - utf-8-validate dev: false - /@orangekit/sdk@1.0.0-beta.18-dev.0(typescript@5.4.5): - resolution: {integrity: sha512-WGpBkoM0UIp++j6F6ql8vRUtyooZ3yV2hV5dtH5QtINHYPTSbo8dCBvDCPsSokrn1ev2bT1BTPpP+PXVGQuOzQ==} + /@orangekit/sdk@1.0.0-beta.18-dev.1(typescript@5.4.5): + resolution: {integrity: sha512-gREDbURdpEMfpkbSDhYpWEiEvDTdLjXbVM0DnZgRMqzFEvUmGZ5M1DkP1eCCNOiU06tWsAhp2Xg6wxl2qfsFpQ==} dependencies: '@bitcoin-js/tiny-secp256k1-asmjs': 2.2.3 '@gelatonetwork/relay-sdk': 5.5.6 From b38296d81b03b414d30b56f717fb4bd1e04de446 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 3 Oct 2024 13:29:12 +0200 Subject: [PATCH 030/179] Update `testnet` config for ledger live manifest --- dapp/config/testnet.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/config/testnet.json b/dapp/config/testnet.json index 4c9b26c58..ade8cb0e6 100644 --- a/dapp/config/testnet.json +++ b/dapp/config/testnet.json @@ -1,5 +1,5 @@ { "id": "testnet", "name": "Acre [testnet]", - "url": "https://dapp.test.acre.fi/" + "url": "https://stake.test.acre.fi/" } From 52bfd1a7f0a62a0cd7e83b7936d9b2af2ea5bcfc Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 3 Oct 2024 13:33:59 +0200 Subject: [PATCH 031/179] Update dapp scripts Simplify the script for creating the ledger-live manifests. --- dapp/ledger-manifest-testnet-preview.json | 31 ------------------- .../ledger-live-manifest-development.json} | 0 .../ledger-live-manifest-mainnet.json} | 0 .../ledger-live-manifest-testnet.json} | 4 +-- .../ledger-manifest-template.json | 0 dapp/package.json | 5 +-- 6 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 dapp/ledger-manifest-testnet-preview.json rename dapp/{ledger-manifest-development.json => manifests/ledger-live/ledger-live-manifest-development.json} (100%) rename dapp/{ledger-manifest-mainnet.json => manifests/ledger-live/ledger-live-manifest-mainnet.json} (100%) rename dapp/{ledger-manifest-testnet.json => manifests/ledger-live/ledger-live-manifest-testnet.json} (85%) rename dapp/{ => manifests/ledger-live}/ledger-manifest-template.json (100%) diff --git a/dapp/ledger-manifest-testnet-preview.json b/dapp/ledger-manifest-testnet-preview.json deleted file mode 100644 index 9464fe6fe..000000000 --- a/dapp/ledger-manifest-testnet-preview.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "id": "acre-testnet", - "name": "Acre [testnet - preview]", - "url": "https://ledger-live-updates--acre-dapp-testnet.netlify.app/?embed=ledger-live", - "homepageUrl": "https:/acre.fi/", - "icon": "https://ledger-live-updates--acre-dapp-testnet.netlify.app/acre.svg", - "platforms": "desktop", - "apiVersion": "^2.0.0", - "manifestVersion": "2", - "branch": "stable", - "categories": ["staking"], - "currencies": ["bitcoin", "bitcoin_testnet"], - "content": { - "shortDescription": { - "en": "Bitcoin Liquid Staking" - }, - "description": { - "en": "Bitcoin Liquid Staking" - } - }, - "permissions": [ - "account.request", - "account.list", - "message.sign", - "transaction.sign", - "transaction.signAndBroadcast", - "bitcoin.getXPub" - ], - "domains": ["http://*"], - "type": "walletApp" -} diff --git a/dapp/ledger-manifest-development.json b/dapp/manifests/ledger-live/ledger-live-manifest-development.json similarity index 100% rename from dapp/ledger-manifest-development.json rename to dapp/manifests/ledger-live/ledger-live-manifest-development.json diff --git a/dapp/ledger-manifest-mainnet.json b/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json similarity index 100% rename from dapp/ledger-manifest-mainnet.json rename to dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json diff --git a/dapp/ledger-manifest-testnet.json b/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json similarity index 85% rename from dapp/ledger-manifest-testnet.json rename to dapp/manifests/ledger-live/ledger-live-manifest-testnet.json index d63282bf2..d0f2afb43 100644 --- a/dapp/ledger-manifest-testnet.json +++ b/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json @@ -1,9 +1,9 @@ { "id": "acre-testnet", "name": "Acre [testnet]", - "url": "https://dapp.test.acre.fi/?embed=ledger-live", + "url": "https://stake.test.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", - "icon": "https://dapp.test.acre.fi/acre.svg", + "icon": "https://stake.test.acre.fi/acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", diff --git a/dapp/ledger-manifest-template.json b/dapp/manifests/ledger-live/ledger-manifest-template.json similarity index 100% rename from dapp/ledger-manifest-template.json rename to dapp/manifests/ledger-live/ledger-manifest-template.json diff --git a/dapp/package.json b/dapp/package.json index 742e1e655..697786509 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -14,10 +14,7 @@ "lint:config": "prettier -c '**/*.@(json|yaml|toml)'", "lint:config:fix": "prettier -w '**/*.@(json|yaml|toml)'", "test": "vitest", - "prepare:dev": "mustache config/development.json ledger-manifest-template.json > ledger-manifest-development.json", - "prepare:testnet": "mustache config/testnet.json ledger-manifest-template.json > ledger-manifest-testnet.json", - "prepare:mainnet": "mustache config/mainnet.json ledger-manifest-template.json > ledger-manifest-mainnet.json", - "prepare:all-env": "pnpm prepare:dev && pnpm prepare:testnet && pnpm prepare:mainnet" + "generate:manifests": "for env in development testnet mainnet; do mustache config/$env.json ./manifests/ledger-live/ledger-manifest-template.json > ./manifests/ledger-live/ledger-live-manifest-$env.json; done" }, "dependencies": { "@acre-btc/sdk": "workspace:*", From 3b8b1b5562873af0d96a44572d03fb6b4249226a Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 3 Oct 2024 13:37:10 +0200 Subject: [PATCH 032/179] Add helper function Add helper function that reads the last used bitcoin address from the local storage to keep the `LAST_USED_BTC_ADDRESS_KEY` const unexported. --- dapp/src/hooks/useLastUsedBtcAddress.ts | 8 ++++++-- dapp/src/wagmiConfig.ts | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dapp/src/hooks/useLastUsedBtcAddress.ts b/dapp/src/hooks/useLastUsedBtcAddress.ts index cbe0b787a..ad4b4e56a 100644 --- a/dapp/src/hooks/useLastUsedBtcAddress.ts +++ b/dapp/src/hooks/useLastUsedBtcAddress.ts @@ -1,7 +1,11 @@ import { useCallback } from "react" -import useLocalStorage from "./useLocalStorage" +import useLocalStorage, { getLocalStorageItem } from "./useLocalStorage" -export const LAST_USED_BTC_ADDRESS_KEY = "lastUsedBtcAddress" +const LAST_USED_BTC_ADDRESS_KEY = "acre.lastUsedBtcAddress" + +export function getLastUsedBtcAddress() { + return getLocalStorageItem(LAST_USED_BTC_ADDRESS_KEY) +} export default function useLastUsedBtcAddress() { const [address, setAddress] = useLocalStorage( diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index beef7ae17..61d77aae5 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -9,8 +9,7 @@ import { import { env } from "./constants" import { router } from "./utils" import { SEARCH_PARAMS_NAMES } from "./router/path" -import { LAST_USED_BTC_ADDRESS_KEY } from "./hooks/useLastUsedBtcAddress" -import { getLocalStorageItem } from "./hooks/useLocalStorage" +import { getLastUsedBtcAddress } from "./hooks/useLastUsedBtcAddress" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id @@ -33,7 +32,7 @@ const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) const orangeKitLedgerLiveConnector = getOrangeKitLedgerLiveConnector({ ...connectorConfig, options: { - tryConnectToAddress: getLocalStorageItem(LAST_USED_BTC_ADDRESS_KEY), + tryConnectToAddress: getLastUsedBtcAddress(), }, }) From 36be355c6b42b2def1f7b7cc4e3f4a193017d33e Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 8 Oct 2024 15:50:24 +0200 Subject: [PATCH 033/179] Set mobile mode only when the dApp is not embedded --- dapp/src/hooks/useMobileMode.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dapp/src/hooks/useMobileMode.ts b/dapp/src/hooks/useMobileMode.ts index 07e7de6a1..25a491c1d 100644 --- a/dapp/src/hooks/useMobileMode.ts +++ b/dapp/src/hooks/useMobileMode.ts @@ -2,11 +2,13 @@ import { screen } from "#/constants" import { userAgent as userAgentUtils } from "#/utils" import { useMediaQuery } from "@chakra-ui/react" import { useMemo } from "react" +import useIsEmbed from "./useIsEmbed" const { MAX_MOBILE_SCREEN_WIDTH } = screen const { getDeviceDetect } = userAgentUtils const useMobileMode = () => { + const { isEmbed } = useIsEmbed() const [isMobileScreen] = useMediaQuery( `(max-width: ${MAX_MOBILE_SCREEN_WIDTH})`, ) @@ -28,7 +30,7 @@ const useMobileMode = () => { return isMobileDevice() }, [isMobileScreen]) - return isMobile + return !isEmbed && isMobile } export default useMobileMode From 87aa0165e6e9940eab3a0058eca3fc15359128fc Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 9 Oct 2024 09:36:49 +0200 Subject: [PATCH 034/179] Add switch account button --- .../ConnectWalletButton.tsx | 11 +++- .../components/ConnectWalletModal/index.tsx | 3 ++ dapp/src/components/Header/ConnectWallet.tsx | 30 +++++++++-- dapp/src/hooks/orangeKit/useBitcoinBalance.ts | 8 +-- dapp/src/hooks/sdk/useBitcoinPosition.ts | 8 +-- dapp/src/hooks/sdk/useFetchActivities.ts | 6 ++- dapp/src/hooks/sdk/useInitializeAcreSdk.ts | 4 +- dapp/src/hooks/useWallet.ts | 52 +++++++++++++++++-- 8 files changed, 102 insertions(+), 20 deletions(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index b3307c506..a3ab2f746 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -35,6 +35,7 @@ type ConnectWalletButtonProps = { isSelected: boolean connector: OrangeKitConnector & { isDisabled: boolean } onSuccess?: OnSuccessCallback + isReconnecting?: boolean } const iconStyles: Record = { @@ -54,6 +55,7 @@ export default function ConnectWalletButton({ isSelected, connector, onSuccess, + isReconnecting, }: ConnectWalletButtonProps) { const { isEmbed } = useIsEmbed() const { @@ -121,6 +123,7 @@ export default function ConnectWalletButton({ const handleConnection = useCallback(() => { onConnect(connector, { + isReconnecting, onSuccess: () => { logPromiseFailure(onSuccessConnection(connector)) }, @@ -129,7 +132,13 @@ export default function ConnectWalletButton({ setConnectionError(errorData) }, }) - }, [onConnect, connector, onSuccessConnection, setConnectionError]) + }, [ + onConnect, + connector, + onSuccessConnection, + setConnectionError, + isReconnecting, + ]) const handleRedirectUser = useCallback(() => { setIsLoading(true) diff --git a/dapp/src/components/ConnectWalletModal/index.tsx b/dapp/src/components/ConnectWalletModal/index.tsx index f779af0cc..b255f46cb 100644 --- a/dapp/src/components/ConnectWalletModal/index.tsx +++ b/dapp/src/components/ConnectWalletModal/index.tsx @@ -10,8 +10,10 @@ import ConnectWalletErrorAlert from "./ConnectWalletErrorAlert" export function ConnectWalletModalBase({ onSuccess, withCloseButton = true, + isReconnecting, }: { onSuccess?: OnSuccessCallback + isReconnecting?: boolean } & BaseModalProps) { const { isEmbed } = useIsEmbed() const connectors = useConnectors() @@ -51,6 +53,7 @@ export function ConnectWalletModalBase({ onClick={() => handleButtonOnClick(connector)} isSelected={selectedConnectorId === connector.id} onSuccess={onSuccess} + isReconnecting={isReconnecting} /> ))} diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 58e8dd75d..5fc923042 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -17,7 +17,12 @@ import { BitcoinIcon } from "#/assets/icons" import { truncateAddress } from "#/utils" import { motion } from "framer-motion" import { MODAL_TYPES } from "#/types" -import { IconCopy, IconLogout, IconWallet } from "@tabler/icons-react" +import { + IconCopy, + IconLogout, + IconWallet, + IconUserCode, +} from "@tabler/icons-react" export default function ConnectWallet() { const { isEmbed } = useIsEmbed() @@ -29,8 +34,8 @@ export default function ConnectWallet() { size: "lg", }) - const handleConnectWallet = () => { - openModal(MODAL_TYPES.CONNECT_WALLET) + const handleConnectWallet = (isReconnecting: boolean = false) => { + openModal(MODAL_TYPES.CONNECT_WALLET, { isReconnecting }) } if (!address) { @@ -40,7 +45,7 @@ export default function ConnectWallet() { variant="card" color="grey.700" leftIcon={} - onClick={handleConnectWallet} + onClick={() => handleConnectWallet(false)} {...((modalType === MODAL_TYPES.CONNECT_WALLET || isOpenGlobalErrorModal) && { pointerEvents: "none", @@ -106,6 +111,23 @@ export default function ConnectWallet() { /> + + } + px={2} + boxSize={5} + onClick={() => handleConnectWallet(true)} + /> + + { - if (!provider) return 0n + if (!provider || !address) return 0n const { total } = await provider.getBalance() return BigInt(total) diff --git a/dapp/src/hooks/sdk/useBitcoinPosition.ts b/dapp/src/hooks/sdk/useBitcoinPosition.ts index 3f7ca2b3b..f1036ef1a 100644 --- a/dapp/src/hooks/sdk/useBitcoinPosition.ts +++ b/dapp/src/hooks/sdk/useBitcoinPosition.ts @@ -1,17 +1,19 @@ import { useAcreContext } from "#/acre-react/hooks" import { useQuery } from "@tanstack/react-query" import { REFETCH_INTERVAL_IN_MILLISECONDS, queryKeysFactory } from "#/constants" +import { useWallet } from "../useWallet" const { userKeys } = queryKeysFactory export default function useBitcoinPosition() { + const { address } = useWallet() const { acre, isConnected } = useAcreContext() return useQuery({ - queryKey: [...userKeys.position(), { acre, isConnected }], - enabled: isConnected && !!acre, + queryKey: [...userKeys.position(), { acre, isConnected, address }], + enabled: isConnected && !!acre && !!address, queryFn: async () => { - if (!isConnected || !acre) + if (!isConnected || !acre || !address) return { sharesBalance: 0n, estimatedBitcoinBalance: 0n } const sharesBalance = await acre.account.sharesBalance() diff --git a/dapp/src/hooks/sdk/useFetchActivities.ts b/dapp/src/hooks/sdk/useFetchActivities.ts index b640da92a..0d35bcbcc 100644 --- a/dapp/src/hooks/sdk/useFetchActivities.ts +++ b/dapp/src/hooks/sdk/useFetchActivities.ts @@ -4,13 +4,15 @@ import { useAcreContext } from "#/acre-react/hooks" import { Activity } from "#/types" import { DepositStatus } from "@acre-btc/sdk" import { useAppDispatch } from "../store/useAppDispatch" +import { useWallet } from "../useWallet" export function useFetchActivities() { const dispatch = useAppDispatch() + const { address } = useWallet() const { acre, isConnected } = useAcreContext() return useCallback(async () => { - if (!acre || !isConnected) return + if (!acre || !isConnected || !address) return const deposits: Activity[] = (await acre.account.getDeposits()).map( (deposit) => ({ @@ -35,5 +37,5 @@ export function useFetchActivities() { ) dispatch(setActivities([...deposits, ...withdrawals])) - }, [acre, dispatch, isConnected]) + }, [acre, dispatch, isConnected, address]) } diff --git a/dapp/src/hooks/sdk/useInitializeAcreSdk.ts b/dapp/src/hooks/sdk/useInitializeAcreSdk.ts index 9ee0d142e..acf662946 100644 --- a/dapp/src/hooks/sdk/useInitializeAcreSdk.ts +++ b/dapp/src/hooks/sdk/useInitializeAcreSdk.ts @@ -3,10 +3,12 @@ import { logPromiseFailure } from "#/utils" import { useAcreContext } from "#/acre-react/hooks" import { BitcoinProvider } from "@acre-btc/sdk" import { useBitcoinProvider } from "../orangeKit/useBitcoinProvider" +import { useWallet } from "../useWallet" export function useInitializeAcreSdk() { const { init } = useAcreContext() const bitcoinProvider = useBitcoinProvider() + const { address } = useWallet() useEffect(() => { const initSDK = async (provider?: BitcoinProvider) => { @@ -14,5 +16,5 @@ export function useInitializeAcreSdk() { } logPromiseFailure(initSDK(bitcoinProvider)) - }, [init, bitcoinProvider]) + }, [init, bitcoinProvider, address]) } diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index 108c9baa3..c137d9375 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -24,6 +24,7 @@ type UseWalletReturn = { onConnect: ( connector: OrangeKitConnector, options?: { + isReconnecting?: boolean onSuccess?: (connector: OrangeKitConnector) => void onError?: OnErrorCallback }, @@ -38,12 +39,12 @@ export function useWallet(): UseWalletReturn { const { disconnect } = useDisconnect() const connector = useConnector() const provider = useBitcoinProvider() - const { data: balance } = useBitcoinBalance() const resetWalletState = useResetWalletState() const { setAddressInLocalStorage, removeAddressFromLocalStorage } = useLastUsedBtcAddress() const [address, setAddress] = useState(undefined) + const { data: balance } = useBitcoinBalance(address) // `isConnected` is variable derived from `status` but does not guarantee us a set `address`. // When `status` is 'connected' properties like `address` are guaranteed to be defined. @@ -53,14 +54,56 @@ export function useWallet(): UseWalletReturn { [accountStatus], ) + const onReconnect = useCallback( + async ( + selectedConnector: OrangeKitConnector, + options: { + onSuccess: (connector: OrangeKitConnector) => void + onError?: OnErrorCallback + }, + ) => { + try { + if (!selectedConnector.connect) return + + await selectedConnector.connect({ chainId, isReconnecting: true }) + const newAddress = await selectedConnector.getBitcoinAddress() + if (newAddress === address) return + + if (options?.onSuccess && typeof selectedConnector !== "function") { + options.onSuccess(selectedConnector) + } + setAddress(newAddress) + resetWalletState() + } catch (error) { + console.error("error in reconnect", error) + // @ts-expect-error test + if (options?.onError) options.onError(error) + } + }, + [address, chainId, resetWalletState], + ) + const onConnect = useCallback( ( selectedConnector: OrangeKitConnector, options?: { onSuccess?: (connector: OrangeKitConnector) => void onError?: OnErrorCallback + isReconnecting?: boolean }, ) => { + if (options?.isReconnecting) { + logPromiseFailure( + onReconnect(selectedConnector, { + onSuccess: () => { + if (options?.onSuccess) options.onSuccess(selectedConnector) + }, + onError: options.onError, + }), + ) + return + } + connect( { connector: typeConversionToConnector(selectedConnector), chainId }, { @@ -80,7 +123,7 @@ export function useWallet(): UseWalletReturn { }, ) }, - [connect, chainId], + [connect, chainId, onReconnect], ) const onDisconnect = useCallback(() => { @@ -88,13 +131,12 @@ export function useWallet(): UseWalletReturn { setAddress(undefined) resetWalletState() removeAddressFromLocalStorage() - }, [disconnect, removeAddressFromLocalStorage, resetWalletState]) + }, [disconnect, resetWalletState, removeAddressFromLocalStorage]) useEffect(() => { const fetchBitcoinAddress = async () => { if (connector) { const btcAddress = await connector.getBitcoinAddress() - setAddress(btcAddress) setAddressInLocalStorage(btcAddress) } else { @@ -103,7 +145,7 @@ export function useWallet(): UseWalletReturn { } logPromiseFailure(fetchBitcoinAddress()) - }, [connector, provider, setAddressInLocalStorage]) + }, [connector, setAddressInLocalStorage, provider]) return useMemo( () => ({ From bcb19cee9dff65b7bcafc7acb45f4fd333b1dd7d Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 9 Oct 2024 10:38:16 +0200 Subject: [PATCH 035/179] Set referral code program based on the embed app --- dapp/src/components/Header/ConnectWallet.tsx | 43 +++++++++++--------- dapp/src/hooks/useIsEmbed.ts | 21 +++++----- dapp/src/hooks/useReferral.ts | 34 +++------------- dapp/src/utils/referralProgram.ts | 21 ++++++++++ dapp/src/wagmiConfig.ts | 25 +++++++----- 5 files changed, 77 insertions(+), 67 deletions(-) diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 5fc923042..1a51c6b30 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -14,7 +14,7 @@ import { useIsEmbed, useModal, useWallet } from "#/hooks" import { CurrencyBalance } from "#/components/shared/CurrencyBalance" import { TextMd } from "#/components/shared/Typography" import { BitcoinIcon } from "#/assets/icons" -import { truncateAddress } from "#/utils" +import { referralProgram, truncateAddress } from "#/utils" import { motion } from "framer-motion" import { MODAL_TYPES } from "#/types" import { @@ -24,8 +24,12 @@ import { IconUserCode, } from "@tabler/icons-react" +function isChangeAccountFeatureSupported(embeddedApp: string | undefined) { + return referralProgram.isEmbedApp(embeddedApp) +} + export default function ConnectWallet() { - const { isEmbed } = useIsEmbed() + const { isEmbed, embeddedApp } = useIsEmbed() const { address, balance, onDisconnect } = useWallet() const { isOpenGlobalErrorModal, modalType, openModal } = useModal() const { hasCopied, onCopy } = useClipboard(address ?? "") @@ -110,23 +114,24 @@ export default function ConnectWallet() { onClick={onCopy} /> - - - } - px={2} - boxSize={5} - onClick={() => handleConnectWallet(true)} - /> - + {isChangeAccountFeatureSupported(embeddedApp) && ( + + } + px={2} + boxSize={5} + onClick={() => handleConnectWallet(true)} + /> + + )} ( - "isEmbed", + const [embeddedApp, setEmbeddedApp] = useLocalStorage( + "acre.embeddedApp", undefined, ) const enableIsEmbed = useCallback(() => { - if (router.getURLParam(SEARCH_PARAMS_NAMES.embed)) { - setIsEmbed(true) + const embeddedAppParam = referralProgram.getEmbeddedApp() + if (embeddedAppParam && referralProgram.isEmbedApp(embeddedAppParam)) { + setEmbeddedApp(embeddedAppParam) } - }, [setIsEmbed]) + }, [setEmbeddedApp]) const disableIsEmbed = useCallback(() => { - setIsEmbed(false) - }, [setIsEmbed]) + setEmbeddedApp(undefined) + }, [setEmbeddedApp]) return { enableIsEmbed, disableIsEmbed, - isEmbed, + isEmbed: !!embeddedApp, + embeddedApp, } } diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index 719cc760e..5f5b83823 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -1,9 +1,7 @@ import { env } from "#/constants" import { useCallback, useMemo } from "react" -import { MODAL_TYPES } from "#/types" import { referralProgram } from "#/utils" import useLocalStorage from "./useLocalStorage" -import { useModal } from "./useModal" import useIsEmbed from "./useIsEmbed" type UseReferralReturn = { @@ -14,39 +12,19 @@ type UseReferralReturn = { export default function useReferral(): UseReferralReturn { const [referral, setReferral] = useLocalStorage( - "referral", + "acre.referral", env.REFERRAL, ) - const { openModal } = useModal() - const { isEmbed } = useIsEmbed() + const { isEmbed, embeddedApp } = useIsEmbed() const detectReferral = useCallback(() => { - const param = referralProgram.getReferralFromURL() - - if (isEmbed) { - // TODO: Set correct referral for embedded dApp - setReferral(0) - return - } - - if (param === null) { - setReferral(env.REFERRAL) + if (isEmbed && embeddedApp) { + setReferral(referralProgram.getReferralByEmbeddedApp(embeddedApp)) return } - const convertedReferral = Number(param) - - if (referralProgram.isValidReferral(convertedReferral)) { - setReferral(convertedReferral) - } else { - console.error("Incorrect referral") - setReferral(null) - openModal(MODAL_TYPES.UNEXPECTED_ERROR, { - withCloseButton: false, - closeOnEsc: false, - }) - } - }, [isEmbed, openModal, setReferral]) + setReferral(env.REFERRAL) + }, [isEmbed, embeddedApp, setReferral]) const resetReferral = useCallback(() => { setReferral(env.REFERRAL) diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index 126648157..e5c3bab8e 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -1,7 +1,14 @@ import { SEARCH_PARAMS_NAMES } from "#/router/path" import router from "./router" +const embeddedApps = ["ledger-live"] as const +export type EmbedApp = (typeof embeddedApps)[number] + const MAX_UINT16 = 65535 +const EMBEDDED_APP_TO_REFERRAL: Record = { + // TODO: set correct referral code + "ledger-live": 123, +} const isValidReferral = (value: number) => { const isInteger = Number.isInteger(value) @@ -11,7 +18,21 @@ const isValidReferral = (value: number) => { const getReferralFromURL = () => router.getURLParam(SEARCH_PARAMS_NAMES.referral) +const getReferralByEmbeddedApp = (embedApp: EmbedApp) => + EMBEDDED_APP_TO_REFERRAL[embedApp] + +const getEmbeddedApp = () => router.getURLParam(SEARCH_PARAMS_NAMES.embed) + +function isEmbedApp(embedApp: unknown): embedApp is EmbedApp { + return ( + typeof embedApp === "string" && + embeddedApps.findIndex((app) => app === embedApp) >= 0 + ) +} export default { isValidReferral, getReferralFromURL, + getEmbeddedApp, + isEmbedApp, + getReferralByEmbeddedApp, } diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 61d77aae5..b46e779d1 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -6,14 +6,13 @@ import { getOrangeKitXverseConnector, getOrangeKitLedgerLiveConnector, } from "@orangekit/react" +import { CreateOrangeKitConnectorFn } from "@orangekit/react/dist/src/wallet/connector" import { env } from "./constants" -import { router } from "./utils" -import { SEARCH_PARAMS_NAMES } from "./router/path" import { getLastUsedBtcAddress } from "./hooks/useLastUsedBtcAddress" +import referralProgram, { EmbedApp } from "./utils/referralProgram" const isTestnet = env.USE_TESTNET const CHAIN_ID = isTestnet ? sepolia.id : mainnet.id -const IsEmbed = router.getURLParam(SEARCH_PARAMS_NAMES.embed) const chains: [Chain, ...Chain[]] = isTestnet ? [sepolia] : [mainnet] const connectorConfig = { @@ -36,19 +35,25 @@ const orangeKitLedgerLiveConnector = getOrangeKitLedgerLiveConnector({ }, }) -const embedConnectors = [orangeKitLedgerLiveConnector()] +const embedConnectorsMap: Record CreateOrangeKitConnectorFn> = { + "ledger-live": orangeKitLedgerLiveConnector, +} + +let createEmbedConnectorFn +const embeddedApp = referralProgram.getEmbeddedApp() +if (referralProgram.isEmbedApp(embeddedApp)) { + createEmbedConnectorFn = embedConnectorsMap[embeddedApp as EmbedApp] +} + const defaultConnectors = [ orangeKitOKXConnector(), orangeKitUnisatConnector(), orangeKitXverseConnector(), ] -const connectors = [ - ...(IsEmbed - ? // TODO: Use correct connector - embedConnectors - : defaultConnectors), -] as unknown as CreateConnectorFn[] +const connectors = (createEmbedConnectorFn !== undefined + ? [createEmbedConnectorFn()] + : defaultConnectors) as unknown as CreateConnectorFn[] const wagmiConfig = createConfig({ chains, From baa90134dee52debd6dac9b1beb794a2dab13d00 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 9 Oct 2024 10:43:27 +0200 Subject: [PATCH 036/179] Set correct referral code for Ledger Live --- dapp/src/utils/referralProgram.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index e5c3bab8e..aaed17f14 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -6,8 +6,7 @@ export type EmbedApp = (typeof embeddedApps)[number] const MAX_UINT16 = 65535 const EMBEDDED_APP_TO_REFERRAL: Record = { - // TODO: set correct referral code - "ledger-live": 123, + "ledger-live": 2083, } const isValidReferral = (value: number) => { From 4cd170875336cb4bac2ef2891d66df5e5a6d1070 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 9 Oct 2024 12:50:11 +0200 Subject: [PATCH 037/179] Update the reconnect flow Update the wagmi config to force an update of the wagmi state stored in the wagmi context. We need to do this to refetch the address and data for new account. --- .../acre-react/contexts/AcreSdkContext.tsx | 1 + dapp/src/hooks/useWallet.ts | 35 ++++++++++++++----- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/dapp/src/acre-react/contexts/AcreSdkContext.tsx b/dapp/src/acre-react/contexts/AcreSdkContext.tsx index dcf8efd00..3cf8e1fce 100644 --- a/dapp/src/acre-react/contexts/AcreSdkContext.tsx +++ b/dapp/src/acre-react/contexts/AcreSdkContext.tsx @@ -37,6 +37,7 @@ export function AcreSdkProvider({ children }: { children: React.ReactNode }) { ) if (bitcoinProvider) { + setIsConnected(false) sdk = await sdk.connect(bitcoinProvider) setIsConnected(true) } else { diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index c137d9375..8d07a5369 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -1,5 +1,11 @@ import { useCallback, useEffect, useMemo, useState } from "react" -import { useAccount, useChainId, useConnect, useDisconnect } from "wagmi" +import { + useAccount, + useChainId, + useConfig, + useConnect, + useDisconnect, +} from "wagmi" import { logPromiseFailure, orangeKit } from "#/utils" import { OnErrorCallback, @@ -34,7 +40,8 @@ type UseWalletReturn = { export function useWallet(): UseWalletReturn { const chainId = useChainId() - const { status: accountStatus } = useAccount() + const config = useConfig() + const { status: accountStatus, address: account } = useAccount() const { connect, status } = useConnect() const { disconnect } = useDisconnect() const connector = useConnector() @@ -64,23 +71,33 @@ export function useWallet(): UseWalletReturn { ) => { try { if (!selectedConnector.connect) return - - await selectedConnector.connect({ chainId, isReconnecting: true }) + const { + accounts: [newAccount], + } = await selectedConnector.connect({ chainId, isReconnecting: true }) const newAddress = await selectedConnector.getBitcoinAddress() if (newAddress === address) return + config.setState((prevState) => ({ + ...prevState, + connections: new Map(prevState.connections).set(prevState.current!, { + // Update accounts to force update of wagmi hooks. + accounts: [newAccount], + connector: orangeKit.typeConversionToConnector(selectedConnector), + chainId, + }), + })) + if (options?.onSuccess && typeof selectedConnector !== "function") { options.onSuccess(selectedConnector) } setAddress(newAddress) resetWalletState() } catch (error) { - console.error("error in reconnect", error) - // @ts-expect-error test - if (options?.onError) options.onError(error) + console.error("Failed to reconnect", error) + if (options?.onError) options.onError(error as Error) } }, - [address, chainId, resetWalletState], + [chainId, config, address, resetWalletState], ) const onConnect = useCallback( @@ -145,7 +162,7 @@ export function useWallet(): UseWalletReturn { } logPromiseFailure(fetchBitcoinAddress()) - }, [connector, setAddressInLocalStorage, provider]) + }, [connector, setAddressInLocalStorage, provider, account]) return useMemo( () => ({ From 74026fced6cc672f8ba7da80a3d799b9baa433d1 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 9 Oct 2024 14:33:14 +0200 Subject: [PATCH 038/179] Refactor for `Layout` component - move the pagination to level up and remove `page_content_padding_x` -move `MobileModeBanner` to a higher level --- dapp/src/components/Header/index.tsx | 3 +-- dapp/src/components/Layout.tsx | 15 +++++++-------- .../pages/DashboardPage/PageLayout/PageLayout.tsx | 2 -- dapp/src/pages/DashboardPage/index.tsx | 9 ++------- dapp/src/theme/utils/semanticTokens.ts | 1 - 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/dapp/src/components/Header/index.tsx b/dapp/src/components/Header/index.tsx index 265aa0468..c836ed09f 100644 --- a/dapp/src/components/Header/index.tsx +++ b/dapp/src/components/Header/index.tsx @@ -13,10 +13,9 @@ export default function Header() { diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index f5bd71c2a..5b4bfa55e 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -6,22 +6,21 @@ import DocsDrawer from "./DocsDrawer" import Header from "./Header" import ModalRoot from "./ModalRoot" import Sidebar from "./Sidebar" +import MobileModeBanner from "./MobileModeBanner" function Layout() { const isMobileMode = useMobileMode() + if (isMobileMode) return + return ( - +
- {!isMobileMode && ( - <> - - - - - )} + + + ) } diff --git a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx b/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx index 62ff0fdd1..f0441e2a5 100644 --- a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx +++ b/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx @@ -9,8 +9,6 @@ function PageLayout(props: GridProps) { w="full" mx="auto" maxW="page_content_max_width" - px="page_content_padding_x" - py={9} gap={8} alignItems="start" gridTemplateColumns={{ diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index cd083af23..4d597b5fe 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -1,6 +1,5 @@ import React from "react" -import { useMobileMode, useTriggerConnectWalletModal } from "#/hooks" -import MobileModeBanner from "#/components/MobileModeBanner" +import { useTriggerConnectWalletModal } from "#/hooks" import { featureFlags } from "#/constants" import DashboardCard from "./DashboardCard" import { PageLayout, PageLayoutColumn } from "./PageLayout" @@ -11,13 +10,9 @@ import BeehiveCard from "./BeehiveCard" import UsefulLinks from "./UsefulLinks" export default function DashboardPage() { - const isMobileMode = useMobileMode() - useTriggerConnectWalletModal() - return isMobileMode ? ( - - ) : ( + return ( diff --git a/dapp/src/theme/utils/semanticTokens.ts b/dapp/src/theme/utils/semanticTokens.ts index cbe173fe7..e2844e198 100644 --- a/dapp/src/theme/utils/semanticTokens.ts +++ b/dapp/src/theme/utils/semanticTokens.ts @@ -3,7 +3,6 @@ export const semanticTokens = { header_height: 24, modal_shift: "9.75rem", // 156px dashboard_card_padding: 5, - page_content_padding_x: 10, }, sizes: { sidebar_width: 80, From c64750ae654b84aa91817e641f09b447264e2426 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Wed, 9 Oct 2024 14:59:02 +0200 Subject: [PATCH 039/179] Set page content max width in Layout component --- dapp/src/components/Header/index.tsx | 2 -- dapp/src/components/Layout.tsx | 4 +++- dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx | 2 -- dapp/src/theme/utils/semanticTokens.ts | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dapp/src/components/Header/index.tsx b/dapp/src/components/Header/index.tsx index c836ed09f..a6c3d1524 100644 --- a/dapp/src/components/Header/index.tsx +++ b/dapp/src/components/Header/index.tsx @@ -14,9 +14,7 @@ export default function Header() { as="header" w="full" mb="4.75rem" // 76px - mx="auto" justify="center" - maxW="page_content_max_width" > diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index 5b4bfa55e..c815386b9 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -8,13 +8,15 @@ import ModalRoot from "./ModalRoot" import Sidebar from "./Sidebar" import MobileModeBanner from "./MobileModeBanner" +const PAGE_MAX_WIDTH = "110rem" // 1760px -> content width + x-axis padding + function Layout() { const isMobileMode = useMobileMode() if (isMobileMode) return return ( - +
diff --git a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx b/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx index f0441e2a5..aa5bf7920 100644 --- a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx +++ b/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx @@ -7,8 +7,6 @@ function PageLayout(props: GridProps) { return ( content width + x-axis padding }, } From ee381eff9ae9845ca67de29e09998b71119a7bea Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 10 Oct 2024 09:17:44 +0200 Subject: [PATCH 040/179] Add responsiveness for transaction table row --- .../TransactionHistory/EstimatedDuration.tsx | 11 +-- .../TransactionHistory/TransactionTable.tsx | 84 +++++++++---------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/dapp/src/pages/DashboardPage/TransactionHistory/EstimatedDuration.tsx b/dapp/src/pages/DashboardPage/TransactionHistory/EstimatedDuration.tsx index e13eaedf1..bd5b880f2 100644 --- a/dapp/src/pages/DashboardPage/TransactionHistory/EstimatedDuration.tsx +++ b/dapp/src/pages/DashboardPage/TransactionHistory/EstimatedDuration.tsx @@ -1,5 +1,5 @@ import React from "react" -import { HStack, Box, Tag, TagLabel } from "@chakra-ui/react" +import { Box, Tag, TagLabel, Flex, TagLeftIcon } from "@chakra-ui/react" import Spinner from "#/components/shared/Spinner" import { convertActivityTypeToLabel, @@ -16,12 +16,13 @@ export default function EstimatedDuration({ if (isActivityCompleted(activity)) return null return ( - + - @@ -35,6 +36,6 @@ export default function EstimatedDuration({ - + ) } diff --git a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx index 7c2547ea9..f4c8dae84 100644 --- a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx +++ b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx @@ -34,12 +34,8 @@ export default function TransactionTable() { colorScheme="gold" > - - - {displayBlockTimestamp(getActivityTimestamp(activity))} - - - + + {activity.type} - - - - - - {activity.txHash ? ( - - - Details - - - - ) : ( - - )} - + + + + + {displayBlockTimestamp(getActivityTimestamp(activity))} + + {activity.txHash ? ( + + + Details + + + + ) : ( + + )} + + From 91771959e6ed7a106daeb5e7c2fb03e33e61c32f Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 10 Oct 2024 10:01:14 +0200 Subject: [PATCH 041/179] Add a basic grid for the dashboard view for the embedded dApp --- dapp/src/pages/DashboardPage/UsefulLinks.tsx | 6 ++-- dapp/src/pages/DashboardPage/index.tsx | 34 +++++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dapp/src/pages/DashboardPage/UsefulLinks.tsx b/dapp/src/pages/DashboardPage/UsefulLinks.tsx index a35b061ad..6202c411f 100644 --- a/dapp/src/pages/DashboardPage/UsefulLinks.tsx +++ b/dapp/src/pages/DashboardPage/UsefulLinks.tsx @@ -1,11 +1,11 @@ import React from "react" -import { VStack } from "@chakra-ui/react" +import { StackProps, VStack } from "@chakra-ui/react" import ButtonLink from "#/components/shared/ButtonLink" import { EXTERNAL_HREF } from "#/constants" -export default function UsefulLinks() { +export default function UsefulLinks(props: StackProps) { return ( - + {[ { label: "Documentation", href: EXTERNAL_HREF.DOCS }, { label: "Blog", href: EXTERNAL_HREF.BLOG }, diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index 4d597b5fe..3c04d1aa0 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -1,6 +1,7 @@ import React from "react" -import { useTriggerConnectWalletModal } from "#/hooks" +import { useIsEmbed, useTriggerConnectWalletModal } from "#/hooks" import { featureFlags } from "#/constants" +import { Grid } from "@chakra-ui/react" import DashboardCard from "./DashboardCard" import { PageLayout, PageLayoutColumn } from "./PageLayout" // import GrantedSeasonPassCard from "./GrantedSeasonPassCard" @@ -9,9 +10,40 @@ import { CurrentSeasonCard } from "./CurrentSeasonCard" import BeehiveCard from "./BeehiveCard" import UsefulLinks from "./UsefulLinks" +const TEMPLATE_AREAS_LEDGER_LIVE = `${featureFlags.TVL_ENABLED ? '"dashboard current-season"' : ""} + ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? '"dashboard beehive"' : ""} + "dashboard acre-points" + "dashboard useful-links"` + export default function DashboardPage() { + const { isEmbed } = useIsEmbed() + useTriggerConnectWalletModal() + if (isEmbed) + return ( + + + {/* TODO: Uncomment in post-launch phases + add `gridArea` and update `templateAreas` */} + {/* */} + {featureFlags.TVL_ENABLED && ( + + )} + {featureFlags.BEEHIVE_COMPONENT_ENABLED && ( + + )} + + + + ) + return ( From 16a4d8e79982738baa56cd37b7b6f6503ef1547d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 10 Oct 2024 10:56:30 +0200 Subject: [PATCH 042/179] Update design for position details card --- dapp/src/pages/DashboardPage/PositionDetails.tsx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/dapp/src/pages/DashboardPage/PositionDetails.tsx b/dapp/src/pages/DashboardPage/PositionDetails.tsx index a0e8305da..8e8dc37e1 100644 --- a/dapp/src/pages/DashboardPage/PositionDetails.tsx +++ b/dapp/src/pages/DashboardPage/PositionDetails.tsx @@ -35,10 +35,10 @@ export default function PositionDetails() { const openWithdrawModal = useTransactionModal(ACTION_FLOW_TYPES.UNSTAKE) return ( - - + + - My position + Acre balance {/* TODO: Uncomment when position will be implemented */} {/* {positionPercentage && ( - + - + From a373330abdbc59c7af33e200099c44c30da92176 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 11 Oct 2024 12:58:17 +0200 Subject: [PATCH 046/179] Disable sidebar for embedded dApp --- dapp/src/contexts/SidebarContext.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dapp/src/contexts/SidebarContext.tsx b/dapp/src/contexts/SidebarContext.tsx index 643563d8e..125b871a1 100644 --- a/dapp/src/contexts/SidebarContext.tsx +++ b/dapp/src/contexts/SidebarContext.tsx @@ -1,3 +1,4 @@ +import useIsEmbed from "#/hooks/useIsEmbed" import React, { createContext, useCallback, useMemo, useState } from "react" type SidebarContextValue = { @@ -17,11 +18,15 @@ export function SidebarContextProvider({ }: { children: React.ReactNode }): React.ReactElement { + const { isEmbed } = useIsEmbed() + const [isOpen, setIsOpen] = useState(false) const onOpen = useCallback(() => { + if (isEmbed) return + setIsOpen(true) - }, []) + }, [isEmbed]) const onClose = useCallback(() => { setIsOpen(false) From cf93e141208ea7afb883cd066f8e6c0daf537d7f Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 14 Oct 2024 17:01:41 +0200 Subject: [PATCH 047/179] Simplify the referral program code Remove unnecessary hooks and simplify the logic. We do not need to store the referral code in the local storage - we get the referral code based on the `embed` param from the URL which is saved in the local storage. --- dapp/src/contexts/StakeFlowContext.tsx | 2 +- dapp/src/hooks/index.ts | 1 - dapp/src/hooks/useDetectReferral.ts | 10 ------- dapp/src/hooks/useInitApp.ts | 2 -- dapp/src/hooks/useIsEmbed.ts | 7 +++-- dapp/src/hooks/useReferral.ts | 40 ++++---------------------- dapp/src/utils/referralProgram.ts | 20 +++++-------- dapp/src/wagmiConfig.ts | 11 ++----- 8 files changed, 20 insertions(+), 73 deletions(-) delete mode 100644 dapp/src/hooks/useDetectReferral.ts diff --git a/dapp/src/contexts/StakeFlowContext.tsx b/dapp/src/contexts/StakeFlowContext.tsx index f50c5b900..54b559d99 100644 --- a/dapp/src/contexts/StakeFlowContext.tsx +++ b/dapp/src/contexts/StakeFlowContext.tsx @@ -25,7 +25,7 @@ export function StakeFlowProvider({ children }: { children: React.ReactNode }) { stake, } = useStakeFlow() const bitcoinRecoveryAddress = useBitcoinRecoveryAddress() - const { referral } = useReferral() + const referral = useReferral() const initStake = useCallback(async () => { if (!acre) throw new Error("Acre SDK not defined") diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index bfd3f635d..85eca4561 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -29,7 +29,6 @@ export { default as useMobileMode } from "./useMobileMode" export { default as useBitcoinRecoveryAddress } from "./useBitcoinRecoveryAddress" export { default as useIsFetchedWalletData } from "./useIsFetchedWalletData" export { default as useLocalStorage } from "./useLocalStorage" -export { default as useDetectReferral } from "./useDetectReferral" export { default as useReferral } from "./useReferral" export { default as useMats } from "./useMats" export { default as useIsEmbed } from "./useIsEmbed" diff --git a/dapp/src/hooks/useDetectReferral.ts b/dapp/src/hooks/useDetectReferral.ts deleted file mode 100644 index e32a457b6..000000000 --- a/dapp/src/hooks/useDetectReferral.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useEffect } from "react" -import useReferral from "./useReferral" - -export default function useDetectReferral() { - const { detectReferral } = useReferral() - - useEffect(() => { - detectReferral() - }, [detectReferral]) -} diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index 109749a17..522cb57ee 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -4,7 +4,6 @@ import { useDisconnectOKX } from "./orangeKit/useDisconnectOKX" import { useInitDataFromSdk, useInitializeAcreSdk } from "./sdk" import { useSentry } from "./sentry" import useDetectEmbed from "./useDetectEmbed" -import useDetectReferral from "./useDetectReferral" import { useDisconnectWallet } from "./useDisconnectWallet" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" @@ -13,7 +12,6 @@ export function useInitApp() { // useDetectThemeMode() useSentry() useDetectEmbed() - useDetectReferral() useInitializeAcreSdk() useInitDataFromSdk() useFetchBTCPriceUSD() diff --git a/dapp/src/hooks/useIsEmbed.ts b/dapp/src/hooks/useIsEmbed.ts index 462be2739..c78e31f65 100644 --- a/dapp/src/hooks/useIsEmbed.ts +++ b/dapp/src/hooks/useIsEmbed.ts @@ -9,9 +9,10 @@ export default function useIsEmbed() { ) const enableIsEmbed = useCallback(() => { - const embeddedAppParam = referralProgram.getEmbeddedApp() - if (embeddedAppParam && referralProgram.isEmbedApp(embeddedAppParam)) { - setEmbeddedApp(embeddedAppParam) + const app = referralProgram.getEmbeddedApp() + + if (app) { + setEmbeddedApp(app) } }, [setEmbeddedApp]) diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index 5f5b83823..570b51afe 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -1,41 +1,11 @@ import { env } from "#/constants" -import { useCallback, useMemo } from "react" import { referralProgram } from "#/utils" -import useLocalStorage from "./useLocalStorage" import useIsEmbed from "./useIsEmbed" -type UseReferralReturn = { - referral: number | null - detectReferral: () => void - resetReferral: () => void -} - -export default function useReferral(): UseReferralReturn { - const [referral, setReferral] = useLocalStorage( - "acre.referral", - env.REFERRAL, - ) - const { isEmbed, embeddedApp } = useIsEmbed() - - const detectReferral = useCallback(() => { - if (isEmbed && embeddedApp) { - setReferral(referralProgram.getReferralByEmbeddedApp(embeddedApp)) - return - } - - setReferral(env.REFERRAL) - }, [isEmbed, embeddedApp, setReferral]) - - const resetReferral = useCallback(() => { - setReferral(env.REFERRAL) - }, [setReferral]) +export default function useReferral() { + const { embeddedApp } = useIsEmbed() - return useMemo( - () => ({ - detectReferral, - resetReferral, - referral, - }), - [detectReferral, resetReferral, referral], - ) + return embeddedApp + ? referralProgram.getReferralByEmbeddedApp(embeddedApp) + : env.REFERRAL } diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index aaed17f14..09bdf8a29 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -4,33 +4,27 @@ import router from "./router" const embeddedApps = ["ledger-live"] as const export type EmbedApp = (typeof embeddedApps)[number] -const MAX_UINT16 = 65535 const EMBEDDED_APP_TO_REFERRAL: Record = { "ledger-live": 2083, } -const isValidReferral = (value: number) => { - const isInteger = Number.isInteger(value) - return isInteger && value >= 0 && value <= MAX_UINT16 -} - -const getReferralFromURL = () => - router.getURLParam(SEARCH_PARAMS_NAMES.referral) - const getReferralByEmbeddedApp = (embedApp: EmbedApp) => EMBEDDED_APP_TO_REFERRAL[embedApp] -const getEmbeddedApp = () => router.getURLParam(SEARCH_PARAMS_NAMES.embed) - function isEmbedApp(embedApp: unknown): embedApp is EmbedApp { return ( typeof embedApp === "string" && embeddedApps.findIndex((app) => app === embedApp) >= 0 ) } + +const getEmbeddedApp = () => { + const app = router.getURLParam(SEARCH_PARAMS_NAMES.embed) + + return isEmbedApp(app) ? app : undefined +} + export default { - isValidReferral, - getReferralFromURL, getEmbeddedApp, isEmbedApp, getReferralByEmbeddedApp, diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index b46e779d1..8d12a8b7b 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -39,20 +39,15 @@ const embedConnectorsMap: Record CreateOrangeKitConnectorFn> = { "ledger-live": orangeKitLedgerLiveConnector, } -let createEmbedConnectorFn -const embeddedApp = referralProgram.getEmbeddedApp() -if (referralProgram.isEmbedApp(embeddedApp)) { - createEmbedConnectorFn = embedConnectorsMap[embeddedApp as EmbedApp] -} - const defaultConnectors = [ orangeKitOKXConnector(), orangeKitUnisatConnector(), orangeKitXverseConnector(), ] -const connectors = (createEmbedConnectorFn !== undefined - ? [createEmbedConnectorFn()] +const embeddedApp = referralProgram.getEmbeddedApp() +const connectors = (embeddedApp !== undefined + ? [embedConnectorsMap[embeddedApp]()] : defaultConnectors) as unknown as CreateConnectorFn[] const wagmiConfig = createConfig({ From e89bb0fece8bde55e0af52c50e984a174d8f5f64 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 14 Oct 2024 17:16:36 +0200 Subject: [PATCH 048/179] Update the `aria-label` param for change acc btn `Disconnect` -> `Change account`. --- dapp/src/components/Header/ConnectWallet.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/Header/ConnectWallet.tsx b/dapp/src/components/Header/ConnectWallet.tsx index 5fc923042..2cec61606 100644 --- a/dapp/src/components/Header/ConnectWallet.tsx +++ b/dapp/src/components/Header/ConnectWallet.tsx @@ -120,7 +120,7 @@ export default function ConnectWallet() { > } px={2} boxSize={5} From 85c21522553f8cc4c00c8857d53f870c0049684d Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 14 Oct 2024 17:25:48 +0200 Subject: [PATCH 049/179] Fix reconnect function Do not reset the wallet state and already fetched data if the user selects the same account. --- dapp/src/hooks/useWallet.ts | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index 8d07a5369..8e203f686 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -71,33 +71,40 @@ export function useWallet(): UseWalletReturn { ) => { try { if (!selectedConnector.connect) return + const prevAddress = await selectedConnector.getBitcoinAddress() const { accounts: [newAccount], } = await selectedConnector.connect({ chainId, isReconnecting: true }) const newAddress = await selectedConnector.getBitcoinAddress() - if (newAddress === address) return - config.setState((prevState) => ({ - ...prevState, - connections: new Map(prevState.connections).set(prevState.current!, { - // Update accounts to force update of wagmi hooks. - accounts: [newAccount], - connector: orangeKit.typeConversionToConnector(selectedConnector), - chainId, - }), - })) + if (newAddress !== prevAddress) { + config.setState((prevState) => ({ + ...prevState, + connections: new Map(prevState.connections).set( + prevState.current!, + { + // Update accounts to force update of wagmi hooks. + accounts: [newAccount], + connector: + orangeKit.typeConversionToConnector(selectedConnector), + chainId, + }, + ), + })) + + setAddress(newAddress) + resetWalletState() + } if (options?.onSuccess && typeof selectedConnector !== "function") { options.onSuccess(selectedConnector) } - setAddress(newAddress) - resetWalletState() } catch (error) { console.error("Failed to reconnect", error) if (options?.onError) options.onError(error as Error) } }, - [chainId, config, address, resetWalletState], + [chainId, config, resetWalletState], ) const onConnect = useCallback( From a2b8d73ca0741a9dd89460dd0ee6d660735608f1 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 15 Oct 2024 14:47:27 +0200 Subject: [PATCH 050/179] Keep the same approach of layout for dApp --- .../DashboardPage/PageLayout/PageLayout.tsx | 25 ------- .../PageLayout/PageLayoutColumn.tsx | 29 -------- .../pages/DashboardPage/PageLayout/index.ts | 2 - dapp/src/pages/DashboardPage/index.tsx | 73 ++++++------------- 4 files changed, 22 insertions(+), 107 deletions(-) delete mode 100644 dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx delete mode 100644 dapp/src/pages/DashboardPage/PageLayout/PageLayoutColumn.tsx delete mode 100644 dapp/src/pages/DashboardPage/PageLayout/index.ts diff --git a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx b/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx deleted file mode 100644 index aa5bf7920..000000000 --- a/dapp/src/pages/DashboardPage/PageLayout/PageLayout.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react" -import { Grid, GridProps } from "@chakra-ui/react" - -function PageLayout(props: GridProps) { - const { children, ...restProps } = props - - return ( - - {children} - - ) -} - -export default PageLayout diff --git a/dapp/src/pages/DashboardPage/PageLayout/PageLayoutColumn.tsx b/dapp/src/pages/DashboardPage/PageLayout/PageLayoutColumn.tsx deleted file mode 100644 index 6e06c7e8f..000000000 --- a/dapp/src/pages/DashboardPage/PageLayout/PageLayoutColumn.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react" -import { StackProps, VStack } from "@chakra-ui/react" - -type PageLayoutColumnProps = StackProps & { - isMain?: boolean -} - -function PageLayoutColumn(props: PageLayoutColumnProps) { - const { isMain = false, ...restProps } = props - - return ( - - ) -} - -export default PageLayoutColumn diff --git a/dapp/src/pages/DashboardPage/PageLayout/index.ts b/dapp/src/pages/DashboardPage/PageLayout/index.ts deleted file mode 100644 index 8197d5e88..000000000 --- a/dapp/src/pages/DashboardPage/PageLayout/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as PageLayout } from "./PageLayout" -export { default as PageLayoutColumn } from "./PageLayoutColumn" diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index 6f30ff62e..fabe4888d 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -1,9 +1,8 @@ import React from "react" -import { useIsEmbed, useTriggerConnectWalletModal } from "#/hooks" +import { useTriggerConnectWalletModal } from "#/hooks" import { featureFlags } from "#/constants" import { Grid } from "@chakra-ui/react" import DashboardCard from "./DashboardCard" -import { PageLayout, PageLayoutColumn } from "./PageLayout" // import GrantedSeasonPassCard from "./GrantedSeasonPassCard" import AcrePointsCard from "./AcrePointsCard" import { CurrentSeasonCard } from "./CurrentSeasonCard" @@ -16,57 +15,29 @@ const TEMPLATE_AREAS_LEDGER_LIVE = `${featureFlags.TVL_ENABLED ? '"dashboard cur "dashboard useful-links"` export default function DashboardPage() { - const { isEmbed } = useIsEmbed() - useTriggerConnectWalletModal() - if (isEmbed) - return ( - - - {/* TODO: Uncomment in post-launch phases + add `gridArea` and update `templateAreas` */} - {/* */} - {featureFlags.TVL_ENABLED && ( - - )} - {featureFlags.BEEHIVE_COMPONENT_ENABLED && ( - - )} - - - - ) - return ( - - - - - - - {featureFlags.TVL_ENABLED && ( - - )} - {/* TODO: Uncomment in post-launch phases */} - {/* */} - {featureFlags.BEEHIVE_COMPONENT_ENABLED && } - - - - - - - + + + {/* TODO: Uncomment in post-launch phases + add `gridArea` and update `templateAreas` */} + {/* */} + {featureFlags.TVL_ENABLED && ( + + )} + {featureFlags.BEEHIVE_COMPONENT_ENABLED && ( + + )} + + + ) } From 71c79de47d84f1134de8704ecbc72c0ee559621f Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 16 Oct 2024 13:36:35 +0200 Subject: [PATCH 051/179] Fix the reconnect flow When the user rejected the connection and wanted to select the account again, they were unable to do so. This commit fixes that bug. --- dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index a3ab2f746..15029898c 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -157,7 +157,8 @@ export default function ConnectWalletButton({ const handleButtonClick = () => { // Do not trigger action again when wallet connection is in progress if (showStatuses) return - onDisconnect() + + if (!isReconnecting) onDisconnect() resetConnectionError() resetMessageStatus() From 4e9541b94b677e06eab8e71cd8a0ec3edca0ace8 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 16 Oct 2024 16:50:19 +0200 Subject: [PATCH 052/179] Display correct statuses when reconnecting --- .../ConnectWalletButton.tsx | 7 ++- dapp/src/hooks/useWallet.ts | 54 +++++++++---------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index 15029898c..395385051 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -63,6 +63,7 @@ export default function ConnectWalletButton({ onConnect, onDisconnect, status: connectionStatus, + reconnectStatus, } = useWallet() const { signMessageStatus, resetMessageStatus, signMessageAndCreateSession } = useSignMessageAndCreateSession() @@ -249,7 +250,11 @@ export default function ConnectWalletButton({ Requires 2 actions: void onDisconnect: () => void + reconnectStatus: Status } export function useWallet(): UseWalletReturn { @@ -61,15 +63,10 @@ export function useWallet(): UseWalletReturn { [accountStatus], ) - const onReconnect = useCallback( - async ( - selectedConnector: OrangeKitConnector, - options: { - onSuccess: (connector: OrangeKitConnector) => void - onError?: OnErrorCallback - }, - ) => { - try { + const queryClient = useQueryClient() + const { mutate: reconnect, status: reconnectStatus } = useMutation( + { + mutationFn: async (selectedConnector: OrangeKitConnector) => { if (!selectedConnector.connect) return const prevAddress = await selectedConnector.getBitcoinAddress() const { @@ -80,6 +77,7 @@ export function useWallet(): UseWalletReturn { if (newAddress !== prevAddress) { config.setState((prevState) => ({ ...prevState, + status: "connected", connections: new Map(prevState.connections).set( prevState.current!, { @@ -95,16 +93,10 @@ export function useWallet(): UseWalletReturn { setAddress(newAddress) resetWalletState() } - - if (options?.onSuccess && typeof selectedConnector !== "function") { - options.onSuccess(selectedConnector) - } - } catch (error) { - console.error("Failed to reconnect", error) - if (options?.onError) options.onError(error as Error) - } + }, + mutationKey: ["reconnect"], }, - [chainId, config, resetWalletState], + queryClient, ) const onConnect = useCallback( @@ -117,14 +109,11 @@ export function useWallet(): UseWalletReturn { }, ) => { if (options?.isReconnecting) { - logPromiseFailure( - onReconnect(selectedConnector, { - onSuccess: () => { - if (options?.onSuccess) options.onSuccess(selectedConnector) - }, - onError: options.onError, - }), - ) + reconnect(selectedConnector, { + onSuccess: (_, connectedConnector) => + options?.onSuccess?.(connectedConnector), + onError: options.onError, + }) return } @@ -147,7 +136,7 @@ export function useWallet(): UseWalletReturn { }, ) }, - [connect, chainId, onReconnect], + [connect, chainId, reconnect], ) const onDisconnect = useCallback(() => { @@ -179,7 +168,16 @@ export function useWallet(): UseWalletReturn { status, onConnect, onDisconnect, + reconnectStatus, }), - [address, balance, isConnected, onConnect, onDisconnect, status], + [ + address, + balance, + isConnected, + onConnect, + onDisconnect, + status, + reconnectStatus, + ], ) } From eb73390d4dfc82b280b111736618e2db4f187ffe Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 16 Oct 2024 17:06:13 +0200 Subject: [PATCH 053/179] Revert "Simplify the referral program code" This reverts commit cf93e141208ea7afb883cd066f8e6c0daf537d7f. We need these changes to support the referral program in standalone dapp correctly. --- dapp/src/contexts/StakeFlowContext.tsx | 2 +- dapp/src/hooks/index.ts | 1 + dapp/src/hooks/useDetectReferral.ts | 10 +++++++ dapp/src/hooks/useInitApp.ts | 2 ++ dapp/src/hooks/useIsEmbed.ts | 7 ++--- dapp/src/hooks/useReferral.ts | 40 ++++++++++++++++++++++---- dapp/src/utils/referralProgram.ts | 20 ++++++++----- dapp/src/wagmiConfig.ts | 11 +++++-- 8 files changed, 73 insertions(+), 20 deletions(-) create mode 100644 dapp/src/hooks/useDetectReferral.ts diff --git a/dapp/src/contexts/StakeFlowContext.tsx b/dapp/src/contexts/StakeFlowContext.tsx index 54b559d99..f50c5b900 100644 --- a/dapp/src/contexts/StakeFlowContext.tsx +++ b/dapp/src/contexts/StakeFlowContext.tsx @@ -25,7 +25,7 @@ export function StakeFlowProvider({ children }: { children: React.ReactNode }) { stake, } = useStakeFlow() const bitcoinRecoveryAddress = useBitcoinRecoveryAddress() - const referral = useReferral() + const { referral } = useReferral() const initStake = useCallback(async () => { if (!acre) throw new Error("Acre SDK not defined") diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 85eca4561..bfd3f635d 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -29,6 +29,7 @@ export { default as useMobileMode } from "./useMobileMode" export { default as useBitcoinRecoveryAddress } from "./useBitcoinRecoveryAddress" export { default as useIsFetchedWalletData } from "./useIsFetchedWalletData" export { default as useLocalStorage } from "./useLocalStorage" +export { default as useDetectReferral } from "./useDetectReferral" export { default as useReferral } from "./useReferral" export { default as useMats } from "./useMats" export { default as useIsEmbed } from "./useIsEmbed" diff --git a/dapp/src/hooks/useDetectReferral.ts b/dapp/src/hooks/useDetectReferral.ts new file mode 100644 index 000000000..e32a457b6 --- /dev/null +++ b/dapp/src/hooks/useDetectReferral.ts @@ -0,0 +1,10 @@ +import { useEffect } from "react" +import useReferral from "./useReferral" + +export default function useDetectReferral() { + const { detectReferral } = useReferral() + + useEffect(() => { + detectReferral() + }, [detectReferral]) +} diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index 522cb57ee..109749a17 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -4,6 +4,7 @@ import { useDisconnectOKX } from "./orangeKit/useDisconnectOKX" import { useInitDataFromSdk, useInitializeAcreSdk } from "./sdk" import { useSentry } from "./sentry" import useDetectEmbed from "./useDetectEmbed" +import useDetectReferral from "./useDetectReferral" import { useDisconnectWallet } from "./useDisconnectWallet" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" @@ -12,6 +13,7 @@ export function useInitApp() { // useDetectThemeMode() useSentry() useDetectEmbed() + useDetectReferral() useInitializeAcreSdk() useInitDataFromSdk() useFetchBTCPriceUSD() diff --git a/dapp/src/hooks/useIsEmbed.ts b/dapp/src/hooks/useIsEmbed.ts index c78e31f65..462be2739 100644 --- a/dapp/src/hooks/useIsEmbed.ts +++ b/dapp/src/hooks/useIsEmbed.ts @@ -9,10 +9,9 @@ export default function useIsEmbed() { ) const enableIsEmbed = useCallback(() => { - const app = referralProgram.getEmbeddedApp() - - if (app) { - setEmbeddedApp(app) + const embeddedAppParam = referralProgram.getEmbeddedApp() + if (embeddedAppParam && referralProgram.isEmbedApp(embeddedAppParam)) { + setEmbeddedApp(embeddedAppParam) } }, [setEmbeddedApp]) diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index 570b51afe..5f5b83823 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -1,11 +1,41 @@ import { env } from "#/constants" +import { useCallback, useMemo } from "react" import { referralProgram } from "#/utils" +import useLocalStorage from "./useLocalStorage" import useIsEmbed from "./useIsEmbed" -export default function useReferral() { - const { embeddedApp } = useIsEmbed() +type UseReferralReturn = { + referral: number | null + detectReferral: () => void + resetReferral: () => void +} + +export default function useReferral(): UseReferralReturn { + const [referral, setReferral] = useLocalStorage( + "acre.referral", + env.REFERRAL, + ) + const { isEmbed, embeddedApp } = useIsEmbed() + + const detectReferral = useCallback(() => { + if (isEmbed && embeddedApp) { + setReferral(referralProgram.getReferralByEmbeddedApp(embeddedApp)) + return + } + + setReferral(env.REFERRAL) + }, [isEmbed, embeddedApp, setReferral]) + + const resetReferral = useCallback(() => { + setReferral(env.REFERRAL) + }, [setReferral]) - return embeddedApp - ? referralProgram.getReferralByEmbeddedApp(embeddedApp) - : env.REFERRAL + return useMemo( + () => ({ + detectReferral, + resetReferral, + referral, + }), + [detectReferral, resetReferral, referral], + ) } diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index 09bdf8a29..aaed17f14 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -4,27 +4,33 @@ import router from "./router" const embeddedApps = ["ledger-live"] as const export type EmbedApp = (typeof embeddedApps)[number] +const MAX_UINT16 = 65535 const EMBEDDED_APP_TO_REFERRAL: Record = { "ledger-live": 2083, } +const isValidReferral = (value: number) => { + const isInteger = Number.isInteger(value) + return isInteger && value >= 0 && value <= MAX_UINT16 +} + +const getReferralFromURL = () => + router.getURLParam(SEARCH_PARAMS_NAMES.referral) + const getReferralByEmbeddedApp = (embedApp: EmbedApp) => EMBEDDED_APP_TO_REFERRAL[embedApp] +const getEmbeddedApp = () => router.getURLParam(SEARCH_PARAMS_NAMES.embed) + function isEmbedApp(embedApp: unknown): embedApp is EmbedApp { return ( typeof embedApp === "string" && embeddedApps.findIndex((app) => app === embedApp) >= 0 ) } - -const getEmbeddedApp = () => { - const app = router.getURLParam(SEARCH_PARAMS_NAMES.embed) - - return isEmbedApp(app) ? app : undefined -} - export default { + isValidReferral, + getReferralFromURL, getEmbeddedApp, isEmbedApp, getReferralByEmbeddedApp, diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 8d12a8b7b..b46e779d1 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -39,15 +39,20 @@ const embedConnectorsMap: Record CreateOrangeKitConnectorFn> = { "ledger-live": orangeKitLedgerLiveConnector, } +let createEmbedConnectorFn +const embeddedApp = referralProgram.getEmbeddedApp() +if (referralProgram.isEmbedApp(embeddedApp)) { + createEmbedConnectorFn = embedConnectorsMap[embeddedApp as EmbedApp] +} + const defaultConnectors = [ orangeKitOKXConnector(), orangeKitUnisatConnector(), orangeKitXverseConnector(), ] -const embeddedApp = referralProgram.getEmbeddedApp() -const connectors = (embeddedApp !== undefined - ? [embedConnectorsMap[embeddedApp]()] +const connectors = (createEmbedConnectorFn !== undefined + ? [createEmbedConnectorFn()] : defaultConnectors) as unknown as CreateConnectorFn[] const wagmiConfig = createConfig({ From cbd881d7d5907dc3341bd3db71aa106f5f778533 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 16 Oct 2024 17:21:34 +0200 Subject: [PATCH 054/179] Set correct referral code for embeded dapp --- dapp/src/hooks/useReferral.ts | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index 5f5b83823..d919850e9 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -1,8 +1,11 @@ import { env } from "#/constants" -import { useCallback, useMemo } from "react" import { referralProgram } from "#/utils" -import useLocalStorage from "./useLocalStorage" + +import { useCallback, useMemo } from "react" +import { MODAL_TYPES } from "#/types" import useIsEmbed from "./useIsEmbed" +import useLocalStorage from "./useLocalStorage" +import { useModal } from "./useModal" type UseReferralReturn = { referral: number | null @@ -15,16 +18,35 @@ export default function useReferral(): UseReferralReturn { "acre.referral", env.REFERRAL, ) + const { openModal } = useModal() const { isEmbed, embeddedApp } = useIsEmbed() const detectReferral = useCallback(() => { + const param = referralProgram.getReferralFromURL() + if (isEmbed && embeddedApp) { setReferral(referralProgram.getReferralByEmbeddedApp(embeddedApp)) return } - setReferral(env.REFERRAL) - }, [isEmbed, embeddedApp, setReferral]) + if (param === null) { + setReferral(env.REFERRAL) + return + } + + const convertedReferral = Number(param) + + if (referralProgram.isValidReferral(convertedReferral)) { + setReferral(convertedReferral) + } else { + console.error("Incorrect referral") + setReferral(null) + openModal(MODAL_TYPES.UNEXPECTED_ERROR, { + withCloseButton: false, + closeOnEsc: false, + }) + } + }, [isEmbed, embeddedApp, openModal, setReferral]) const resetReferral = useCallback(() => { setReferral(env.REFERRAL) From 908e8efcec016c8e74ecf84fef59808ad3f651ae Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 17 Oct 2024 08:28:51 +0200 Subject: [PATCH 055/179] Rename the `TEMPLATE_AREAS_LEDGER_LIVE` to `TEMPLATE_AREA` --- dapp/src/pages/DashboardPage/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index fabe4888d..b76cf40f8 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -9,7 +9,7 @@ import { CurrentSeasonCard } from "./CurrentSeasonCard" import BeehiveCard from "./BeehiveCard" import UsefulLinks from "./UsefulLinks" -const TEMPLATE_AREAS_LEDGER_LIVE = `${featureFlags.TVL_ENABLED ? '"dashboard current-season"' : ""} +const TEMPLATE_AREAS = `${featureFlags.TVL_ENABLED ? '"dashboard current-season"' : ""} ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? '"dashboard beehive"' : ""} "dashboard acre-points" "dashboard useful-links"` @@ -25,7 +25,7 @@ export default function DashboardPage() { lg: "1fr 31%", "2xl": "1fr 36%", }} - templateAreas={TEMPLATE_AREAS_LEDGER_LIVE} + templateAreas={TEMPLATE_AREAS} > {/* TODO: Uncomment in post-launch phases + add `gridArea` and update `templateAreas` */} From 8bfd363e67c19da09b4f6085116eddb7234fd662 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 17 Oct 2024 08:45:14 +0200 Subject: [PATCH 056/179] Set the `maxW` based on the embedded app --- dapp/src/components/Layout.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index 193ff2ddb..be988923a 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -10,7 +10,7 @@ import MobileModeBanner from "./MobileModeBanner" const PAGE_MAX_WIDTH = { standalone: "110rem", // 1760px - embed: "68rem", // 1088px + "ledger-live": "68rem", // 1088px } function Layout() { @@ -19,13 +19,13 @@ function Layout() { if (isMobileMode) return + const maxWidth = isEmbed + ? // TODO: Select correct max-width by `embeddedApp` + PAGE_MAX_WIDTH["ledger-live"] + : PAGE_MAX_WIDTH.standalone + return ( - +
From 13a4cfcaa7e64916dab25dff7177fd9ccf2b4d8d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 17 Oct 2024 09:12:50 +0200 Subject: [PATCH 057/179] Set the correct values for the max width of the layout --- dapp/src/components/Layout.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index be988923a..19e22049f 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -8,9 +8,10 @@ import ModalRoot from "./ModalRoot" import Sidebar from "./Sidebar" import MobileModeBanner from "./MobileModeBanner" +const PADDING = "2.5rem" // 40px const PAGE_MAX_WIDTH = { - standalone: "110rem", // 1760px - "ledger-live": "68rem", // 1088px + standalone: "90rem", // 1440px + "ledger-live": "63rem", // 1008px } function Layout() { @@ -25,7 +26,12 @@ function Layout() { : PAGE_MAX_WIDTH.standalone return ( - +
From b5de9670f0e50f0d130201c62dee0f65916ccd24 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 17 Oct 2024 11:22:53 +0200 Subject: [PATCH 058/179] Changing the max width for a standalone dAPP --- dapp/src/components/Layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index 19e22049f..b1b8c3d52 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -10,7 +10,7 @@ import MobileModeBanner from "./MobileModeBanner" const PADDING = "2.5rem" // 40px const PAGE_MAX_WIDTH = { - standalone: "90rem", // 1440px + standalone: "63rem", // 1008px "ledger-live": "63rem", // 1008px } From f55e76b883dfc2d9f1725451a03cee4424bc4a6d Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 17 Oct 2024 11:47:59 +0200 Subject: [PATCH 059/179] Use equal width for the deposit/withdraw buttons --- dapp/src/pages/DashboardPage/PositionDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/pages/DashboardPage/PositionDetails.tsx b/dapp/src/pages/DashboardPage/PositionDetails.tsx index eafdb0e0a..563bf3822 100644 --- a/dapp/src/pages/DashboardPage/PositionDetails.tsx +++ b/dapp/src/pages/DashboardPage/PositionDetails.tsx @@ -20,7 +20,7 @@ const isWithdrawalFlowEnabled = featureFlags.WITHDRAWALS_ENABLED const buttonStyles: ButtonProps = { size: "lg", flex: 1, - maxW: "12.5rem", // 200px + w: { base: "auto", lg: 40 }, fontWeight: "bold", lineHeight: 6, px: 7, From a506f31795ee231600cbe3fe6f1695211c83b5dd Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Fri, 18 Oct 2024 09:06:02 +0200 Subject: [PATCH 060/179] Set row height to fit content height in CSS Grid --- dapp/src/pages/DashboardPage/index.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index b76cf40f8..7ccb65ec0 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -14,18 +14,21 @@ const TEMPLATE_AREAS = `${featureFlags.TVL_ENABLED ? '"dashboard current-season" "dashboard acre-points" "dashboard useful-links"` +const GRID_TEMPLATE_ROWS = `${featureFlags.TVL_ENABLED ? "auto" : ""} ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? "auto" : ""} auto 1fr` + export default function DashboardPage() { useTriggerConnectWalletModal() return ( {/* TODO: Uncomment in post-launch phases + add `gridArea` and update `templateAreas` */} From aecbe9a41bc388d7d93f144eb14a8b3f1fb32ec8 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 12:30:52 +0200 Subject: [PATCH 061/179] Update `useWallet` hook The `onConnect` function works in normal mode and in reconnecting mode so we don't need to return two independent statuses but just one. --- .../components/ConnectWalletModal/ConnectWalletButton.tsx | 7 +------ dapp/src/hooks/useWallet.ts | 7 ++++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index 395385051..15029898c 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -63,7 +63,6 @@ export default function ConnectWalletButton({ onConnect, onDisconnect, status: connectionStatus, - reconnectStatus, } = useWallet() const { signMessageStatus, resetMessageStatus, signMessageAndCreateSession } = useSignMessageAndCreateSession() @@ -250,11 +249,7 @@ export default function ConnectWalletButton({ Requires 2 actions: void onDisconnect: () => void - reconnectStatus: Status } export function useWallet(): UseWalletReturn { @@ -165,10 +164,12 @@ export function useWallet(): UseWalletReturn { isConnected, address, balance, - status, + status: + status === "idle" && reconnectStatus !== "idle" + ? reconnectStatus + : status, onConnect, onDisconnect, - reconnectStatus, }), [ address, From 504d59083339fca27ad9ced2b9be2520f2fe4aea Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 14:58:51 +0200 Subject: [PATCH 062/179] Bump orangekit package --- dapp/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dapp/package.json b/dapp/package.json index 2b4781f3c..25cb4a07d 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -21,7 +21,7 @@ "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@orangekit/react": "1.0.0-beta.33-dev.5", + "@orangekit/react": "1.0.0-beta.33-dev.6", "@orangekit/sign-in-with-wallet": "1.0.0-beta.6", "@reduxjs/toolkit": "^2.2.0", "@rehooks/local-storage": "^2.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f4ddbd85..86402d437 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^11.11.0 version: 11.11.5(@emotion/react@11.11.4)(@types/react@18.3.3)(react@18.3.1) '@orangekit/react': - specifier: 1.0.0-beta.33-dev.5 - version: 1.0.0-beta.33-dev.5(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) + specifier: 1.0.0-beta.33-dev.6 + version: 1.0.0-beta.33-dev.6(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5) '@orangekit/sign-in-with-wallet': specifier: 1.0.0-beta.6 version: 1.0.0-beta.6(bech32@2.0.0)(ethers@6.13.0) @@ -5794,11 +5794,11 @@ packages: - ethers dev: false - /@orangekit/react@1.0.0-beta.33-dev.5(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): - resolution: {integrity: sha512-Vm2ArRbEpP+REm+aZgdsp648mvYzZ8/rVPjKmrJhvZi6erVGx0lpSM5p8vd42hmF402zUkg4Kwafh5ocpz5P0g==} + /@orangekit/react@1.0.0-beta.33-dev.6(@tanstack/react-query@5.45.0)(@types/react@18.3.3)(react-dom@18.3.1)(react-native@0.74.2)(typescript@5.4.5): + resolution: {integrity: sha512-xmWEd8OIf4xQ1+9CA60bcnh13oyBjVQdqXUeT8ZppT5i79hNmUutkW3y27gQPYDH/mhGCZIhJxj5SYx8PGJcBg==} dependencies: '@ledgerhq/wallet-api-client': 1.5.10 - '@orangekit/sdk': 1.0.0-beta.18-dev.1(typescript@5.4.5) + '@orangekit/sdk': 1.0.0-beta.18-dev.2(typescript@5.4.5) '@rainbow-me/rainbowkit': 2.0.2(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(viem@2.8.16)(wagmi@2.5.12) ethers: 6.12.1 react: 18.3.1 @@ -5854,8 +5854,8 @@ packages: - utf-8-validate dev: false - /@orangekit/sdk@1.0.0-beta.18-dev.1(typescript@5.4.5): - resolution: {integrity: sha512-gREDbURdpEMfpkbSDhYpWEiEvDTdLjXbVM0DnZgRMqzFEvUmGZ5M1DkP1eCCNOiU06tWsAhp2Xg6wxl2qfsFpQ==} + /@orangekit/sdk@1.0.0-beta.18-dev.2(typescript@5.4.5): + resolution: {integrity: sha512-cOzQ13P8qKpV2C0Gv2iS5r9F1ku1Y1creKFVq9ihLp1CSZBkTVBsBjsG1pPPcGaLSBTW3P+kKrxy6Y/Ct9yJTg==} dependencies: '@bitcoin-js/tiny-secp256k1-asmjs': 2.2.3 '@gelatonetwork/relay-sdk': 5.5.6 From 7ee4d06029eef497e20ca1a68d5f1a52a1f47d89 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 15:04:14 +0200 Subject: [PATCH 063/179] Update connection modal for embedded apps We want to display the close button in connect wallet modal to allow users to close the modal, otherwise we end up in loop (user won't sign massage and can't close modal). Display an empty sate dashboard for not logged user. --- dapp/src/hooks/useTriggerConnectWalletModal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/hooks/useTriggerConnectWalletModal.ts b/dapp/src/hooks/useTriggerConnectWalletModal.ts index 644638ef0..d916759db 100644 --- a/dapp/src/hooks/useTriggerConnectWalletModal.ts +++ b/dapp/src/hooks/useTriggerConnectWalletModal.ts @@ -14,7 +14,7 @@ export default function useTriggerConnectWalletModal() { if (!isMounted.current && isEmbed && !isSignedMessage) { isMounted.current = true openModal(MODAL_TYPES.CONNECT_WALLET, { - withCloseButton: false, + withCloseButton: true, closeOnEsc: false, }) } From a757133ef1786bae4f5cbd67a4b34cf75bc4640b Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 15:33:57 +0200 Subject: [PATCH 064/179] Update the Dashboard layout Display the `BeehiveCard` component below the Acre points card. --- dapp/src/pages/DashboardPage/index.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dapp/src/pages/DashboardPage/index.tsx b/dapp/src/pages/DashboardPage/index.tsx index a122a05f8..82e3d5cfa 100644 --- a/dapp/src/pages/DashboardPage/index.tsx +++ b/dapp/src/pages/DashboardPage/index.tsx @@ -10,10 +10,12 @@ import BeehiveCard from "./BeehiveCard" import UsefulLinks from "./UsefulLinks" import AcrePointsTemplateCard from "./AcrePointsTemplateCard" -const TEMPLATE_AREAS = `${featureFlags.TVL_ENABLED ? '"dashboard current-season"' : ""} - ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? '"dashboard beehive"' : ""} - "dashboard acre-points" - "dashboard useful-links"` +const TEMPLATE_AREAS = ` + ${featureFlags.TVL_ENABLED ? '"dashboard current-season"' : ""} + "dashboard acre-points" + ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? '"dashboard beehive"' : ""} + "dashboard useful-links" +` const GRID_TEMPLATE_ROWS = `${featureFlags.TVL_ENABLED ? "auto" : ""} ${featureFlags.BEEHIVE_COMPONENT_ENABLED ? "auto" : ""} auto 1fr` @@ -37,14 +39,14 @@ export default function DashboardPage() { {featureFlags.TVL_ENABLED && ( )} - {featureFlags.BEEHIVE_COMPONENT_ENABLED && ( - - )} {featureFlags.ACRE_POINTS_ENABLED ? ( ) : ( )} + {featureFlags.BEEHIVE_COMPONENT_ENABLED && ( + + )} ) From 60b474dbd1140f97c06211e9e61c9ccd82556a1d Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 16:01:13 +0200 Subject: [PATCH 065/179] Remove unnecessary import --- dapp/src/components/ConnectWalletModal/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/dapp/src/components/ConnectWalletModal/index.tsx b/dapp/src/components/ConnectWalletModal/index.tsx index b255f46cb..a076f11d5 100644 --- a/dapp/src/components/ConnectWalletModal/index.tsx +++ b/dapp/src/components/ConnectWalletModal/index.tsx @@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react" import { ModalBody, ModalHeader, ModalCloseButton } from "@chakra-ui/react" import { useConnectors, useIsEmbed, useWalletConnectionError } from "#/hooks" import { OrangeKitConnector, BaseModalProps, OnSuccessCallback } from "#/types" -// import { wallets } from "#/constants" import withBaseModal from "../ModalRoot/withBaseModal" import ConnectWalletButton from "./ConnectWalletButton" import ConnectWalletErrorAlert from "./ConnectWalletErrorAlert" From 2db829648d4e3fcdca59a5d95386ae13e0039eca Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 21 Oct 2024 16:06:10 +0200 Subject: [PATCH 066/179] Update `useTriggerConnectWalletModal` hook Set `closeOnEsc` to `true` because the user can close the modal using the button. --- dapp/src/hooks/useTriggerConnectWalletModal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/hooks/useTriggerConnectWalletModal.ts b/dapp/src/hooks/useTriggerConnectWalletModal.ts index d916759db..2a869c0cd 100644 --- a/dapp/src/hooks/useTriggerConnectWalletModal.ts +++ b/dapp/src/hooks/useTriggerConnectWalletModal.ts @@ -15,7 +15,7 @@ export default function useTriggerConnectWalletModal() { isMounted.current = true openModal(MODAL_TYPES.CONNECT_WALLET, { withCloseButton: true, - closeOnEsc: false, + closeOnEsc: true, }) } }, [closeModal, isEmbed, isSignedMessage, openModal]) From 6583918fb520ba3c4705cb4fdaa30ee09a266546 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Tue, 22 Oct 2024 14:17:26 +0200 Subject: [PATCH 067/179] Set the `maxW` based on the embedded app --- dapp/src/components/Layout.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dapp/src/components/Layout.tsx b/dapp/src/components/Layout.tsx index b1b8c3d52..99742d22e 100644 --- a/dapp/src/components/Layout.tsx +++ b/dapp/src/components/Layout.tsx @@ -16,13 +16,12 @@ const PAGE_MAX_WIDTH = { function Layout() { const isMobileMode = useMobileMode() - const { isEmbed } = useIsEmbed() + const { embeddedApp } = useIsEmbed() if (isMobileMode) return - const maxWidth = isEmbed - ? // TODO: Select correct max-width by `embeddedApp` - PAGE_MAX_WIDTH["ledger-live"] + const maxWidth = embeddedApp + ? PAGE_MAX_WIDTH[embeddedApp] : PAGE_MAX_WIDTH.standalone return ( From 3a87ceea31893d24da6c45cd540b1fdff8853823 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Tue, 22 Oct 2024 20:01:43 +0200 Subject: [PATCH 068/179] Implement `Footer` component --- dapp/src/components/Footer.tsx | 87 ++++++++++++++++++++++++++++++ dapp/src/components/Layout.tsx | 3 ++ dapp/src/constants/externalHref.ts | 2 + dapp/src/theme/Footer.ts | 57 ++++++++++++++++++++ dapp/src/theme/index.ts | 2 + 5 files changed, 151 insertions(+) create mode 100644 dapp/src/components/Footer.tsx create mode 100644 dapp/src/theme/Footer.ts diff --git a/dapp/src/components/Footer.tsx b/dapp/src/components/Footer.tsx new file mode 100644 index 000000000..d1b3e903a --- /dev/null +++ b/dapp/src/components/Footer.tsx @@ -0,0 +1,87 @@ +import React from "react" +import { + Box, + useMultiStyleConfig, + List, + ListItem, + LinkProps, + Link, + Button, + Icon, +} from "@chakra-ui/react" +import { EXTERNAL_HREF } from "#/constants" +import { AcreSignIcon, ArrowUpRight } from "#/assets/icons" + +const NAVIGATION: Pick[] = [ + { + children: "Acre.fi", + href: EXTERNAL_HREF.WEBSITE, + isExternal: true, + }, + { + children: "Docs", + href: EXTERNAL_HREF.DOCS, + isExternal: true, + }, + { + children: "FAQ", + href: EXTERNAL_HREF.FAQ, + isExternal: true, + }, + { + children: "Blog", + href: EXTERNAL_HREF.BLOG, + isExternal: true, + }, + { + children: "Discord", + href: EXTERNAL_HREF.DISCORD, + isExternal: true, + }, + { + children: "X", + href: EXTERNAL_HREF.X, + isExternal: true, + }, +] + +const DOCUMENTS: Pick[] = [ + { + children: "Privacy Policy", + href: EXTERNAL_HREF.PRIVACY_POLICY, + isExternal: true, + }, + { + children: "Terms of Use", + href: EXTERNAL_HREF.TERMS_OF_USE, + isExternal: true, + }, +] + +export default function Footer() { + const styles = useMultiStyleConfig("Footer") + + return ( + + + + + {[NAVIGATION, DOCUMENTS].map((items) => ( + + {items.map((link) => ( + + From 1f9ca68a5cc0183c023e1f6f4645b9dcacfa3e1e Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 5 Nov 2024 10:47:07 +0100 Subject: [PATCH 162/179] Remove unnused variable --- dapp/src/pages/DashboardPage/PositionDetails.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dapp/src/pages/DashboardPage/PositionDetails.tsx b/dapp/src/pages/DashboardPage/PositionDetails.tsx index c04eac053..563bf3822 100644 --- a/dapp/src/pages/DashboardPage/PositionDetails.tsx +++ b/dapp/src/pages/DashboardPage/PositionDetails.tsx @@ -1,10 +1,6 @@ import React from "react" import { CurrencyBalanceWithConversion } from "#/components/shared/CurrencyBalanceWithConversion" -import { - useAllActivitiesCount, - useBitcoinPosition, - useTransactionModal, -} from "#/hooks" +import { useBitcoinPosition, useTransactionModal } from "#/hooks" import { ACTION_FLOW_TYPES } from "#/types" import { Button, @@ -37,7 +33,6 @@ export default function PositionDetails() { const openDepositModal = useTransactionModal(ACTION_FLOW_TYPES.STAKE) const openWithdrawModal = useTransactionModal(ACTION_FLOW_TYPES.UNSTAKE) - const activitiesCount = useAllActivitiesCount() return ( From 6e293bdd64aadf8f8daec604f7fc3d8c0abb3ae8 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Tue, 5 Nov 2024 14:13:46 +0100 Subject: [PATCH 163/179] Update `AcrePointsCard` tooltip --- dapp/src/pages/DashboardPage/AcrePointsCard.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx index 6d44baad1..3f14aedac 100644 --- a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx +++ b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx @@ -56,14 +56,12 @@ export default function AcrePointsCard(props: CardProps) { Your Acre points balance - + {isWalletConnected && ( + + )} From 8d531a65d98864c227c44d754f75caf21c3f650b Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Tue, 5 Nov 2024 14:16:21 +0100 Subject: [PATCH 164/179] Add TODO comment --- dapp/src/pages/DashboardPage/AcrePointsCard.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx index 3f14aedac..358967934 100644 --- a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx +++ b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx @@ -58,6 +58,7 @@ export default function AcrePointsCard(props: CardProps) { {isWalletConnected && ( From ccf0521a0010177e46adf152a1fa90addeb8018a Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Tue, 5 Nov 2024 15:59:30 +0100 Subject: [PATCH 165/179] Use existing boolean --- dapp/src/pages/DashboardPage/AcrePointsCard.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx index 358967934..8acce1d18 100644 --- a/dapp/src/pages/DashboardPage/AcrePointsCard.tsx +++ b/dapp/src/pages/DashboardPage/AcrePointsCard.tsx @@ -30,9 +30,7 @@ export default function AcrePointsCard(props: CardProps) { updatePointsData, isCalculationInProgress, } = useAcrePoints() - const { address } = useWallet() - - const isWalletConnected = !!address + const { isConnected } = useWallet() const formattedTotalPointsAmount = numberToLocaleString(totalBalance) const formattedClaimablePointsAmount = numberToLocaleString(claimableBalance) @@ -56,7 +54,7 @@ export default function AcrePointsCard(props: CardProps) { Your Acre points balance - {isWalletConnected && ( + {isConnected && ( Date: Tue, 5 Nov 2024 16:48:06 +0100 Subject: [PATCH 166/179] Fix tooltip precision bug --- .../shared/CurrencyBalance/index.tsx | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 213925581..30e12dc78 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from "react" +import React, { useCallback } from "react" import { Box, useMultiStyleConfig, @@ -7,7 +7,6 @@ import { Tooltip, } from "@chakra-ui/react" import { - bigIntToUserAmount, formatTokenAmount, getCurrencyByType, numberToLocaleString, @@ -61,15 +60,17 @@ export function CurrencyBalance({ decimals, desiredDecimals: currencyDesiredDecimals, } = getCurrencyByType(currency) - const desiredDecimals = customDesiredDecimals ?? currencyDesiredDecimals - const balance = useMemo(() => { - const value = amount ?? 0 - if (shouldBeFormatted || typeof value === "bigint") - return formatTokenAmount(value, decimals, desiredDecimals, withRoundUp) + const getBalance = useCallback( + (desiredDecimals: number) => { + const value = amount ?? 0 + if (shouldBeFormatted || typeof value === "bigint") + return formatTokenAmount(value, decimals, desiredDecimals, withRoundUp) - return numberToLocaleString(value, desiredDecimals) - }, [amount, decimals, desiredDecimals, shouldBeFormatted, withRoundUp]) + return numberToLocaleString(value, desiredDecimals) + }, + [amount, decimals, shouldBeFormatted, withRoundUp], + ) const content = ( @@ -79,7 +80,7 @@ export function CurrencyBalance({ {...textProps} {...balanceTextProps} > - {balance} + {getBalance(customDesiredDecimals ?? currencyDesiredDecimals)} {withDots && "..."} @@ -89,7 +90,8 @@ export function CurrencyBalance({ ) if (withTooltip) { - const tooltipLabel = `${bigIntToUserAmount(BigInt(amount ?? 0), decimals, decimals)} ${symbol}` + const fullPrecisionDecimals = (amount ?? 0).toString().length + const tooltipLabel = `${getBalance(fullPrecisionDecimals)} ${symbol}` return ( From 6d158a0948fab1650717b6e839a925eb52fba075 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Tue, 5 Nov 2024 17:06:52 +0100 Subject: [PATCH 167/179] Fix wallet connection bug The bug is that the `window.unisat` and `window.XverseProviders.BitcoinProvider` have `undefined` values. The orangekit package refers to these fields under the hood and the `isInstalled` function always returns `false`. Due to this, users were redirected to download the wallet extension even if they had it installed. To fix this bug here we use the dynamic import to get functions that create connectors. --- dapp/src/DApp.tsx | 64 +++++++++++++++++++++++++++-------------- dapp/src/main.tsx | 6 +++- dapp/src/utils/delay.ts | 7 +++++ dapp/src/utils/index.ts | 1 + dapp/src/wagmiConfig.ts | 43 ++++++++++++++------------- 5 files changed, 79 insertions(+), 42 deletions(-) create mode 100644 dapp/src/utils/delay.ts diff --git a/dapp/src/DApp.tsx b/dapp/src/DApp.tsx index ab80d3d06..aa67ce180 100644 --- a/dapp/src/DApp.tsx +++ b/dapp/src/DApp.tsx @@ -1,8 +1,8 @@ -import React from "react" -import { ChakraProvider } from "@chakra-ui/react" +import React, { useEffect, useState } from "react" +import { Center, Fade, Icon } from "@chakra-ui/react" import { Provider as ReduxProvider } from "react-redux" import { RouterProvider } from "react-router-dom" -import { WagmiProvider } from "wagmi" +import { Config, WagmiProvider } from "wagmi" import { QueryClientProvider } from "@tanstack/react-query" import { ReactQueryDevtools } from "@tanstack/react-query-devtools" import { AcreSdkProvider } from "./acre-react/contexts" @@ -15,9 +15,10 @@ import { import { useInitApp } from "./hooks" import { router } from "./router" import { store } from "./store" -import theme from "./theme" -import wagmiConfig from "./wagmiConfig" +import getWagmiConfig from "./wagmiConfig" import queryClient from "./queryClient" +import { delay, logPromiseFailure } from "./utils" +import { AcreLogo } from "./assets/icons" function DApp() { useInitApp() @@ -32,24 +33,45 @@ function DApp() { } function DAppProviders() { + const [config, setConfig] = useState() + + useEffect(() => { + const setWagmiConfig = async () => { + await delay(500) + const wagmiConfig = await getWagmiConfig() + setConfig(wagmiConfig) + } + + logPromiseFailure(setWagmiConfig()) + }, []) + + if (!config) + return ( + +
+ +
+
+ ) + return ( - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + ) } diff --git a/dapp/src/main.tsx b/dapp/src/main.tsx index f04f38140..0ae5c1617 100644 --- a/dapp/src/main.tsx +++ b/dapp/src/main.tsx @@ -1,8 +1,10 @@ /* eslint-disable no-console */ import React from "react" import ReactDOM from "react-dom/client" +import { ChakraProvider } from "@chakra-ui/react" import DAppProviders from "./DApp" import { env } from "./constants" +import theme from "./theme" const { NETWORK_TYPE, LATEST_COMMIT_HASH } = env @@ -14,6 +16,8 @@ console.log( ReactDOM.createRoot(document.getElementById("root")!).render( - + + + , ) diff --git a/dapp/src/utils/delay.ts b/dapp/src/utils/delay.ts new file mode 100644 index 000000000..99fb9ead7 --- /dev/null +++ b/dapp/src/utils/delay.ts @@ -0,0 +1,7 @@ +function delay(ms: number) { + return new Promise((resolve) => { + setTimeout(resolve, ms) + }) +} + +export default delay diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index dd28bfd8f..a30ac3327 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -16,3 +16,4 @@ export { default as userAgent } from "./userAgent" export { default as referralProgram } from "./referralProgram" export { default as acreApi } from "./acreApi" export { default as router } from "./router" +export { default as delay } from "./delay" diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 29623f0d6..3ff580f7d 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -1,10 +1,5 @@ import { http, createConfig, CreateConnectorFn } from "wagmi" import { Chain, mainnet, sepolia } from "wagmi/chains" -import { - getOrangeKitUnisatConnector, - getOrangeKitOKXConnector, - getOrangeKitXverseConnector, -} from "@orangekit/react" import { env } from "./constants" const isTestnet = env.USE_TESTNET @@ -21,21 +16,29 @@ const transports = chains.reduce( {}, ) -const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) -const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) -const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) +async function getWagmiConfig() { + const { + getOrangeKitUnisatConnector, + getOrangeKitOKXConnector, + getOrangeKitXverseConnector, + } = await import("@orangekit/react") -const connectors = [ - orangeKitOKXConnector(), - orangeKitUnisatConnector(), - orangeKitXverseConnector(), -] as unknown as CreateConnectorFn[] + const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) + const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) + const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) -const wagmiConfig = createConfig({ - chains, - multiInjectedProviderDiscovery: false, - connectors, - transports, -}) + const connectors = [ + orangeKitOKXConnector(), + orangeKitUnisatConnector(), + orangeKitXverseConnector(), + ] as unknown as CreateConnectorFn[] -export default wagmiConfig + return createConfig({ + chains, + multiInjectedProviderDiscovery: false, + connectors, + transports, + }) +} + +export default getWagmiConfig From c047222fce4d9fe7511437b912bcd327cb1083cb Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 11:29:29 +0100 Subject: [PATCH 168/179] Update `zIndex` value for sidebar When the modal is open the buttons on the sidebar don't work. This commit fixes it. --- dapp/src/theme/utils/zIndices.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dapp/src/theme/utils/zIndices.ts b/dapp/src/theme/utils/zIndices.ts index 8ea14ef60..3e9fb1a4b 100644 --- a/dapp/src/theme/utils/zIndices.ts +++ b/dapp/src/theme/utils/zIndices.ts @@ -1,5 +1,5 @@ export const zIndices = { - sidebar: 1400, + sidebar: 1450, drawer: 1470, mobileBanner: 1500, header: 1400, From 8b364a05ff3cb18151b6598f1dadf2de261375c4 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 11:42:04 +0100 Subject: [PATCH 169/179] Update `tryRequest` fn in custom bitcoin provider The Ledger throws an error with `Signature interrupted by user` message when a user closes the transaction/sign message native window. We check if the error thrown by Ledger has this message and throw `UserRejectedRequestError` from `viem` to be consistent with orangekit package. --- .../ActiveStakingStep/DepositBTCModal.tsx | 7 ++----- .../ActiveUnstakingStep/SignMessageModal.tsx | 12 ++---------- dapp/src/utils/index.ts | 1 - dapp/src/utils/ledgerLive.ts | 18 ------------------ .../orangekit/ledger-live/bitcoin-provider.ts | 3 ++- 5 files changed, 6 insertions(+), 35 deletions(-) delete mode 100644 dapp/src/utils/ledgerLive.ts diff --git a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx index 98c563dbe..6a9472487 100644 --- a/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveStakingStep/DepositBTCModal.tsx @@ -9,7 +9,7 @@ import { useStakeFlowContext, useVerifyDepositAddress, } from "#/hooks" -import { eip1193, ledgerLive, logPromiseFailure } from "#/utils" +import { eip1193, logPromiseFailure } from "#/utils" import { PROCESS_STATUSES } from "#/types" import { Highlight, ModalCloseButton } from "@chakra-ui/react" import { TextMd } from "#/components/shared/Typography" @@ -53,10 +53,7 @@ export default function DepositBTCModal() { const onDepositBTCError = useCallback( (error: unknown) => { - if ( - eip1193.didUserRejectRequest(error) || - ledgerLive.didUserRejectRequest(error) - ) { + if (eip1193.didUserRejectRequest(error)) { handlePause() } else { onError(error) diff --git a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx index 4de884847..03f7d84a7 100644 --- a/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx +++ b/dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx @@ -10,12 +10,7 @@ import { } from "#/hooks" import { ACTION_FLOW_TYPES, PROCESS_STATUSES } from "#/types" import { Button, ModalCloseButton } from "@chakra-ui/react" -import { - dateToUnixTimestamp, - eip1193, - ledgerLive, - logPromiseFailure, -} from "#/utils" +import { dateToUnixTimestamp, eip1193, logPromiseFailure } from "#/utils" import { setStatus } from "#/store/action-flow" import { useInitializeWithdraw } from "#/acre-react/hooks" import { queryKeysFactory } from "#/constants" @@ -111,10 +106,7 @@ export default function SignMessageModal() { (error: unknown) => { if (!sessionIdToPromise[sessionId.current].shouldOpenErrorModal) return - if ( - eip1193.didUserRejectRequest(error) || - ledgerLive.didUserRejectRequest(error) - ) { + if (eip1193.didUserRejectRequest(error)) { handlePause() } else { onSignMessageError() diff --git a/dapp/src/utils/index.ts b/dapp/src/utils/index.ts index 8d53b392e..f85066048 100644 --- a/dapp/src/utils/index.ts +++ b/dapp/src/utils/index.ts @@ -16,4 +16,3 @@ export { default as userAgent } from "./userAgent" export { default as referralProgram } from "./referralProgram" export { default as acreApi } from "./acreApi" export { default as router } from "./router" -export { default as ledgerLive } from "./ledgerLive" diff --git a/dapp/src/utils/ledgerLive.ts b/dapp/src/utils/ledgerLive.ts deleted file mode 100644 index 2c1f859bc..000000000 --- a/dapp/src/utils/ledgerLive.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { LedgerLiveError } from "#/types" -import { isObject, isString } from "./type-check" - -function isLedgerLiveError(arg: unknown): arg is LedgerLiveError { - return isObject(arg) && arg.name === "Error" && isString(arg.message) -} -function didUserRejectRequest(error: unknown): boolean { - return !!( - isLedgerLiveError(error) && - error.message && - error.message.includes("Signature interrupted by user") - ) -} - -export default { - isLedgerLiveError, - didUserRejectRequest, -} diff --git a/dapp/src/utils/orangekit/ledger-live/bitcoin-provider.ts b/dapp/src/utils/orangekit/ledger-live/bitcoin-provider.ts index 1f88fa995..742281234 100644 --- a/dapp/src/utils/orangekit/ledger-live/bitcoin-provider.ts +++ b/dapp/src/utils/orangekit/ledger-live/bitcoin-provider.ts @@ -37,7 +37,8 @@ function tryRequest(): TryRequestFn { // the request. if ( err?.message === "UserRefusedOnDevice" || - err?.message === "Canceled by user" + err?.message === "Canceled by user" || + err?.message === "Signature interrupted by user" ) { throw new UserRejectedRequestError(err) } From b7804f2bb7147e763b2ed47aaf77263d77b002a4 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 11:47:53 +0100 Subject: [PATCH 170/179] Rename const value `LEDGER` -> `LEDGER_LIVE`. --- dapp/src/constants/wallets.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dapp/src/constants/wallets.ts b/dapp/src/constants/wallets.ts index 30f7b3264..2149e0645 100644 --- a/dapp/src/constants/wallets.ts +++ b/dapp/src/constants/wallets.ts @@ -31,7 +31,7 @@ const XVERSE: WalletInfo = { }, } -const LEDGER: WalletInfo = { +const LEDGER_LIVE: WalletInfo = { id: "orangekit-ledger-live", downloadUrls: { desktop: "https://www.ledger.com/ledger-live", @@ -42,13 +42,13 @@ const SUPPORTED_WALLET_IDS = [ UNISAT.id, ...(featureFlags.OKX_WALLET_ENABLED ? [OKX.id] : []), ...(featureFlags.XVERSE_WALLET_ENABLED ? [XVERSE.id] : []), - LEDGER.id, + LEDGER_LIVE.id, ] export default { UNISAT, OKX, XVERSE, - LEDGER, + LEDGER_LIVE, SUPPORTED_WALLET_IDS, } From a2599fa2d0c774826b233598dc7cc5deb4b270d1 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 11:50:45 +0100 Subject: [PATCH 171/179] Update Ledger Live manifests Update the url to `bitcoin.acre.fi` and `bitcoin.test.acre.fi`. --- dapp/config/mainnet.json | 2 +- dapp/config/testnet.json | 2 +- dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json | 4 ++-- dapp/manifests/ledger-live/ledger-live-manifest-testnet.json | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dapp/config/mainnet.json b/dapp/config/mainnet.json index 828c70373..0fb50b83e 100644 --- a/dapp/config/mainnet.json +++ b/dapp/config/mainnet.json @@ -1,5 +1,5 @@ { "id": "mainnet", "name": "Acre", - "url": "https://stake.acre.fi/" + "url": "https://bitcoin.acre.fi/" } diff --git a/dapp/config/testnet.json b/dapp/config/testnet.json index ade8cb0e6..080160e91 100644 --- a/dapp/config/testnet.json +++ b/dapp/config/testnet.json @@ -1,5 +1,5 @@ { "id": "testnet", "name": "Acre [testnet]", - "url": "https://stake.test.acre.fi/" + "url": "https://bitcoin.test.acre.fi/" } diff --git a/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json b/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json index 24573e028..b135a159b 100644 --- a/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json +++ b/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json @@ -1,9 +1,9 @@ { "id": "acre-mainnet", "name": "Acre", - "url": "https://stake.acre.fi/?embed=ledger-live", + "url": "https://bitcoin.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", - "icon": "https://stake.acre.fi/acre.svg", + "icon": "https://bitcoin.acre.fi/acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", diff --git a/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json b/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json index f9ab0c798..9e5c4bf86 100644 --- a/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json +++ b/dapp/manifests/ledger-live/ledger-live-manifest-testnet.json @@ -1,9 +1,9 @@ { "id": "acre-testnet", "name": "Acre [testnet]", - "url": "https://stake.test.acre.fi/?embed=ledger-live", + "url": "https://bitcoin.test.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", - "icon": "https://stake.test.acre.fi/acre.svg", + "icon": "https://bitcoin.test.acre.fi/acre.svg", "platforms": "desktop", "apiVersion": "^2.0.0", "manifestVersion": "2", From 9d13616cc074e2d50cce0193c8809f78930b0c3e Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Wed, 6 Nov 2024 13:29:14 +0100 Subject: [PATCH 172/179] Refactor tooltip balance value --- .../shared/CurrencyBalance/index.tsx | 20 +++++++++++++------ .../TransactionHistory/TransactionTable.tsx | 8 +++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 30e12dc78..3f86de165 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -7,6 +7,7 @@ import { Tooltip, } from "@chakra-ui/react" import { + fixedPointNumberToString, formatTokenAmount, getCurrencyByType, numberToLocaleString, @@ -60,16 +61,24 @@ export function CurrencyBalance({ decimals, desiredDecimals: currencyDesiredDecimals, } = getCurrencyByType(currency) + const desiredDecimals = customDesiredDecimals ?? currencyDesiredDecimals const getBalance = useCallback( - (desiredDecimals: number) => { - const value = amount ?? 0 + (options: { withFullPrecision?: boolean } = {}) => { + const { withFullPrecision } = options + + const value = amount ?? 0n + + if (withFullPrecision) { + return fixedPointNumberToString(BigInt(value), decimals, withRoundUp) + } + if (shouldBeFormatted || typeof value === "bigint") return formatTokenAmount(value, decimals, desiredDecimals, withRoundUp) return numberToLocaleString(value, desiredDecimals) }, - [amount, decimals, shouldBeFormatted, withRoundUp], + [amount, decimals, desiredDecimals, shouldBeFormatted, withRoundUp], ) const content = ( @@ -80,7 +89,7 @@ export function CurrencyBalance({ {...textProps} {...balanceTextProps} > - {getBalance(customDesiredDecimals ?? currencyDesiredDecimals)} + {getBalance()} {withDots && "..."}
@@ -90,8 +99,7 @@ export function CurrencyBalance({ ) if (withTooltip) { - const fullPrecisionDecimals = (amount ?? 0).toString().length - const tooltipLabel = `${getBalance(fullPrecisionDecimals)} ${symbol}` + const tooltipLabel = `${getBalance({ withFullPrecision: true })} ${symbol}` return ( diff --git a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx index 71a4d1a89..7da2295b8 100644 --- a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx +++ b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx @@ -16,11 +16,17 @@ import { IconArrowUpRight } from "@tabler/icons-react" import { useActivities } from "#/hooks" import { semanticTokens } from "#/theme/utils" import EstimatedDuration from "./EstimatedDuration" +import { createActivity } from "#/tests/factories" const BLOCK_EXPLORER_CELL_MIN_WIDTH = 16 export default function TransactionTable() { - const activities = useActivities() + // const activities = useActivities() + const activities = [ + createActivity({ + amount: 122200000n, + }), + ] return ( From 3ce27f444696eab74202524062951871152febb1 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Wed, 6 Nov 2024 13:43:52 +0100 Subject: [PATCH 173/179] Revert mock activities --- dapp/.env | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dapp/.env b/dapp/.env index fee5456ea..380a1f9b0 100644 --- a/dapp/.env +++ b/dapp/.env @@ -10,7 +10,7 @@ VITE_ETH_HOSTNAME_HTTP="https://sepolia.infura.io/v3/c80e8ccdcc4c4a809bce4fc1653 VITE_REFERRAL=0 # ENDPOINTS -VITE_TBTC_API_ENDPOINT="" +VITE_TBTC_API_ENDPOINT="https://tbtc.api.test.acre.fi/tbtc-api/v1/" VITE_ACRE_API_ENDPOINT="http://localhost:8788/api/v1/" # API KEYS @@ -23,8 +23,8 @@ VITE_FEATURE_FLAG_GAMIFICATION_ENABLED="false" VITE_FEATURE_FLAG_WITHDRAWALS_ENABLED="false" VITE_FEATURE_FLAG_OKX_WALLET_ENABLED="false" VITE_FEATURE_FLAG_XVERSE_WALLET_ENABLED="false" -VITE_FEATURE_FLAG_BEEHIVE_COMPONENT_ENABLED="false" +VITE_FEATURE_FLAG_BEEHIVE_COMPONENT_ENABLED="true" VITE_FEATURE_FLAG_ACRE_POINTS_ENABLED="true" -VITE_FEATURE_FLAG_TVL_ENABLED="false" +VITE_FEATURE_FLAG_TVL_ENABLED="true" VITE_FEATURE_GATING_DAPP_ENABLED="true" From eab545586cbb9521b84edce4dfd28f2ab2305265 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Wed, 6 Nov 2024 13:44:57 +0100 Subject: [PATCH 174/179] Revert "Revert mock activities" This reverts commit 3ce27f444696eab74202524062951871152febb1. --- dapp/.env | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dapp/.env b/dapp/.env index 380a1f9b0..fee5456ea 100644 --- a/dapp/.env +++ b/dapp/.env @@ -10,7 +10,7 @@ VITE_ETH_HOSTNAME_HTTP="https://sepolia.infura.io/v3/c80e8ccdcc4c4a809bce4fc1653 VITE_REFERRAL=0 # ENDPOINTS -VITE_TBTC_API_ENDPOINT="https://tbtc.api.test.acre.fi/tbtc-api/v1/" +VITE_TBTC_API_ENDPOINT="" VITE_ACRE_API_ENDPOINT="http://localhost:8788/api/v1/" # API KEYS @@ -23,8 +23,8 @@ VITE_FEATURE_FLAG_GAMIFICATION_ENABLED="false" VITE_FEATURE_FLAG_WITHDRAWALS_ENABLED="false" VITE_FEATURE_FLAG_OKX_WALLET_ENABLED="false" VITE_FEATURE_FLAG_XVERSE_WALLET_ENABLED="false" -VITE_FEATURE_FLAG_BEEHIVE_COMPONENT_ENABLED="true" +VITE_FEATURE_FLAG_BEEHIVE_COMPONENT_ENABLED="false" VITE_FEATURE_FLAG_ACRE_POINTS_ENABLED="true" -VITE_FEATURE_FLAG_TVL_ENABLED="true" +VITE_FEATURE_FLAG_TVL_ENABLED="false" VITE_FEATURE_GATING_DAPP_ENABLED="true" From 5f45eadd4303926c59019590536afe5a45dbb574 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Wed, 6 Nov 2024 13:45:28 +0100 Subject: [PATCH 175/179] Revert mock activities --- .../DashboardPage/TransactionHistory/TransactionTable.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx index 7da2295b8..71a4d1a89 100644 --- a/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx +++ b/dapp/src/pages/DashboardPage/TransactionHistory/TransactionTable.tsx @@ -16,17 +16,11 @@ import { IconArrowUpRight } from "@tabler/icons-react" import { useActivities } from "#/hooks" import { semanticTokens } from "#/theme/utils" import EstimatedDuration from "./EstimatedDuration" -import { createActivity } from "#/tests/factories" const BLOCK_EXPLORER_CELL_MIN_WIDTH = 16 export default function TransactionTable() { - // const activities = useActivities() - const activities = [ - createActivity({ - amount: 122200000n, - }), - ] + const activities = useActivities() return ( From 51e17720d6e4674f46c67ebec468500f08188053 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 13:56:10 +0100 Subject: [PATCH 176/179] Save the bitcoin address in the redux store We need a single source of true for a connected Bitcoin address, so we store it in the redux store. Otherwise, the `useEffect` hook that fetches the Bitcoin address causes unnecessary updates of other hooks. --- dapp/src/hooks/useWallet.ts | 116 +++++++++++------------- dapp/src/store/wallet/walletSelector.ts | 3 + dapp/src/store/wallet/walletSlice.ts | 8 +- 3 files changed, 65 insertions(+), 62 deletions(-) diff --git a/dapp/src/hooks/useWallet.ts b/dapp/src/hooks/useWallet.ts index 0e55abd05..2786a4472 100644 --- a/dapp/src/hooks/useWallet.ts +++ b/dapp/src/hooks/useWallet.ts @@ -1,12 +1,13 @@ -import { useCallback, useEffect, useMemo, useState } from "react" +import { useCallback, useMemo } from "react" import { + Connector, useAccount, useChainId, useConfig, useConnect, useDisconnect, } from "wagmi" -import { logPromiseFailure, orangeKit } from "#/utils" +import { orangeKit } from "#/utils" import { OnErrorCallback, OrangeKitConnector, @@ -14,8 +15,8 @@ import { Status, } from "#/types" import { useMutation, useQueryClient } from "@tanstack/react-query" -import { useConnector } from "./orangeKit/useConnector" -import { useBitcoinProvider } from "./orangeKit/useBitcoinProvider" +import { useDispatch, useSelector } from "react-redux" +import { selectWalletAddress, setAddress } from "#/store/wallet" import useBitcoinBalance from "./orangeKit/useBitcoinBalance" import useResetWalletState from "./useResetWalletState" import useLastUsedBtcAddress from "./useLastUsedBtcAddress" @@ -41,30 +42,54 @@ type UseWalletReturn = { } export function useWallet(): UseWalletReturn { - const chainId = useChainId() - const config = useConfig() - const { status: accountStatus, address: account } = useAccount() - const { connect, status } = useConnect() - const { disconnect } = useDisconnect() - const connector = useConnector() - const provider = useBitcoinProvider() + const queryClient = useQueryClient() + const dispatch = useDispatch() + const btcAddress = useSelector(selectWalletAddress) const resetWalletState = useResetWalletState() const { setAddressInLocalStorage, removeAddressFromLocalStorage } = useLastUsedBtcAddress() - const [address, setAddress] = useState(undefined) - const { data: balance } = useBitcoinBalance(address) - const [ethAddress, setEthAddress] = useState(undefined) + const { data: balance } = useBitcoinBalance(btcAddress) + + const chainId = useChainId() + const config = useConfig() + // `useAccount` hook returns the Ethereum address + const { status: accountStatus, address: account } = useAccount() - // `isConnected` is variable derived from `status` but does not guarantee us a set `address`. - // When `status` is 'connected' properties like `address` are guaranteed to be defined. - // Let's use `status` to make sure the account is connected. + // `isConnected` is variable derived from `status` but does not guarantee us a + // set `address`. When `status` is 'connected' properties like `address` are + // guaranteed to be defined. Let's use `status` to make sure the account is + // connected. const isConnected = useMemo( () => orangeKit.isConnectedStatus(accountStatus), [accountStatus], ) - const queryClient = useQueryClient() + const { connect, status } = useConnect({ + mutation: { + onSuccess: async (_, { connector }) => { + const connectedConnector = typeConversionToOrangeKitConnector( + connector as Connector, + ) + const bitcoinAddress = await connectedConnector.getBitcoinAddress() + + dispatch(setAddress(bitcoinAddress)) + setAddressInLocalStorage(bitcoinAddress) + }, + }, + }) + + const { disconnect } = useDisconnect({ + mutation: { + onSuccess: () => { + config.setState((prevState) => ({ ...prevState, current: null })) + dispatch(setAddress(undefined)) + removeAddressFromLocalStorage() + resetWalletState() + }, + }, + }) + const { mutate: reconnect, status: reconnectStatus } = useMutation( { mutationFn: async (selectedConnector: OrangeKitConnector) => { @@ -90,12 +115,16 @@ export function useWallet(): UseWalletReturn { }, ), })) - - setAddress(newAddress) resetWalletState() } }, mutationKey: ["reconnect"], + onSuccess: async (_, selectedConnector) => { + const bitcoinAddress = await selectedConnector.getBitcoinAddress() + + dispatch(setAddress(bitcoinAddress)) + setAddressInLocalStorage(bitcoinAddress) + }, }, queryClient, ) @@ -140,61 +169,26 @@ export function useWallet(): UseWalletReturn { [connect, chainId, reconnect], ) - const onDisconnect = useCallback(() => { - disconnect( - {}, - { - onSuccess: () => { - resetWalletState() - setAddress(undefined) - removeAddressFromLocalStorage() - }, - }, - ) - }, [disconnect, resetWalletState, removeAddressFromLocalStorage]) - - useEffect(() => { - const fetchBitcoinAddress = async () => { - if ( - connector && - typeof connector.getAccounts === "function" && - typeof connector.getBitcoinAddress === "function" - ) { - const btcAddress = await connector.getBitcoinAddress() - const accounts = await connector.getAccounts() - - setAddress(btcAddress) - setAddressInLocalStorage(btcAddress) - setEthAddress(accounts[0]) - } else { - setAddress(undefined) - setEthAddress(undefined) - } - } - - logPromiseFailure(fetchBitcoinAddress()) - }, [connector, setAddressInLocalStorage, provider, account]) - return useMemo( () => ({ isConnected, - address, - ethAddress, + address: btcAddress, + ethAddress: account, balance, status: status === "idle" && reconnectStatus !== "idle" ? reconnectStatus : status, onConnect, - onDisconnect, + onDisconnect: disconnect, }), [ - address, + btcAddress, balance, - ethAddress, + account, isConnected, onConnect, - onDisconnect, + disconnect, status, reconnectStatus, ], diff --git a/dapp/src/store/wallet/walletSelector.ts b/dapp/src/store/wallet/walletSelector.ts index 3909ec540..e97ac2001 100644 --- a/dapp/src/store/wallet/walletSelector.ts +++ b/dapp/src/store/wallet/walletSelector.ts @@ -34,3 +34,6 @@ export const selectIsSignedMessage = (state: RootState): boolean => export const selectHasFetchedActivities = (state: RootState): boolean => state.wallet.hasFetchedActivities + +export const selectWalletAddress = (state: RootState): string | undefined => + state.wallet.address diff --git a/dapp/src/store/wallet/walletSlice.ts b/dapp/src/store/wallet/walletSlice.ts index ba89834f0..fc8dc986d 100644 --- a/dapp/src/store/wallet/walletSlice.ts +++ b/dapp/src/store/wallet/walletSlice.ts @@ -9,6 +9,7 @@ export type WalletState = { latestActivities: ActivitiesByIds activities: Activity[] hasFetchedActivities: boolean + address: string | undefined } export const initialState: WalletState = { @@ -18,6 +19,7 @@ export const initialState: WalletState = { latestActivities: {}, activities: [], hasFetchedActivities: false, + address: undefined, } export const walletSlice = createSlice({ @@ -101,7 +103,7 @@ export const walletSlice = createSlice({ const activityId = action.payload delete state.latestActivities[activityId] }, - resetState: () => initialState, + resetState: (state) => ({ ...initialState, address: state.address }), activityInitialized(state, action: PayloadAction) { const activity = action.payload state.latestActivities = { @@ -110,6 +112,9 @@ export const walletSlice = createSlice({ } state.activities = [...state.activities, activity] }, + setAddress(state, action: PayloadAction) { + state.address = action.payload + }, }, }) @@ -121,5 +126,6 @@ export const { deleteLatestActivity, resetState, activityInitialized, + setAddress, } = walletSlice.actions export default walletSlice.reducer From 49c77ea4b90f3622bf32ec296242a4de0c8ce49c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 14:03:55 +0100 Subject: [PATCH 177/179] Update Ledger manifest configs Set the full id in config instead of `acre-` template. The `id` for the mainnet must be just `acre`. --- dapp/config/development.json | 2 +- dapp/config/mainnet.json | 2 +- dapp/config/testnet.json | 2 +- dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json | 2 +- dapp/manifests/ledger-live/ledger-manifest-template.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dapp/config/development.json b/dapp/config/development.json index c53925a4c..2b2dd2892 100644 --- a/dapp/config/development.json +++ b/dapp/config/development.json @@ -1,5 +1,5 @@ { - "id": "dev", + "id": "acre-dev", "name": "Acre [dev]", "url": "http://localhost:5173/" } diff --git a/dapp/config/mainnet.json b/dapp/config/mainnet.json index 0fb50b83e..dfc81b44b 100644 --- a/dapp/config/mainnet.json +++ b/dapp/config/mainnet.json @@ -1,5 +1,5 @@ { - "id": "mainnet", + "id": "acre", "name": "Acre", "url": "https://bitcoin.acre.fi/" } diff --git a/dapp/config/testnet.json b/dapp/config/testnet.json index 080160e91..e627f31bf 100644 --- a/dapp/config/testnet.json +++ b/dapp/config/testnet.json @@ -1,5 +1,5 @@ { - "id": "testnet", + "id": "acre-testnet", "name": "Acre [testnet]", "url": "https://bitcoin.test.acre.fi/" } diff --git a/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json b/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json index b135a159b..eb892f6cc 100644 --- a/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json +++ b/dapp/manifests/ledger-live/ledger-live-manifest-mainnet.json @@ -1,5 +1,5 @@ { - "id": "acre-mainnet", + "id": "acre", "name": "Acre", "url": "https://bitcoin.acre.fi/?embed=ledger-live", "homepageUrl": "https:/acre.fi/", diff --git a/dapp/manifests/ledger-live/ledger-manifest-template.json b/dapp/manifests/ledger-live/ledger-manifest-template.json index 08fd0883b..5dc0d624f 100644 --- a/dapp/manifests/ledger-live/ledger-manifest-template.json +++ b/dapp/manifests/ledger-live/ledger-manifest-template.json @@ -1,5 +1,5 @@ { - "id": "acre-{{id}}", + "id": "{{id}}", "name": "{{name}}", "url": "{{{url}}}?embed=ledger-live", "homepageUrl": "https:/acre.fi/", From 7a8935b5c167fd854cf26fc0a1e32f71d45ed999 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Wed, 6 Nov 2024 14:30:00 +0100 Subject: [PATCH 178/179] Remove unnecessary commented code --- dapp/src/wagmiConfig.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/dapp/src/wagmiConfig.ts b/dapp/src/wagmiConfig.ts index 8d801d053..19d1cf4e4 100644 --- a/dapp/src/wagmiConfig.ts +++ b/dapp/src/wagmiConfig.ts @@ -20,35 +20,6 @@ const transports = chains.reduce( {}, ) -// const orangeKitUnisatConnector = getOrangeKitUnisatConnector(connectorConfig) -// const orangeKitOKXConnector = getOrangeKitOKXConnector(connectorConfig) -// const orangeKitXverseConnector = getOrangeKitXverseConnector(connectorConfig) -// const orangeKitLedgerLiveConnector = orangeKit.getOrangeKitLedgerLiveConnector({ -// ...connectorConfig, -// options: { -// tryConnectToAddress: getLastUsedBtcAddress(), -// }, -// }) - -// const embedConnectorsMap: Record CreateOrangeKitConnectorFn> = { -// "ledger-live": orangeKitLedgerLiveConnector, -// } - -// let createEmbedConnectorFn -// const embeddedApp = referralProgram.getEmbeddedApp() -// if (referralProgram.isEmbedApp(embeddedApp)) { -// createEmbedConnectorFn = embedConnectorsMap[embeddedApp as EmbedApp] -// } - -// const defaultConnectors = [ -// orangeKitOKXConnector(), -// orangeKitUnisatConnector(), -// orangeKitXverseConnector(), -// ] - -// const connectors = (createEmbedConnectorFn !== undefined -// ? [createEmbedConnectorFn()] -// : defaultConnectors) as unknown as CreateConnectorFn[] async function getWagmiConfig() { const { getOrangeKitUnisatConnector, From 5ddc866eef4eb74dfa7e1f45ba9c2543716e87f4 Mon Sep 17 00:00:00 2001 From: Kamil Pyszkowski Date: Wed, 6 Nov 2024 14:42:25 +0100 Subject: [PATCH 179/179] Update `getBalance` conditions --- dapp/src/components/shared/CurrencyBalance/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dapp/src/components/shared/CurrencyBalance/index.tsx b/dapp/src/components/shared/CurrencyBalance/index.tsx index 3f86de165..0579d8a24 100644 --- a/dapp/src/components/shared/CurrencyBalance/index.tsx +++ b/dapp/src/components/shared/CurrencyBalance/index.tsx @@ -69,14 +69,14 @@ export function CurrencyBalance({ const value = amount ?? 0n - if (withFullPrecision) { - return fixedPointNumberToString(BigInt(value), decimals, withRoundUp) - } + if (shouldBeFormatted || typeof value === "bigint") { + if (withFullPrecision) + return fixedPointNumberToString(BigInt(value), decimals, withRoundUp) - if (shouldBeFormatted || typeof value === "bigint") return formatTokenAmount(value, decimals, desiredDecimals, withRoundUp) + } - return numberToLocaleString(value, desiredDecimals) + return numberToLocaleString(value.toString(), desiredDecimals) }, [amount, decimals, desiredDecimals, shouldBeFormatted, withRoundUp], )