Skip to content

Commit

Permalink
refactor: rename taproot utxo
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo committed Jan 19, 2024
1 parent c82c612 commit 04e3231
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { isDefined } from '@shared/utils';
import { sumNumbers } from '@app/common/math/helpers';
import { BtcSizeFeeEstimator } from '@app/common/transactions/bitcoin/fees/btc-size-fee-estimator';
import { createCounter } from '@app/common/utils/counter';
import { TaprootUtxo, UtxoResponseItem } from '@app/query/bitcoin/bitcoin-client';
import { UtxoResponseItem, UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';

const idealInscriptionValue = 10_000;

Expand All @@ -22,7 +22,7 @@ interface SelectInscriptionCoinFailure {
type SelectInscriptionCoinResult = SelectInscriptionCoinSuccess | SelectInscriptionCoinFailure;

interface SelectInscriptionTransferCoinsArgs {
inscriptionInput: TaprootUtxo;
inscriptionInput: UtxoWithDerivationPath;
nativeSegwitUtxos: UtxoResponseItem[];
feeRate: number;
recipient: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { BitcoinNetworkModes } from '@shared/constants';
import { getNativeSegwitAddressIndexDerivationPath } from '@shared/crypto/bitcoin/p2wpkh-address-gen';
import { Inscription } from '@shared/models/inscription.model';

import { TaprootUtxo } from '@app/query/bitcoin/bitcoin-client';
import { UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';

export function createUtxoFromInscription(inscription: Inscription): TaprootUtxo {
interface CreateUtxoFromInscriptionArgs {
inscription: Inscription;
network: BitcoinNetworkModes;
accountIndex: number;
}

export function createUtxoFromInscription({
inscription,
network,
accountIndex,
}: CreateUtxoFromInscriptionArgs): UtxoWithDerivationPath {
const { genesis_block_hash, genesis_timestamp, genesis_block_height, value, addressIndex } =
inscription;

Expand All @@ -17,5 +29,6 @@ export function createUtxoFromInscription(inscription: Inscription): TaprootUtxo
},
value: Number(value),
addressIndex,
derivationPath: getNativeSegwitAddressIndexDerivationPath(network, accountIndex, addressIndex),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import { AverageBitcoinFeeRates, BtcFeeType } from '@shared/models/fees/bitcoin-
import { SupportedInscription } from '@shared/models/inscription.model';

import { useOnMount } from '@app/common/hooks/use-on-mount';
import { TaprootUtxo } from '@app/query/bitcoin/bitcoin-client';
import { UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';
import { useCurrentAccountIndex } from '@app/store/accounts/account';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';

import { useSendInscriptionRouteState } from '../hooks/use-send-inscription-route-state';
import { createUtxoFromInscription } from './create-utxo-from-inscription';
Expand All @@ -18,7 +20,7 @@ interface SendInscriptionContextState {
inscription: SupportedInscription;
selectedFeeType: BtcFeeType;
setSelectedFeeType(value: BtcFeeType | null): void;
utxo: TaprootUtxo;
utxo: UtxoWithDerivationPath;
}
export function useSendInscriptionState() {
const location = useLocation();
Expand All @@ -29,14 +31,22 @@ export function useSendInscriptionState() {
export function SendInscriptionContainer() {
const [selectedFeeType, setSelectedFeeType] = useState<BtcFeeType | null>(null);
const [inscription, setInscription] = useState<SupportedInscription | null>(null);
const [utxo, setUtxo] = useState<TaprootUtxo | null>(null);
const [utxo, setUtxo] = useState<UtxoWithDerivationPath | null>(null);

const routeState = useSendInscriptionRouteState();
const network = useCurrentNetwork();
const currentAccountIndex = useCurrentAccountIndex();

useOnMount(() => {
if (!routeState.inscription) return;
setInscription(routeState.inscription);
setUtxo(createUtxoFromInscription(routeState.inscription));
setUtxo(
createUtxoFromInscription({
inscription: routeState.inscription,
network: network.chain.bitcoin.bitcoinNetwork,
accountIndex: currentAccountIndex,
})
);
});

if (!inscription || !utxo) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { OrdinalSendFormValues } from '@shared/models/form.model';
import { determineUtxosForSpend } from '@app/common/transactions/bitcoin/coinselect/local-coin-selection';
import { createCounter } from '@app/common/utils/counter';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { TaprootUtxo } from '@app/query/bitcoin/bitcoin-client';
import { UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';
import { useBitcoinScureLibNetworkConfig } from '@app/store/accounts/blockchain/bitcoin/bitcoin-keychain';
import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
import { useCurrentAccountTaprootSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks';

import { selectInscriptionTransferCoins } from '../coinselect/select-inscription-coins';

export function useGenerateUnsignedOrdinalTx(taprootInput: TaprootUtxo) {
export function useGenerateUnsignedOrdinalTx(inscriptionInput: UtxoWithDerivationPath) {
const createTaprootSigner = useCurrentAccountTaprootSigner();
const createNativeSegwitSigner = useCurrentAccountNativeSegwitSigner();
const networkMode = useBitcoinScureLibNetworkConfig();
Expand All @@ -30,8 +30,6 @@ export function useGenerateUnsignedOrdinalTx(taprootInput: TaprootUtxo) {
}

function formTaprootOrdinalTx(values: OrdinalSendFormValues) {
const inscriptionInput = taprootInput;

const taprootSigner = createTaprootSigner?.(inscriptionInput.addressIndex);
const nativeSegwitSigner = createNativeSegwitSigner?.(0);

Expand All @@ -58,13 +56,13 @@ export function useGenerateUnsignedOrdinalTx(taprootInput: TaprootUtxo) {

// Inscription input
tx.addInput({
txid: taprootInput.txid,
index: taprootInput.vout,
txid: inscriptionInput.txid,
index: inscriptionInput.vout,
tapInternalKey: taprootSigner.payment.tapInternalKey,
sequence: 0,
witnessUtxo: {
script: taprootSigner.payment.script,
amount: BigInt(taprootInput.value),
amount: BigInt(inscriptionInput.value),
},
});
signingConfig.push({
Expand Down Expand Up @@ -122,7 +120,7 @@ export function useGenerateUnsignedOrdinalTx(taprootInput: TaprootUtxo) {
const tx = new btc.Transaction();

// Fee-covering Native Segwit inputs
[taprootInput, ...inputs].forEach(input =>
[inscriptionInput, ...inputs].forEach(input =>
tx.addInput({
txid: input.txid,
index: input.vout,
Expand All @@ -135,7 +133,7 @@ export function useGenerateUnsignedOrdinalTx(taprootInput: TaprootUtxo) {
);

// Inscription output
tx.addOutputAddress(values.recipient, BigInt(taprootInput.value), networkMode);
tx.addOutputAddress(values.recipient, BigInt(inscriptionInput.value), networkMode);

// Recipient and change outputs
outputs.forEach(output => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { baseCurrencyAmountInQuote } from '@app/common/money/calculate-money';
import { formatMoneyPadded, i18nFormatCurrency } from '@app/common/money/format-money';
import { FeesListItem } from '@app/components/bitcoin-fees-list/bitcoin-fees-list';
import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks';
import { TaprootUtxo } from '@app/query/bitcoin/bitcoin-client';
import { UtxoWithDerivationPath } from '@app/query/bitcoin/bitcoin-client';
import { useAverageBitcoinFeeRates } from '@app/query/bitcoin/fees/fee-estimates.hooks';
import { useCryptoCurrencyMarketData } from '@app/query/common/market-data/market-data.hooks';
import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';
Expand All @@ -16,7 +16,7 @@ import { selectInscriptionTransferCoins } from '../coinselect/select-inscription

interface UseSendInscriptionFeesListArgs {
recipient: string;
utxo: TaprootUtxo;
utxo: UtxoWithDerivationPath;
}
export function useSendInscriptionFeesList({ recipient, utxo }: UseSendInscriptionFeesListArgs) {
const createNativeSegwitSigner = useCurrentAccountNativeSegwitSigner();
Expand Down
4 changes: 2 additions & 2 deletions src/app/query/bitcoin/address/utxos-by-address.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { InscriptionResponseItem } from '@shared/models/inscription.model';

import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks';

import { TaprootUtxo, UtxoResponseItem } from '../bitcoin-client';
import { UtxoResponseItem, UtxoWithDerivationPath } from '../bitcoin-client';
import { useInscriptionsByAddressQuery } from '../ordinals/inscriptions.query';
import { useBitcoinPendingTransactionsInputs } from './transactions-by-address.hooks';
import { useGetUtxosByAddressQuery } from './utxos-by-address.query';

export function filterUtxosWithInscriptions(
inscriptions: InscriptionResponseItem[],
utxos: TaprootUtxo[] | UtxoResponseItem[]
utxos: UtxoWithDerivationPath[] | UtxoResponseItem[]
) {
return utxos.filter(
utxo =>
Expand Down
23 changes: 16 additions & 7 deletions src/app/query/bitcoin/address/utxos-by-address.query.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useQuery } from '@tanstack/react-query';

import { getTaprootAddress } from '@shared/crypto/bitcoin/bitcoin.utils';
import { getNativeSegwitAddressIndexDerivationPath } from '@shared/crypto/bitcoin/p2wpkh-address-gen';

import { createCounter } from '@app/common/utils/counter';
import { AppUseQueryConfig } from '@app/query/query-config';
Expand All @@ -10,7 +11,7 @@ import { useCurrentTaprootAccount } from '@app/store/accounts/blockchain/bitcoin
import { useBitcoinClient } from '@app/store/common/api-clients.hooks';
import { useCurrentNetwork } from '@app/store/networks/networks.selectors';

import { TaprootUtxo, UtxoResponseItem } from '../bitcoin-client';
import { UtxoResponseItem, UtxoWithDerivationPath } from '../bitcoin-client';
import { hasInscriptions } from './address.utils';

const staleTime = 3 * 60 * 1000;
Expand Down Expand Up @@ -50,7 +51,7 @@ export function useTaprootAccountUtxosQuery() {
async () => {
let currentNumberOfAddressesWithoutUtxos = 0;
const addressIndexCounter = createCounter(0);
let foundUnspentTransactions: TaprootUtxo[] = [];
let foundUnspentTransactions: UtxoWithDerivationPath[] = [];
while (currentNumberOfAddressesWithoutUtxos < stopSearchAfterNumberAddressesWithoutUtxos) {
const address = getTaprootAddress({
index: addressIndexCounter.getValue(),
Expand All @@ -67,11 +68,19 @@ export function useTaprootAccountUtxosQuery() {
}

foundUnspentTransactions = [
...unspentTransactions.map(utxo => ({
// adds addresss index of which utxo belongs
...utxo,
addressIndex: addressIndexCounter.getValue(),
})),
...unspentTransactions.map(utxo => {
const addressIndex = addressIndexCounter.getValue();
return {
// adds addresss index of which utxo belongs
...utxo,
addressIndex,
derivationPath: getNativeSegwitAddressIndexDerivationPath(
network.chain.bitcoin.bitcoinNetwork,
currentAccountIndex,
addressIndex
),
};
}),
...foundUnspentTransactions,
];

Expand Down
4 changes: 2 additions & 2 deletions src/app/query/bitcoin/balance/btc-taproot-balance.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { sumNumbers } from '@app/common/math/helpers';

import { filterUtxosWithInscriptions } from '../address/utxos-by-address.hooks';
import { useTaprootAccountUtxosQuery } from '../address/utxos-by-address.query';
import { TaprootUtxo } from '../bitcoin-client';
import { UtxoWithDerivationPath } from '../bitcoin-client';
import { useGetInscriptionsInfiniteQuery } from '../ordinals/inscriptions.query';

export function useCurrentTaprootAccountUninscribedUtxos() {
Expand All @@ -19,7 +19,7 @@ export function useCurrentTaprootAccountUninscribedUtxos() {
return filterUtxosWithInscriptions(
inscriptions,
utxos.filter(utxo => utxo.status.confirmed)
) as TaprootUtxo[];
) as UtxoWithDerivationPath[];
}, [query.data?.pages, utxos]);
}

Expand Down
3 changes: 2 additions & 1 deletion src/app/query/bitcoin/bitcoin-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ export interface UtxoResponseItem {
value: number;
}

export interface TaprootUtxo extends UtxoResponseItem {
export interface UtxoWithDerivationPath extends UtxoResponseItem {
addressIndex: number;
derivationPath: string;
}

class AddressApi {
Expand Down

0 comments on commit 04e3231

Please sign in to comment.