Skip to content

Commit

Permalink
Merge pull request #5264 from leather-wallet/release/signer-fix
Browse files Browse the repository at this point in the history
Release - Signer Fix
  • Loading branch information
kyranjamie authored Apr 18, 2024
2 parents 399e552 + b3109ed commit e9c8503
Show file tree
Hide file tree
Showing 30 changed files with 714 additions and 293 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ export function determineUtxosForSpendAllMultipleRecipients({
});

// Fee has already been deducted from the amount with send all
const outputs = recipients.map(({ address, amount }) => ({ value: BigInt(amount), address }));
const outputs = recipients.map(({ address, amount }) => ({
value: BigInt(amount.amount.toNumber()),
address,
}));

const fee = Math.ceil(sizeInfo.txVBytes * feeRate);

Expand Down Expand Up @@ -190,7 +193,10 @@ export function determineUtxosForSpendMultipleRecipients({
address?: string;
}[] = [
// outputs[0] = the desired amount going to recipient
...recipients.map(({ address, amount }) => ({ value: BigInt(amount), address })),
...recipients.map(({ address, amount }) => ({
value: BigInt(amount.amount.toNumber()),
address,
})),
// outputs[recipients.length] = the remainder to be returned to a change address
{ value: sum - BigInt(amount) - BigInt(fee) },
];
Expand Down
16 changes: 16 additions & 0 deletions src/app/components/account/bitcoin-account-loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { useConfigBitcoinEnabled } from '@app/query/common/remote-config/remote-
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { Signer } from '@app/store/accounts/blockchain/bitcoin/bitcoin-signer';
import { useNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useTaprootSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';

interface BitcoinAccountLoaderBaseProps {
children(account: Signer<P2Ret>): React.ReactNode;
Expand All @@ -29,3 +31,17 @@ export function BitcoinNativeSegwitAccountLoader({ children, ...props }: BtcAcco
if (!signer || !isBitcoinEnabled) return null;
return children(signer(0));
}

export function BitcoinTaprootAccountLoader({ children, ...props }: BtcAccountLoaderProps) {
const isBitcoinEnabled = useConfigBitcoinEnabled();
const network = useCurrentNetwork();

const currentAccountIndex = useCurrentAccountIndex();

const properIndex = 'current' in props ? currentAccountIndex : props.index;

const signer = useTaprootSigner(properIndex, network.chain.bitcoin.bitcoinNetwork);

if (!signer || !isBitcoinEnabled) return null;
return children(signer(0));
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ export function RunesAssetItemLayout({ rune }: RunesAssetItemLayoutProps) {
<Pressable my="space.02">
<ItemLayout
flagImg={<RunesAvatarIcon />}
titleLeft={rune.rune_name.toUpperCase()}
captionLeft="RUNE"
titleLeft={rune.spaced_rune_name ?? rune.rune_name}
captionLeft="Runes"
titleRight={
<BasicTooltip
asChild
label={formattedBalance.isAbbreviated ? balance : undefined}
side="left"
>
<styled.span data-testid={rune.rune_name} fontWeight={500} textStyle="label.02">
{formattedBalance.value}
{formattedBalance.value} {rune.symbol}
</styled.span>
</BasicTooltip>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ interface RunesAssetListProps {
runes: RuneToken[];
}
export function RunesAssetList({ runes }: RunesAssetListProps) {
return runes.map(rune => <RunesAssetItemLayout key={rune.rune_id} rune={rune} />);
return runes.map((rune, i) => <RunesAssetItemLayout key={`${rune.rune_id}${i}`} rune={rune} />);
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ export function CryptoCurrencyAssetItemLayout({

const captionRight = (
<SkeletonLoader width="78px" isLoading={isLoading}>
{rightElement ? (
rightElement
) : (
{!rightElement && (
<Caption>
<Flex alignItems="center" gap="space.02" color="inherit">
<BulletSeparator>
Expand Down
6 changes: 2 additions & 4 deletions src/app/components/loaders/runes-loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ interface RunesLoaderProps {
children(runes: RuneToken[]): React.ReactNode;
}
export function RunesLoader({ addresses, children }: RunesLoaderProps) {
const runes = useRuneTokens(addresses)
.flatMap(query => query.data)
.filter(isDefined);
return children(runes);
const runes = useRuneTokens(addresses);
return children(runes.filter(isDefined));
}
27 changes: 16 additions & 11 deletions src/app/features/asset-list/asset-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import { Stack } from 'leather-styles/jsx';

import { useBtcAssetBalance } from '@app/common/hooks/balance/btc/use-btc-balance';
import { useWalletType } from '@app/common/use-wallet-type';
import {
BitcoinNativeSegwitAccountLoader,
BitcoinTaprootAccountLoader,
} from '@app/components/account/bitcoin-account-loader';
import { BitcoinContractEntryPoint } from '@app/components/bitcoin-contract-entry-point/bitcoin-contract-entry-point';
import { CryptoCurrencyAssetItemLayout } from '@app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.layout';
import { CurrentStacksAccountLoader } from '@app/components/loaders/stacks-account-loader';
import { useHasBitcoinLedgerKeychain } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger';
import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentAccountTaprootIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
import { BtcAvatarIcon } from '@app/ui/components/avatar/btc-avatar-icon';

Expand All @@ -25,7 +28,6 @@ import { StacksFungibleTokenAssetList } from './components/stacks-fungible-token
export function AssetsList() {
const hasBitcoinLedgerKeys = useHasBitcoinLedgerKeychain();
const bitcoinAddressNativeSegwit = useCurrentAccountNativeSegwitAddressIndexZero();
const { address: bitcoinAddressTaproot } = useCurrentAccountTaprootIndexZeroSigner();
const network = useCurrentNetwork();

const { btcAvailableAssetBalance, btcAvailableUsdBalance, isInitialLoading } = useBtcAssetBalance(
Expand Down Expand Up @@ -76,15 +78,18 @@ export function AssetsList() {
)}
</CurrentStacksAccountLoader>

{whenWallet({
software: (
<BitcoinFungibleTokenAssetList
btcAddressNativeSegwit={bitcoinAddressNativeSegwit}
btcAddressTaproot={bitcoinAddressTaproot}
/>
),
ledger: null,
})}
<BitcoinNativeSegwitAccountLoader current>
{nativeSegwitAccount => (
<BitcoinTaprootAccountLoader current>
{taprootAccount => (
<BitcoinFungibleTokenAssetList
btcAddressNativeSegwit={nativeSegwitAccount.address}
btcAddressTaproot={taprootAccount.address}
/>
)}
</BitcoinTaprootAccountLoader>
)}
</BitcoinNativeSegwitAccountLoader>

<PendingBrc20TransferList />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { HStack, Stack, styled } from 'leather-styles/jsx';

import type { Money } from '@shared/models/money.model';

import { formatMoney } from '@app/common/money/format-money';

interface SendTransferConfirmationDetailsProps {
currentAddress: string;
recipient: string;
time: string;
total: string;
feeRowValue: string;
amount: Money;
}
export function SendTransferConfirmationDetails({
currentAddress,
recipient,
time,
total,
feeRowValue,
amount,
}: SendTransferConfirmationDetailsProps) {
return (
<Stack border="active" borderRadius="sm" p="space.05" gap="space.04" width="100%">
Expand All @@ -25,19 +25,9 @@ export function SendTransferConfirmationDetails({
<styled.span>{recipient}</styled.span>
</HStack>
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Fee</styled.span>
<styled.span>{feeRowValue}</styled.span>
</HStack>
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Total</styled.span>
<styled.span>{total}</styled.span>
<styled.span color="ink.text-subdued">Amount</styled.span>
<styled.span>{formatMoney(amount)}</styled.span>
</HStack>
{time && (
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Estimated Time</styled.span>
<styled.span>{time}</styled.span>
</HStack>
)}
</Stack>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HStack, Stack, styled } from 'leather-styles/jsx';

import type { RpcSendTransferRecipient } from '@shared/rpc/methods/send-transfer';

import { formatMoney } from '@app/common/money/format-money';
import { truncateMiddle } from '@app/ui/utils/truncate-middle';

interface SendTransferDetailsProps {
Expand Down Expand Up @@ -31,7 +32,7 @@ export function SendTransferDetails({ recipients, currentAddress }: SendTransfer
</HStack>
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span textStyle="caption.01">Amount</styled.span>
<styled.span textStyle="label.01">{amount}</styled.span>
<styled.span textStyle="label.01">{formatMoney(amount)}</styled.span>
</HStack>
</Stack>
))}
Expand Down
57 changes: 35 additions & 22 deletions src/app/pages/rpc-send-transfer/rpc-send-transfer-confirmation.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { useLocation, useNavigate } from 'react-router-dom';

import { Stack } from 'leather-styles/jsx';
import { HStack, Stack, styled } from 'leather-styles/jsx';
import get from 'lodash.get';

import { decodeBitcoinTx } from '@shared/crypto/bitcoin/bitcoin.utils';
import { logger } from '@shared/logger';
import { CryptoCurrencies } from '@shared/models/currencies.model';
import { createMoney, createMoneyFromDecimal } from '@shared/models/money.model';
import { createMoney } from '@shared/models/money.model';
import { RouteUrls } from '@shared/route-urls';
import type { RpcSendTransferRecipient } from '@shared/rpc/methods/send-transfer';
import { makeRpcSuccessResponse } from '@shared/rpc/rpc-methods';

import { useAnalytics } from '@app/common/hooks/analytics/use-analytics';
import { baseCurrencyAmountInQuote } from '@app/common/money/calculate-money';
import { formatMoney, formatMoneyPadded, i18nFormatCurrency } from '@app/common/money/format-money';
import { satToBtc } from '@app/common/money/unit-conversion';
import { baseCurrencyAmountInQuote, sumMoney } from '@app/common/money/calculate-money';
import {
formatMoney,
formatMoneyPadded,
formatMoneyWithoutSymbol,
i18nFormatCurrency,
} from '@app/common/money/format-money';
import { InfoCardFooter } from '@app/components/info-card/info-card';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { useBitcoinBroadcastTransaction } from '@app/query/bitcoin/transaction/use-bitcoin-broadcast-transaction';
Expand Down Expand Up @@ -50,17 +54,12 @@ export function RpcSendTransferConfirmation() {
const btcMarketData = useCryptoCurrencyMarketData('BTC');

const psbt = decodeBitcoinTx(tx);
const transferAmount = satToBtc(psbt.outputs[0].amount.toString()).toString();
const txFiatValue = i18nFormatCurrency(
baseCurrencyAmountInQuote(createMoneyFromDecimal(Number(transferAmount), symbol), btcMarketData)
);
const transferAmount = sumMoney(recipients.map(r => r.amount));
const txFiatValue = i18nFormatCurrency(baseCurrencyAmountInQuote(transferAmount, btcMarketData));
const txFiatValueSymbol = btcMarketData.price.symbol;
const feeInBtc = satToBtc(fee);
const summaryFee = formatMoneyPadded(createMoney(Number(fee), symbol));
const sendingValue = formatMoney(createMoneyFromDecimal(Number(transferAmount), symbol));
const totalSpend = formatMoney(
createMoneyFromDecimal(Number(transferAmount) + Number(feeInBtc), symbol)
);
const feeMoney = createMoney(Number(fee), symbol);
const summaryFee = formatMoneyPadded(feeMoney);
const totalSpend = sumMoney([transferAmount, feeMoney]);

function formBtcTxSummaryState(txId: string) {
return {
Expand All @@ -71,11 +70,11 @@ export function RpcSendTransferConfirmation() {
txId,
recipients,
fee: summaryFee,
txValue: transferAmount,
txValue: formatMoneyWithoutSymbol(transferAmount),
arrivesIn: time,
totalSpend,
totalSpend: formatMoney(totalSpend),
symbol,
sendingValue,
sendingValue: formatMoney(transferAmount),
txFiatValue,
txFiatValueSymbol,
feeRowValue,
Expand Down Expand Up @@ -121,17 +120,31 @@ export function RpcSendTransferConfirmation() {

return (
<>
<Stack gap={4} width="100%">
<Stack width="100%" gap={4} height="100%" pb="100px">
{recipients.map((recipient, index) => (
<SendTransferConfirmationDetails
key={index}
currentAddress={truncateMiddle(bitcoinAddress)}
recipient={truncateMiddle(recipient.address)}
time={time}
total={totalSpend}
feeRowValue={feeRowValue}
amount={recipient.amount}
/>
))}
<Stack border="active" borderRadius="sm" p="space.05" gap="space.04" width="100%">
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Fee</styled.span>
<styled.span>{feeRowValue}</styled.span>
</HStack>
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Total amount</styled.span>
<styled.span>{formatMoney(totalSpend)}</styled.span>
</HStack>
{time && (
<HStack alignItems="center" gap="space.04" justifyContent="space-between">
<styled.span color="ink.text-subdued">Estimated time</styled.span>
<styled.span>{time}</styled.span>
</HStack>
)}
</Stack>
</Stack>

<InfoCardFooter>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/rpc-send-transfer/use-rpc-send-transfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function useRpcSendTransfer() {

const recipients = recipientsAddresses.map((address, index) => ({
address,
amount: amounts[index],
amount: createMoney(Number(amounts[index]), 'BTC'),
}));

return {
Expand Down
Loading

0 comments on commit e9c8503

Please sign in to comment.