koilib 5.1.1 → 5.2.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.
package/dist/koinos.js CHANGED
@@ -10675,6 +10675,14 @@ class Serializer {
10675
10675
  * Preformat bytes for base64url, base58 or hex string
10676
10676
  */
10677
10677
  this.bytesConversion = true;
10678
+ /**
10679
+ * Verify checksum in addresses during serialization
10680
+ * or deserialization
10681
+ */
10682
+ this.verifyChecksum = {
10683
+ serialize: true,
10684
+ deserialize: false,
10685
+ };
10678
10686
  this.types = types;
10679
10687
  this.root = light_1.Root.fromJSON(this.types);
10680
10688
  if (opts === null || opts === void 0 ? void 0 : opts.defaultTypeName)
@@ -10682,7 +10690,7 @@ class Serializer {
10682
10690
  if (opts && typeof opts.bytesConversion !== "undefined")
10683
10691
  this.bytesConversion = opts.bytesConversion;
10684
10692
  }
10685
- btypeDecode(valueBtypeEncoded, protobufType) {
10693
+ btypeDecode(valueBtypeEncoded, protobufType, verifyChecksum) {
10686
10694
  const valueBtypeDecoded = {};
10687
10695
  Object.keys(protobufType.fields).forEach((fieldName) => {
10688
10696
  // @ts-ignore
@@ -10706,10 +10714,10 @@ class Serializer {
10706
10714
  // it's an enum
10707
10715
  return itemEncoded;
10708
10716
  }
10709
- return this.btypeDecode(itemEncoded, protoBuf);
10717
+ return this.btypeDecode(itemEncoded, protoBuf, verifyChecksum);
10710
10718
  }
10711
10719
  // native types
10712
- return (0, utils_1.btypeDecodeValue)(itemEncoded, typeField);
10720
+ return (0, utils_1.btypeDecodeValue)(itemEncoded, typeField, verifyChecksum);
10713
10721
  });
10714
10722
  return;
10715
10723
  }
@@ -10721,15 +10729,15 @@ class Serializer {
10721
10729
  valueBtypeDecoded[name] = valueBtypeEncoded[name];
10722
10730
  return;
10723
10731
  }
10724
- valueBtypeDecoded[name] = this.btypeDecode(valueBtypeEncoded[name], protoBuf);
10732
+ valueBtypeDecoded[name] = this.btypeDecode(valueBtypeEncoded[name], protoBuf, verifyChecksum);
10725
10733
  return;
10726
10734
  }
10727
10735
  // native types
10728
- valueBtypeDecoded[name] = (0, utils_1.btypeDecodeValue)(valueBtypeEncoded[name], typeField);
10736
+ valueBtypeDecoded[name] = (0, utils_1.btypeDecodeValue)(valueBtypeEncoded[name], typeField, verifyChecksum);
10729
10737
  });
10730
10738
  return valueBtypeDecoded;
10731
10739
  }
10732
- btypeEncode(valueBtypeDecoded, protobufType) {
10740
+ btypeEncode(valueBtypeDecoded, protobufType, verifyChecksum) {
10733
10741
  const valueBtypeEncoded = {};
10734
10742
  Object.keys(protobufType.fields).forEach((fieldName) => {
10735
10743
  // @ts-ignore
@@ -10753,10 +10761,10 @@ class Serializer {
10753
10761
  // it's an enum
10754
10762
  return itemDecoded;
10755
10763
  }
10756
- return this.btypeEncode(itemDecoded, protoBuf);
10764
+ return this.btypeEncode(itemDecoded, protoBuf, verifyChecksum);
10757
10765
  }
10758
10766
  // native types
10759
- return (0, utils_1.btypeEncodeValue)(itemDecoded, typeField);
10767
+ return (0, utils_1.btypeEncodeValue)(itemDecoded, typeField, verifyChecksum);
10760
10768
  });
10761
10769
  return;
10762
10770
  }
@@ -10768,11 +10776,11 @@ class Serializer {
10768
10776
  valueBtypeEncoded[name] = valueBtypeDecoded[name];
10769
10777
  return;
10770
10778
  }
10771
- valueBtypeEncoded[name] = this.btypeEncode(valueBtypeDecoded[name], protoBuf);
10779
+ valueBtypeEncoded[name] = this.btypeEncode(valueBtypeDecoded[name], protoBuf, verifyChecksum);
10772
10780
  return;
