Skip to content

Commit

Permalink
fix: testnet4 fees, add bip32derivation to inputs, polish code
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarkhanzadian committed Dec 4, 2024
1 parent 960b522 commit f3b9f64
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCallback } from 'react';
import { useNetworkPreferenceBitcoinScureLibNetworkConfig } from '@/store/settings/settings.read';

import {
BtcSignerDefaultBip32Derivation,
CoinSelectionRecipient,
CoinSelectionUtxo,
generateBitcoinUnsignedTransactionNativeSegwit,
Expand All @@ -19,17 +20,25 @@ interface GenerateBtcUnsignedTransactionCallbackArgs {
isSendingMax: boolean;
utxos: CoinSelectionUtxo[];
values: BtcTransactionValues;
bip32Derivation: BtcSignerDefaultBip32Derivation[];
}

export function useGenerateBtcUnsignedTransactionNativeSegwit(address: string, publicKey: string) {
const network = useNetworkPreferenceBitcoinScureLibNetworkConfig();

return useCallback(
({ feeRate, isSendingMax, values, utxos }: GenerateBtcUnsignedTransactionCallbackArgs) =>
({
feeRate,
isSendingMax,
values,
utxos,
bip32Derivation,
}: GenerateBtcUnsignedTransactionCallbackArgs) =>
generateBitcoinUnsignedTransactionNativeSegwit({
feeRate,
isSendingMax,
network,
bip32Derivation,
payerAddress: address,
payerPublicKey: publicKey,
recipients: values.recipients,
Expand Down
1 change: 0 additions & 1 deletion apps/mobile/src/features/psbt-signer/psbt-signer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export function PsbtSigner({ psbtHex, onEdit, onSuccess }: PsbtSignerProps) {
}),
[psbtHex, net, psbtAddresses]
);
console.log(psbtDetails);
const totalBtc = sumMoney([
psbtDetails.addressNativeSegwitTotal,
psbtDetails.addressTaprootTotal,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
// import { useEffect } from 'react';
// import { useFormContext } from 'react-hook-form';
import { TokenBalance } from '@/features/balances/token-balance';

// import { z } from 'zod';
import { Box, Pressable } from '@leather.io/ui/native';

import { SendFormBaseContext, useSendFormContext } from '../send-form-context';
Expand All @@ -17,10 +14,7 @@ export function SendFormAsset<T extends SendFormBaseContext<T>>({
}: SendFormAssetProps) {
const { formData } = useSendFormContext<T>();
const { availableBalance, fiatBalance, protocol, symbol, name } = formData;
// const { setValue } = useFormContext<z.infer<typeof schema>>();
// useEffect(() => {
// setValue('senderDerivationPath', '');
// }, [setValue]);

return (
<Pressable onPress={onPress}>
<Box borderColor="ink.border-default" borderRadius="sm" borderWidth={1}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { useCallback } from 'react';

import { useGenerateBtcUnsignedTransactionNativeSegwit } from '@/common/transactions/bitcoin-transactions.hooks';
import { useBitcoinAccounts } from '@/store/keychains/bitcoin/bitcoin-keychains.read';
import { bytesToHex } from '@noble/hashes/utils';
import BigNumber from 'bignumber.js';

import { CoinSelectionRecipient, CoinSelectionUtxo, getBitcoinFees } from '@leather.io/bitcoin';
import {
CoinSelectionRecipient,
CoinSelectionUtxo,
getBitcoinFees,
payerToBip32Derivation,
} from '@leather.io/bitcoin';
import { AverageBitcoinFeeRates } from '@leather.io/models';
import { Utxo } from '@leather.io/query';
import { createMoneyFromDecimal } from '@leather.io/utils';
Expand Down Expand Up @@ -49,6 +55,12 @@ interface GetTxFeesArgs {
export function useSendFormBtc() {
const route = useSendSheetRoute<CurrentRoute>();
const navigation = useSendSheetNavigation<CurrentRoute>();
const { account } = route.params;

const bitcoinKeychain = useBitcoinAccounts().accountIndexByPaymentType(
account.fingerprint,
account.accountIndex
);

const generateTx = useGenerateBtcUnsignedTransactionNativeSegwit(
route.params.address,
Expand All @@ -68,18 +80,17 @@ export function useSendFormBtc() {
// Temporary logs until we can hook up to approver flow

async onInitSendTransfer(data: SendFormBtcContext, values: SendFormBtcSchema) {
// eslint-disable-next-line no-console, lingui/no-unlocalized-strings
console.log('Send form data:', parseSendFormValues(values));

const parsedSendFormValues = parseSendFormValues(values);
const coinSelectionUtxos = createCoinSelectionUtxos(data.utxos);

console.log({ values });
const nativeSegwitPayer = bitcoinKeychain.nativeSegwit.derivePayer({ addressIndex: 0 });

const tx = await generateTx({
feeRate: Number(values.feeRate),
isSendingMax: false,
values: parsedSendFormValues,
utxos: coinSelectionUtxos,
bip32Derivation: [payerToBip32Derivation(nativeSegwitPayer)],
});

const fees = getTxFees({
Expand All @@ -91,10 +102,6 @@ export function useSendFormBtc() {
// Show an error toast here?
if (!tx) throw new Error('Attempted to generate raw tx, but no tx exists');
// eslint-disable-next-line no-console, lingui/no-unlocalized-strings
console.log('tx hex:', tx.hex);
// eslint-disable-next-line no-console, lingui/no-unlocalized-strings
console.log('psbt:', tx.psbt);
// eslint-disable-next-line no-console, lingui/no-unlocalized-strings
console.log('fees:', fees);

const psbtHex = bytesToHex(tx.psbt);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { hexToBytes } from '@noble/hashes/utils';
import * as btc from '@scure/btc-signer';
import { BtcSignerDefaultBip32Derivation } from 'bitcoin-signer';

import { BitcoinError, BitcoinErrorMessage } from '../bitcoin-error';
import { BtcSignerNetwork } from '../bitcoin.network';
Expand All @@ -15,6 +16,7 @@ export interface GenerateBitcoinUnsignedTransactionArgs {
isSendingMax?: boolean;
payerAddress: string;
payerPublicKey: string;
bip32Derivation: BtcSignerDefaultBip32Derivation[];
network: BtcSignerNetwork;
recipients: CoinSelectionRecipient[];
utxos: CoinSelectionUtxo[];
Expand All @@ -25,6 +27,7 @@ export async function generateBitcoinUnsignedTransactionNativeSegwit({
isSendingMax,
payerAddress,
payerPublicKey,
bip32Derivation,
network,
recipients,
utxos,
Expand All @@ -46,6 +49,7 @@ export async function generateBitcoinUnsignedTransactionNativeSegwit({
txid: input.txid,
index: input.vout,
sequence: 0,
bip32Derivation,
witnessUtxo: {
// script = 0014 + pubKeyHash
script: p2wpkh.script,
Expand Down
16 changes: 11 additions & 5 deletions packages/query/src/bitcoin/clients/bitcoin-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
BESTINSLOT_API_BASE_URL_TESTNET,
BitcoinTx,
} from '@leather.io/models';
import { whenNetwork } from '@leather.io/utils';
import { match, whenNetwork } from '@leather.io/utils';

import { UtxoResponseItem } from '../../../types/utxo';
import { useLeatherNetwork } from '../../leather-query-provider';
Expand Down Expand Up @@ -80,10 +80,16 @@ function FeeEstimatesApi() {
fast: high_fee_per_kb / 1000,
};
},
async getFeeEstimatesFromMempoolSpaceApi(): Promise<FeeResult> {
const resp = await axios.get<FeeEstimateMempoolSpaceApiResponse>(
`https://mempool.space/api/v1/fees/recommended`
);
async getFeeEstimatesFromMempoolSpaceApi(
network: 'main' | 'test3' | 'test4'
): Promise<FeeResult> {
const matchNetwork = match<'main' | 'test3' | 'test4'>();
const networkApi = matchNetwork(network, {
main: 'https://mempool.space/api/v1/fees/recommended',
test3: 'https://mempool.space/testnet/api/v1/fees/recommended',
test4: 'https://mempool.space/testnet4/api/v1/fees/recommended',
});
const resp = await axios.get<FeeEstimateMempoolSpaceApiResponse>(networkApi);

Check warning on line 92 in packages/query/src/bitcoin/clients/bitcoin-client.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/clients/bitcoin-client.ts#L83-L92

Added lines #L83 - L92 were not covered by tests
const { fastestFee, halfHourFee, hourFee } = resp.data;
return {
slow: hourFee,
Expand Down
2 changes: 1 addition & 1 deletion packages/query/src/bitcoin/fees/fee-estimates.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function useAverageBitcoinFeeRates(): UseQueryResult<AverageBitcoinFeeRat
return useQuery({
...createGetBitcoinFeeEstimatesQueryOptions({
client,
network: network.chain.bitcoin.mode,
network: network.chain.bitcoin.bitcoinNetwork,

Check warning on line 17 in packages/query/src/bitcoin/fees/fee-estimates.hooks.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/fees/fee-estimates.hooks.ts#L17

Added line #L17 was not covered by tests
}),
select(feeEstimates) {
if (feeEstimates.every(isRejected)) {
Expand Down
12 changes: 8 additions & 4 deletions packages/query/src/bitcoin/fees/fee-estimates.query.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { BitcoinNetworkModes } from '@leather.io/models';
import { BitcoinNetwork } from '@leather.io/models';

Check warning on line 1 in packages/query/src/bitcoin/fees/fee-estimates.query.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/fees/fee-estimates.query.ts#L1

Added line #L1 was not covered by tests

import { BitcoinQueryPrefixes } from '../../query-prefixes';
import { BitcoinClient } from '../clients/bitcoin-client';

async function fetchBitcoinFeeEstimates(client: BitcoinClient, network: BitcoinNetworkModes) {
async function fetchBitcoinFeeEstimates(client: BitcoinClient, network: BitcoinNetwork) {

Check warning on line 6 in packages/query/src/bitcoin/fees/fee-estimates.query.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/fees/fee-estimates.query.ts#L6

Added line #L6 was not covered by tests
if (network === 'mainnet')
return Promise.allSettled([
client.feeEstimatesApi.getFeeEstimatesFromMempoolSpaceApi(),
client.feeEstimatesApi.getFeeEstimatesFromMempoolSpaceApi('main'),

Check warning on line 9 in packages/query/src/bitcoin/fees/fee-estimates.query.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/fees/fee-estimates.query.ts#L9

Added line #L9 was not covered by tests
client.feeEstimatesApi.getFeeEstimatesFromBlockcypherApi('main'),
]);

if (network === 'testnet4')
return Promise.allSettled([client.feeEstimatesApi.getFeeEstimatesFromMempoolSpaceApi('test4')]);

Check warning on line 14 in packages/query/src/bitcoin/fees/fee-estimates.query.ts

View check run for this annotation

Codecov / codecov/patch

packages/query/src/bitcoin/fees/fee-estimates.query.ts#L13-L14

Added lines #L13 - L14 were not covered by tests

// Using `allSettled` so we can add more testnet apis to the array
return Promise.allSettled([client.feeEstimatesApi.getFeeEstimatesFromBlockcypherApi('test3')]);
}

interface CreateGetBitcoinFeeEstimatesQueryOptionsArgs {
client: BitcoinClient;
network: BitcoinNetworkModes;
network: BitcoinNetwork;
}
export function createGetBitcoinFeeEstimatesQueryOptions({
client,
Expand Down

0 comments on commit f3b9f64

Please sign in to comment.