diff --git a/package-lock.json b/package-lock.json index aefaeb884..7c262ab8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "dependencies": { "@bosonprotocol/common": "^1.8.0", - "@bosonprotocol/core-sdk": "^1.9.0", + "@bosonprotocol/core-sdk": "^1.9.1-alpha.1", "@bosonprotocol/ethers-sdk": "^1.4.1", "@bosonprotocol/ipfs-storage": "^1.5.0", "@bosonprotocol/widgets-sdk": "^1.8.0", @@ -2005,9 +2005,9 @@ } }, "node_modules/@bosonprotocol/core-sdk": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@bosonprotocol/core-sdk/-/core-sdk-1.9.0.tgz", - "integrity": "sha512-cVwdFypQTQwpddvlxtLyMspLCP2cSJtbzMt36nKjjmm1NLUefHlGqsGkTPMOweBN9Zk1zMNWR7X4CUWLafLYtA==", + "version": "1.9.1-alpha.1", + "resolved": "https://registry.npmjs.org/@bosonprotocol/core-sdk/-/core-sdk-1.9.1-alpha.1.tgz", + "integrity": "sha512-fOsNGzbUmuWBdfqRqkiWxSY/iZlXqT38tq+eFvE0wRubLJiztcQw8zlwgbG1+OA0h2sGeXUM4yhToRHiCsuULw==", "dependencies": { "@bosonprotocol/common": "^1.8.0", "@ethersproject/abi": "^5.5.0", @@ -21991,9 +21991,9 @@ } }, "@bosonprotocol/core-sdk": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@bosonprotocol/core-sdk/-/core-sdk-1.9.0.tgz", - "integrity": "sha512-cVwdFypQTQwpddvlxtLyMspLCP2cSJtbzMt36nKjjmm1NLUefHlGqsGkTPMOweBN9Zk1zMNWR7X4CUWLafLYtA==", + "version": "1.9.1-alpha.1", + "resolved": "https://registry.npmjs.org/@bosonprotocol/core-sdk/-/core-sdk-1.9.1-alpha.1.tgz", + "integrity": "sha512-fOsNGzbUmuWBdfqRqkiWxSY/iZlXqT38tq+eFvE0wRubLJiztcQw8zlwgbG1+OA0h2sGeXUM4yhToRHiCsuULw==", "requires": { "@bosonprotocol/common": "^1.8.0", "@ethersproject/abi": "^5.5.0", diff --git a/package.json b/package.json index 72766eca2..7567f0451 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@bosonprotocol/common": "^1.8.0", - "@bosonprotocol/core-sdk": "^1.9.0", + "@bosonprotocol/core-sdk": "^1.9.1-alpha.1", "@bosonprotocol/ethers-sdk": "^1.4.1", "@bosonprotocol/ipfs-storage": "^1.5.0", "@bosonprotocol/widgets-sdk": "^1.8.0", diff --git a/src/components/offer/OfferCard.tsx b/src/components/offer/OfferCard.tsx index acf18bc03..6d19fe04f 100644 --- a/src/components/offer/OfferCard.tsx +++ b/src/components/offer/OfferCard.tsx @@ -36,7 +36,7 @@ const Card = styled.div<{ isCarousel: boolean }>` 8px 8px 8px rgba(0, 0, 0, 0.05), 16px 16px 16px rgba(0, 0, 0, 0.05); - img { + img[data-testid=image] { transform: translate(-50%, -50%) scale(1.05); } } @@ -277,6 +277,7 @@ export default function OfferCard({ {offer.exchangeToken && ( (false); const symbolUpperCase = currencySymbol.toUpperCase() as keyof typeof currencyImages; - if (!currencyImages[symbolUpperCase]) { - return null; + if (currencyImages[symbolUpperCase]) { + const Icon = currencyImages[symbolUpperCase]; + return ( + + + + ); + } + + if (error) { + return <>{symbolUpperCase}; } - const Icon = currencyImages[symbolUpperCase]; + + const url = + address === ethers.constants.AddressZero + ? `https://raw.githubusercontent.com/trustwallet/assets/8d1c9e051c8b9999cc58ae7e17bac1541dd483a3/blockchains/${chain}/info/logo.png` + : `https://raw.githubusercontent.com/trustwallet/assets/8d1c9e051c8b9999cc58ae7e17bac1541dd483a3/blockchains/${chain}/assets/${address}/logo.png`; + return ( - - - + { + setError(true); + }} + /> ); } diff --git a/src/components/price/index.tsx b/src/components/price/index.tsx index 292b8b301..2e29d0814 100644 --- a/src/components/price/index.tsx +++ b/src/components/price/index.tsx @@ -11,6 +11,9 @@ const Root = styled.div` `; const CurrencyIconContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; img { height: 25px; width: 25px; @@ -21,12 +24,14 @@ interface IProps { value: string; decimals: string; currencySymbol: string; + address: string; } export default function Price({ value, decimals, currencySymbol, + address, ...rest }: IProps) { let formattedValue = ""; @@ -40,7 +45,7 @@ export default function Price({ return ( - + {formattedValue ? ( { const in10days = dayjs(dateNow).add(10, "day").startOf("day").toDate().getTime() / 1000; - const validFromDate_lte = - props.type !== "soon" && props.valid ? now + "" : null; - const validFromDate_gte = props.type === "soon" ? now + "" : null; - const validUntilDate_lte = props.type === "hot" ? in10days + "" : null; - const validUntilDate_gte = validUntilDate_lte - ? null - : props.type !== "soon" && props.valid - ? now + "" - : null; + let validFromDate_lte: string | null = null; + let validFromDate_gte: string | null = null; + let validUntilDate_lte: string | null = null; + let validUntilDate_gte: string | null = null; + + if (props.type) { + if (props.type === "hot") { + validFromDate_gte = now + ""; + validUntilDate_lte = in10days + ""; + } else if (props.type === "gone") { + validFromDate_lte = now + ""; + validUntilDate_gte = now + ""; + } else if (props.type === "soon") { + validFromDate_gte = now + ""; + } else { + throw new Error(`type not supported=${props.type}`); + } + } else { + if (props.valid) { + validFromDate_lte = now + ""; + validUntilDate_gte = now + ""; + } else { + // TODO: is there a use case for this? + } + } const variables = { validFromDate_lte: validFromDate_lte, diff --git a/src/pages/account/funds/FundItem.tsx b/src/pages/account/funds/FundItem.tsx index 448d03b37..71166a1ee 100644 --- a/src/pages/account/funds/FundItem.tsx +++ b/src/pages/account/funds/FundItem.tsx @@ -1,5 +1,6 @@ +import { CoreSDK } from "@bosonprotocol/core-sdk"; import { FundsEntityFieldsFragment } from "@bosonprotocol/core-sdk/dist/cjs/subgraph"; -import { BigNumber, utils } from "ethers"; +import { BigNumber, constants, utils } from "ethers"; import { useState } from "react"; import { ImSpinner2 } from "react-icons/im"; import styled from "styled-components"; @@ -150,6 +151,7 @@ interface Props { buyerFlexBasisCells: [number, number, number]; reload: () => void; isTabSellerSelected: boolean; + coreSDK: CoreSDK; } const getNumberWithoutDecimals = (value: string, decimals: string): string => { @@ -176,8 +178,11 @@ export default function FundItem({ sellerFlexBasisCells, isHighlighted, isAllFundsBeingWithdrawn, + coreSDK, reload }: Props) { + const exchangeToken = fund.token.address; + const [isBeingWithdrawn, setIsBeingWithdrawn] = useState(false); const [isWithdrawInvalid, setIsWithdrawInvalid] = useState(true); const [withdrawError, setWithdrawError] = useState(null); @@ -190,7 +195,7 @@ export default function FundItem({ accountId, tokensToWithdraw: [ { - address: fund.token.address, + address: exchangeToken, amount: isWithdrawInvalid || !Number(amountToWithdraw) ? BigNumber.from("0") @@ -208,9 +213,25 @@ export default function FundItem({ : BigNumber.from( getNumberWithoutDecimals(amountToDeposit, fund.token.decimals) ), - tokenAddress: fund.token.address + tokenAddress: exchangeToken }); + const approveToken = async (value: string) => { + const isNativeCoin = constants.AddressZero === exchangeToken; + if (isNativeCoin) { + return; + } + const allowance = await coreSDK.getExchangeTokenAllowance(exchangeToken); + + if (Number(allowance) < Number(value)) { + const tx = await coreSDK.approveExchangeToken( + exchangeToken, + constants.MaxInt256 + ); + await tx.wait(); + } + }; + const flexBasisCells = isTabSellerSelected ? sellerFlexBasisCells : buyerFlexBasisCells; @@ -275,6 +296,7 @@ export default function FundItem({ const tx = await withdrawFunds(); await tx?.wait(); setAmountToWithdraw("0"); + setIsWithdrawInvalid(true); } catch (error) { console.error(error); setWithdrawError(error); @@ -315,9 +337,11 @@ export default function FundItem({ try { setDepositError(null); setIsBeingDeposit(true); + await approveToken(amountToDeposit); const tx = await depositFunds(); await tx?.wait(); setAmountToDeposit("0"); + setIsDepositInvalid(true); } catch (error) { console.error(error); setDepositError(error); diff --git a/src/pages/account/funds/Funds.tsx b/src/pages/account/funds/Funds.tsx index 3390d405d..758569eb5 100644 --- a/src/pages/account/funds/Funds.tsx +++ b/src/pages/account/funds/Funds.tsx @@ -139,6 +139,9 @@ export default function Funds({ sellerId, buyerId }: Props) { setIsAllFundsBeingWithdrawn(false); } }; + if (!accountId) { + return

You have to interact with the protocol before adding funds

; + } return ( {uiFunds.length ? ( @@ -181,6 +184,7 @@ export default function Funds({ sellerId, buyerId }: Props) { sellerFlexBasisCells={sellerFlexBasisCells} buyerFlexBasisCells={buyerFlexBasisCells} isTabSellerSelected={isTabSellerSelected} + coreSDK={core} /> )) ) : ( diff --git a/src/pages/exchange/Exchange.tsx b/src/pages/exchange/Exchange.tsx index d093f36df..3cbf7aa8a 100644 --- a/src/pages/exchange/Exchange.tsx +++ b/src/pages/exchange/Exchange.tsx @@ -370,6 +370,7 @@ export default function Exchange() { Price Price