10773
10781
  }
10774
10782
  // native types
10775
- valueBtypeEncoded[name] = (0, utils_1.btypeEncodeValue)(valueBtypeDecoded[name], typeField);
10783
+ valueBtypeEncoded[name] = (0, utils_1.btypeEncodeValue)(valueBtypeDecoded[name], typeField, verifyChecksum);
10776
10784
  });
10777
10785
  return valueBtypeEncoded;
10778
10786
  }
@@ -10787,8 +10795,11 @@ class Serializer {
10787
10795
  const bytesConversion = (opts === null || opts === void 0 ? void 0 : opts.bytesConversion) === undefined
10788
10796
  ? this.bytesConversion
10789
10797
  : opts.bytesConversion;
10798
+ const verifyChecksum = (opts === null || opts === void 0 ? void 0 : opts.verifyChecksum) === undefined
10799
+ ? this.verifyChecksum.serialize
10800
+ : opts.verifyChecksum;
10790
10801
  if (bytesConversion) {
10791
- object = this.btypeDecode(valueDecoded, protobufType);
10802
+ object = this.btypeDecode(valueDecoded, protobufType, verifyChecksum);
10792
10803
  }
10793
10804
  else {
10794
10805
  object = valueDecoded;
@@ -10815,8 +10826,11 @@ class Serializer {
10815
10826
  const bytesConversion = (opts === null || opts === void 0 ? void 0 : opts.bytesConversion) === undefined
10816
10827
  ? this.bytesConversion
10817
10828
  : opts.bytesConversion;
10829
+ const verifyChecksum = (opts === null || opts === void 0 ? void 0 : opts.verifyChecksum) === undefined
10830
+ ? this.verifyChecksum.deserialize
10831
+ : opts.verifyChecksum;
10818
10832
  if (bytesConversion) {
10819
- return this.btypeEncode(object, protobufType);
10833
+ return this.btypeEncode(object, protobufType, verifyChecksum);
10820
10834
  }
10821
10835
  return object;
10822
10836
  }
@@ -10919,6 +10933,13 @@ const btypesOperation = {
10919
10933
  },
10920
10934
  },
10921
10935
  },
10936
+ set_system_contract: {
10937
+ type: "object",
10938
+ subtypes: {
10939
+ contract_id: { type: "bytes", btype: "CONTRACT_ID" },
10940
+ system_contract: { type: "bool" },
10941
+ },
10942
+ },
10922
10943
  };
