koilib 5.1.1 → 5.2.1

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
@@ -10029,6 +10029,9 @@ class Contract {
10029
10029
  args = argu;
10030
10030
  }
10031
10031
  const operation = await this.encodeOperation({ name, args });
10032
+ if (opts.onlyOperation) {
10033
+ return { operation };
10034
+ }
10032
10035
  if (readOnly) {
10033
10036
  if (!output)
10034
10037
  throw new Error(`No output defined for ${name}`);
@@ -10054,7 +10057,11 @@ class Contract {
10054
10057
  ...(opts.payer && { payer: opts.payer }),
10055
10058
  ...(opts.payee && { payee: opts.payee }),
10056
10059
  },
10057
- operations: [operation],
10060
+ operations: [
10061
+ ...(opts.previousOperations ? opts.previousOperations : []),
10062
+ operation,
10063
+ ...(opts.nextOperations ? opts.nextOperations : []),
10064
+ ],
10058
10065
  });
10059
10066
  const optsSend = {
10060
10067
  broadcast: opts.broadcast,
@@ -10675,6 +10682,14 @@ class Serializer {
10675
10682
  * Preformat bytes for base64url, base58 or hex string
10676
10683
  */
10677
10684
  this.bytesConversion = true;
10685
+ /**
10686
+ * Verify checksum in addresses during serialization
10687
+ * or deserialization
10688
+ */
10689
+ this.verifyChecksum = {
10690
+ serialize: true,
10691
+ deserialize: false,
10692
+ };
10678
10693
  this.types = types;
10679
10694
  this.root = light_1.Root.fromJSON(this.types);
10680
10695
  if (opts === null || opts === void 0 ? void 0 : opts.defaultTypeName)
@@ -10682,7 +10697,7 @@ class Serializer {
10682
10697
  if (opts && typeof opts.bytesConversion !== "undefined")
10683
10698
  this.bytesConversion = opts.bytesConversion;
10684
10699
  }
10685
- btypeDecode(valueBtypeEncoded, protobufType) {
10700
+ btypeDecode(valueBtypeEncoded, protobufType, verifyChecksum) {
10686
10701
  const valueBtypeDecoded = {};
10687
10702
  Object.keys(protobufType.fields).forEach((fieldName) => {
10688
10703
  // @ts-ignore
@@ -10706,10 +10721,10 @@ class Serializer {
10706
10721
  // it's an enum
10707
10722
  return itemEncoded;
10708
10723
  }
10709
- return this.btypeDecode(itemEncoded, protoBuf);
10724
+ return this.btypeDecode(itemEncoded, protoBuf, verifyChecksum);
10710
10725
  }
10711
10726
  // native types
10712
- return (0, utils_1.btypeDecodeValue)(itemEncoded, typeField);
10727
+ return (0, utils_1.btypeDecodeValue)(itemEncoded, typeField, verifyChecksum);
10713
10728
  });
10714
10729
  return;
10715
10730
  }
@@ -10721,15 +10736,15 @@ class Serializer {
10721
10736
  valueBtypeDecoded[name] = valueBtypeEncoded[name];
10722
10737
  return;
10723
10738
  }
10724
- valueBtypeDecoded[name] = this.btypeDecode(valueBtypeEncoded[name], protoBuf);
10739
+ valueBtypeDecoded[name] = this.btypeDecode(valueBtypeEncoded[name], protoBuf, verifyChecksum);
10725
10740
  return;
10726
10741
  }
10727
10742
  // native types
10728
- valueBtypeDecoded[name] = (0, utils_1.btypeDecodeValue)(valueBtypeEncoded[name], typeField);
10743
+ valueBtypeDecoded[name] = (0, utils_1.btypeDecodeValue)(valueBtypeEncoded[name], typeField, verifyChecksum);
10729
10744
  });
10730
10745
  return valueBtypeDecoded;
10731
10746
  }
