@exodus/bip322-js 1.1.0-rc.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,42 @@
1
- import secp256k1 from '@exodus/secp256k1';
2
- import * as bitcoinMessage from 'bitcoinjs-message';
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ // Import dependencies
27
+ const secp256k1_1 = require("@exodus/secp256k1");
28
+ const bitcoinMessage = __importStar(require("bitcoinjs-message"));
29
+ /**
30
+ * Class that implement BIP137-related utility functions.
31
+ */
3
32
  class BIP137 {
33
+ /**
34
+ * Check if a given signature satisified the format of a BIP-137 signature.
35
+ * @param signature Base64-encoded signature to be checked
36
+ * @returns True if the provided signature correspond to a valid BIP-137 signature, false if otherwise
37
+ */
4
38
  static isBIP137Signature(signature) {
39
+ // Check if the provided signature satisified the format of a BIP-137 signature
5
40
  const signatureBuffer = Buffer.from(signature, 'base64');
6
41
  if (signatureBuffer.byteLength === 65) {
7
42
  return true;
@@ -10,12 +45,27 @@ class BIP137 {
10
45
  return false;
11
46
  }
12
47
  }
48
+ /**
49
+ * Derive the public key that signed a valid BIP-137 signature.
50
+ * @param message Message signed by the signature
51
+ * @param signature Base-64 encoded signature to be decoded
52
+ * @returns Public key that signs the provided signature
53
+ */
13
54
  static derivePubKey(message, signature) {
55
+ // Compute the hash signed by the signer
14
56
  const messageHash = bitcoinMessage.magicHash(message);
57
+ // Decode the provided BIP-137 signature
15
58
  const signatureDecoded = this.decodeSignature(Buffer.from(signature, 'base64'));
16
- const recoveredPublicKey = secp256k1.ecdsaRecover(signatureDecoded.signature, signatureDecoded.recovery, messageHash, signatureDecoded.compressed);
59
+ // Recover the public key
60
+ const recoveredPublicKey = (0, secp256k1_1.ecdsaRecover)(signatureDecoded.signature, signatureDecoded.recovery, messageHash, signatureDecoded.compressed);
17
61
  return Buffer.from(recoveredPublicKey);
18
62
  }
63
+ /**
64
+ * Decode a BIP-137 signature.
65
+ * Function copied from bitcoinjs-message library.
66
+ * @param signature BIP-137 signature to be decoded
67
+ * @returns Decoded BIP-137 signature
68
+ */
19
69
  static decodeSignature(signature) {
20
70
  if (signature.length !== 65)
21
71
  throw new Error('Invalid signature length');
@@ -30,5 +80,5 @@ class BIP137 {
30
80
  };
31
81
  }
32
82
  }
33
- export default BIP137;
83
+ exports.default = BIP137;
34
84
  //# sourceMappingURL=BIP137.js.map
@@ -1,5 +1,22 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Class that implement variable length integer (VarInt) in Javascript.
4
+ * Reference: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
5
+ */
1
6
  declare class VarInt {
7
+ /**
8
+ * Encode an integer i as a variable length integer.
9
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L180
10
+ * @param i Integer to be encoded
11
+ * @returns Encoded varint
12
+ */
2
13
  static encode(i: number): Buffer;
14
+ /**
15
+ * Decode a variable length integer from a Buffer into a number.
16
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L160
17
+ * @param b Buffer which contain the varint
18
+ * @returns Decoded number
19
+ */
3
20
  static decode(b: Buffer): number;
4
21
  }
5
22
  export default VarInt;
@@ -1,4 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Class that implement variable length integer (VarInt) in Javascript.
5
+ * Reference: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer
6
+ */
1
7
  class VarInt {
8
+ /**
9
+ * Encode an integer i as a variable length integer.
10
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L180
11
+ * @param i Integer to be encoded
12
+ * @returns Encoded varint
13
+ */
2
14
  static encode(i) {
3
15
  if (i < 0xFD) {
4
16
  const buffer = Buffer.alloc(1);
@@ -20,8 +32,8 @@ class VarInt {
20
32
  else if (i < 0x1000000000000) {
21
33
  const buffer = Buffer.alloc(9);
22
34
  buffer.writeUInt8(0xff);
23
- buffer.writeUIntLE(i, 1, 6);
24
- buffer.writeUInt8(0x00, 7);
35
+ buffer.writeUIntLE(i, 1, 6); // Cannot write UInt64LE in Node JS
36
+ buffer.writeUInt8(0x00, 7); // Pad two extra 0x00 at the end to emulate UInt64LE
25
37
  buffer.writeUInt8(0x00, 8);
26
38
  return buffer;
27
39
  }
@@ -29,24 +41,37 @@ class VarInt {
29
41
  throw new Error(`Integer too large: ${i}`);
30
42
  }
31
43
  }
44
+ /**
45
+ * Decode a variable length integer from a Buffer into a number.
46
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L160
47
+ * @param b Buffer which contain the varint
48
+ * @returns Decoded number
49
+ */
32
50
  static decode(b) {
51
+ // Check for empty buffer
33
52
  if (b.byteLength === 0) {
34
53
  throw new Error('Empty buffer provided');
35
54
  }
55
+ // Read first byte from the buffer
36
56
  const i = b.readUInt8();
57
+ // Check if i is indicating its length
37
58
  if (i === 0xfd) {
59
+ // 0xfd means the next two bytes are the number
38
60
  return b.readUInt16LE(1);
39
61
  }
40
62
  else if (i === 0xfe) {
63
+ // 0xfe means the next four bytes are the number
41
64
  return b.readUInt32LE(1);
42
65
  }
43
66
  else if (i === 0xff) {
67
+ // 0xff means the next eight bytes are the number, but Node JS can only read up to 6 bytes
44
68
  return b.readUIntLE(1, 6);
45
69
  }
46
70
  else {
71
+ // Anything else is just the integer
47
72
  return i;
48
73
  }
49
74
  }
50
75
  }
51
- export default VarInt;
76
+ exports.default = VarInt;
52
77
  //# sourceMappingURL=VarInt.js.map
@@ -1,5 +1,22 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Class that implement variable length string (VarStr) in Javascript.
4
+ * Reference: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_string
5
+ */
1
6
  declare class VarStr {
7
+ /**
8
+ * Encode a string buffer as a variable length string.
9
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L203
10
+ * @param s String buffer to be encoded
11
+ * @returns Encoded varstr
12
+ */
2
13
  static encode(s: Buffer): Buffer;
14
+ /**
15
+ * Decode a variable length string from a Buffer into a string buffer.
16
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L194
17
+ * @param v Varstr to be decoded
18
+ * @returns Decoded string buffer
19
+ */
3
20
  static decode(v: Buffer): Buffer;
4
21
  }
5
22
  export default VarStr;
@@ -1,14 +1,41 @@
1
- import VarInt from "./VarInt";
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // Import dependency
7
+ const VarInt_1 = __importDefault(require("./VarInt"));
8
+ /**
9
+ * Class that implement variable length string (VarStr) in Javascript.
10
+ * Reference: https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_string
11
+ */
2
12
  class VarStr {
13
+ /**
14
+ * Encode a string buffer as a variable length string.
15
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L203
16
+ * @param s String buffer to be encoded
17
+ * @returns Encoded varstr
18
+ */
3
19
  static encode(s) {
4
- const lengthBuffer = VarInt.encode(s.length);
20
+ // Encode the length of the string using encodeVarInt
21
+ const lengthBuffer = VarInt_1.default.encode(s.length);
22
+ // Concat the actual string right after the length of the string
5
23
  return Buffer.concat([lengthBuffer, s]);
6
24
  }
25
+ /**
26
+ * Decode a variable length string from a Buffer into a string buffer.
27
+ * Reference: https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/helper.py#L194
28
+ * @param v Varstr to be decoded
29
+ * @returns Decoded string buffer
30
+ */
7
31
  static decode(v) {
8
- const length = VarInt.decode(v);
9
- const lengthByteLength = VarInt.encode(length).byteLength;
32
+ // Find the length of the string by using read_varint on the string
33
+ const length = VarInt_1.default.decode(v);
34
+ // Get the length of the VarInt used to represent the length of the string
35
+ const lengthByteLength = VarInt_1.default.encode(length).byteLength;
36
+ // Return from lengthByteLength to (length + lengthByteLength) in the buffer which contain the actual string
10
37
  return v.subarray(lengthByteLength, length + lengthByteLength);
11
38
  }
12
39
  }
13
- export default VarStr;
40
+ exports.default = VarStr;
14
41
  //# sourceMappingURL=VarStr.js.map
@@ -1,5 +1,23 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Class that implement witness data serialization and deserialization.
4
+ */
1
5
  declare class Witness {
6
+ /**
7
+ * Encode array of witness into its base-64 encoded format.
8
+ * Follows the encoding scheme found in buidl-python:
9
+ * https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/witness.py#L35
10
+ * @param witnesses Array of witness data
11
+ * @returns Base-64 encoded witness data
12
+ */
2
13
  static serialize(witnesses: Uint8Array[]): string;
14
+ /**
15
+ * Decode encoded witness data, either as a base-64 encoded string or as a decoded string in a buffer, into an array of witness.
16
+ * Follows the decoding scheme found in buidl-python:
17
+ * https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/witness.py#L62
18
+ * @param encodedWitness Base-64 encoded witness data, or encoded witness data that have already been decoded
19
+ * @returns Decoded witness data
20
+ */
3
21
  static deserialize(encodedWitness: string | Buffer): Buffer[];
4
22
  }
5
23
  export default Witness;
@@ -1,33 +1,70 @@
1
- import VarInt from "./VarInt";
2
- import VarStr from "./VarStr";
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // Import dependencies
7
+ const VarInt_1 = __importDefault(require("./VarInt"));
8
+ const VarStr_1 = __importDefault(require("./VarStr"));
9
+ /**
10
+ * Class that implement witness data serialization and deserialization.
11
+ */
3
12
  class Witness {
13
+ /**
14
+ * Encode array of witness into its base-64 encoded format.
15
+ * Follows the encoding scheme found in buidl-python:
16
+ * https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/witness.py#L35
17
+ * @param witnesses Array of witness data
18
+ * @returns Base-64 encoded witness data
19
+ */
4
20
  static serialize(witnesses) {
5
- let witnessStack = VarInt.encode(witnesses.length);
21
+ // The first element to be included is the length of the witness array as VarInt
22
+ let witnessStack = VarInt_1.default.encode(witnesses.length);
23
+ // Then, for each witness array,
6
24
  witnesses.forEach((witness) => {
7
- witnessStack = Buffer.concat([witnessStack, VarStr.encode(Buffer.from(witness))]);
25
+ // Append each witness as a VarStr to the witness stack
26
+ witnessStack = Buffer.concat([witnessStack, VarStr_1.default.encode(Buffer.from(witness))]);
8
27
  });
28
+ // Return the base-64 encoded witness stack
9
29
  return witnessStack.toString('base64');
10
30
  }
31
+ /**
32
+ * Decode encoded witness data, either as a base-64 encoded string or as a decoded string in a buffer, into an array of witness.
33
+ * Follows the decoding scheme found in buidl-python:
34
+ * https://github.com/buidl-bitcoin/buidl-python/blob/d79e9808e8ca60975d315be41293cb40d968626d/buidl/witness.py#L62
35
+ * @param encodedWitness Base-64 encoded witness data, or encoded witness data that have already been decoded
36
+ * @returns Decoded witness data
37
+ */
11
38
  static deserialize(encodedWitness) {
39
+ // Store the decoded witness stack
12
40
  let witnessDecoded = [];
41
+ // Preprocess the encodedWitness if needed
13
42
  let witnessToDecode;
14
43
  if (typeof encodedWitness === 'string') {
44
+ // Decode the encoded witness if it is a string (assuming it is encoded using base-64)
15
45
  witnessToDecode = Buffer.from(encodedWitness, 'base64');
16
46
  }
17
47
  else {
18
48
  witnessToDecode = encodedWitness;
19
49
  }
20
- const witnessCount = VarInt.decode(witnessToDecode);
21
- const varIntLength = VarInt.encode(witnessCount).byteLength;
50
+ // Read a VarInt which indicate the number of elements within the original witness array
51
+ const witnessCount = VarInt_1.default.decode(witnessToDecode);
52
+ // Slice the VarInt in front of the witness buffer before decoding each witness
53
+ const varIntLength = VarInt_1.default.encode(witnessCount).byteLength;
22
54
  witnessToDecode = witnessToDecode.subarray(varIntLength);
55
+ // Loop for each witness encoded
23
56
  for (let i = 0; i < witnessCount; i++) {
24
- const witness = VarStr.decode(witnessToDecode);
57
+ // Read a VarStr from the remaining buffer
58
+ const witness = VarStr_1.default.decode(witnessToDecode);
59
+ // Append the decoded witness to witnessDecoded
25
60
  witnessDecoded.push(witness);
26
- const witnessLength = VarStr.encode(witness).byteLength;
61
+ // Slice the read witness off witnessToDecode before next iteration
62
+ const witnessLength = VarStr_1.default.encode(witness).byteLength;
27
63
  witnessToDecode = witnessToDecode.subarray(witnessLength);
28
64
  }
65
+ // Return deserialized witness data
29
66
  return witnessDecoded;
30
67
  }
31
68
  }
32
- export default Witness;
69
+ exports.default = Witness;
33
70
  //# sourceMappingURL=Witness.js.map
@@ -1,7 +1,17 @@
1
- import Address from "./Address";
2
- import BIP137 from "./BIP137";
3
- import VarInt from "./VarInt";
4
- import VarStr from "./VarStr";
5
- import Witness from "./Witness";
6
- export { Address, BIP137, VarInt, VarStr, Witness };
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Witness = exports.VarStr = exports.VarInt = exports.BIP137 = exports.Address = void 0;
7
+ const Address_1 = __importDefault(require("./Address"));
8
+ exports.Address = Address_1.default;
9
+ const BIP137_1 = __importDefault(require("./BIP137"));
10
+ exports.BIP137 = BIP137_1.default;
11
+ const VarInt_1 = __importDefault(require("./VarInt"));
12
+ exports.VarInt = VarInt_1.default;
13
+ const VarStr_1 = __importDefault(require("./VarStr"));
14
+ exports.VarStr = VarStr_1.default;
15
+ const Witness_1 = __importDefault(require("./Witness"));
16
+ exports.Witness = Witness_1.default;
7
17
  //# sourceMappingURL=index.js.map
package/dist/index.js CHANGED
@@ -1,6 +1,18 @@
1
- import BIP322 from "./BIP322";
2
- import Signer from "./Signer";
3
- import Verifier from "./Verifier";
4
- import { Witness, Address, BIP137 } from "./helpers";
5
- export { BIP322, Signer, Verifier, Witness, Address, BIP137 };
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BIP137 = exports.Address = exports.Witness = exports.Verifier = exports.Signer = exports.BIP322 = void 0;
7
+ // Import modules to be exported
8
+ const BIP322_1 = __importDefault(require("./BIP322"));
9
+ exports.BIP322 = BIP322_1.default;
10
+ const Signer_1 = __importDefault(require("./Signer"));
11
+ exports.Signer = Signer_1.default;
12
+ const Verifier_1 = __importDefault(require("./Verifier"));
13
+ exports.Verifier = Verifier_1.default;
14
+ const helpers_1 = require("./helpers");
15
+ Object.defineProperty(exports, "Witness", { enumerable: true, get: function () { return helpers_1.Witness; } });
16
+ Object.defineProperty(exports, "Address", { enumerable: true, get: function () { return helpers_1.Address; } });
17
+ Object.defineProperty(exports, "BIP137", { enumerable: true, get: function () { return helpers_1.BIP137; } });
6
18
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,48 +1,46 @@
1
1
  {
2
- "name": "@exodus/bip322-js",
3
- "version": "1.1.0-rc.0",
4
- "description": "A Javascript library that provides utility functions related to the BIP-322 signature scheme",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "type": "module",
8
- "publishConfig": {
9
- "access": "restricted"
10
- },
11
- "scripts": {
12
- "build": "tsc",
13
- "doc": "typedoc src/index.ts",
14
- "prepack": "npm run build",
15
- "test": "run -T exodus-test --jest --esbuild"
16
- },
17
- "keywords": [
18
- "bip322",
19
- "bitcoinjs",
20
- "javascript",
21
- "typescript",
22
- "no-WASM"
23
- ],
24
- "author": "Ken Sze <acken2@outlook.com>",
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/ExodusMovement/exodus-hydra.git.git"
28
- },
29
- "license": "MIT",
30
- "devDependencies": {
31
- "@types/create-hash": "^1",
32
- "@types/node": "^20.2.5",
33
- "typedoc": "^0.24.8",
34
- "typescript": "^5.1.3"
35
- },
36
- "dependencies": {
37
- "@exodus/bitcoinerlab-secp256k1": "^1.0.5-exodus.1",
38
- "@exodus/bitcoinjs": "^1.1.0",
39
- "@exodus/secp256k1": "4.0.2-exodus.0",
40
- "bitcoinjs-message": "^2.2.0",
41
- "create-hash": "^1.2.0"
42
- },
43
- "homepage": "https://github.com/ExodusMovement/exodus-hydra.git/tree/master/libraries/bip322-js",
44
- "bugs": {
45
- "url": "https://github.com/ExodusMovement/exodus-hydra.git/issues?q=is%3Aissue+is%3Aopen+label%3Abip322-js"
46
- },
47
- "gitHead": "81d6f87cbb318c861c654a3001f2a0cfa54ac912"
2
+ "name": "@exodus/bip322-js",
3
+ "version": "1.1.0",
4
+ "description": "A Javascript library that provides utility functions related to the BIP-322 signature scheme",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "restricted"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "doc": "typedoc src/index.ts",
13
+ "prepack": "npm run build",
14
+ "test": "jest",
15
+ "test:coverage": "nyc --reporter=text --reporter=text-summary --reporter=lcov npm test"
16
+ },
17
+ "keywords": [
18
+ "bip322",
19
+ "bitcoinjs",
20
+ "javascript",
21
+ "typescript",
22
+ "no-WASM"
23
+ ],
24
+ "author": "Ken Sze <acken2@outlook.com>",
25
+ "repository": "https://github.com/ExodusMovement/bip322-js/",
26
+ "license": "MIT",
27
+ "devDependencies": {
28
+ "@babel/core": "^7.22.20",
29
+ "@babel/preset-env": "^7.22.20",
30
+ "@babel/preset-flow": "^7.22.15",
31
+ "@babel/preset-typescript": "^7.22.15",
32
+ "@types/node": "^20.2.5",
33
+ "@types/secp256k1": "^4.0.3",
34
+ "babel-jest": "^29.7.0",
35
+ "jest": "^29.7.0",
36
+ "nyc": "^15.1.0",
37
+ "typedoc": "^0.24.8",
38
+ "typescript": "^5.1.3"
39
+ },
40
+ "dependencies": {
41
+ "@exodus/secp256k1": "4.0.2-exodus.0",
42
+ "@exodus/bitcoinjs-lib": "^6.1.6",
43
+ "bitcoinjs-message": "^2.2.0",
44
+ "ecpair": "^2.0.1"
45
+ }
48
46
  }