Skip to content

Commit

Permalink
fix: support regtest address validation
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Nov 21, 2024
1 parent 11513af commit f573af4
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
14 changes: 14 additions & 0 deletions src/shared/rpc/methods/send-transfer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,18 @@ describe('`sendTransfer` method', () => {
);
expect(result.success).toEqual(false);
});

test('that it supports regtest addresses', () => {
const result = rpcSendTransferParamsSchema.safeParse({
network: 'sbtcTestnet',
account: 0,
recipients: [
{
address: 'bcrt1pzxz00vdnc8j4rz6u9axp6jmh60f8v7t8zkmwzm4x3899fvvl78nseyz7r2',
amount: '100',
},
],
});
expect(result.success).toEqual(true);
});
});
32 changes: 27 additions & 5 deletions src/shared/rpc/methods/send-transfer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { SendTransferRequestParams } from '@btckit/types';
import { z } from 'zod';

import { type BitcoinNetworkModes } from '@leather.io/models';
import { type BitcoinNetworkModes, type DefaultNetworkConfigurations } from '@leather.io/models';
import { uniqueArray } from '@leather.io/utils';

import { FormErrorMessages } from '@shared/error-messages';
Expand All @@ -11,7 +11,7 @@ import {
} from '@shared/forms/address-validators';
import { checkIfDigitsOnly } from '@shared/forms/amount-validators';

import { defaultNetworksSchema } from '../rpc-schemas';
import { defaultNetworkIdSchema } from '../rpc-schemas';
import {
accountSchema,
formatValidationErrors,
Expand All @@ -21,17 +21,35 @@ import {

export const defaultRpcSendTransferNetwork = 'mainnet';

function defaultNetworkIdToBitcoinNetworkMode(
networkId: DefaultNetworkConfigurations
): BitcoinNetworkModes {
switch (networkId) {
case 'mainnet':
return 'mainnet';
case 'testnet':
case 'testnet4':
return 'testnet';
case 'sbtcTestnet':
case 'sbtcDevenv':
case 'devnet':
return 'regtest';
case 'signet':
return 'signet';
}
}

export const rpcSendTransferParamsSchemaLegacy = z.object({
account: accountSchema.optional(),
address: z.string(),
amount: z.string(),
network: defaultNetworksSchema.optional(),
network: defaultNetworkIdSchema.optional(),
});

export const rpcSendTransferParamsSchema = z
.object({
account: accountSchema.optional(),
network: defaultNetworksSchema.optional(),
network: defaultNetworkIdSchema.optional(),
recipients: z
.array(
z.object({
Expand All @@ -54,8 +72,12 @@ export const rpcSendTransferParamsSchema = z
})
.refine(
({ network, recipients }) => {
if (!network) return true;

const addressNetworks = recipients.map(recipient =>
btcAddressNetworkValidator(network as BitcoinNetworkModes).isValidSync(recipient.address)
btcAddressNetworkValidator(defaultNetworkIdToBitcoinNetworkMode(network)).isValidSync(
recipient.address
)
);

return !addressNetworks.some(val => val === false);
Expand Down
4 changes: 2 additions & 2 deletions src/shared/rpc/methods/sign-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { z } from 'zod';

import type { PaymentTypes } from '@leather.io/rpc';

import { defaultNetworksSchema } from '../rpc-schemas';
import { defaultNetworkIdSchema } from '../rpc-schemas';
import {
accountSchema,
formatValidationErrors,
Expand All @@ -14,7 +14,7 @@ const rpcSignMessageParamsSchema = z.object({
type: z.enum(['bip322']).optional(),
account: accountSchema.optional(),
message: z.string(),
network: defaultNetworksSchema.optional(),
network: defaultNetworkIdSchema.optional(),
paymentType: z.enum(['p2tr', 'p2wpkh'] as [PaymentTypes, PaymentTypes]).optional(),
});

Expand Down
4 changes: 2 additions & 2 deletions src/shared/rpc/methods/sign-psbt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
RpcResponse,
} from '@leather.io/rpc';

import { defaultNetworksSchema } from '../rpc-schemas';
import { defaultNetworkIdSchema } from '../rpc-schemas';
import {
accountSchema,
formatValidationErrors,
Expand Down Expand Up @@ -36,7 +36,7 @@ const rpcSignPsbtParamsSchema = z.object({
allowedSighash: z.array(z.any()).optional(),
broadcast: z.boolean().optional(),
hex: z.string(),
network: defaultNetworksSchema.optional(),
network: defaultNetworkIdSchema.optional(),
signAtIndex: z
.union([z.number(), z.array(z.number())])
.optional()
Expand Down
9 changes: 6 additions & 3 deletions src/shared/rpc/rpc-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import {
WalletDefaultNetworkConfigurationIds,
} from '@leather.io/models';

type NonEmptyNetworkList = [DefaultNetworkConfigurations, ...DefaultNetworkConfigurations[]];
type NonEmptyDefaultNetworkIdList = [
DefaultNetworkConfigurations,
...DefaultNetworkConfigurations[],
];

export const defaultNetworksSchema = z.enum(
Object.values(WalletDefaultNetworkConfigurationIds) as NonEmptyNetworkList
export const defaultNetworkIdSchema = z.enum(
Object.values(WalletDefaultNetworkConfigurationIds) as NonEmptyDefaultNetworkIdList
);

0 comments on commit f573af4

Please sign in to comment.