Skip to content

Commit

Permalink
📄 docs: build src after comment address namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonandjay committed Oct 5, 2023
1 parent 5382260 commit 6463bbc
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 0 deletions.
153 changes: 153 additions & 0 deletions src/address.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,170 @@
/// <reference types="node" />
/**
* bitcoin address decode and encode tools, include base58、bech32 and output script
*
* networks support bitcoin、litecoin、bitcoin testnet、litecoin testnet、bitcoin regtest、litecoin regtest and so on
*
* addresses support P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
*
* @packageDocumentation
*/
import { Network } from './networks';
/** base58check decode result */
export interface Base58CheckResult {
/** address hash */
hash: Buffer;
/** address version: 0x00 for P2PKH, 0x05 for P2SH */
version: number;
}
/** bech32 decode result */
export interface Bech32Result {
/** address version: 0x00 for P2WPKH、P2WSH, 0x01 for P2TR*/
version: number;
/** address prefix: bc for P2WPKH、P2WSH、P2TR */
prefix: string;
/** address data:20 bytes for P2WPKH, 32 bytes for P2WSH、P2TR */
data: Buffer;
}
/**
* decode address with base58 specification, return address version and address hash if valid
* @example
* ```ts
* // valid case
* fromBase58Check('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH')
* // => {version: 0, hash: <Buffer 75 1e 76 e8 19 91 96 d4 54 94 1c 45 d1 b3 a3 23 f1 43 3b d6>}
*
* // invalid case: address is too short
* fromBase58Check('7SeEnXWPaCCALbVrTnszCVGfRU8cGfx')
* // => throw new TypeError('7SeEnXWPaCCALbVrTnszCVGfRU8cGfx is too short')
*
* // invalid case: address is too long
* fromBase58Check('j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe')
* // => throw new TypeError('j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe is too long')
* ```
*/
export declare function fromBase58Check(address: string): Base58CheckResult;
/**
* decode address with bech32 specification, return address version、address prefix and address data if valid
* @example
* ```ts
* // valid case
* fromBech32('BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4')
* // => {version: 0, prefix: 'bc', data: <Buffer 75 1e 76 e8 19 91 96 d4 54 94 1c 45 d1 b3 a3 23 f1 43 3b d6>}
*
* // invalid case
* fromBase58Check('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5')
* // => Invalid checksum
*
* // invalid case
* fromBase58Check('tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7')
* // => Mixed-case string
*
* // invalid case
* fromBase58Check('tb1pw508d6qejxtdg4y5r3zarquvzkan')
* // => Excess padding
*
* // invalid case
* fromBase58Check('bc1zw508d6qejxtdg4y5r3zarvaryvq37eag7')
* // => Excess padding
*
* // invalid case
* fromBase58Check('bc1zw508d6qejxtdg4y5r3zarvaryvq37eag7')
* // => Non-zero padding
*
* // invalid case
* fromBase58Check('tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv')
* // => uses wrong encoding
*
* // invalid case
* fromBase58Check('bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd')
* // => uses wrong encoding
* ```
*/
export declare function fromBech32(address: string): Bech32Result;
/**
* encode address hash to base58 address with version
*
* @example
* ```ts
* // valid case
* toBase58Check('751e76e8199196d454941c45d1b3a323f1433bd6', 0)
* // => 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
* ```
*/
export declare function toBase58Check(hash: Buffer, version: number): string;
/**
* encode address hash to bech32 address with version and prefix
*
* @example
* ```ts
* // valid case
* toBech32('000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433', 0, 'tb)
* // => tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy
* ```
*/
export declare function toBech32(data: Buffer, version: number, prefix: string): string;
/**
* decode address from output script with network, return address if matched
* @example
* ```ts
* // valid case
* fromOutputScript('OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG', 'bicoin)
* // => 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
*
* // invalid case
* fromOutputScript('031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_TRUE 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_0 75', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_0 751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd675', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 75', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd675', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', undefined)
* // => has no matching Address
*
* ```
*/
export declare function fromOutputScript(output: Buffer, network?: Network): string;
/**
* encodes address to output script with network, return output script if address matched
* @example
* ```ts
* // valid case
* toOutputScript('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH', 'bicoin)
* // => OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG
*
* // invalid case
* toOutputScript('24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE', undefined)
* // => has no matching Script
*
* // invalid case
* toOutputScript('BC1SW50QGDZ25J', { "bech32": "foo" })
* // => has an invalid prefix
*
* // invalid case
* toOutputScript('bc1rw5uspcuh', undefined)
* // => has no matching Script
* ```
*/
export declare function toOutputScript(address: string, network?: Network): Buffer;
137 changes: 137 additions & 0 deletions src/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ function _toFutureSegwitAddress(output, network) {
console.warn(FUTURE_SEGWIT_VERSION_WARNING);
return toBech32(data, version, network.bech32);
}
/**
* decode address with base58 specification, return address version and address hash if valid
* @example
* ```ts
* // valid case
* fromBase58Check('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH')
* // => {version: 0, hash: <Buffer 75 1e 76 e8 19 91 96 d4 54 94 1c 45 d1 b3 a3 23 f1 43 3b d6>}
*
* // invalid case: address is too short
* fromBase58Check('7SeEnXWPaCCALbVrTnszCVGfRU8cGfx')
* // => throw new TypeError('7SeEnXWPaCCALbVrTnszCVGfRU8cGfx is too short')
*
* // invalid case: address is too long
* fromBase58Check('j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe')
* // => throw new TypeError('j9ywUkWg2fTQrouxxh5rSZhRvrjMkEUfuiKe is too long')
* ```
*/
function fromBase58Check(address) {
const payload = Buffer.from(bs58check.decode(address));
// TODO: 4.0.0, move to "toOutputScript"
Expand All @@ -51,6 +68,43 @@ function fromBase58Check(address) {
return { version, hash };
}
exports.fromBase58Check = fromBase58Check;
/**
* decode address with bech32 specification, return address version、address prefix and address data if valid
* @example
* ```ts
* // valid case
* fromBech32('BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4')
* // => {version: 0, prefix: 'bc', data: <Buffer 75 1e 76 e8 19 91 96 d4 54 94 1c 45 d1 b3 a3 23 f1 43 3b d6>}
*
* // invalid case
* fromBase58Check('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5')
* // => Invalid checksum
*
* // invalid case
* fromBase58Check('tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7')
* // => Mixed-case string
*
* // invalid case
* fromBase58Check('tb1pw508d6qejxtdg4y5r3zarquvzkan')
* // => Excess padding
*
* // invalid case
* fromBase58Check('bc1zw508d6qejxtdg4y5r3zarvaryvq37eag7')
* // => Excess padding
*
* // invalid case
* fromBase58Check('bc1zw508d6qejxtdg4y5r3zarvaryvq37eag7')
* // => Non-zero padding
*
* // invalid case
* fromBase58Check('tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv')
* // => uses wrong encoding
*
* // invalid case
* fromBase58Check('bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd')
* // => uses wrong encoding
* ```
*/
function fromBech32(address) {
let result;
let version;
Expand All @@ -73,6 +127,16 @@ function fromBech32(address) {
};
}
exports.fromBech32 = fromBech32;
/**
* encode address hash to base58 address with version
*
* @example
* ```ts
* // valid case
* toBase58Check('751e76e8199196d454941c45d1b3a323f1433bd6', 0)
* // => 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
* ```
*/
function toBase58Check(hash, version) {
(0, types_1.typeforce)(
(0, types_1.tuple)(types_1.Hash160bit, types_1.UInt8),
Expand All @@ -84,6 +148,16 @@ function toBase58Check(hash, version) {
return bs58check.encode(payload);
}
exports.toBase58Check = toBase58Check;
/**
* encode address hash to bech32 address with version and prefix
*
* @example
* ```ts
* // valid case
* toBech32('000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433', 0, 'tb)
* // => tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy
* ```
*/
function toBech32(data, version, prefix) {
const words = bech32_1.bech32.toWords(data);
words.unshift(version);
Expand All @@ -92,6 +166,48 @@ function toBech32(data, version, prefix) {
: bech32_1.bech32m.encode(prefix, words);
}
exports.toBech32 = toBech32;
/**
* decode address from output script with network, return address if matched
* @example
* ```ts
* // valid case
* fromOutputScript('OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG', 'bicoin)
* // => 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
*
* // invalid case
* fromOutputScript('031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_TRUE 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_0 75', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_0 751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd675', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 75', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd675', undefined)
* // => has no matching Address
*
* // invalid case
* fromOutputScript('OP_1 fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', undefined)
* // => has no matching Address
*
* ```
*/
function fromOutputScript(output, network) {
// TODO: Network
network = network || networks.bitcoin;
Expand All @@ -116,6 +232,27 @@ function fromOutputScript(output, network) {
throw new Error(bscript.toASM(output) + ' has no matching Address');
}
exports.fromOutputScript = fromOutputScript;
/**
* encodes address to output script with network, return output script if address matched
* @example
* ```ts
* // valid case
* toOutputScript('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH', 'bicoin)
* // => OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG
*
* // invalid case
* toOutputScript('24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE', undefined)
* // => has no matching Script
*
* // invalid case
* toOutputScript('BC1SW50QGDZ25J', { "bech32": "foo" })
* // => has an invalid prefix
*
* // invalid case
* toOutputScript('bc1rw5uspcuh', undefined)
* // => has no matching Script
* ```
*/
function toOutputScript(address, network) {
network = network || networks.bitcoin;
let decodeBase58;
Expand Down
4 changes: 4 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ import * as payments from './payments';
import * as script from './script';
export { address, crypto, networks, payments, script };
export { Block } from './block';
/** @hidden */
export { TaggedHashPrefix } from './crypto';
export { Psbt, PsbtTxInput, PsbtTxOutput, Signer, SignerAsync, HDSigner, HDSignerAsync, } from './psbt';
/** @hidden */
export { OPS as opcodes } from './ops';
export { Transaction } from './transaction';
/** @hidden */
export { Network } from './networks';
/** @hidden */
export { Payment, PaymentCreator, PaymentOpts, Stack, StackElement, } from './payments';
export { Input as TxInput, Output as TxOutput } from './transaction';
export { initEccLib } from './ecc_lib';
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Object.defineProperty(exports, 'Psbt', {
return psbt_1.Psbt;
},
});
/** @hidden */
var ops_1 = require('./ops');
Object.defineProperty(exports, 'opcodes', {
enumerable: true,
Expand Down
Loading

0 comments on commit 6463bbc

Please sign in to comment.