10732
- btypeEncode(valueBtypeDecoded, protobufType) {
10747
+ btypeEncode(valueBtypeDecoded, protobufType, verifyChecksum) {
10733
10748
  const valueBtypeEncoded = {};
10734
10749
  Object.keys(protobufType.fields).forEach((fieldName) => {
10735
10750
  // @ts-ignore
@@ -10753,10 +10768,10 @@ class Serializer {
10753
10768
  // it's an enum
10754
10769
  return itemDecoded;
10755
10770
  }
10756
- return this.btypeEncode(itemDecoded, protoBuf);
10771
+ return this.btypeEncode(itemDecoded, protoBuf, verifyChecksum);
10757
10772
  }
10758
10773
  // native types
10759
- return (0, utils_1.btypeEncodeValue)(itemDecoded, typeField);
10774
+ return (0, utils_1.btypeEncodeValue)(itemDecoded, typeField, verifyChecksum);
10760
10775
  });
10761
10776
  return;
10762
10777
  }
@@ -10768,11 +10783,11 @@ class Serializer {
10768
10783
  valueBtypeEncoded[name] = valueBtypeDecoded[name];
10769
10784
  return;
10770
10785
  }
10771
- valueBtypeEncoded[name] = this.btypeEncode(valueBtypeDecoded[name], protoBuf);
10786
+ valueBtypeEncoded[name] = this.btypeEncode(valueBtypeDecoded[name], protoBuf, verifyChecksum);
10772
10787
  return;
10773
10788
  }
10774
10789
  // native types
10775
- valueBtypeEncoded[name] = (0, utils_1.btypeEncodeValue)(valueBtypeDecoded[name], typeField);
10790
+ valueBtypeEncoded[name] = (0, utils_1.btypeEncodeValue)(valueBtypeDecoded[name], typeField, verifyChecksum);
10776
10791
  });
10777
10792
  return valueBtypeEncoded;
10778
10793
  }
@@ -10787,8 +10802,11 @@ class Serializer {
10787
10802
  const bytesConversion = (opts === null || opts === void 0 ? void 0 : opts.bytesConversion) === undefined
10788
10803
  ? this.bytesConversion
10789
10804
  : opts.bytesConversion;
10805
+ const verifyChecksum = (opts === null || opts === void 0 ? void 0 : opts.verifyChecksum) === undefined
10806
+ ? this.verifyChecksum.serialize
10807
+ : opts.verifyChecksum;
10790
10808
  if (bytesConversion) {
10791
- object = this.btypeDecode(valueDecoded, protobufType);
10809
+ object = this.btypeDecode(valueDecoded, protobufType, verifyChecksum);
10792
10810
  }
10793
10811
  else {
10794
10812
  object = valueDecoded;
@@ -10815,8 +10833,11 @@ class Serializer {
10815
10833
  const bytesConversion = (opts === null || opts === void 0 ? void 0 : opts.bytesConversion) === undefined
10816
10834
  ? this.bytesConversion
10817
10835
  : opts.bytesConversion;
10836
+ const verifyChecksum = (opts === null || opts === void 0 ? void 0 : opts.verifyChecksum) === undefined
10837
+ ? this.verifyChecksum.deserialize
10838
+ : opts.verifyChecksum;
10818
10839
  if (bytesConversion) {
10819
- return this.btypeEncode(object, protobufType);
10840
+ return this.btypeEncode(object, protobufType, verifyChecksum);
10820
10841
  }
10821
10842
  return object;
10822
10843
  }
@@ -10919,6 +10940,13 @@ const btypesOperation = {
10919
10940
  },
10920
10941
  },
10921
10942
  },
10943
+ set_system_contract: {
10944
+ type: "object",
10945
+ subtypes: {
10946
+ contract_id: { type: "bytes", btype: "CONTRACT_ID" },
10947
+ system_contract: { type: "bool" },
10948
+ },
10949
+ },
10922
10950
  };