10923
10944
  /**
10924
10945
  * The Signer Class contains the private key needed to sign transactions.
@@ -11270,7 +11291,7 @@ class Signer {
11270
11291
  if (!block.signature)
11271
11292
  throw new Error("Missing block signature");
11272
11293
  signatures = [block.signature];
11273
- const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader);
11294
+ const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader, false);
11274
11295
  const message = protocol_proto_js_1.koinos.protocol.block_header.create(headerDecoded);
11275
11296
  headerBytes = protocol_proto_js_1.koinos.protocol.block_header.encode(message).finish();
11276
11297
  }
@@ -11281,7 +11302,7 @@ class Signer {
11281
11302
  if (!transaction.signatures)
11282
11303
  throw new Error("Missing transaction signatures");
11283
11304
  signatures = transaction.signatures;
11284
- const headerDecoded = (0, utils_1.btypeDecode)(transaction.header, btypeTransactionHeader);
11305
+ const headerDecoded = (0, utils_1.btypeDecode)(transaction.header, btypeTransactionHeader, false);
11285
11306
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11286
11307
  headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header.encode(message).finish();
11287
11308
  }
@@ -11394,7 +11415,7 @@ class Signer {
11394
11415
  const operationsHashes = [];
11395
11416
  if (tx.operations) {
11396
11417
  for (let index = 0; index < ((_b = tx.operations) === null || _b === void 0 ? void 0 : _b.length); index += 1) {
11397
- const operationDecoded = (0, utils_1.btypeDecode)(tx.operations[index], btypesOperation);
11418
+ const operationDecoded = (0, utils_1.btypeDecode)(tx.operations[index], btypesOperation, false);
11398
11419
  const message = protocol_proto_js_1.koinos.protocol.operation.create(operationDecoded);
11399
11420
  const operationEncoded = protocol_proto_js_1.koinos.protocol.operation
11400
11421
  .encode(message)
@@ -11417,7 +11438,7 @@ class Signer {
11417
11438
  ...(payee && { payee }),
11418
11439
  // TODO: Option to resolve names (payer, payee)
11419
11440
  };
11420
- const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader);
11441
+ const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader, false);
11421
11442
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11422
11443
  const headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header
11423
11444
  .encode(message)
@@ -11441,7 +11462,7 @@ class Signer {
11441
11462
  if (block.transactions) {
11442
11463
  for (let index = 0; index < block.transactions.length; index++) {
11443
11464
  const tx = block.transactions[index];
11444
- const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader);
11465
+ const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader, false);
11445
11466
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11446
11467
  const headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header
11447
11468
  .encode(message)
@@ -11483,7 +11504,7 @@ class Signer {
11483
11504
  ])),
11484
11505
  signer: this.address,
11485
11506
  };
11486
- const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader);
11507
+ const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader, false);
11487
11508
  const message = protocol_proto_js_1.koinos.protocol.block_header.create(headerDecoded);
11488
11509
  const headerBytes = protocol_proto_js_1.koinos.protocol.block_header
11489
11510
  .encode(message)
@@ -11576,7 +11597,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11576
11597
  return (mod && mod.__esModule) ? mod : { "default": mod };
11577
11598
  };
11578
11599
  Object.defineProperty(exports, "__esModule", ({ value: true }));
11579
- exports.tokenAbi = exports.btypeEncode = exports.btypeDecode = exports.btypeEncodeValue = exports.btypeDecodeValue = exports.parseUnits = exports.formatUnits = exports.bitcoinAddress = exports.bitcoinDecode = exports.bitcoinEncode = exports.calculateMerkleRoot = exports.decodeBase64 = exports.multihash = exports.encodeBase64 = exports.decodeBase64url = exports.encodeBase64url = exports.decodeBase58 = exports.encodeBase58 = exports.toHexString = exports.toUint8Array = void 0;
11600
+ exports.tokenAbi = exports.btypeEncode = exports.btypeDecode = exports.btypeEncodeValue = exports.btypeDecodeValue = exports.parseUnits = exports.formatUnits = exports.isChecksumWif = exports.isChecksumAddress = exports.isChecksum = exports.bitcoinAddress = exports.bitcoinDecode = exports.bitcoinEncode = exports.calculateMerkleRoot = exports.decodeBase64 = exports.multihash = exports.encodeBase64 = exports.decodeBase64url = exports.encodeBase64url = exports.decodeBase58 = exports.encodeBase58 = exports.toHexString = exports.toUint8Array = void 0;
11580
11601
  const multibase = __importStar(__webpack_require__(6957));
11581
11602
  const sha256_1 = __webpack_require__(3061);
11582
11603
  const ripemd160_1 = __webpack_require__(830);
@@ -11757,6 +11778,82 @@ function bitcoinAddress(publicKey) {
11757
11778
  return bitcoinEncode(hash160, "public");
11758
11779
  }
11759
11780
  exports.bitcoinAddress = bitcoinAddress;
11781
+ /**
11782
+ * Checks if the last 4 bytes matches with the double sha256
11783
+ * of the first part
11784
+ */
11785
+ function isChecksum(buffer) {
11786
+ const dataLength = buffer.length - 4;
11787
+ const data = new Uint8Array(dataLength);
11788
+ data.set(buffer.slice(0, dataLength));
11789
+ const checksum = new Uint8Array(4);
11790
+ checksum.set(buffer.slice(dataLength));
11791
+ const doubleHash = (0, sha256_1.sha256)((0, sha256_1.sha256)(data));
11792
+ // checksum must be the first 4 bytes of the double hash
11793
+ for (let i = 0; i < 4; i += 1) {
11794
+ if (checksum[i] !== doubleHash[i])
11795
+ return false;
11796
+ }
11797
+ return true;
11798
+ }
11799
+ exports.isChecksum = isChecksum;
11800
+ /**
11801
+ * Checks if the checksum of an address is correct.
11802
+ *
11803
+ * The address has 3 parts in this order:
11804
+ * - prefix: 1 byte
11805
+ * - data: 20 bytes
11806
+ * - checksum: 4 bytes
11807
+ *
11808
+ * checks:
11809
+ * - It must be "pay to public key hash" (P2PKH). That is prefix 0
11810
+ * - checksum = first 4 bytes of sha256(sha256(prefix + data))
11811
+ *
11812
+ * See [How to generate a bitcoin address step by step](https://medium.com/coinmonks/how-to-generate-a-bitcoin-address-step-by-step-9d7fcbf1ad0b).
11813
+ */
11814
+ function isChecksumAddress(address) {
11815
+ const bufferAddress = typeof address === "string" ? decodeBase58(address) : address;
11816
+ // it must have 25 bytes
11817
+ if (bufferAddress.length !== 25)
11818
+ return false;
11819
+ // it must have prefix 0 (P2PKH address)
11820
+ if (bufferAddress[0] !== 0)
11821
+ return false;
11822
+ return isChecksum(bufferAddress);
11823
+ }
11824
+ exports.isChecksumAddress = isChecksumAddress;
11825
+ /**
11826
+ * Checks if the checksum of an private key WIF is correct.
11827
+ *
11828
+ * The private key WIF has 3 parts in this order:
11829
+ * - prefix: 1 byte
11830
+ * - private key: 32 bytes
11831
+ * - compressed: 1 byte for compressed public key (no byte for uncompressed)
11832
+ * - checksum: 4 bytes
11833
+ *
11834
+ * checks:
11835
+ * - It must use version 0x80 in the prefix
11836
+ * - If the corresponding public key is compressed the byte 33 must be 0x01
11837
+ * - checksum = first 4 bytes of
11838
+ * sha256(sha256(prefix + private key + compressed))
11839
+ *
11840
+ * See [Bitcoin WIF](https://en.bitcoin.it/wiki/Wallet_import_format).
11841
+ */
11842
+ function isChecksumWif(wif) {
11843
+ const bufferWif = typeof wif === "string" ? decodeBase58(wif) : wif;
11844
+ // it must have 37 or 38 bytes
11845
+ if (bufferWif.length !== 37 && bufferWif.length !== 38)
11846
+ return false;
11847
+ const compressed = bufferWif.length === 38;
11848
+ // if compressed then the last byte must be 0x01
11849
+ if (compressed && bufferWif[33] !== 1)
11850
+ return false;
11851
+ // it must have prefix version for private keys (0x80)
11852
+ if (bufferWif[0] !== 128)
11853
+ return false;
11854
+ return isChecksum(bufferWif);
11855
+ }
11856
+ exports.isChecksumWif = isChecksumWif;
11760
11857
  /**
11761
11858
  * Function to format a number in a decimal point number
11762
11859
  * @example
@@ -11814,7 +11911,7 @@ function copyValue(value) {
11814
11911
  }
11815
11912
  return JSON.parse(JSON.stringify(value));
11816
11913
  }
11817
- function btypeDecodeValue(valueEncoded, typeField) {
11914
+ function btypeDecodeValue(valueEncoded, typeField, verifyChecksum) {
11818
11915
  // No byte conversion
11819
11916
  if (typeField.type !== "bytes")
11820
11917
  return copyValue(valueEncoded);
@@ -11826,9 +11923,14 @@ function btypeDecodeValue(valueEncoded, typeField) {
11826
11923
  // Specific byte conversion
11827
11924
  switch (typeField.btype) {
11828
11925
  case "BASE58":
11926
+ return decodeBase58(value);
11829
11927
  case "CONTRACT_ID":
11830
11928
  case "ADDRESS":
11831
- return decodeBase58(value);
11929
+ const valueDecoded = decodeBase58(value);
11930
+ if (verifyChecksum && !isChecksumAddress(valueDecoded)) {
11931
+ throw new Error(`${value} is an invalid address`);
11932
+ }
11933
+ return valueDecoded;
11832
11934
  case "BASE64":
11833
11935
  return decodeBase64url(value);
11834
11936
  case "HEX":
@@ -11840,7 +11942,7 @@ function btypeDecodeValue(valueEncoded, typeField) {
11840
11942
  }
11841
11943
  }
11842
11944
  exports.btypeDecodeValue = btypeDecodeValue;
11843
- function btypeEncodeValue(valueDecoded, typeField) {
11945
+ function btypeEncodeValue(valueDecoded, typeField, verifyChecksum) {
11844
11946
  // No byte conversion
11845
11947
  if (typeField.type !== "bytes")
11846
11948
  return copyValue(valueDecoded);
@@ -11852,9 +11954,14 @@ function btypeEncodeValue(valueDecoded, typeField) {
11852
11954
  // Specific byte conversion
11853
11955
  switch (typeField.btype) {
11854
11956
  case "BASE58":
11957
+ return encodeBase58(value);
11855
11958
  case "CONTRACT_ID":
11856
11959
  case "ADDRESS":
11857
- return encodeBase58(value);
11960
+ const valueEncoded = encodeBase58(value);
11961
+ if (verifyChecksum && !isChecksumAddress(value)) {
11962
+ throw new Error(`${valueEncoded} is an invalid address`);
11963
+ }
11964
+ return valueEncoded;
11858
11965
  case "BASE64":
11859
11966
  return encodeBase64url(value);
11860
11967
  case "HEX":
@@ -11866,7 +11973,7 @@ function btypeEncodeValue(valueDecoded, typeField) {
11866
11973
  }
11867
11974
  }
11868
11975
  exports.btypeEncodeValue = btypeEncodeValue;
11869
- function btypeDecode(valueEncoded, fields) {
11976
+ function btypeDecode(valueEncoded, fields, verifyChecksum) {
11870
11977
  if (typeof valueEncoded !== "object")
11871
11978
  return valueEncoded;
11872
11979
  const valueDecoded = {};
@@ -11876,18 +11983,18 @@ function btypeDecode(valueEncoded, fields) {
11876
11983
  if (fields[name].rule === "repeated")
11877
11984
  valueDecoded[name] = valueEncoded[name].map((itemEncoded) => {
11878
11985
  if (fields[name].subtypes)
11879
- return btypeDecode(itemEncoded, fields[name].subtypes);
11880
- return btypeDecodeValue(itemEncoded, fields[name]);
11986
+ return btypeDecode(itemEncoded, fields[name].subtypes, verifyChecksum);
11987
+ return btypeDecodeValue(itemEncoded, fields[name], verifyChecksum);
11881
11988
  });
11882
11989
  else if (fields[name].subtypes)
11883
- valueDecoded[name] = btypeDecode(valueEncoded[name], fields[name].subtypes);
11990
+ valueDecoded[name] = btypeDecode(valueEncoded[name], fields[name].subtypes, verifyChecksum);
11884
11991
  else
11885
- valueDecoded[name] = btypeDecodeValue(valueEncoded[name], fields[name]);
11992
+ valueDecoded[name] = btypeDecodeValue(valueEncoded[name], fields[name], verifyChecksum);
11886
11993
  });
11887
11994
  return valueDecoded;
11888
11995
  }
11889
11996
  exports.btypeDecode = btypeDecode;
11890
- function btypeEncode(valueDecoded, fields) {
11997
+ function btypeEncode(valueDecoded, fields, verifyChecksum) {
11891
11998
  if (typeof valueDecoded !== "object")
11892
11999
  return valueDecoded;
11893
12000
  const valueEncoded = {};
@@ -11897,13 +12004,13 @@ function btypeEncode(valueDecoded, fields) {
11897
12004
  if (fields[name].rule === "repeated")
11898
12005
  valueEncoded[name] = valueDecoded[name].map((itemDecoded) => {
11899
12006
  if (fields[name].subtypes)
11900
- return btypeEncode(itemDecoded, fields[name].subtypes);
11901
- return btypeEncodeValue(itemDecoded, fields[name]);
12007
+ return btypeEncode(itemDecoded, fields[name].subtypes, verifyChecksum);
12008
+ return btypeEncodeValue(itemDecoded, fields[name], verifyChecksum);
11902
12009
  });
11903
12010
  else if (fields[name].subtypes)
11904
- valueEncoded[name] = btypeEncode(valueDecoded[name], fields[name].subtypes);
12011
+ valueEncoded[name] = btypeEncode(valueDecoded[name], fields[name].subtypes, verifyChecksum);
11905
12012
  else
11906
- valueEncoded[name] = btypeEncodeValue(valueDecoded[name], fields[name]);
12013
+ valueEncoded[name] = btypeEncodeValue(valueDecoded[name], fields[name], verifyChecksum);
11907
12014
  });
11908
12015
  return valueEncoded;
11909
12016
  }