diff options
| author | David Simão <[email protected]> | 2024-06-05 09:01:26 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-06-05 10:01:26 +0200 |
| commit | 3ae93934bc4cf5f6414acfa28ea727f758d18756 (patch) | |
| tree | de1c649f829dbcdca838c4fedcac76c3450ccff6 /src/modules | |
| parent | badaa6d60593fe41a1afa0e9a8bef6ae5bb8a352 (diff) | |
| download | faker-3ae93934bc4cf5f6414acfa28ea727f758d18756.tar.xz faker-3ae93934bc4cf5f6414acfa28ea727f758d18756.zip | |
feat(bitcoinAddress): multiple bitcoin address types and testnet (#2922)
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/finance/bitcoin.ts | 72 | ||||
| -rw-r--r-- | src/modules/finance/index.ts | 53 |
2 files changed, 114 insertions, 11 deletions
diff --git a/src/modules/finance/bitcoin.ts b/src/modules/finance/bitcoin.ts new file mode 100644 index 00000000..f7cfaf70 --- /dev/null +++ b/src/modules/finance/bitcoin.ts @@ -0,0 +1,72 @@ +import type { Casing } from '../string'; + +/** + * The bitcoin address families. + */ +export enum BitcoinAddressFamily { + Legacy = 'legacy', + Segwit = 'segwit', + Bech32 = 'bech32', + Taproot = 'taproot', +} + +/** + * The bitcoin address families. + */ +export type BitcoinAddressFamilyType = `${BitcoinAddressFamily}`; + +/** + * The different bitcoin networks. + */ +export enum BitcoinNetwork { + Mainnet = 'mainnet', + Testnet = 'testnet', +} + +/** + * The different bitcoin networks. + */ +export type BitcoinNetworkType = `${BitcoinNetwork}`; + +type BitcoinAddressOptions = { + prefix: Record<BitcoinNetworkType, string>; + length: { min: number; max: number }; + casing: Casing; + exclude: string; +}; + +export const BitcoinAddressSpecs: Record< + BitcoinAddressFamilyType, + BitcoinAddressOptions +> = { + [BitcoinAddressFamily.Legacy]: { + prefix: { [BitcoinNetwork.Mainnet]: '1', [BitcoinNetwork.Testnet]: 'm' }, + length: { min: 26, max: 34 }, + casing: 'mixed', + exclude: '0OIl', + }, + [BitcoinAddressFamily.Segwit]: { + prefix: { [BitcoinNetwork.Mainnet]: '3', [BitcoinNetwork.Testnet]: '2' }, + length: { min: 26, max: 34 }, + casing: 'mixed', + exclude: '0OIl', + }, + [BitcoinAddressFamily.Bech32]: { + prefix: { + [BitcoinNetwork.Mainnet]: 'bc1', + [BitcoinNetwork.Testnet]: 'tb1', + }, + length: { min: 42, max: 42 }, + casing: 'lower', + exclude: '1bBiIoO', + }, + [BitcoinAddressFamily.Taproot]: { + prefix: { + [BitcoinNetwork.Mainnet]: 'bc1p', + [BitcoinNetwork.Testnet]: 'tb1p', + }, + length: { min: 62, max: 62 }, + casing: 'lower', + exclude: '1bBiIoO', + }, +}; diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts index b78b6a3f..4c84fe4c 100644 --- a/src/modules/finance/index.ts +++ b/src/modules/finance/index.ts @@ -1,5 +1,11 @@ import { FakerError } from '../../errors/faker-error'; import { ModuleBase } from '../../internal/module-base'; +import type { BitcoinAddressFamilyType, BitcoinNetworkType } from './bitcoin'; +import { + BitcoinAddressFamily, + BitcoinAddressSpecs, + BitcoinNetwork, +} from './bitcoin'; import iban from './iban'; /** @@ -486,23 +492,48 @@ export class FinanceModule extends ModuleBase { /** * Generates a random Bitcoin address. * + * @param options An optional options object. + * @param options.type The bitcoin address type (`'legacy'`, `'sewgit'`, `'bech32'` or `'taproot'`). Defaults to a random address type. + * @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'`). + * + * @default faker.helpers.arrayElement(['legacy','sewgit','bech32','taproot']) + */ + type?: BitcoinAddressFamilyType; + /** + * The bitcoin network (`'mainnet'` or `'testnet'`). + * + * @default 'mainnet' + */ + network?: BitcoinNetworkType; + } = {} + ): string { + const { + type = this.faker.helpers.enumValue(BitcoinAddressFamily), + network = BitcoinNetwork.Mainnet, + } = options; + const addressSpec = BitcoinAddressSpecs[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; } /** |
