Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send btc integrate with tx consolidation logic #766

Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d6df19b
Add btc send screen skeleton
victorkirov Jan 15, 2024
4ccd4dd
Implement MAX
victorkirov Jan 15, 2024
76c9f31
extract amount selector to component
victorkirov Jan 15, 2024
63f2bb4
Add max dust filtered callout
victorkirov Jan 15, 2024
2ea224a
Fix minor styling
victorkirov Jan 15, 2024
5207c5d
Add fee display
victorkirov Jan 16, 2024
ed664f4
Implement fee selection
victorkirov Jan 17, 2024
de83299
Add insufficient funds on fee selector
victorkirov Jan 17, 2024
b20e4b6
add insufficient funds message on custom fee selector
victorkirov Jan 17, 2024
002dc58
Add insufficient funds gate
victorkirov Jan 17, 2024
b7e4ded
fix some todos
victorkirov Jan 17, 2024
4d1b558
Add min and max fee rate
victorkirov Jan 17, 2024
e2b0b1a
fix container styling
victorkirov Jan 17, 2024
5f79616
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
victorkirov Jan 18, 2024
f304895
fix styling
victorkirov Jan 18, 2024
a14b8d4
Fix fee summary on confirm page
victorkirov Jan 18, 2024
225f1bd
fix some component interactions
victorkirov Jan 18, 2024
23dd157
fix a few minor bugs
victorkirov Jan 19, 2024
75fa52d
fix rbf typing
victorkirov Jan 19, 2024
b92ad64
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
victorkirov Jan 19, 2024
cf3cc1f
Close window if ledger
victorkirov Jan 19, 2024
aecf750
Update src/app/ui-library/input.tsx
victorkirov Jan 23, 2024
38223d4
Update src/app/ui-library/input.tsx
victorkirov Jan 23, 2024
0d0409c
Add address editable field
victorkirov Jan 23, 2024
d2925dd
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
victorkirov Jan 23, 2024
bbd6829
chore: package-lock exact version
teebszet Jan 31, 2024
5a56cd8
refactor: use classnames for variants in ui-library button
teebszet Jan 31, 2024
24d429f
refactor: use css classnames in ui input
teebszet Jan 31, 2024
bc45210
fix: edit and pencil icon row
teebszet Jan 31, 2024
06b4efa
fix: recipient input next should be disabled when error
teebszet Jan 31, 2024
1a36ad9
fix: confirm/cancel translation keys
teebszet Jan 31, 2024
c04c058
Update core
victorkirov Jan 31, 2024
d9c0d67
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
victorkirov Jan 31, 2024
fe42aaf
Remove unneeded toNumbers
victorkirov Jan 31, 2024
cde4e39
Move error text to feedback
victorkirov Jan 31, 2024
fa243f8
add new for BigNumber
victorkirov Jan 31, 2024
636aa49
Make sats/vByte consistent
victorkirov Jan 31, 2024
a750d7b
Fix fee select styling
victorkirov Jan 31, 2024
38a9c9a
Fix input styling
victorkirov Jan 31, 2024
e2d094c
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
teebszet Feb 1, 2024
b753ca2
switch to new spinner
victorkirov Feb 1, 2024
305df4c
chore: bump core version
teebszet Feb 2, 2024
45f881d
Merge branch 'develop' into victor/eng-3548-ext-send-btc-integrate-tx…
victorkirov Feb 2, 2024
bbcb677
fix: rotate faders icon
teebszet Feb 2, 2024
d2c60d0
Revert "Fix fee select styling"
teebszet Feb 2, 2024
5e00bbb
fix: minor spacing, styling, and colour fixes
teebszet Feb 2, 2024
3e08755
fix: react key warning fix
teebszet Feb 2, 2024
8282c07
bump core
victorkirov Feb 2, 2024
11395ba
Fix api
victorkirov Feb 2, 2024
4929264
Merge branch 'develop' of https://github.com/secretkeylabs/xverse-web…
victorkirov Feb 13, 2024
6702d63
Don't log insufficient funds message
victorkirov Feb 13, 2024
0d6d8b2
Fix insufficient amount on load
victorkirov Feb 13, 2024
c14f289
Enable rbf on txns
victorkirov Feb 13, 2024
804d050
chore: bump core version
teebszet Feb 15, 2024
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
30 changes: 7 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@phosphor-icons/react": "^2.0.10",
"@react-spring/web": "^9.6.1",
"@scure/btc-signer": "1.2.1",
"@secretkeylabs/xverse-core": "9.1.2",
"@secretkeylabs/xverse-core": "9.1.2-a1e1d3d",
"@stacks/connect": "7.4.1",
"@stacks/stacks-blockchain-api-types": "6.1.1",
"@stacks/transactions": "6.9.0",
Expand Down Expand Up @@ -55,7 +55,6 @@
"react-router-dom": "^6.4.0",
"react-select": "^5.4.0",
"react-share": "^4.4.1",
"react-spinners": "^0.13.7",
"react-switch": "^7.0.0",
"react-tabs": "^6.0.2",
"react-tooltip": "^5.4.0",
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/accountRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import { CaretDown, DotsThreeVertical } from '@phosphor-icons/react';
import { Account, currencySymbolMap } from '@secretkeylabs/xverse-core';
import InputFeedback from '@ui-library/inputFeedback';
import Spinner from '@ui-library/spinner';
import { EMPTY_LABEL, LoaderSize, MAX_ACC_NAME_LENGTH } from '@utils/constants';
import { getAccountGradient } from '@utils/gradient';
import { isLedgerAccount, validateAccountName } from '@utils/helper';
import { useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { NumericFormat } from 'react-number-format';
import { MoonLoader } from 'react-spinners';
import 'react-tooltip/dist/react-tooltip.css';
import styled from 'styled-components';

Expand Down Expand Up @@ -293,7 +293,7 @@
}
handleRenameAccountModalClose();
} catch (err) {
console.error(err);

Check warning on line 296 in src/app/components/accountRow/index.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
} finally {
setIsAccountNameChangeLoading(false);
}
Expand Down Expand Up @@ -330,7 +330,7 @@
{isAccountListView && !totalBalance && (
<Balance isSelected={isSelected}>
{EMPTY_LABEL}
<MoonLoader color="white" size={12} />
<Spinner color="white" size={12} />
</Balance>
)}
</TransparentSpan>
Expand Down
6 changes: 3 additions & 3 deletions src/app/components/button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MoonLoader } from 'react-spinners';
import Spinner from '@ui-library/spinner';
import styled from 'styled-components';

