Skip to content

Commit

Permalink
feat: fetch zonefile data from bns v2 api
Browse files Browse the repository at this point in the history
  • Loading branch information
alter-eggo authored and kyranjamie committed Nov 13, 2024
1 parent e3cfac7 commit d25956d
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 183 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@
"@leather.io/constants": "0.13.1",
"@leather.io/crypto": "1.6.8",
"@leather.io/models": "0.19.0",
"@leather.io/query": "2.20.0",
"@leather.io/query": "2.21.1",
"@leather.io/stacks": "1.3.1",
"@leather.io/tokens": "0.10.0",
"@leather.io/ui": "1.32.2",
"@leather.io/ui": "1.33.0",
"@leather.io/utils": "0.17.0",
"@ledgerhq/hw-transport-webusb": "6.27.19",
"@noble/hashes": "1.5.0",
Expand Down
275 changes: 128 additions & 147 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions src/app/common/hooks/account/use-account-names.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useQuery } from '@tanstack/react-query';

import { bitcoinNetworkModeToCoreNetworkMode } from '@leather.io/bitcoin';
import { createGetBnsNamesOwnedByAddressQueryOptions } from '@leather.io/query';
import { createGetBnsNamesOwnedByAddressQueryOptions, useBnsV2Client } from '@leather.io/query';
import { isUndefined } from '@leather.io/utils';

