aboutsummaryrefslogtreecommitdiff
path: root/src/modules/finance
diff options
context:
space:
mode:
authorDavid Simão <[email protected]>2024-06-05 09:01:26 +0100
committerGitHub <[email protected]>2024-06-05 10:01:26 +0200
commit3ae93934bc4cf5f6414acfa28ea727f758d18756 (patch)
treede1c649f829dbcdca838c4fedcac76c3450ccff6 /src/modules/finance
parentbadaa6d60593fe41a1afa0e9a8bef6ae5bb8a352 (diff)
downloadfaker-3ae93934bc4cf5f6414acfa28ea727f758d18756.tar.xz
faker-3ae93934bc4cf5f6414acfa28ea727f758d18756.zip
feat(bitcoinAddress): multiple bitcoin address types and testnet (#2922)
Diffstat (limited to 'src/modules/finance')
-rw-r--r--src/modules/finance/bitcoin.ts72
-rw-r--r--src/modules/finance/index.ts53
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;
}
/**