interface ButtonProps {
Expand Down Expand Up @@ -117,7 +117,7 @@ function ActionButton({
disabled={disabled || processing}
>
{processing ? (
<MoonLoader color="white" size={10} />
<Spinner color="white" size={10} />
) : (
<>
{src && <ButtonImage src={src} />}
Expand All @@ -138,7 +138,7 @@ function ActionButton({
warning={warning}
>
{processing ? (
<MoonLoader color="#12151E" size={12} />
<Spinner color="#12151E" size={12} />
) : (
<>
{src && <ButtonImage src={src} />}
Expand Down
12 changes: 9 additions & 3 deletions src/app/components/confirmBtcTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import { btcTransaction, Transport } from '@secretkeylabs/xverse-core';
import Callout from '@ui-library/callout';
import { StickyHorizontalSplitButtonContainer, StyledP } from '@ui-library/common.styled';
import Spinner from '@ui-library/spinner';
import { isLedgerAccount } from '@utils/helper';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { MoonLoader } from 'react-spinners';
import styled from 'styled-components';
import SendLayout from '../../layouts/sendLayout';
import TransactionSummary from './transactionSummary';
Expand Down Expand Up @@ -60,8 +60,12 @@
onCancel: () => void;
onBackClick?: () => void;
confirmDisabled?: boolean;
getFeeForFeeRate?: (feeRate: number, useEffectiveFeeRate?: boolean) => Promise<number>;
getFeeForFeeRate?: (
feeRate: number,
useEffectiveFeeRate?: boolean,
) => Promise<number | undefined>;
onFeeRateSet?: (feeRate: number) => void;
feeRate?: number;
};

function ConfirmBtcTransaction({
Expand All @@ -82,6 +86,7 @@
confirmDisabled = false,
getFeeForFeeRate,
onFeeRateSet,
feeRate,
}: Props) {
const [isModalVisible, setIsModalVisible] = useState(false);
const [currentStepIndex, setCurrentStepIndex] = useState(0);
Expand Down Expand Up @@ -109,7 +114,7 @@

const handleConnectAndConfirm = async () => {
if (!selectedAccount) {
console.error('No account selected');

Check warning on line 117 in src/app/components/confirmBtcTransaction/index.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
return;
}
setIsButtonDisabled(true);
Expand All @@ -130,7 +135,7 @@
try {
onConfirm(transport);
} catch (err) {
console.error(err);

Check warning on line 138 in src/app/components/confirmBtcTransaction/index.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
setIsTxRejected(true);
}
};
Expand All @@ -146,7 +151,7 @@

return isLoading ? (
<LoaderContainer>
<MoonLoader color="white" size={50} />
<Spinner size={50} />
</LoaderContainer>
) : (
<>
Expand All @@ -168,6 +173,7 @@
isPartialTransaction={isPartialTransaction}
getFeeForFeeRate={getFeeForFeeRate}
onFeeRateSet={onFeeRateSet}
feeRate={feeRate}
isSubmitting={isSubmitting}
/>
{!isLoading && (
Expand Down
60 changes: 52 additions & 8 deletions src/app/components/confirmBtcTransaction/transactionSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,28 @@ import useWalletSelector from '@hooks/useWalletSelector';

import AssetModal from '@components/assetModal';
import TransferFeeView from '@components/transferFeeView';
import { btcTransaction } from '@secretkeylabs/xverse-core';
import useBtcFeeRate from '@hooks/useBtcFeeRate';
import { btcTransaction, getBtcFiatEquivalent } from '@secretkeylabs/xverse-core';
import SelectFeeRate from '@ui-components/selectFeeRate';
import Callout from '@ui-library/callout';
import { BLOG_LINK } from '@utils/constants';
import BigNumber from 'bignumber.js';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import AmountWithInscriptionSatribute from './itemRow/amountWithInscriptionSatribute';
import ReceiveSection from './receiveSection';
import TransferSection from './transferSection';
import TxInOutput from './txInOutput/txInOutput';
import { getNetAmount, isScriptOutput, isSpendOutput } from './utils';

const Container = styled.div((props) => ({
background: props.theme.colors.elevation1,
borderRadius: 12,
padding: '12px 16px',
marginBottom: 12,
}));

const ScriptCallout = styled(Callout)`
margin-bottom: ${(props) => props.theme.space.s};
`;
Expand All @@ -32,12 +42,12 @@ type Props = {
inputs: btcTransaction.EnhancedInput[];
outputs: btcTransaction.EnhancedOutput[];
feeOutput?: btcTransaction.TransactionFeeOutput;

// TODO: these are for txn screens which we will tackle next
// TODO: By having these as generic props here, we can use the generic set fee rate component for all use cases
getFeeForFeeRate?: (feeRate: number, useEffectiveFeeRate?: boolean) => Promise<number>;
getFeeForFeeRate?: (
feeRate: number,
useEffectiveFeeRate?: boolean,
) => Promise<number | undefined>;
onFeeRateSet?: (feeRate: number) => void;
// TODO: use this to disable the edit fee component when it is created
feeRate?: number;
isSubmitting?: boolean;
};

Expand All @@ -49,15 +59,19 @@ function TransactionSummary({
isSubmitting,
getFeeForFeeRate,
onFeeRateSet,
feeRate,
}: Props) {
const [inscriptionToShow, setInscriptionToShow] = useState<
btcTransaction.IOInscription | undefined
>(undefined);

const { network } = useWalletSelector();
const { network, fiatCurrency, btcFiatRate } = useWalletSelector();
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
const { t: rareSatsT } = useTranslation('translation', { keyPrefix: 'RARE_SATS' });
const { t: tUnits } = useTranslation('translation', { keyPrefix: 'UNITS' });

const { btcAddress, ordinalsAddress } = useWalletSelector();
const { data: recommendedFees } = useBtcFeeRate();

const hasOutputScript = outputs.some((output) => isScriptOutput(output));

Expand Down Expand Up @@ -85,6 +99,11 @@ function TransactionSummary({
const feesHaveInscribedRareSats = feeOutput?.inscriptions.length || feeOutput?.satributes.length;
const showInscribeRareSatWarning = paymentHasInscribedRareSats || feesHaveInscribedRareSats;

const satsToFiat = (sats: string) =>
getBtcFiatEquivalent(new BigNumber(sats), new BigNumber(btcFiatRate)).toNumber().toFixed(2);

const showFeeSelector = !!(feeRate && getFeeForFeeRate && onFeeRateSet);

return (
<>
{inscriptionToShow && (
Expand Down Expand Up @@ -131,7 +150,7 @@ function TransactionSummary({

<TransactionDetailComponent title={t('NETWORK')} value={network.type} />

{feeOutput && (
{feeOutput && !showFeeSelector && (
<TransferFeeView
fee={new BigNumber(feeOutput.amount)}
currency={t('SATS')}
Expand All @@ -140,6 +159,31 @@ function TransactionSummary({
onShowInscription={setInscriptionToShow}
/>
)}
{feeOutput && showFeeSelector && (
<Container>
<SelectFeeRate
fee={feeOutput.amount.toString()}
feeUnits="Sats"
feeRate={feeRate.toString()}
feeRateUnits={tUnits('SATS_PER_VB')}
setFeeRate={(newFeeRate) => onFeeRateSet(+newFeeRate)}
baseToFiat={satsToFiat}
fiatUnit={fiatCurrency}
getFeeForFeeRate={getFeeForFeeRate}
feeRates={{
medium: recommendedFees?.regular,
high: recommendedFees?.priority,
}}
feeRateLimits={recommendedFees?.limits}
isLoading={isSubmitting}
/>
<AmountWithInscriptionSatribute
inscriptions={feeOutput.inscriptions}
satributes={feeOutput.satributes}
onShowInscription={setInscriptionToShow}
/>
</Container>
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ function TransferSection({
satributesFromPayment.push(...item.satributes);
});

const hasData =
showAmount ||
(isPartialTransaction && inputFromOrdinal.length > 0) ||
outputsFromOrdinal.length > 0;

if (!hasData) return null;

return (
<Container>
<Header spaceBetween>
Expand Down
7 changes: 4 additions & 3 deletions src/app/components/speedUpTransaction/btc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function SpeedUpBtcTransaction({
isBroadcasting,
}: Props) {
const { t } = useTranslation('translation', { keyPrefix: 'SPEED_UP_TRANSACTION' });
const { t: tUnits } = useTranslation('translation', { keyPrefix: 'UNITS' });
const { btcFiatRate, fiatCurrency } = useWalletSelector();
const theme = useTheme();

Expand All @@ -91,7 +92,7 @@ function SpeedUpBtcTransaction({
value={rbfTxSummary?.currentFeeRate}
displayType="text"
thousandSeparator
suffix=" Sats /vB"
suffix={` ${tUnits('SATS_PER_VB')}`}
/>
</HighlightedText>
</DetailText>
Expand Down Expand Up @@ -124,7 +125,7 @@ function SpeedUpBtcTransaction({
value={obj.feeRate}
displayType="text"
thousandSeparator
suffix=" Sats /vByte"
suffix={` ${tUnits('SATS_PER_VB')}`}
/>
</SecondaryText>
</div>
Expand Down Expand Up @@ -179,7 +180,7 @@ function SpeedUpBtcTransaction({
value={customFeeRate}
displayType="text"
thousandSeparator
suffix=" Sats /vByte"
suffix={` ${tUnits('SATS_PER_VB')}`}
/>
</SecondaryText>
</>
Expand Down
5 changes: 3 additions & 2 deletions src/app/components/transactionSetting/editBtcFee.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ function EditBtcFee({
feeOptionSelected,
}: Props) {
const { t } = useTranslation('translation');

const { network, btcAddress, btcFiatRate, fiatCurrency, selectedAccount, ordinalsAddress } =
useWalletSelector();
const [totalFee, setTotalFee] = useState(fee);
Expand Down Expand Up @@ -389,12 +390,12 @@ function EditBtcFee({
value={feeRateInput?.toString()}
onChange={onInputEditFeesChange}
/>
<FeeText>Sats /vByte</FeeText>
<FeeText>{t('UNITS.SATS_PER_VB')}</FeeText>
</InputContainer>
<CustomTextsContainer>
<Row>
<TotalFeeText typography="body_medium_m" color="white_200">
{t('TRANSACTION_SETTING.TOTAL_FEE')}
{t('TRANSACTION_SETTING.TOTAL_FEE')}:
</TotalFeeText>
<NumericFormat
value={totalFee}
Expand Down
Loading
Loading