import { parseIfValidPunycode } from '@app/common/utils';
Expand All @@ -18,9 +18,10 @@ export function useCurrentAccountDisplayName() {
const address = useCurrentStacksAccountAddress();
const { chain } = useCurrentNetworkState();
const network = bitcoinNetworkModeToCoreNetworkMode(chain.bitcoin.mode);
const client = useBnsV2Client();

return useQuery({
...createGetBnsNamesOwnedByAddressQueryOptions({ address, network }),
...createGetBnsNamesOwnedByAddressQueryOptions({ address, network, client }),
select: resp => {
if (isUndefined(account?.index) && (!account || typeof account?.index !== 'number'))
return 'Account';
Expand All @@ -34,11 +35,12 @@ export function useCurrentAccountDisplayName() {
export function useAccountDisplayName({ address, index }: { index: number; address: string }) {
const { chain } = useCurrentNetworkState();
const network = bitcoinNetworkModeToCoreNetworkMode(chain.bitcoin.mode);

const client = useBnsV2Client();
const query = useQuery({
...createGetBnsNamesOwnedByAddressQueryOptions({
address,
network,
client,
}),
select: resp => {
const names = resp.names ?? [];
Expand Down
9 changes: 6 additions & 3 deletions src/app/common/hooks/use-key-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo } from 'react';

import { generateSecretKey } from '@stacks/wallet-sdk';

import { useBitcoinClient } from '@leather.io/query';
import { useBitcoinClient, useBnsV2Client } from '@leather.io/query';

import { logger } from '@shared/logger';
import { InternalMethods } from '@shared/message-types';
Expand All @@ -29,11 +29,14 @@ export function useKeyActions() {
const defaultKeyDetails = useCurrentKeyDetails();
const btcClient = useBitcoinClient();
const stxClient = useStacksClient();
const bnsV2Client = useBnsV2Client();

return useMemo(
() => ({
async setPassword(password: string) {
return dispatch(keyActions.setWalletEncryptionPassword({ password, stxClient, btcClient }));
return dispatch(
keyActions.setWalletEncryptionPassword({ password, stxClient, btcClient, bnsV2Client })
);
},

generateWalletKey() {
Expand Down Expand Up @@ -76,6 +79,6 @@ export function useKeyActions() {
return dispatch(inMemoryKeyActions.lockWallet());
},
}),
[btcClient, defaultKeyDetails, dispatch, stxClient]
[bnsV2Client, btcClient, defaultKeyDetails, dispatch, stxClient]
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useIsFetching } from '@tanstack/react-query';

import { BitcoinQueryPrefixes, StacksQueryPrefixes } from '@leather.io/query';
import { BitcoinQueryPrefixes, BnsV2QueryPrefixes, StacksQueryPrefixes } from '@leather.io/query';
import { sumNumbers } from '@leather.io/utils';

function areAnyQueriesFetching(...args: number[]) {
Expand All @@ -16,7 +16,7 @@ export function useIsFetchingCollectiblesRelatedQuery() {
const n5 = useIsFetching({ queryKey: [BitcoinQueryPrefixes.GetInscriptions] });

// BNS
const n6 = useIsFetching({ queryKey: [StacksQueryPrefixes.GetBnsNamesByAddress] });
const n6 = useIsFetching({ queryKey: [BnsV2QueryPrefixes.GetBnsNamesByAddress] });

// NFTs
const n7 = useIsFetching({ queryKey: [StacksQueryPrefixes.GetNftMetadata] });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@ import { useCallback, useState } from 'react';

import { useFormikContext } from 'formik';

import { type StacksClient, useStacksClient } from '@leather.io/query';
import { type BnsV2Client, useBnsV2Client } from '@leather.io/query';

import { FormErrorMessages } from '@shared/error-messages';
import { logger } from '@shared/logger';
import { BitcoinSendFormValues, StacksSendFormValues } from '@shared/models/form.model';

import { useCurrentNetworkState } from '@app/store/networks/networks.hooks';

// Handles validating the BNS name lookup
export function useRecipientBnsName() {
const { setFieldError, setFieldValue, values } = useFormikContext<
BitcoinSendFormValues | StacksSendFormValues
>();
const [bnsAddress, setBnsAddress] = useState('');
const currentNetwork = useCurrentNetworkState();
const client = useStacksClient();

const client = useBnsV2Client();

const getBnsAddressAndValidate = useCallback(
async (
fetchFn: (client: StacksClient, name: string, isTestnet?: boolean) => Promise<string | null>
fetchFn: (client: BnsV2Client, name: string, isTestnet?: boolean) => Promise<string | null>
) => {
setBnsAddress('');
if (!values.recipientBnsName) return;

try {
const owner = await fetchFn(client, values.recipientBnsName, currentNetwork.isTestnet);
const owner = await fetchFn(client, values.recipientBnsName);

if (owner) {
setBnsAddress(owner);
setFieldError('recipient', undefined);
Expand All @@ -40,7 +39,7 @@ export function useRecipientBnsName() {
logger.error('Error fetching bns address', e);
}
},
[client, currentNetwork.isTestnet, setFieldError, setFieldValue, values.recipientBnsName]
[client, setFieldError, setFieldValue, values.recipientBnsName]
);

return { bnsAddress, getBnsAddressAndValidate, setBnsAddress };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';

import { useFormikContext } from 'formik';

import type { StacksClient } from '@leather.io/query';
import type { BnsV2Client } from '@leather.io/query';

import { BitcoinSendFormValues, StacksSendFormValues } from '@shared/models/form.model';

Expand All @@ -12,7 +12,7 @@ import { RecipientAddressDisplayer } from './components/recipient-address-displa
import { useRecipientBnsName } from './hooks/use-recipient-bns-name';

interface RecipientBnsNameTypeFieldProps {
fetchFn(client: StacksClient, name: string, isTestnet?: boolean): Promise<string | null>;
fetchFn(client: BnsV2Client, name: string, isTestnet?: boolean): Promise<string | null>;
topInputOverlay: React.JSX.Element;
rightLabel: React.JSX.Element;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fetchNameOwner } from '@leather.io/query';
import { fetchStacksNameOwner } from '@leather.io/query';

import { RecipientField } from '../../../components/recipient-fields/recipient-field';

export function StacksRecipientField() {
return <RecipientField bnsLookupFn={fetchNameOwner} />;
return <RecipientField bnsLookupFn={fetchStacksNameOwner} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import * as yup from 'yup';

import { bitcoinNetworkModeToCoreNetworkMode } from '@leather.io/bitcoin';

import { FormErrorMessages } from '@shared/error-messages';
import { btcAddressNetworkValidator, btcAddressValidator } from '@shared/forms/address-validators';
import {
btcAddressNetworkValidator,
btcAddressValidator,
nonEmptyStringValidator,
} from '@shared/forms/address-validators';
import { BitcoinSendFormValues } from '@shared/models/form.model';

import { formatPrecisionError } from '@app/common/error-formatters';
Expand Down Expand Up @@ -70,9 +73,7 @@ export function useBtcSendForm() {
utxos,
})
),
recipient: yup
.string()
.defined(FormErrorMessages.AddressRequired)
recipient: nonEmptyStringValidator()
.concat(btcAddressValidator())
.concat(btcAddressNetworkValidator(currentNetwork.chain.bitcoin.mode))
.concat(notCurrentAddressValidator(nativeSegwitSigner.address || ''))
Expand All @@ -88,7 +89,7 @@ export function useBtcSendForm() {
values: BitcoinSendFormValues,
formikHelpers: FormikHelpers<BitcoinSendFormValues>
) {
// Validate and check high fee warning firsts
// Validate and check high fee warning first
await formikHelpers.validateForm();
sendFormNavigate.toChooseTransactionFee(isSendingMax, utxos, values);
},
Expand Down
11 changes: 7 additions & 4 deletions src/app/store/software-keys/software-key.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { AddressVersion } from '@stacks/transactions';

import {
type BitcoinClient,
type BnsV2Client,
BnsV2QueryPrefixes,
type StacksClient,
StacksQueryPrefixes,
fetchNamesForAddress,
} from '@leather.io/query';

Expand Down Expand Up @@ -31,8 +32,9 @@ function setWalletEncryptionPassword(args: {
password: string;
stxClient: StacksClient;
btcClient: BitcoinClient;
bnsV2Client: BnsV2Client;
}): AppThunk {
const { password, stxClient, btcClient } = args;
const { password, stxClient, btcClient, bnsV2Client } = args;

return async (dispatch, getState) => {
const secretKey = selectDefaultWalletKey(getState());
Expand All @@ -57,11 +59,12 @@ function setWalletEncryptionPassword(args: {
async function doesStacksAddressHaveBnsName(address: string) {
const controller = new AbortController();
const resp = await fetchNamesForAddress({
address,
client: bnsV2Client,
address: address,
network: 'mainnet',
signal: controller.signal,
});
queryClient.setQueryData([StacksQueryPrefixes.GetBnsNamesByAddress, address], resp);
queryClient.setQueryData([BnsV2QueryPrefixes.GetBnsNamesByAddress, address], resp);
return resp.names.length > 0;
}

Expand Down
7 changes: 7 additions & 0 deletions src/shared/forms/address-validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import { isEmptyString, isUndefined } from '@leather.io/utils';

import { FormErrorMessages } from '@shared/error-messages';

export function nonEmptyStringValidator(message = FormErrorMessages.AddressRequired) {
return yup.string().test({
message,
test: value => value !== undefined && value.trim() !== '',
});
}

export function btcAddressValidator() {
return yup.string().test({
message: FormErrorMessages.InvalidAddress,
Expand Down
19 changes: 16 additions & 3 deletions tests/mocks/mock-stacks-bns.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Page } from '@playwright/test';

import { bnsV2NamesByAddressResponseSchema } from '@leather.io/query';

import { TEST_ACCOUNT_1_STX_ADDRESS } from './constants';

export async function mockMainnetTestAccountStacksBnsNameRequest(page: Page) {
Expand All @@ -12,13 +14,24 @@ export async function mockMainnetTestAccountStacksBnsNameRequest(page: Page) {
);
}

const mockedBnsV2NamesResponse = {
const mockedBnsV2NamesResponse = bnsV2NamesByAddressResponseSchema.parse({
total: 1,
current_burn_block: 869830,
limit: 50,
offset: 0,
names: [{ full_name: 'leather.btc', name_string: 'leather', namespace_string: 'btc' }],
};
names: [
{
full_name: 'leather.btc',
name_string: 'leather',
namespace_string: 'btc',
owner: 'leather',
registered_at: '2021-09-29T20:00:00Z',
renewal_height: 'sdlkfsldjks',
stx_burn: '0',
revoked: false,
},
],
});

export async function mockBnsV2NamesRequest(page: Page) {
await page.route(`**/api.bnsv2.com/names/address/${TEST_ACCOUNT_1_STX_ADDRESS}/valid`, route =>
Expand Down
2 changes: 1 addition & 1 deletion tests/specs/compliance-checks/compliance-checks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ test.describe('Compliance checks', () => {
// Please forgive this timeout, we need to give the page time in order to
// make the request, to be sure it was made. If this test ends up failing
// due to a race condition, please let the author know.
await delay(1500);
await delay(2000);

const userAndRecipientAddressCount = 2;

Expand Down

0 comments on commit d25956d

Please sign in to comment.