Skip to content

Commit

Permalink
feat(bitcoinAddress): ✨ Add support for different address types and t…
Browse files Browse the repository at this point in the history
…estnet
  • Loading branch information
madoke committed May 25, 2024
1 parent b97984c commit 098d49a
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 16 deletions.
20 changes: 19 additions & 1 deletion src/definitions/finance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { Currency } from '../modules/finance';
import type {
BitcoinAddressType,
BitcoinNetwork,
Currency,
} from '../modules/finance';
import type { Casing } from '../modules/string';
import type { LocaleEntry } from './definitions';
/**
* The possible definitions related to finance.
Expand Down Expand Up @@ -26,4 +31,17 @@ export type FinanceDefinition = LocaleEntry<{
* Types of transactions (e.g. `deposit`).
*/
transaction_type: string[];

/**
* Specifications for generating different types of bitcoin addresses (e.g. `bech32`).
*/
bitcoin_address_specs: Record<
BitcoinAddressType,
{
prefix: Record<BitcoinNetwork, string>;
length: { min: number; max: number };
casing: Casing;
exclude: string;
}
>;
}>;
8 changes: 8 additions & 0 deletions src/locales/base/finance/bitcoin_address_specs/bech32.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Casing } from '../../../../modules/string';

export default {
prefix: { mainnet: 'bc1', testnet: 'tb1' },
length: { min: 42, max: 42 },
casing: 'lower' as Casing,
exclude: '1bBiIoO',
};
18 changes: 18 additions & 0 deletions src/locales/base/finance/bitcoin_address_specs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/
import type { FinanceDefinition } from '../../../..';
import bech32 from './bech32';
import legacy from './legacy';
import segwit from './segwit';
import taproot from './taproot';

const bitcoin_address_specs: FinanceDefinition['bitcoin_address_specs'] = {
bech32,
legacy,
segwit,
taproot,
};

export default bitcoin_address_specs;
8 changes: 8 additions & 0 deletions src/locales/base/finance/bitcoin_address_specs/legacy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Casing } from '../../../../modules/string';

export default {
prefix: { mainnet: '1', testnet: 'm' },
length: { min: 26, max: 34 },
casing: 'mixed' as Casing,
exclude: '0OIl',
};
8 changes: 8 additions & 0 deletions src/locales/base/finance/bitcoin_address_specs/segwit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Casing } from '../../../../modules/color';

export default {
prefix: { mainnet: '3', testnet: '2' },
length: { min: 26, max: 34 },
casing: 'mixed' as Casing,
exclude: '0OIl',
};
8 changes: 8 additions & 0 deletions src/locales/base/finance/bitcoin_address_specs/taproot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Casing } from '../../../../modules/string';

export default {
prefix: { mainnet: 'bc1p', testnet: 'tb1p' },
length: { min: 62, max: 62 },
casing: 'lower' as Casing,
exclude: '1bBiIoO',
};
12 changes: 12 additions & 0 deletions src/locales/base/finance/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* This file is automatically generated.
* Run 'pnpm run generate:locales' to update.
*/
import type { FinanceDefinition } from '../../..';
import bitcoin_address_specs from './bitcoin_address_specs';

const finance: FinanceDefinition = {
bitcoin_address_specs,
};

