Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/connectkit/bundle-analysis.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/connectkit/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@rozoai/intent-pay",
"private": false,
"version": "0.1.18",
"version": "0.1.19-beta.3",
"author": "RozoAI",
"homepage": "https://github.com/RozoAI/intent-pay",
"license": "BSD-2-Clause",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const AmountInputField: React.FC<{
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
currency?: string;
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
}> = ({ value, onChange, currency = "$", onKeyDown }) => {
}> = ({ value, onChange, currency, onKeyDown }) => {
// Focus the input when the component mounts so the user can start typing immediately
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
Expand All @@ -72,7 +72,7 @@ const AmountInputField: React.FC<{
placeholder="0.00"
onKeyDown={onKeyDown}
/>
{currency !== "$" && (
{currency && currency !== "$" && (
<AnimatedCurrency $small>{currency}</AnimatedCurrency>
)}
</Container>
Expand Down
15 changes: 10 additions & 5 deletions packages/connectkit/src/components/Common/AmountInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@ const MultiCurrencySelectAmount: React.FC<{
const maxUsdLimit = paymentState.getOrderUsdLimit();

const balanceToken = selectedTokenOption.balance.token;
const fiatSymbol = balanceToken.fiatSymbol ?? "$";

const minimumMessage =
selectedTokenOption.minimumRequired.usd > 0
? `Minimum
${formatUsd(selectedTokenOption.minimumRequired.usd, "up")}`
${formatUsd(
selectedTokenOption.minimumRequired.usd,
"up",
balanceToken.fiatISO,
)}`
: null;

const [usdValue, setUsdValue] = useState("");
Expand Down Expand Up @@ -87,10 +92,10 @@ const MultiCurrencySelectAmount: React.FC<{
if (Number(sanitizedUsdValue) > selectedTokenOption.balance.usd) {
setMessage(
`Amount exceeds your balance:
${formatUsd(selectedTokenOption.balance.usd)}`,
${formatUsd(selectedTokenOption.balance.usd, "down", balanceToken.fiatISO)}`,
);
} else if (Number(usdValue) > maxUsdLimit) {
setMessage(`Maximum ${formatUsd(maxUsdLimit)}`);
setMessage(`Maximum ${formatUsd(maxUsdLimit, "down", balanceToken.fiatISO)}`);
} else {
setMessage(minimumMessage);
}
Expand Down Expand Up @@ -166,7 +171,7 @@ const MultiCurrencySelectAmount: React.FC<{
<AmountInputField
value={isEditingUsd ? usdValue : tokenValue}
onChange={handleAmountChange}
currency={isEditingUsd ? "$" : balanceToken.symbol}
currency={isEditingUsd ? fiatSymbol : balanceToken.symbol}
onKeyDown={handleKeyDown}
/>
<MaxButton onClick={handleMax}>Max</MaxButton>
Expand All @@ -178,7 +183,7 @@ const MultiCurrencySelectAmount: React.FC<{
<SecondaryAmount>
{isEditingUsd
? `${tokenValue} ${balanceToken.symbol}`
: `$${usdValue}`}
: `${fiatSymbol}${usdValue}`}
</SecondaryAmount>
</SwitchButton>
</SwitchContainer>
Expand Down
18 changes: 16 additions & 2 deletions packages/connectkit/src/components/Common/OrderHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getAddressContraction } from "@rozoai/intent-common";
import { getAddressContraction, getKnownToken } from "@rozoai/intent-common";
import { useWallet } from "@solana/wallet-adapter-react";
import { motion } from "framer-motion";
import React from "react";
Expand Down Expand Up @@ -53,6 +53,20 @@ export const OrderHeader = ({
stellarPublicKey ?? "",
);
const orderUsd = order?.destFinalCallTokenAmount.usd;
const destinationFiatISO = React.useMemo(() => {
if (!paymentState.payParams?.toChain || !paymentState.payParams?.toToken) {
return order?.destFinalCallTokenAmount.token.fiatISO;
}

return getKnownToken(
paymentState.payParams.toChain,
paymentState.payParams.toToken,
)?.fiatISO;
}, [
order?.destFinalCallTokenAmount.token.fiatISO,
paymentState.payParams?.toChain,
paymentState.payParams?.toToken,
]);
const appId = paymentState.payParams?.appId;

const titleAmountContent = (() => {
Expand All @@ -65,7 +79,7 @@ export const OrderHeader = ({
) : null;
} else {
return orderUsd != null ? (
<span>{formatUsd(orderUsd, "nearest")}</span>
<span>{formatUsd(orderUsd, "nearest", destinationFiatISO)}</span>
) : null;
}
})();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ import React from "react";
import { WalletPaymentOption } from "@rozoai/intent-common";
import defaultTheme from "../../../constants/defaultTheme";
import styled from "../../../styles/styled";
import { roundTokenAmount } from "../../../utils/format";
import { ModalBody } from "../../Common/Modal/styles";

const PaymentBreakdown: React.FC<{
paymentOption: WalletPaymentOption;
}> = ({ paymentOption }) => {
const subtotalUsd = paymentOption.required.usd;
const feesUsd = paymentOption.fees.usd;
const totalUsd = subtotalUsd + feesUsd;
const tokenSymbol = paymentOption.required.token.symbol;
const feeTokenAmount = roundTokenAmount(
paymentOption.fees.amount,
paymentOption.fees.token,
"nearest",
);
const totalTokenAmount = roundTokenAmount(
paymentOption.required.amount,
paymentOption.required.token,
"nearest",
);

return (
<FeesContainer>
Expand All @@ -25,13 +35,13 @@ const PaymentBreakdown: React.FC<{
{feesUsd === 0 ? (
<Badge>Free</Badge>
) : (
<ModalBody>${feesUsd.toFixed(2)}</ModalBody>
<ModalBody>{`${feeTokenAmount} ${tokenSymbol}`}</ModalBody>
)}
</FeeRow>
<FeeRow style={{ marginTop: 8 }}>
<ModalBody style={{ fontWeight: 600 }}>Total</ModalBody>
<ModalBody style={{ fontWeight: 600 }}>
${subtotalUsd.toFixed(2)}
{`${totalTokenAmount} ${tokenSymbol}`}
</ModalBody>
</FeeRow>
</FeesContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import ExternalPaymentSpinner from "../../Spinners/ExternalPaymentSpinner";
const SelectDepositAddressAmount: React.FC = () => {
const { paymentState, setRoute, triggerResize } = usePayContext();
const { selectedDepositAddressOption } = paymentState;
const fiatISO = selectedDepositAddressOption?.token.fiatISO;

const maxUsdLimit = paymentState.getOrderUsdLimit();
const minUsd = selectedDepositAddressOption?.minimumUsd ?? 0;
const minimumMessage =
minUsd > 0 ? `Minimum ${formatUsd(minUsd, "up")}` : null;
minUsd > 0 ? `Minimum ${formatUsd(minUsd, "up", fiatISO)}` : null;

const [usdInput, setUsdInput] = useState<string>("");
const [message, setMessage] = useState<string | null>(minimumMessage);
Expand All @@ -43,7 +44,7 @@ const SelectDepositAddressAmount: React.FC = () => {
setUsdInput(value);

if (Number(value) > maxUsdLimit) {
setMessage(`Maximum ${formatUsd(maxUsdLimit)}`);
setMessage(`Maximum ${formatUsd(maxUsdLimit, "down", fiatISO)}`);
} else {
setMessage(minimumMessage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { usePayContext } from "../../../hooks/usePayContext";

import { ModalContent, ModalH1, PageContent } from "../../Common/Modal/styles";

import { RozoPayOrderMode } from "@rozoai/intent-common";
import { getKnownToken, RozoPayOrderMode } from "@rozoai/intent-common";
import { useRozoPay } from "../../../hooks/useDaimoPay";
import { OptionsList } from "../../Common/OptionsList";
import { OrderHeader } from "../../Common/OrderHeader";
Expand Down Expand Up @@ -69,12 +69,16 @@ const SelectDepositAddressChain: React.FC = () => {

let disabledReason: string | undefined;
if (isDisabledByMinimum) {
const destinationFiatISO = getKnownToken(
option.token.chainId,
option.token.token,
)?.fiatISO;
if (option.minimumUsd <= 0) {
disabledReason = "Minimum amount not available";
} else if (order?.mode === RozoPayOrderMode.HYDRATED) {
disabledReason = `Minimum: $${option.minimumUsd.toFixed(2)}`;
disabledReason = `Minimum: ${option.minimumUsd.toFixed(2)} ${destinationFiatISO}`;
} else if (order?.mode === RozoPayOrderMode.SALE) {
disabledReason = `Minimum: $${option.minimumUsd.toFixed(2)}`;
disabledReason = `Minimum: ${option.minimumUsd.toFixed(2)} ${destinationFiatISO}`;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import ExternalPaymentSpinner from "../../Spinners/ExternalPaymentSpinner";
const SelectExternalAmount: React.FC = () => {
const { paymentState, setRoute, triggerResize } = usePayContext();
const { selectedExternalOption } = paymentState;
const fiatISO = selectedExternalOption?.paymentToken?.fiatISO;

const maxUsdLimit = paymentState.getOrderUsdLimit();
const minimumMessage =
(selectedExternalOption?.minimumUsd ?? 0) > 0
? `Minimum ${formatUsd(selectedExternalOption?.minimumUsd ?? 0, "up")}`
? `Minimum ${formatUsd(
selectedExternalOption?.minimumUsd ?? 0,
"up",
fiatISO,
)}`
: null;

const [usdInput, setUsdInput] = useState<string>("");
Expand All @@ -44,7 +49,7 @@ const SelectExternalAmount: React.FC = () => {
setUsdInput(value);

if (Number(value) > maxUsdLimit) {
setMessage(`Maximum ${formatUsd(maxUsdLimit)}`);
setMessage(`Maximum ${formatUsd(maxUsdLimit, "down", fiatISO)}`);
} else {
setMessage(minimumMessage);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import useIsMobile from "../../../hooks/useIsMobile";
import { usePayContext } from "../../../hooks/usePayContext";
import { usePusherPayout } from "../../../hooks/usePusherPayout";
import styled from "../../../styles/styled";
import { formatUsd } from "../../../utils/format";
import { formatUsd, roundUsd } from "../../../utils/format";
import Button from "../../Common/Button";
import CircleTimer from "../../Common/CircleTimer";
import CopyToClipboardIcon from "../../Common/CopyToClipboard/CopyToClipboardIcon";
Expand Down Expand Up @@ -471,7 +471,10 @@ export default function WaitingDepositAddress() {
{tronUnderpay ? (
<TronUnderpayContent orderId={order?.id?.toString()} />
) : feeError ? (
<FeeErrorContent feeError={feeError} />
<FeeErrorContent
feeError={feeError}
fiatISO={order?.destFinalCallTokenAmount.token.fiatISO}
/>
) : failed ? (
selectedDepositAddressOption && (
<DepositFailed name={selectedDepositAddressOption.id} />
Expand Down Expand Up @@ -528,7 +531,13 @@ function TronUnderpayContent({ orderId }: { orderId?: string }) {
);
}

function FeeErrorContent({ feeError }: { feeError: FeeErrorData }) {
function FeeErrorContent({
feeError,
fiatISO,
}: {
feeError: FeeErrorData;
fiatISO?: string;
}) {
return (
<ModalContent
style={{
Expand All @@ -552,7 +561,7 @@ function FeeErrorContent({ feeError }: { feeError: FeeErrorData }) {
<br />
<br />
Maximum allowed amount:{" "}
{formatUsd(feeError.maxAllowed, "nearest")}
{formatUsd(feeError.maxAllowed, "nearest", fiatISO)}
</>
)}
</ModalBody>
Expand Down Expand Up @@ -653,20 +662,28 @@ function CopyableInfo({
}) {
const underpayment = depAddr?.underpayment;
const isExpired = depAddr?.expirationS != null && remainingS === 0;
const sourceTokenSymbol = depAddr?.displayToken?.symbol;

return (
<CopyableInfoWrapper>
{underpayment && <UnderpaymentInfo underpayment={underpayment} />}
{feeData !== null && (
<FeeDisplayRow
title="Fee"
value={feeData.fee === 0 ? "Free" : formatUsd(feeData.fee, "nearest")}
value={
feeData.fee === 0
? "Free"
: formatAmountWithTokenSymbol(feeData.fee, sourceTokenSymbol)
}
/>
)}
<CopyRowOrThrobber
title="Send Exactly"
value={depAddr?.amount}
valueText={formatUsd(Number(depAddr?.amount) || 0, "nearest")}
valueText={formatAmountWithTokenSymbol(
Number(depAddr?.amount) || 0,
sourceTokenSymbol,
)}
smallText={depAddr?.coins}
disabled={isExpired}
/>
Expand All @@ -691,6 +708,12 @@ function CopyableInfo({
);
}

function formatAmountWithTokenSymbol(amount: number, tokenSymbol?: string) {
const roundedAmount = roundUsd(amount, "nearest");
if (!tokenSymbol) return roundedAmount;
return `${roundedAmount} ${tokenSymbol}`;
}

function UnderpaymentInfo({ underpayment }: { underpayment: Underpayment }) {
// Default message
return (
Expand Down
23 changes: 16 additions & 7 deletions packages/connectkit/src/hooks/useSolanaPaymentOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { rozoSolana, solana, WalletPaymentOption } from "@rozoai/intent-common";
import {
getKnownToken,
rozoSolana,
solana,
WalletPaymentOption,
} from "@rozoai/intent-common";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { PayParams } from "../payment/paymentFsm";
import { TrpcClient } from "../utils/trpc";
Expand Down Expand Up @@ -40,7 +45,7 @@ export function useSolanaPaymentOptions({
// Get Solana chain IDs from supported chains
const solanaChainIds = useMemo(() => {
return new Set(
chains.filter((c) => c.type === "solana").map((c) => c.chainId)
chains.filter((c) => c.type === "solana").map((c) => c.chainId),
);
}, [chains]);

Expand All @@ -51,7 +56,7 @@ export function useSolanaPaymentOptions({
const memoizedPreferredTokens = useMemo(
() => payParams?.preferredTokens,
// eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(payParams?.preferredTokens)]
[JSON.stringify(payParams?.preferredTokens)],
);

const filteredOptions = useMemo(() => {
Expand Down Expand Up @@ -82,7 +87,7 @@ export function useSolanaPaymentOptions({
(pt) =>
pt.chainId === option.balance.token.chainId &&
normalizeAddress(pt.token) ===
normalizeAddress(option.balance.token.token)
normalizeAddress(option.balance.token.token),
);
})
.map((item) => {
Expand All @@ -97,10 +102,14 @@ export function useSolanaPaymentOptions({
};

// Set `disabledReason` manually (based on current usdRequired state, not API Request)
const destinationFiatISO = getKnownToken(
item.balance.token.chainId,
item.balance.token.token,
)?.fiatISO;
if (item.balance.usd < usd) {
value.disabledReason = `Balance too low: $${item.balance.usd.toFixed(
2
)}`;
value.disabledReason = `Balance too low: ${item.balance.usd.toFixed(
2,
)} ${destinationFiatISO}`;
}

return value;
Expand Down
Loading