Skip to content

Instantly share code, notes, and snippets.

@bolasblack
Last active May 18, 2023 13:36
Show Gist options
  • Save bolasblack/fa1ddb5b2a0f5b4329234b91dcdcd61d to your computer and use it in GitHub Desktop.
Save bolasblack/fa1ddb5b2a0f5b4329234b91dcdcd61d to your computer and use it in GitHub Desktop.
#!/usr/bin/env ts-node
/**
* Usage:
*
* pnpm ts-node scripts/generate-btc-ordinal-addresses.ts 'mainnet | testnet' 'mnemonic' 0 1000 | jq -r 'map(.address) | join("\n")' > /save/to/some/file
*/
import { BIP32Factory } from 'bip32';
import * as bip39 from 'bip39';
import * as ecc from 'tiny-secp256k1';
import * as bitcoin from 'bitcoinjs-lib';
const bip32 = BIP32Factory(ecc);
bitcoin.initEccLib(ecc);
export interface GeneratedAddressInfo {
derivePath: string;
address: string;
}
export async function generate(
mnemonic: string,
network: 'mainnet' | 'testnet',
startIndex: number,
endIndex: number,
): Promise<GeneratedAddressInfo[]> {
const isTestnet = network !== 'mainnet';
const btcNetwork = isTestnet
? bitcoin.networks.testnet
: bitcoin.networks.bitcoin;
const seed = bip39.mnemonicToSeedSync(mnemonic);
const rootKey = bip32.fromSeed(seed, btcNetwork);
const generatedAddresses: GeneratedAddressInfo[] = [];
for (let i = startIndex; i < endIndex; i++) {
const derivePath = `m/86'/${isTestnet ? 1 : 0}'/${i /* account */}'/0/0`;
const derivedKey = rootKey.derivePath(derivePath);
const { address } = bitcoin.payments.p2tr({
// Since internalKey is an xOnly pubkey, we drop the DER header byte
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/52559f889cda4d51496c0f771b866e77831c913f/test/integration/taproot.spec.ts#L42
pubkey: derivedKey.publicKey.slice(1, 33),
network: btcNetwork,
});
generatedAddresses.push({
derivePath: `${derivePath}`,
address: address!,
});
}
return generatedAddresses;
}
if (require.main === module) {
if (process.argv.length < 4) {
console.log(
`Usage: ts-node generate-btc-ordinal-addresses.ts "[mainnet | testnet]" "[mnemonic]" "<address start index>" "<address end index>"`,
);
process.exit(0);
}
const [
_runner,
_binaryFilePath,
networkName,
mnemonic,
_startIndex = '0',
_endIndex = '1000',
] = process.argv;
const startIndex = Number(_startIndex);
const endIndex = Number(_endIndex);
generate(mnemonic, networkName as any, startIndex, endIndex)
.then(res => {
console.log(JSON.stringify(res, null, ' '));
})
.catch(err => {
console.error(err);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment