Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 1x 1x 1x 7x 14x 1x 6x 6x 6x 11x 11x 1x 10x 10x 10x 10x | import { BitcoinError, BitcoinErrorCode, Network } from ".";
import { Base58Check } from "./Base58Check";
export type WifDecodeResult = {
privateKey: Buffer;
compressed: boolean;
prefix: number;
};
export class Wif {
/**
* Finds the associated network for the given prefix
* @param prefix single byte prefix
* @returns
*/
public static decodePrefix(prefix: number): Network {
for (const network of Network.all) {
if (network.wifPrefix === prefix) return network;
}
throw new BitcoinError(BitcoinErrorCode.UnknownWifPrefix, { prefix });
}
/**
* Encodes a private key using the WIF format. Can encode with compressed
* or uncompressed format and can be for testnet or mainnet.
*
* Mainnet prefix: 0x80
* Testnet prefix: 0xef
*
* Algorithm for WIF is:
* 1. Start with the prefix
* 2. Encode the secret in 32-byte big-endian format
* 3. If the SEC format used for the public key address was compressed add
* a suffix of 0x01
* 4. Combine wthe prefix from #1, serialized secret from #2, and suffix from #3
* 5. Do hash256 of the result from #4 and get the first 4 bytes
* 6. Take the combination of #4 and #5 and encode it with Base58
*
* @param prefix a single byte prefix, usually 0x05 for mainnet or 0xef for testnet
* @param privateKey a 32-byte private key as a big-endian buffer
* @param compressed default of true
*/
public static encode(prefix: number, privateKey: Buffer, compressed: boolean = true) {
// 1. prefix
const prefixBuf = Buffer.from([prefix]);
// 2. encode as 32-byte big-endian number
// 3. suffix
const suffix = compressed ? Buffer.from([0x01]) : Buffer.alloc(0);
// 4. combine 1, 2, and 3
return Base58Check.encode(Buffer.concat([prefixBuf, privateKey, suffix]));
}
/**
* To decode a WIF value, we must first decode the base58check
* input. If this validates then we need to split the resulting
* buffer of data into two or three parts.
*
* The first byte is the prefix
* The next 32-bytes are the private key
*
* @param buf
*/
public static decode(input: string): WifDecodeResult {
const raw = Base58Check.decode(input);
if (raw.length !== 33 && raw.length !== 34) {
throw new BitcoinError(BitcoinErrorCode.InvalidWifEncoding, { input });
}
// prefix is the first byte
const prefix = raw[0];
// next 32-bytes are the private key
const privateKey = raw.slice(1, 33);
// check for compressed byte
const compressed = raw.length === 34 && raw[33] === 0x01;
// return our result object
return { privateKey, compressed, prefix };
}
}
|