export default finance;
2 changes: 2 additions & 0 deletions src/locales/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { LocaleDefinition } from '../..';
import color from './color';
import database from './database';
import finance from './finance';
import hacker from './hacker';
import internet from './internet';
import location from './location';
Expand All @@ -14,6 +15,7 @@ import system from './system';
const base: LocaleDefinition = {
color,
database,
finance,
hacker,
internet,
location,
Expand Down
47 changes: 36 additions & 11 deletions src/modules/finance/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export interface Currency {
symbol: string;
}

export type BitcoinAddressType = 'legacy' | 'segwit' | 'bech32' | 'taproot';

export type BitcoinNetwork = 'mainnet' | 'testnet';

/**
* Puts a space after every 4 characters.
*
Expand Down Expand Up @@ -486,23 +490,44 @@ export class FinanceModule extends ModuleBase {
/**
* Generates a random Bitcoin address.
*
* @param options An options object.
* @param options.type The bitcoin address type (legacy, sewgit, bech32 or taproot). Defaults to `legacy`
* @param options.network The bitcoin network (mainnet or testnet). Defaults to `mainnet`.
*
* @example
* faker.finance.bitcoinAddress() // '3ySdvCkTLVy7gKD4j6JfSaf5d'
* faker.finance.bitcoinAddress() // '1TeZEFLmGPLEQrSRdAcnZLoWwYeiHwmRog'
* faker.finance.bitcoinAddress({ type: 'bech32' }) // 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'
* faker.finance.bitcoinAddress({ type: 'bech32', network: 'testnet' }) // 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx'
*
* @since 3.1.0
*/
bitcoinAddress(): string {
const addressLength = this.faker.number.int({ min: 25, max: 39 });

let address = this.faker.helpers.arrayElement(['1', '3']);

address += this.faker.string.alphanumeric({
length: addressLength,
casing: 'mixed',
exclude: '0OIl',
bitcoinAddress(options?: {
/**
* The bitcoin address type (legacy, sewgit, bech32 or taproot). Defaults to `legacy`.
*
* @default 'legacy'
*/
type?: BitcoinAddressType;
/**
* The bitcoin network (mainnet or testnet). Defaults to `mainnet`.
*
* @default 0
*/
network?: BitcoinNetwork;
}): string {
const { type = 'legacy', network = 'mainnet' } = options || {};
const addressSpec =
this.faker.definitions.finance.bitcoin_address_specs[type];
const addressPrefix = addressSpec.prefix[network];
const addressLength = this.faker.number.int(addressSpec.length);

const address = this.faker.string.alphanumeric({
length: addressLength - addressPrefix.length,
casing: addressSpec.casing,
exclude: addressSpec.exclude,
});

return address;
return addressPrefix + address;
}

/**
Expand Down
18 changes: 15 additions & 3 deletions test/modules/__snapshots__/finance.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ exports[`finance > 42 > bic > noArgs 1`] = `"YTPECC2VXXX"`;

exports[`finance > 42 > bic > with branch code 1`] = `"JYTPCD52XXX"`;

exports[`finance > 42 > bitcoinAddress 1`] = `"3JAaa4SAH2YQdbbiwrhB9hnsMcvA3Ba"`;
exports[`finance > 42 > bitcoinAddress > noArgs 1`] = `"1XJAaa4SAH2YQdbbiwrhB9hnsMcvA"`;

exports[`finance > 42 > bitcoinAddress > with type and network option 1`] = `"1XJAaa4SAH2YQdbbiwrhB9hnsMcvA"`;

exports[`finance > 42 > bitcoinAddress > with type option 1`] = `"1XJAaa4SAH2YQdbbiwrhB9hnsMcvA"`;

exports[`finance > 42 > creditCardCVV 1`] = `"397"`;

Expand Down Expand Up @@ -108,7 +112,11 @@ exports[`finance > 1211 > bic > noArgs 1`] = `"XFZROMRC"`;

exports[`finance > 1211 > bic > with branch code 1`] = `"YXFZNPOROTR"`;

exports[`finance > 1211 > bitcoinAddress 1`] = `"3eZEFLmGPLEQrSRdAcnZLoWwYeiHwmRogjbyG9G"`;
exports[`finance > 1211 > bitcoinAddress > noArgs 1`] = `"1TeZEFLmGPLEQrSRdAcnZLoWwYeiHwmRog"`;

exports[`finance > 1211 > bitcoinAddress > with type and network option 1`] = `"1TeZEFLmGPLEQrSRdAcnZLoWwYeiHwmRog"`;

exports[`finance > 1211 > bitcoinAddress > with type option 1`] = `"1TeZEFLmGPLEQrSRdAcnZLoWwYeiHwmRog"`;

exports[`finance > 1211 > creditCardCVV 1`] = `"982"`;

Expand Down Expand Up @@ -192,7 +200,11 @@ exports[`finance > 1337 > bic > noArgs 1`] = `"EHLILK9ZXXX"`;

exports[`finance > 1337 > bic > with branch code 1`] = `"GEHLGGI9XXX"`;

exports[`finance > 1337 > bitcoinAddress 1`] = `"1hsjwgYJ7oC8ZrMNmqzLbhEubpcwQ"`;
exports[`finance > 1337 > bitcoinAddress > noArgs 1`] = `"1ahsjwgYJ7oC8ZrMNmqzLbhEubpc"`;

exports[`finance > 1337 > bitcoinAddress > with type and network option 1`] = `"1ahsjwgYJ7oC8ZrMNmqzLbhEubpc"`;

exports[`finance > 1337 > bitcoinAddress > with type option 1`] = `"1ahsjwgYJ7oC8ZrMNmqzLbhEubpc"`;

exports[`finance > 1337 > creditCardCVV 1`] = `"212"`;

Expand Down
10 changes: 9 additions & 1 deletion test/modules/finance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ describe('finance', () => {
'currencyCode',
'currencyName',
'currencySymbol',
'bitcoinAddress',
'litecoinAddress',
'creditCardCVV',
'ethereumAddress',
Expand Down Expand Up @@ -91,6 +90,15 @@ describe('finance', () => {
ellipsis: true,
});
});

t.describe('bitcoinAddress', (t) => {
t.it('noArgs')
.it('with type option', { type: 'legacy' })
.it('with type and network option', {
type: 'legacy',
network: 'mainnet',
});
});
});

describe.each(times(NON_SEEDED_BASED_RUN).map(() => faker.seed()))(
Expand Down

0 comments on commit 098d49a

Please sign in to comment.