10923
10951
  /**
10924
10952
  * The Signer Class contains the private key needed to sign transactions.
@@ -11270,7 +11298,7 @@ class Signer {
11270
11298
  if (!block.signature)
11271
11299
  throw new Error("Missing block signature");
11272
11300
  signatures = [block.signature];
11273
- const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader);
11301
+ const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader, false);
11274
11302
  const message = protocol_proto_js_1.koinos.protocol.block_header.create(headerDecoded);
11275
11303
  headerBytes = protocol_proto_js_1.koinos.protocol.block_header.encode(message).finish();
11276
11304
  }
@@ -11281,7 +11309,7 @@ class Signer {
11281
11309
  if (!transaction.signatures)
11282
11310
  throw new Error("Missing transaction signatures");
11283
11311
  signatures = transaction.signatures;
11284
- const headerDecoded = (0, utils_1.btypeDecode)(transaction.header, btypeTransactionHeader);
11312
+ const headerDecoded = (0, utils_1.btypeDecode)(transaction.header, btypeTransactionHeader, false);
11285
11313
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11286
11314
  headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header.encode(message).finish();
11287
11315
  }
@@ -11394,7 +11422,7 @@ class Signer {
11394
11422
  const operationsHashes = [];
11395
11423
  if (tx.operations) {
11396
11424
  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);
11425
+ const operationDecoded = (0, utils_1.btypeDecode)(tx.operations[index], btypesOperation, false);
11398
11426
  const message = protocol_proto_js_1.koinos.protocol.operation.create(operationDecoded);
11399
11427
  const operationEncoded = protocol_proto_js_1.koinos.protocol.operation
11400
11428
  .encode(message)
@@ -11417,7 +11445,7 @@ class Signer {
11417
11445
  ...(payee && { payee }),
11418
11446
  // TODO: Option to resolve names (payer, payee)
11419
11447
  };
11420
- const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader);
11448
+ const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader, false);
11421
11449
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11422
11450
  const headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header
11423
11451
  .encode(message)
@@ -11441,7 +11469,7 @@ class Signer {
11441
11469
  if (block.transactions) {
11442
11470
  for (let index = 0; index < block.transactions.length; index++) {
11443
11471
  const tx = block.transactions[index];
11444
- const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader);
11472
+ const headerDecoded = (0, utils_1.btypeDecode)(tx.header, btypeTransactionHeader, false);
11445
11473
  const message = protocol_proto_js_1.koinos.protocol.transaction_header.create(headerDecoded);
11446
11474
  const headerBytes = protocol_proto_js_1.koinos.protocol.transaction_header
11447
11475
  .encode(message)
@@ -11483,7 +11511,7 @@ class Signer {
11483
11511
  ])),
11484
11512
  signer: this.address,
11485
11513
  };
11486
- const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader);
11514
+ const headerDecoded = (0, utils_1.btypeDecode)(block.header, btypeBlockHeader, false);
11487
11515
  const message = protocol_proto_js_1.koinos.protocol.block_header.create(headerDecoded);
11488
11516
  const headerBytes = protocol_proto_js_1.koinos.protocol.block_header
11489
11517
  .encode(message)
@@ -11576,7 +11604,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11576
11604
  return (mod && mod.__esModule) ? mod : { "default": mod };
11577
11605
  };
11578
11606
  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;
11607
+ 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
11608
  const multibase = __importStar(__webpack_require__(6957));
11581
11609
  const sha256_1 = __webpack_require__(3061);
11582
11610
  const ripemd160_1 = __webpack_require__(830);
@@ -11757,6 +11785,82 @@ function bitcoinAddress(publicKey) {
11757
11785
  return bitcoinEncode(hash160, "public");
11758
11786
  }
11759
11787
  exports.bitcoinAddress = bitcoinAddress;
11788
+ /**
11789
+ * Checks if the last 4 bytes matches with the double sha256
11790
+ * of the first part
11791
+ */
11792
+ function isChecksum(buffer) {
11793
+ const dataLength = buffer.length - 4;
11794
+ const data = new Uint8Array(dataLength);
11795
+ data.set(buffer.slice(0, dataLength));
11796
+ const checksum = new Uint8Array(4);
11797
+ checksum.set(buffer.slice(dataLength));
11798
+ const doubleHash = (0, sha256_1.sha256)((0, sha256_1.sha256)(data));
11799
+ // checksum must be the first 4 bytes of the double hash
11800
+ for (let i = 0; i < 4; i += 1) {
11801
+ if (checksum[i] !== doubleHash[i])
11802
+ return false;
11803
+ }
11804
+ return true;
11805
+ }
11806
+ exports.isChecksum = isChecksum;
11807
+ /**
11808
+ * Checks if the checksum of an address is correct.
11809
+ *
11810
+ * The address has 3 parts in this order:
11811
+ * - prefix: 1 byte
11812
+ * - data: 20 bytes
11813
+ * - checksum: 4 bytes
11814
+ *
11815
+ * checks:
11816
+ * - It must be "pay to public key hash" (P2PKH). That is prefix 0
11817
+ * - checksum = first 4 bytes of sha256(sha256(prefix + data))
11818
+ *
11819
+ * See [How to generate a bitcoin address step by step](https://medium.com/coinmonks/how-to-generate-a-bitcoin-address-step-by-step-9d7fcbf1ad0b).
11820
+ */
11821
+ function isChecksumAddress(address) {
11822
+ const bufferAddress = typeof address === "string" ? decodeBase58(address) : address;
11823
+ // it must have 25 bytes
11824
+ if (bufferAddress.length !== 25)
11825
+ return false;
11826
+ // it must have prefix 0 (P2PKH address)
11827
+ if (bufferAddress[0] !== 0)
11828
+ return false;
11829
+ return isChecksum(bufferAddress);
11830
+ }
11831
+ exports.isChecksumAddress = isChecksumAddress;
11832
+ /**
11833
+ * Checks if the checksum of an private key WIF is correct.
11834
+ *
11835
+ * The private key WIF has 3 parts in this order:
11836
+ * - prefix: 1 byte
11837
+ * - private key: 32 bytes
11838
+ * - compressed: 1 byte for compressed public key (no byte for uncompressed)
11839
+ * - checksum: 4 bytes
11840
+ *
11841
+ * checks:
11842
+ * - It must use version 0x80 in the prefix
11843
+ * - If the corresponding public key is compressed the byte 33 must be 0x01
11844
+ * - checksum = first 4 bytes of
11845
+ * sha256(sha256(prefix + private key + compressed))
11846
+ *
11847
+ * See [Bitcoin WIF](https://en.bitcoin.it/wiki/Wallet_import_format).
11848
+ */
11849
+ function isChecksumWif(wif) {
11850
+ const bufferWif = typeof wif === "string" ? decodeBase58(wif) : wif;
11851
+ // it must have 37 or 38 bytes
11852
+ if (bufferWif.length !== 37 && bufferWif.length !== 38)
11853
+ return false;
11854
+ const compressed = bufferWif.length === 38;
11855
+ // if compressed then the last byte must be 0x01
11856
+ if (compressed && bufferWif[33] !== 1)
11857
+ return false;
11858
+ // it must have prefix version for private keys (0x80)
11859
+ if (bufferWif[0] !== 128)
11860
+ return false;
11861
+ return isChecksum(bufferWif);
11862
+ }
11863
+ exports.isChecksumWif = isChecksumWif;
11760
11864
  /**
11761
11865
  * Function to format a number in a decimal point number
11762
11866
  * @example
@@ -11814,7 +11918,7 @@ function copyValue(value) {
11814
11918
  }
11815
11919
  return JSON.parse(JSON.stringify(value));
11816
11920
  }
11817
- function btypeDecodeValue(valueEncoded, typeField) {
11921
+ function btypeDecodeValue(valueEncoded, typeField, verifyChecksum) {
11818
11922
  // No byte conversion
11819
11923
  if (typeField.type !== "bytes")
11820
11924
  return copyValue(valueEncoded);
@@ -11826,9 +11930,14 @@ function btypeDecodeValue(valueEncoded, typeField) {
11826
11930
  // Specific byte conversion
11827
11931
  switch (typeField.btype) {
11828
11932
  case "BASE58":
11933
+ return decodeBase58(value);
11829
11934
  case "CONTRACT_ID":
11830
11935
  case "ADDRESS":
11831
- return decodeBase58(value);
11936
+ const valueDecoded = decodeBase58(value);
11937
+ if (verifyChecksum && !isChecksumAddress(valueDecoded)) {
11938
+ throw new Error(`${value} is an invalid address`);
11939
+ }
11940
+ return valueDecoded;
11832
11941
  case "BASE64":
11833
11942
  return decodeBase64url(value);
11834
11943
  case "HEX":
@@ -11840,7 +11949,7 @@ function btypeDecodeValue(valueEncoded, typeField) {
11840
11949
  }
11841
11950
  }
11842
11951
  exports.btypeDecodeValue = btypeDecodeValue;
11843
- function btypeEncodeValue(valueDecoded, typeField) {
11952
+ function btypeEncodeValue(valueDecoded, typeField, verifyChecksum) {
11844
11953
  // No byte conversion
11845
11954
  if (typeField.type !== "bytes")
11846
11955
  return copyValue(valueDecoded);
@@ -11852,9 +11961,14 @@ function btypeEncodeValue(valueDecoded, typeField) {
11852
11961
  // Specific byte conversion
11853
11962
  switch (typeField.btype) {
11854
11963
  case "BASE58":
11964
+ return encodeBase58(value);
11855
11965
  case "CONTRACT_ID":
11856
11966
  case "ADDRESS":
11857
- return encodeBase58(value);
11967
+ const valueEncoded = encodeBase58(value);
11968
+ if (verifyChecksum && !isChecksumAddress(value)) {
11969
+ throw new Error(`${valueEncoded} is an invalid address`);
11970
+ }
11971
+ return valueEncoded;
11858
11972
  case "BASE64":
11859
11973
  return encodeBase64url(value);
11860
11974
  case "HEX":
@@ -11866,7 +11980,7 @@ function btypeEncodeValue(valueDecoded, typeField) {
11866
11980
  }
11867
11981
  }
11868
11982
  exports.btypeEncodeValue = btypeEncodeValue;
11869
- function btypeDecode(valueEncoded, fields) {
11983
+ function btypeDecode(valueEncoded, fields, verifyChecksum) {
11870
11984
  if (typeof valueEncoded !== "object")
11871
11985
  return valueEncoded;
11872
11986
  const valueDecoded = {};
@@ -11876,18 +11990,18 @@ function btypeDecode(valueEncoded, fields) {
11876
11990
  if (fields[name].rule === "repeated")
11877
11991
  valueDecoded[name] = valueEncoded[name].map((itemEncoded) => {
11878
11992
  if (fields[name].subtypes)
11879
- return btypeDecode(itemEncoded, fields[name].subtypes);
11880
- return btypeDecodeValue(itemEncoded, fields[name]);
11993
+ return btypeDecode(itemEncoded, fields[name].subtypes, verifyChecksum);
11994
+ return btypeDecodeValue(itemEncoded, fields[name], verifyChecksum);
11881
11995
  });
11882
11996
  else if (fields[name].subtypes)
11883
- valueDecoded[name] = btypeDecode(valueEncoded[name], fields[name].subtypes);
11997
+ valueDecoded[name] = btypeDecode(valueEncoded[name], fields[name].subtypes, verifyChecksum);
11884
11998
  else
11885
- valueDecoded[name] = btypeDecodeValue(valueEncoded[name], fields[name]);
11999
+ valueDecoded[name] = btypeDecodeValue(valueEncoded[name], fields[name], verifyChecksum);
11886
12000
  });
11887
12001
  return valueDecoded;
11888
12002
  }
11889
12003
  exports.btypeDecode = btypeDecode;
11890
- function btypeEncode(valueDecoded, fields) {
12004
+ function btypeEncode(valueDecoded, fields, verifyChecksum) {
11891
12005
  if (typeof valueDecoded !== "object")
11892
12006
  return valueDecoded;
11893
12007
  const valueEncoded = {};
@@ -11897,13 +12011,13 @@ function btypeEncode(valueDecoded, fields) {
11897
12011
  if (fields[name].rule === "repeated")
11898
12012
  valueEncoded[name] = valueDecoded[name].map((itemDecoded) => {
11899
12013
  if (fields[name].subtypes)
11900
- return btypeEncode(itemDecoded, fields[name].subtypes);
11901
- return btypeEncodeValue(itemDecoded, fields[name]);
12014
+ return btypeEncode(itemDecoded, fields[name].subtypes, verifyChecksum);
12015
+ return btypeEncodeValue(itemDecoded, fields[name], verifyChecksum);
11902
12016
  });
11903
12017
  else if (fields[name].subtypes)
11904
- valueEncoded[name] = btypeEncode(valueDecoded[name], fields[name].subtypes);
12018
+ valueEncoded[name] = btypeEncode(valueDecoded[name], fields[name].subtypes, verifyChecksum);
11905
12019
  else
11906
- valueEncoded[name] = btypeEncodeValue(valueDecoded[name], fields[name]);
12020
+ valueEncoded[name] = btypeEncodeValue(valueDecoded[name], fields[name], verifyChecksum);
11907
12021
  });
11908
12022
  return valueEncoded;
11909
12023
  }