refactor: psbt ui inputs query

This commit is contained in:
fbwoolf
2023-06-14 08:18:47 -05:00
committed by Fara Woolf
parent 38afa40453
commit f320e8455c
17 changed files with 278 additions and 89 deletions

View File

@@ -3,7 +3,10 @@ import { BitcoinTransactionItem } from '@app/features/activity-list/components/t
import { StacksTransaction } from './stacks-transaction/stacks-transaction';
import { TransactionListTxs } from './transaction-list.model';
function renderTransaction(tx: TransactionListTxs) {
interface TransactionListItemProps {
tx: TransactionListTxs;
}
export function TransactionListItem({ tx }: TransactionListItemProps) {
switch (tx.blockchain) {
case 'bitcoin':
return <BitcoinTransactionItem transaction={tx.transaction} />;
@@ -13,10 +16,3 @@ function renderTransaction(tx: TransactionListTxs) {
return null;
}
}
interface TransactionListItemProps {
tx: TransactionListTxs;
}
export function TransactionListItem({ tx }: TransactionListItemProps) {
return renderTransaction(tx);
}

View File

@@ -1,5 +1,10 @@
import * as btc from '@scure/btc-signer';
import {
PsbtDecodedUtxosMainnet,
PsbtDecodedUtxosTestnet,
} from '@app/features/psbt-signer/hooks/use-psbt-decoded-utxos';
import { PsbtPlaceholderNode } from '../psbt-decoded-request-node/psbt-placeholder-node';
import { PsbtUnsignedInputList } from '../psbt-unsigned-input-list/psbt-unsigned-input-list';
import { PsbtUnsignedOutputList } from '../psbt-unsigned-output-list/psbt-unsigned-output-list';
@@ -7,16 +12,17 @@ import { PsbtUnsignedOutputList } from '../psbt-unsigned-output-list/psbt-unsign
interface PsbtDecodedRequestSimpleProps {
bitcoinAddressNativeSegwit: string;
bitcoinAddressTaproot: string;
inputs: btc.TransactionInputRequired[];
inputs: PsbtDecodedUtxosMainnet | PsbtDecodedUtxosTestnet;
outputs: btc.TransactionOutputRequired[];
showPlaceholder: boolean;
}
export function PsbtDecodedRequestSimple({
bitcoinAddressNativeSegwit,
bitcoinAddressTaproot,
inputs,
outputs,
showPlaceholder,
inputs,
}: PsbtDecodedRequestSimpleProps) {
if (showPlaceholder) return <PsbtPlaceholderNode />;

View File

@@ -24,6 +24,7 @@ export function PsbtDecodedRequest({ psbt }: PsbtDecodedRequestProps) {
shouldDefaultToAdvancedView,
shouldShowPlaceholder,
showAdvancedView,
unsignedUtxos,
} = usePsbtDecodedRequest({
unsignedInputs,
unsignedOutputs,
@@ -45,7 +46,7 @@ export function PsbtDecodedRequest({ psbt }: PsbtDecodedRequestProps) {
<PsbtDecodedRequestSimple
bitcoinAddressNativeSegwit={nativeSegwitSigner.address}
bitcoinAddressTaproot={bitcoinAddressTaproot}
inputs={unsignedInputs}
inputs={unsignedUtxos}
outputs={unsignedOutputs}
showPlaceholder={shouldShowPlaceholder}
/>

View File

@@ -0,0 +1,49 @@
import { truncateMiddle } from '@stacks/ui-utils';
import { logger } from '@shared/logger';
import { i18nFormatCurrency } from '@app/common/money/format-money';
import { satToBtc } from '@app/common/money/unit-conversion';
import { OrdApiInscriptionTxOutput } from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
import { TaprootUtxo } from '@app/query/bitcoin/ordinals/use-taproot-address-utxos.query';
import { useCalculateBitcoinFiatValue } from '@app/query/common/market-data/market-data.hooks';
import { PsbtDecodedNodeLayout } from '../../psbt-decoded-request-node/psbt-decoded-node.layout';
import { PsbtUnsignedInputWithInscription } from './psbt-unsigned-input-with-inscription';
interface PsbtUnsignedInputItemWithPossibleInscriptionProps {
addressNativeSegwit: string;
addressTaproot: string;
utxo: TaprootUtxo & OrdApiInscriptionTxOutput;
}
export function PsbtUnsignedInputItemWithPossibleInscription({
addressNativeSegwit,
addressTaproot,
utxo,
}: PsbtUnsignedInputItemWithPossibleInscriptionProps) {
const calculateBitcoinFiatValue = useCalculateBitcoinFiatValue();
const isInputCurrentAddress =
utxo.address === addressNativeSegwit || utxo.address === addressTaproot;
const inputValue = satToBtc(utxo.value).toString();
if (!utxo.address) {
logger.error('UTXO does not have an address');
return null;
}
return utxo.inscriptions ? (
<PsbtUnsignedInputWithInscription
address={utxo.address}
inputValue={inputValue}
path={utxo.inscriptions}
/>
) : (
<PsbtDecodedNodeLayout
hoverLabel={utxo.address}
subtitle={truncateMiddle(utxo.address)}
subValue={i18nFormatCurrency(calculateBitcoinFiatValue(inputValue))}
value={`${isInputCurrentAddress ? '-' : '+'}${inputValue}`}
/>
);
}

View File

@@ -1,18 +1,17 @@
import { truncateMiddle } from '@stacks/ui-utils';
import { BitcoinTransactionVectorOutput } from '@shared/models/transactions/bitcoin-transaction.model';
import { i18nFormatCurrency } from '@app/common/money/format-money';
import { satToBtc } from '@app/common/money/unit-conversion';
import { OrdApiInscriptionTxOutput } from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
import { TaprootUtxo } from '@app/query/bitcoin/ordinals/use-taproot-address-utxos.query';
import { useCalculateBitcoinFiatValue } from '@app/query/common/market-data/market-data.hooks';
import { PsbtDecodedNodeLayout } from '../../psbt-decoded-request-node/psbt-decoded-node.layout';
import { PsbtUnsignedInputWithInscription } from './psbt-unsigned-input-with-inscription';
interface PsbtUnsignedInputItemProps {
addressNativeSegwit: string;
addressTaproot: string;
utxo: TaprootUtxo & OrdApiInscriptionTxOutput;
utxo: BitcoinTransactionVectorOutput;
}
export function PsbtUnsignedInputItem({
addressNativeSegwit,
@@ -22,24 +21,15 @@ export function PsbtUnsignedInputItem({
const calculateBitcoinFiatValue = useCalculateBitcoinFiatValue();
const isInputCurrentAddress =
utxo.address === addressNativeSegwit || utxo.address === addressTaproot;
utxo.scriptpubkey_address === addressNativeSegwit ||
utxo.scriptpubkey_address === addressTaproot;
const inputValue = satToBtc(utxo.value).toString();
const fiatValue = i18nFormatCurrency(calculateBitcoinFiatValue(utxo.value));
const inscription = utxo.inscriptions;
if (!utxo.address) return null;
return inscription ? (
<PsbtUnsignedInputWithInscription
address={utxo.address}
inputValue={inputValue}
path={inscription}
/>
) : (
return (
<PsbtDecodedNodeLayout
hoverLabel={utxo.address}
subtitle={truncateMiddle(utxo.address)}
subValue={`${fiatValue} USD`}
hoverLabel={utxo.scriptpubkey_address}
subtitle={truncateMiddle(utxo.scriptpubkey_address)}
subValue={i18nFormatCurrency(calculateBitcoinFiatValue(inputValue))}
value={`${isInputCurrentAddress ? '-' : '+'}${inputValue}`}
/>
);

View File

@@ -0,0 +1,12 @@
import { Box, Text } from '@stacks/ui';
import { HasChildren } from '@app/common/has-children';
export function PsbtUnsignedInputListLayout({ children }: HasChildren) {
return (
<Box background="white" borderTopLeftRadius="16px" borderTopRightRadius="16px" p="loose">
<Text fontWeight={500}>Inputs</Text>
{children}
</Box>
);
}

View File

@@ -1,40 +1,62 @@
import * as btc from '@scure/btc-signer';
import { Box, Text } from '@stacks/ui';
import { isUndefined } from '@shared/utils';
import { useOrdinalsAwareUtxoQueries } from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
import {
PsbtDecodedUtxosMainnet,
PsbtDecodedUtxosTestnet,
} from '@app/features/psbt-signer/hooks/use-psbt-decoded-utxos';
import { PsbtDecodedNodeLayout } from '../psbt-decoded-request-node/psbt-decoded-node.layout';
import { PsbtUnsignedInputItem } from './components/psbt-unsigned-input-item';
import { PsbtUnsignedInputItemWithPossibleInscription } from './components/psbt-unsigned-input-item-with-possible-inscription';
import { PsbtUnsignedInputListLayout } from './components/psbt-unsigned-input-list.layout';
interface PsbtUnsignedInputListProps {
addressNativeSegwit: string;
addressTaproot: string;
inputs: btc.TransactionInputRequired[];
inputs: PsbtDecodedUtxosMainnet | PsbtDecodedUtxosTestnet;
}
export function PsbtUnsignedInputList({
addressNativeSegwit,
addressTaproot,
inputs,
}: PsbtUnsignedInputListProps) {
const unsignedUtxos = useOrdinalsAwareUtxoQueries(inputs).map(query => query.data);
if (!inputs.utxos.length)
return (
<PsbtUnsignedInputListLayout>
<PsbtDecodedNodeLayout value="No inputs found" />
</PsbtUnsignedInputListLayout>
);
return (
<Box background="white" borderTopLeftRadius="16px" borderTopRightRadius="16px" p="loose">
<Text fontWeight={500}>Inputs</Text>
{unsignedUtxos.map(utxo => {
if (isUndefined(utxo)) return <PsbtDecodedNodeLayout value="No input data found" />;
return (
<PsbtUnsignedInputItem
addressNativeSegwit={addressNativeSegwit}
addressTaproot={addressTaproot}
key={utxo.transaction}
utxo={utxo}
/>
);
})}
</Box>
);
switch (inputs.network) {
case 'mainnet':
return (
<PsbtUnsignedInputListLayout>
{inputs.utxos.map((utxo, i) => {
return (
<PsbtUnsignedInputItemWithPossibleInscription
addressNativeSegwit={addressNativeSegwit}
addressTaproot={addressTaproot}
key={i}
utxo={utxo}
/>
);
})}
</PsbtUnsignedInputListLayout>
);
case 'testnet':
return (
<PsbtUnsignedInputListLayout>
{inputs.utxos.map((utxo, i) => {
return (
<PsbtUnsignedInputItem
addressNativeSegwit={addressNativeSegwit}
addressTaproot={addressTaproot}
key={i}
utxo={utxo}
/>
);
})}
</PsbtUnsignedInputListLayout>
);
default:
return null;
}
}

View File

@@ -33,7 +33,7 @@ export function PsbtUnsignedOutputItem({
<PsbtDecodedNodeLayout
hoverLabel={addressFromScript}
subtitle={truncateMiddle(addressFromScript)}
subValue={`${i18nFormatCurrency(calculateBitcoinFiatValue(outputValue))} USD`}
subValue={i18nFormatCurrency(calculateBitcoinFiatValue(outputValue))}
value={`${isOutputCurrentAddress ? '+' : ' '}${outputValue}`}
/>
);

View File

@@ -0,0 +1,12 @@
import { Box, Text } from '@stacks/ui';
import { HasChildren } from '@app/common/has-children';
export function PsbtUnsignedOutputListLayout({ children }: HasChildren) {
return (
<Box background="white" borderTopLeftRadius="16px" borderTopRightRadius="16px" p="loose">
<Text fontWeight={500}>Outputs</Text>
{children}
</Box>
);
}

View File

@@ -1,7 +1,8 @@
import * as btc from '@scure/btc-signer';
import { Box, Text } from '@stacks/ui';
import { PsbtDecodedNodeLayout } from '../psbt-decoded-request-node/psbt-decoded-node.layout';
import { PsbtUnsignedOutputItem } from './components/psbt-unsigned-output-item';
import { PsbtUnsignedOutputListLayout } from './components/psbt-unsigned-output-list.layout';
interface PsbtUnsignedOutputListProps {
addressNativeSegwit: string;
@@ -13,9 +14,15 @@ export function PsbtUnsignedOutputList({
addressTaproot,
outputs,
}: PsbtUnsignedOutputListProps) {
if (!outputs.length)
return (
<PsbtUnsignedOutputListLayout>
<PsbtDecodedNodeLayout value="No outputs found" />
</PsbtUnsignedOutputListLayout>
);
return (
<Box background="white" borderBottomLeftRadius="16px" borderBottomRightRadius="16px" p="loose">
<Text fontWeight={500}>Outputs</Text>
<PsbtUnsignedOutputListLayout>
{outputs.map((output, i) => {
return (
<PsbtUnsignedOutputItem
@@ -26,6 +33,6 @@ export function PsbtUnsignedOutputList({
/>
);
})}
</Box>
</PsbtUnsignedOutputListLayout>
);
}

View File

@@ -4,29 +4,41 @@ import * as btc from '@scure/btc-signer';
import { BitcoinNetworkModes } from '@shared/constants';
import { getAddressFromOutScript } from '@shared/crypto/bitcoin/bitcoin.utils';
import { isUndefined } from '@shared/utils';
import {
OrdApiInscriptionTxOutput,
useOrdinalsAwareUtxoQueries,
} from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
import {
PsbtDecodedUtxosMainnet,
PsbtDecodedUtxosTestnet,
usePsbtDecodedUtxos,
} from './use-psbt-decoded-utxos';
function isPlaceholderTransaction(
address: string,
inputs: (OrdApiInscriptionTxOutput | undefined)[],
outputs: btc.TransactionOutputRequired[],
network: BitcoinNetworkModes
network: BitcoinNetworkModes,
unsignedOutputs: btc.TransactionOutputRequired[],
unsignedUtxos: PsbtDecodedUtxosMainnet | PsbtDecodedUtxosTestnet
) {
const inputsNotFromCurrentAddress = inputs.filter(input => {
return input?.address !== address;
});
const outputsNotToCurrentAddress = outputs.filter(output => {
let utxosNotFromCurrentAddress = [];
switch (unsignedUtxos.network) {
case 'mainnet':
utxosNotFromCurrentAddress = unsignedUtxos.utxos.filter(utxo => utxo.address !== address);
break;
case 'testnet':
utxosNotFromCurrentAddress = unsignedUtxos.utxos.filter(
vo => vo.scriptpubkey_address !== address
);
break;
}
const outputsNotToCurrentAddress = unsignedOutputs.filter(output => {
const addressFromScript = getAddressFromOutScript(output.script, network);
return addressFromScript !== address;
});
return inputsNotFromCurrentAddress.length === 0 && outputsNotToCurrentAddress.length === 0;
return utxosNotFromCurrentAddress.length === 0 && outputsNotToCurrentAddress.length === 0;
}
interface UsePsbtDecodedRequestArgs {
@@ -40,20 +52,20 @@ export function usePsbtDecodedRequest({
const [showAdvancedView, setShowAdvancedView] = useState(false);
const network = useCurrentNetwork();
const nativeSegwitSigner = useCurrentAccountNativeSegwitIndexZeroSigner();
const unsignedUtxos = useOrdinalsAwareUtxoQueries(unsignedInputs).map(query => query.data);
const unsignedUtxos = usePsbtDecodedUtxos(unsignedInputs);
const defaultToAdvancedView = useCallback(() => {
const noInputs = isUndefined(unsignedUtxos) || !unsignedUtxos.length;
const noOutputs = isUndefined(unsignedOutputs) || !unsignedOutputs.length;
const noInputs = !unsignedInputs.length;
const noOutputs = !unsignedOutputs.length;
return noInputs || noOutputs;
}, [unsignedOutputs, unsignedUtxos]);
}, [unsignedInputs.length, unsignedOutputs.length]);
const showPlaceholder = useCallback(() => {
return isPlaceholderTransaction(
nativeSegwitSigner.address,
unsignedUtxos,
network.chain.bitcoin.network,
unsignedOutputs,
network.chain.bitcoin.network
unsignedUtxos
);
}, [nativeSegwitSigner.address, network.chain.bitcoin.network, unsignedOutputs, unsignedUtxos]);
@@ -62,5 +74,6 @@ export function usePsbtDecodedRequest({
shouldDefaultToAdvancedView: defaultToAdvancedView(),
shouldShowPlaceholder: showPlaceholder(),
showAdvancedView,
unsignedUtxos,
};
}

View File

@@ -0,0 +1,44 @@
import * as btc from '@scure/btc-signer';
import { WalletDefaultNetworkConfigurationIds } from '@shared/constants';
import { BitcoinTransactionVectorOutput } from '@shared/models/transactions/bitcoin-transaction.model';
import { isDefined } from '@shared/utils';
import {
OrdApiInscriptionTxOutput,
useOrdinalsAwareUtxoQueries,
} from '@app/query/bitcoin/ordinals/ordinals-aware-utxo.query';
import { TaprootUtxo } from '@app/query/bitcoin/ordinals/use-taproot-address-utxos.query';
import { useGetBitcoinTransactionQueries } from '@app/query/bitcoin/transaction/transaction.query';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
export interface PsbtDecodedUtxosMainnet {
network: WalletDefaultNetworkConfigurationIds.mainnet;
utxos: (TaprootUtxo & OrdApiInscriptionTxOutput)[];
}
export interface PsbtDecodedUtxosTestnet {
network: WalletDefaultNetworkConfigurationIds.testnet;
utxos: BitcoinTransactionVectorOutput[];
}
export function usePsbtDecodedUtxos(
unsignedInputs: btc.TransactionInputRequired[]
): PsbtDecodedUtxosMainnet | PsbtDecodedUtxosTestnet {
const network = useCurrentNetwork();
const unsignedUtxos = useGetBitcoinTransactionQueries(unsignedInputs)
.map(query => query.data)
.filter(isDefined)
.map((input, i) => input.vout[unsignedInputs[i].index]);
// Mainnet only enabled query
const unsignedUtxosWithInscriptions = useOrdinalsAwareUtxoQueries(unsignedInputs)
.map(query => query.data)
.filter(isDefined);
return network.chain.bitcoin.network === 'mainnet' && unsignedUtxosWithInscriptions.length
? {
network: WalletDefaultNetworkConfigurationIds.mainnet,
utxos: unsignedUtxosWithInscriptions,
}
: { network: WalletDefaultNetworkConfigurationIds.testnet, utxos: unsignedUtxos };
}

View File

@@ -7,6 +7,7 @@ import { isTypedArray } from '@shared/utils';
import { Prettify } from '@shared/utils/type-utils';
import { QueryPrefixes } from '@app/query/query-prefixes';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';
import { TaprootUtxo } from './use-taproot-address-utxos.query';
@@ -58,11 +59,14 @@ const queryOptions = {
} as const;
export function useOrdinalsAwareUtxoQueries(utxos: TaprootUtxo[] | btc.TransactionInputRequired[]) {
const network = useCurrentNetwork();
return useQueries({
queries: utxos.map(utxo => {
const txId = isTypedArray(utxo.txid) ? bytesToHex(utxo.txid) : utxo.txid;
const txIndex = 'index' in utxo ? utxo.index : utxo.vout;
return {
enabled: network.chain.bitcoin.network === 'mainnet',
queryKey: makeOrdinalsAwareUtxoQueryKey(txId, txIndex),
queryFn: () => fetchOrdinalsAwareUtxo(txId, txIndex),
select: (resp: OrdApiInscriptionTxOutput) =>

View File

@@ -1,4 +1,8 @@
import { useQuery } from '@tanstack/react-query';
import * as btc from '@scure/btc-signer';
import { bytesToHex } from '@stacks/common';
import { UseQueryResult, useQueries, useQuery } from '@tanstack/react-query';
import { BitcoinTransaction } from '@shared/models/transactions/bitcoin-transaction.model';
import { AppUseQueryConfig } from '@app/query/query-config';
import { useBitcoinClient } from '@app/store/common/api-clients.hooks';
@@ -29,3 +33,26 @@ export function useGetBitcoinTransaction<T extends unknown = FetchBitcoinTransac
...options,
});
}
const queryOptions = {
cacheTime: Infinity,
staleTime: 15 * 60 * 1000,
refetchOnWindowFocus: false,
} as const;
export function useGetBitcoinTransactionQueries(
inputs: btc.TransactionInputRequired[]
): UseQueryResult<BitcoinTransaction>[] {
const client = useBitcoinClient();
return useQueries({
queries: inputs.map(input => {
const txId = bytesToHex(input.txid);
return {
queryKey: ['bitcoin-transaction', txId],
queryFn: () => fetchBitcoinTransaction(client)(txId),
...queryOptions,
};
}),
});
}

View File

@@ -7,6 +7,7 @@ import { CryptoCurrencies } from '@shared/models/currencies.model';
import { MarketData, createMarketData, createMarketPair } from '@shared/models/market.model';
import { createMoney, currencyDecimalsMap } from '@shared/models/money.model';
import { createMoneyFromDecimal } from '@shared/models/money.model';
import { isNumber } from '@shared/utils';
import { calculateMeanAverage } from '@app/common/math/calculate-averages';
import { convertAmountToFractionalUnit } from '@app/common/money/calculate-money';
@@ -58,8 +59,11 @@ export function useCalculateBitcoinFiatValue() {
const btcMarketData = useCryptoCurrencyMarketData('BTC');
return useCallback(
(value: string) =>
baseCurrencyAmountInQuote(createMoneyFromDecimal(Number(value), 'BTC'), btcMarketData),
(value: string | number) =>
baseCurrencyAmountInQuote(
createMoneyFromDecimal(isNumber(value) ? value : Number(value), 'BTC'),
btcMarketData
),
[btcMarketData]
);
}

View File

@@ -25,7 +25,7 @@ interface BitcoinTransactionStatus {
block_time: number | null;
}
interface BitcoinTransactionVectorOutput {
export interface BitcoinTransactionVectorOutput {
scriptpubkey: string;
scriptpubkey_asm: string;
scriptpubkey_type: string;

View File

@@ -23,6 +23,10 @@ const bitcoinTestnet: BitcoinNetwork = {
wif: 0xef,
};
// For testing mainnet
const tempHex =
'70736274ff0100fd36010200000004350db8bb43dc351cf4f611aab22363c1fcfb27c61f2f7e55f3e38a1384248c660100000000ffffffff8fcf2bcf05c76ef86595c3bbe2f944064b34eede0c4c3c5dce4f1f94e663183d0000000000ffffffff8391b15b124ad2276c13916a61efabbfcc34f4211b3e6123829eaeab8096b8420000000000ffffffffe4653717d3c1544b073f97978998558be6c8e8aa7e51922303ec4814551fa16e0000000000ffffffff041027000000000000225120e25ef2545bce7dd7bd4215cdc76d16fe72c63163dca3f7a0757efa928841c96b7c920000000000001600146a9d9d7679bfeaf45c3a7d5b88826ec657ea91e2c4090000000000001600146a9d9d7679bfeaf45c3a7d5b88826ec657ea91e2983a0000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52f00000000000100fdaa0301000000000102371586ae4679b5e411fced4b36ec421f65527447be8e3d0206419f979214fdf20000000000fdffffff5466bdc917b6a13f1db9429ee649a08b6b3860366e87202e0934d193e07a0d5b0100000000fdffffff02102700000000000022512044cab551f8178996c12870fcfd0399e3b0e4b9bb0312fc1c8b07b02e2dc17b0af92a0000000000002251207f4d47576eeaaa79a4cf320bf0b1876e50d943bdbbfc2823d99df37e642a37880140c6dff1e2084c2ae245c8b4b7751b9a5b1145f347d9d0ae06b8e2ec4591a2ab53fea2e5c6a356dfc6a54f51a7f15f1d1db8f056e8713842bfed58a1e063841c090341b00ba699988211aaa2e2464290bbc7db231765c5eaff65e0a7c2be27315093caa4009f2b302912f125d6bc28680bc1cfca7796647259e003a601f12683c1808081fd4c02204878d26dbb1678c06558222e1fd68e9ed68783fbb68d9f2bcb7ace09b225149dac0063036f726401032468eb6429a613f2564a36ce39589cda9ae404605267c4e0908c27ad1f144a0de900000000010117746578742f68746d6c3b636861727365743d7574662d38004dde013c626f64792f3e3c7363726970743e6a3d323b643d646f63756d656e743b623d642e626f64790a636c6173732055524c536561726368506172616d737b6765743d6b3d3e6b3d3d22746f6b656e4944223f6a3a307d286173796e6328293d3e7b713d225c6e220a6a3d393532302b282b617761697428617761697420666574636828222f636f6e74656e742f6463656538306631316133313034616233326633313665623763656466323839653436616531313533353362383165376432343362643431616462343734376669302229292e7465787428292b6a29253330300a69662869734e614e286a292972657475726e3b0a683d28617761697428617761697420666574636828222f636f6e74656e742f6539306434613134316661643237386339306530633436373532363030346534396164613963353833396365333634613536663231336136323936346562363869302229292e746578742829292e73706c69742871290a622e696e6e657248544d4c3d685b305d3b0a7a3d646f63756d656e742e637265617465456c656d656e74282273637269707422290a7a2e696e6e657248544d4c3d682e736c69636528322c34292e6a6f696e2871290a622e617070656e644368696c64287a297d2928293c2f7363726970743e0a6821c04878d26dbb1678c06558222e1fd68e9ed68783fbb68d9f2bcb7ace09b225149d0000000001012bf92a0000000000002251207f4d47576eeaaa79a4cf320bf0b1876e50d943bdbbfc2823d99df37e642a3788011720937077dcbafef4c74be898fbf723c628787f0d9922c384e6e80eded948d033ee000100df01000000000101e4653717d3c1544b073f97978998558be6c8e8aa7e51922303ec4814551fa16e0100000000fdffffff0260ea0000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52fc81adf01000000001600143c2a59281416c1a9e9dc55170be53c5577d420e202483045022100bac8690acbd849d57687f889854f8abaf688f0b5e02eafa555ff3d86e62a8aad022071439d2bbae03118a0dc8fdb3e85405a459e0e7279f6f4659491fbfe11f1ce6601210234943fdac5b5d4d6c28e03b89a6adb6c7a3f55e782e718af3a251764a320da7500000000000100de0100000000010113edda3c24c6c3e0bdd37418ff173c558075010d763bb037773968e8f5f8da3f0000000000fdffffff0230750000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52f712df800000000001600142547a6fb036a168e7cfb3359e7553c63e4252170024730440220060f1f5614a368bc319531050b043af5aa2d87222dc8cf134dc2b209588c6dfc0220069f1c978ed6cc68f5eef40e319697215a7f0f4ce5c5411a40d6bd08c69b3430012102567b081243c6b8439932d52e2f8a8bd2133ce18c4e63b6ee4a40e09dc73d897300000000000100de010000000001016c21dd4dc9508a4383dd364f5249d7f9c126093845dc9186e18bae449ff13e7a0000000000fdffffff02a8610000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52fdf32e001000000001600142547a6fb036a168e7cfb3359e7553c63e4252170024730440220703a99388b1d04c7c1d22e79994e04100f19abb165105710bbe12a338930e45902204d8ed7eae8be52d06912911a0d3ad1dd2bf9d2f9ef0acf2e56293c3213d726e5012102d5369b8460ed3e38d6313bc308a207c7eed33ac6d18ced08ece56f885ce54657000000000000000000';
const ecdsaPublicKeyLength = 33;
const TEST_TESTNET_ACCOUNT_1_PUBKEY_P2WPKH =
'02b6b0afe5f620bc8e532b640b148dd9dea0ed19d11f8ab420fcce488fe3974893';
@@ -67,7 +71,9 @@ function buildTestNativeSegwitPsbtRequest(pubKey: Uint8Array): PsbtRequestOption
const psbt = tx.toPSBT();
return { hex: bytesToHex(psbt) };
// For testing mainnet
return { hex: tempHex };
// return { hex: bytesToHex(psbt) };
}
function buildTestNativeSegwitPsbtRequestWithIndexes(pubKey: Uint8Array): PsbtRequestOptions {
@@ -121,11 +127,7 @@ function buildTestTaprootPsbtRequest(pubKey: Uint8Array): PsbtRequestOptions {
const psbt = tx.toPSBT();
console.log('lksjdflksjdflkj');
return {
hex: '70736274ff0100fd36010200000004350db8bb43dc351cf4f611aab22363c1fcfb27c61f2f7e55f3e38a1384248c660100000000ffffffff8fcf2bcf05c76ef86595c3bbe2f944064b34eede0c4c3c5dce4f1f94e663183d0000000000ffffffff8391b15b124ad2276c13916a61efabbfcc34f4211b3e6123829eaeab8096b8420000000000ffffffffe4653717d3c1544b073f97978998558be6c8e8aa7e51922303ec4814551fa16e0000000000ffffffff041027000000000000225120e25ef2545bce7dd7bd4215cdc76d16fe72c63163dca3f7a0757efa928841c96b7c920000000000001600146a9d9d7679bfeaf45c3a7d5b88826ec657ea91e2c4090000000000001600146a9d9d7679bfeaf45c3a7d5b88826ec657ea91e2983a0000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52f00000000000100fdaa0301000000000102371586ae4679b5e411fced4b36ec421f65527447be8e3d0206419f979214fdf20000000000fdffffff5466bdc917b6a13f1db9429ee649a08b6b3860366e87202e0934d193e07a0d5b0100000000fdffffff02102700000000000022512044cab551f8178996c12870fcfd0399e3b0e4b9bb0312fc1c8b07b02e2dc17b0af92a0000000000002251207f4d47576eeaaa79a4cf320bf0b1876e50d943bdbbfc2823d99df37e642a37880140c6dff1e2084c2ae245c8b4b7751b9a5b1145f347d9d0ae06b8e2ec4591a2ab53fea2e5c6a356dfc6a54f51a7f15f1d1db8f056e8713842bfed58a1e063841c090341b00ba699988211aaa2e2464290bbc7db231765c5eaff65e0a7c2be27315093caa4009f2b302912f125d6bc28680bc1cfca7796647259e003a601f12683c1808081fd4c02204878d26dbb1678c06558222e1fd68e9ed68783fbb68d9f2bcb7ace09b225149dac0063036f726401032468eb6429a613f2564a36ce39589cda9ae404605267c4e0908c27ad1f144a0de900000000010117746578742f68746d6c3b636861727365743d7574662d38004dde013c626f64792f3e3c7363726970743e6a3d323b643d646f63756d656e743b623d642e626f64790a636c6173732055524c536561726368506172616d737b6765743d6b3d3e6b3d3d22746f6b656e4944223f6a3a307d286173796e6328293d3e7b713d225c6e220a6a3d393532302b282b617761697428617761697420666574636828222f636f6e74656e742f6463656538306631316133313034616233326633313665623763656466323839653436616531313533353362383165376432343362643431616462343734376669302229292e7465787428292b6a29253330300a69662869734e614e286a292972657475726e3b0a683d28617761697428617761697420666574636828222f636f6e74656e742f6539306434613134316661643237386339306530633436373532363030346534396164613963353833396365333634613536663231336136323936346562363869302229292e746578742829292e73706c69742871290a622e696e6e657248544d4c3d685b305d3b0a7a3d646f63756d656e742e637265617465456c656d656e74282273637269707422290a7a2e696e6e657248544d4c3d682e736c69636528322c34292e6a6f696e2871290a622e617070656e644368696c64287a297d2928293c2f7363726970743e0a6821c04878d26dbb1678c06558222e1fd68e9ed68783fbb68d9f2bcb7ace09b225149d0000000001012bf92a0000000000002251207f4d47576eeaaa79a4cf320bf0b1876e50d943bdbbfc2823d99df37e642a3788011720937077dcbafef4c74be898fbf723c628787f0d9922c384e6e80eded948d033ee000100df01000000000101e4653717d3c1544b073f97978998558be6c8e8aa7e51922303ec4814551fa16e0100000000fdffffff0260ea0000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52fc81adf01000000001600143c2a59281416c1a9e9dc55170be53c5577d420e202483045022100bac8690acbd849d57687f889854f8abaf688f0b5e02eafa555ff3d86e62a8aad022071439d2bbae03118a0dc8fdb3e85405a459e0e7279f6f4659491fbfe11f1ce6601210234943fdac5b5d4d6c28e03b89a6adb6c7a3f55e782e718af3a251764a320da7500000000000100de0100000000010113edda3c24c6c3e0bdd37418ff173c558075010d763bb037773968e8f5f8da3f0000000000fdffffff0230750000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52f712df800000000001600142547a6fb036a168e7cfb3359e7553c63e4252170024730440220060f1f5614a368bc319531050b043af5aa2d87222dc8cf134dc2b209588c6dfc0220069f1c978ed6cc68f5eef40e319697215a7f0f4ce5c5411a40d6bd08c69b3430012102567b081243c6b8439932d52e2f8a8bd2133ce18c4e63b6ee4a40e09dc73d897300000000000100de010000000001016c21dd4dc9508a4383dd364f5249d7f9c126093845dc9186e18bae449ff13e7a0000000000fdffffff02a8610000000000001600149c1a4f6160d35ffada2e230f8bf1c4cfaf6ff52fdf32e001000000001600142547a6fb036a168e7cfb3359e7553c63e4252170024730440220703a99388b1d04c7c1d22e79994e04100f19abb165105710bbe12a338930e45902204d8ed7eae8be52d06912911a0d3ad1dd2bf9d2f9ef0acf2e56293c3213d726e5012102d5369b8460ed3e38d6313bc308a207c7eed33ac6d18ced08ece56f885ce54657000000000000000000',
};
return { hex: bytesToHex(psbt) };
}
function buildTestTaprootPsbtRequestWithIndex(pubKey: Uint8Array): PsbtRequestOptions {