@steemit/steem-js 1.0.0 → 1.0.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/index.js CHANGED
@@ -5,7 +5,7 @@ import * as assert from 'assert';
5
5
  import assert__default from 'assert';
6
6
  import * as buffer from 'buffer';
7
7
  import * as crypto from 'crypto';
8
- import { randomBytes, createHash as createHash$2, createCipheriv, createDecipheriv, createHmac as createHmac$1 } from 'crypto';
8
+ import { randomBytes, createHash as createHash$2, createCipheriv, createDecipheriv, createHmac as createHmac$2 } from 'crypto';
9
9
  import axios from 'axios';
10
10
  import * as https from 'https';
11
11
  import * as http from 'http';
@@ -6056,6 +6056,98 @@ const setConfig = (newConfig) => {
6056
6056
  // Alias for setConfig to match the API's setOptions
6057
6057
  const setOptions$1 = setConfig;
6058
6058
 
6059
+ const config$1 = /*#__PURE__*/Object.freeze({
6060
+ __proto__: null,
6061
+ Config: Config,
6062
+ getConfig: getConfig,
6063
+ setConfig: setConfig,
6064
+ setOptions: setOptions$1
6065
+ });
6066
+
6067
+ /**
6068
+ * Debug utility for controlled debug output
6069
+ * Can be enabled via:
6070
+ * 1. Config: steem.config.set({ debug: true })
6071
+ * 2. Environment variable: DEBUG=steem-js or DEBUG=steem-js:*
6072
+ * 3. Specific debug flags: DEBUG=steem-js:transaction,steem-js:signature
6073
+ */
6074
+ // Check if debug is enabled via environment variable
6075
+ const DEBUG_ENV = process.env.DEBUG || '';
6076
+ const DEBUG_ENABLED = DEBUG_ENV.includes('steem-js');
6077
+ // Parse debug flags from environment
6078
+ const DEBUG_FLAGS = DEBUG_ENV.split(',').map(f => f.trim());
6079
+ function isDebugEnabled(flag) {
6080
+ // Check config first
6081
+ const configDebug = getConfig().get('debug');
6082
+ if (configDebug === true) {
6083
+ return true;
6084
+ }
6085
+ if (configDebug === false) {
6086
+ return false;
6087
+ }
6088
+ // Check environment variable
6089
+ if (!DEBUG_ENABLED) {
6090
+ return false;
6091
+ }
6092
+ // If no flag specified, check for general steem-js debug
6093
+ if (!flag) {
6094
+ return DEBUG_ENV.includes('steem-js') && !DEBUG_ENV.includes('steem-js:');
6095
+ }
6096
+ // Check for specific flag
6097
+ const flagPattern = `steem-js:${flag}`;
6098
+ return DEBUG_FLAGS.some(f => f === flagPattern || f === 'steem-js:*');
6099
+ }
6100
+ const debug = {
6101
+ /**
6102
+ * Log debug information
6103
+ * @param flag - Optional debug flag (e.g., 'transaction', 'signature')
6104
+ * @param args - Arguments to log
6105
+ */
6106
+ log(flag, ...args) {
6107
+ if (isDebugEnabled(flag)) {
6108
+ const prefix = flag ? `[steem-js:${flag}]` : '[steem-js]';
6109
+ console.log(prefix, ...args);
6110
+ }
6111
+ },
6112
+ /**
6113
+ * Log transaction debug info
6114
+ */
6115
+ transaction(...args) {
6116
+ this.log('transaction', ...args);
6117
+ },
6118
+ /**
6119
+ * Log signature debug info
6120
+ */
6121
+ signature(...args) {
6122
+ this.log('signature', ...args);
6123
+ },
6124
+ /**
6125
+ * Log warning (always shown, but can be controlled)
6126
+ */
6127
+ warn(...args) {
6128
+ if (isDebugEnabled() || getConfig().get('debug_warnings') !== false) {
6129
+ console.warn('[steem-js]', ...args);
6130
+ }
6131
+ },
6132
+ /**
6133
+ * Log error (always shown)
6134
+ */
6135
+ error(...args) {
6136
+ console.error('[steem-js]', ...args);
6137
+ },
6138
+ /**
6139
+ * Check if debug is enabled for a specific flag
6140
+ */
6141
+ isEnabled(flag) {
6142
+ return isDebugEnabled(flag);
6143
+ }
6144
+ };
6145
+
6146
+ const debug$1 = /*#__PURE__*/Object.freeze({
6147
+ __proto__: null,
6148
+ debug: debug
6149
+ });
6150
+
6059
6151
  const sleep = (ms) => {
6060
6152
  return new Promise(resolve => setTimeout(resolve, ms));
6061
6153
  };
@@ -6101,6 +6193,7 @@ const utils = /*#__PURE__*/Object.freeze({
6101
6193
  __proto__: null,
6102
6194
  camelCase: camelCase,
6103
6195
  chunk: chunk,
6196
+ debug: debug,
6104
6197
  flatten: flatten,
6105
6198
  isValidAddress: isValidAddress,
6106
6199
  isValidAmount: isValidAmount,
@@ -8281,17 +8374,18 @@ function requireCreateHash () {
8281
8374
  var createHashExports = requireCreateHash();
8282
8375
  const createHash = /*@__PURE__*/getDefaultExportFromCjs(createHashExports);
8283
8376
 
8284
- var createHmac;
8377
+ var createHmac$1;
8285
8378
  var hasRequiredCreateHmac;
8286
8379
 
8287
8380
  function requireCreateHmac () {
8288
- if (hasRequiredCreateHmac) return createHmac;
8381
+ if (hasRequiredCreateHmac) return createHmac$1;
8289
8382
  hasRequiredCreateHmac = 1;
8290
- createHmac = require$$3$1.createHmac;
8291
- return createHmac;
8383
+ createHmac$1 = require$$3$1.createHmac;
8384
+ return createHmac$1;
8292
8385
  }
8293
8386
 
8294
- requireCreateHmac();
8387
+ var createHmacExports = requireCreateHmac();
8388
+ const createHmac = /*@__PURE__*/getDefaultExportFromCjs(createHmacExports);
8295
8389
 
8296
8390
  /** @arg {string|Buffer} data
8297
8391
  @arg {string} [digest = null] - 'hex', 'binary' or 'base64'
@@ -8313,6 +8407,9 @@ function sha512(data, encoding) {
8313
8407
  }
8314
8408
  return createHash('sha512').update(data).digest();
8315
8409
  }
8410
+ function HmacSHA256(buffer, secret) {
8411
+ return createHmac('sha256', secret).update(buffer).digest();
8412
+ }
8316
8413
  function ripemd160$1(data) {
8317
8414
  return createHash('rmd160').update(data).digest();
8318
8415
  }
@@ -8598,7 +8695,7 @@ class PrivateKey {
8598
8695
  throw new Error("Expecting parameter to be a Buffer type");
8599
8696
  }
8600
8697
  if (32 !== buf.length) {
8601
- console.log(`WARN: Expecting 32 bytes, instead got ${buf.length}, stack trace:`, new Error().stack);
8698
+ debug.warn(`WARN: Expecting 32 bytes, instead got ${buf.length}, stack trace:`, new Error().stack);
8602
8699
  }
8603
8700
  if (buf.length === 0) {
8604
8701
  throw new Error("Empty buffer");
@@ -8717,6 +8814,278 @@ const toPublic = (data) => {
8717
8814
  return data;
8718
8815
  };
8719
8816
 
8817
+ function enforce(type, value) {
8818
+ switch (type) {
8819
+ case 'Array': {
8820
+ if (Array.isArray(value))
8821
+ return;
8822
+ break;
8823
+ }
8824
+ case 'Boolean': {
8825
+ if (typeof value === 'boolean')
8826
+ return;
8827
+ break;
8828
+ }
8829
+ case 'Buffer': {
8830
+ if (Buffer.isBuffer(value))
8831
+ return;
8832
+ break;
8833
+ }
8834
+ case 'Number': {
8835
+ if (typeof value === 'number')
8836
+ return;
8837
+ break;
8838
+ }
8839
+ case 'String': {
8840
+ if (typeof value === 'string')
8841
+ return;
8842
+ break;
8843
+ }
8844
+ default: {
8845
+ if (typeof type === 'function' && getName(value.constructor) === getName(type))
8846
+ return;
8847
+ }
8848
+ }
8849
+ throw new TypeError('Expected ' + (typeof type === 'function' ? getName(type) : type) + ', got ' + value);
8850
+ }
8851
+ function getName(fn) {
8852
+ const match = fn.toString().match(/function (.*?)\(/);
8853
+ return match ? match[1] : null;
8854
+ }
8855
+
8856
+ class ECSignature {
8857
+ constructor(r, s) {
8858
+ enforce(bigi, r);
8859
+ enforce(bigi, s);
8860
+ this.r = r;
8861
+ this.s = s;
8862
+ }
8863
+ static parseCompact(buffer) {
8864
+ if (buffer.length !== 65)
8865
+ throw new Error('Invalid signature length');
8866
+ let i = buffer.readUInt8(0) - 27;
8867
+ if ((i & 7) !== i)
8868
+ throw new Error('Invalid signature parameter');
8869
+ const compressed = !!(i & 4);
8870
+ i = i & 3;
8871
+ const r = bigi.fromBuffer(buffer.slice(1, 33));
8872
+ const s = bigi.fromBuffer(buffer.slice(33));
8873
+ return {
8874
+ compressed,
8875
+ i,
8876
+ signature: new ECSignature(r, s)
8877
+ };
8878
+ }
8879
+ static fromDER(buffer) {
8880
+ if (buffer.readUInt8(0) !== 0x30)
8881
+ throw new Error('Not a DER sequence');
8882
+ if (buffer.readUInt8(1) !== buffer.length - 2)
8883
+ throw new Error('Invalid sequence length');
8884
+ if (buffer.readUInt8(2) !== 0x02)
8885
+ throw new Error('Expected a DER integer');
8886
+ const rLen = buffer.readUInt8(3);
8887
+ if (rLen === 0)
8888
+ throw new Error('R length is zero');
8889
+ let offset = 4 + rLen;
8890
+ if (buffer.readUInt8(offset) !== 0x02)
8891
+ throw new Error('Expected a DER integer (2)');
8892
+ const sLen = buffer.readUInt8(offset + 1);
8893
+ if (sLen === 0)
8894
+ throw new Error('S length is zero');
8895
+ const rB = buffer.slice(4, offset);
8896
+ const sB = buffer.slice(offset + 2);
8897
+ offset += 2 + sLen;
8898
+ if (rLen > 1 && rB.readUInt8(0) === 0x00) {
8899
+ if (!(rB.readUInt8(1) & 0x80))
8900
+ throw new Error('R value excessively padded');
8901
+ }
8902
+ if (sLen > 1 && sB.readUInt8(0) === 0x00) {
8903
+ if (!(sB.readUInt8(1) & 0x80))
8904
+ throw new Error('S value excessively padded');
8905
+ }
8906
+ if (offset !== buffer.length)
8907
+ throw new Error('Invalid DER encoding');
8908
+ const r = bigi.fromBuffer(rB);
8909
+ const s = bigi.fromBuffer(sB);
8910
+ if (r.signum() < 0)
8911
+ throw new Error('R value is negative');
8912
+ if (s.signum() < 0)
8913
+ throw new Error('S value is negative');
8914
+ return new ECSignature(r, s);
8915
+ }
8916
+ static parseScriptSignature(buffer) {
8917
+ const hashType = buffer.readUInt8(buffer.length - 1);
8918
+ const hashTypeMod = hashType & -129;
8919
+ if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04)
8920
+ throw new Error('Invalid hashType');
8921
+ return {
8922
+ signature: ECSignature.fromDER(buffer.slice(0, -1)),
8923
+ hashType
8924
+ };
8925
+ }
8926
+ toCompact(i, compressed) {
8927
+ if (compressed)
8928
+ i += 4;
8929
+ i += 27;
8930
+ const buffer = Buffer.alloc(65);
8931
+ buffer.writeUInt8(i, 0);
8932
+ this.r.toBuffer(32).copy(buffer, 1);
8933
+ this.s.toBuffer(32).copy(buffer, 33);
8934
+ return buffer;
8935
+ }
8936
+ toDER() {
8937
+ const rBa = this.r.toBuffer();
8938
+ const sBa = this.s.toBuffer();
8939
+ const sequence = [];
8940
+ // INTEGER
8941
+ sequence.push(0x02, rBa.length);
8942
+ Array.from(rBa).forEach(b => sequence.push(b));
8943
+ // INTEGER
8944
+ sequence.push(0x02, sBa.length);
8945
+ Array.from(sBa).forEach(b => sequence.push(b));
8946
+ // SEQUENCE
8947
+ sequence.unshift(0x30, sequence.length);
8948
+ return Buffer.from(sequence);
8949
+ }
8950
+ toScriptSignature(hashType) {
8951
+ const hashTypeBuffer = Buffer.alloc(1);
8952
+ hashTypeBuffer.writeUInt8(hashType, 0);
8953
+ return Buffer.concat([this.toDER(), hashTypeBuffer]);
8954
+ }
8955
+ }
8956
+
8957
+ // https://tools.ietf.org/html/rfc6979#section-3.2
8958
+ function deterministicGenerateK(curve, hash, d, checkSig, nonce) {
8959
+ enforce('Buffer', hash);
8960
+ enforce(bigi, d);
8961
+ if (nonce) {
8962
+ hash = sha256$1(Buffer.concat([hash, Buffer.alloc(nonce)]));
8963
+ }
8964
+ // sanity check
8965
+ assert__default.equal(hash.length, 32, 'Hash must be 256 bit');
8966
+ const x = d.toBuffer(32);
8967
+ let k = Buffer.alloc(32);
8968
+ let v = Buffer.alloc(32);
8969
+ // Step B
8970
+ v.fill(1);
8971
+ // Step C
8972
+ k.fill(0);
8973
+ // Step D
8974
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([0]), x, hash]), k);
8975
+ // Step E
8976
+ v = HmacSHA256(v, k);
8977
+ // Step F
8978
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([1]), x, hash]), k);
8979
+ // Step G
8980
+ v = HmacSHA256(v, k);
8981
+ // Step H1/H2a, ignored as tlen === qlen (256 bit)
8982
+ // Step H2b
8983
+ v = HmacSHA256(v, k);
8984
+ let T = bigi.fromBuffer(v);
8985
+ // Step H3, repeat until T is within the interval [1, n - 1] and passes the supplied check
8986
+ while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0) || !checkSig(T)) {
8987
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([0])]), k);
8988
+ v = HmacSHA256(v, k);
8989
+ // Step H1/H2a, again, ignored as tlen === qlen (256 bit)
8990
+ // Step H2b again
8991
+ v = HmacSHA256(v, k);
8992
+ T = bigi.fromBuffer(v);
8993
+ }
8994
+ return T;
8995
+ }
8996
+ function sign$3(curve, hash, d, nonce) {
8997
+ const e = bigi.fromBuffer(hash);
8998
+ const n = curve.n;
8999
+ const G = curve.G;
9000
+ let r;
9001
+ let s;
9002
+ deterministicGenerateK(curve, hash, d, function (k) {
9003
+ // find canonically valid signature
9004
+ const Q = G.multiply(k);
9005
+ if (curve.isInfinity(Q))
9006
+ return false;
9007
+ const tempR = Q.affineX.mod(n);
9008
+ if (tempR.signum() === 0)
9009
+ return false;
9010
+ const tempS = k.modInverse(n).multiply(e.add(d.multiply(tempR))).mod(n);
9011
+ if (tempS.signum() === 0)
9012
+ return false;
9013
+ r = tempR;
9014
+ s = tempS;
9015
+ return true;
9016
+ }, nonce);
9017
+ if (!r || !s)
9018
+ throw new Error('Unable to find valid signature');
9019
+ const N_OVER_TWO = n.shiftRight(1);
9020
+ // enforce low S values, see bip62: 'low s values in signatures'
9021
+ const finalS = s.compareTo(N_OVER_TWO) > 0 ? n.subtract(s) : s;
9022
+ return new ECSignature(r, finalS);
9023
+ }
9024
+ /**
9025
+ * Recover a public key from a signature.
9026
+ *
9027
+ * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
9028
+ * Key Recovery Operation".
9029
+ *
9030
+ * http://www.secg.org/download/aid-780/sec1-v2.pdf
9031
+ */
9032
+ function recoverPubKey(curve, e, signature, i) {
9033
+ assert__default.strictEqual(i & 3, i, 'Recovery param is more than two bits');
9034
+ const n = curve.n;
9035
+ const G = curve.G;
9036
+ const r = signature.r;
9037
+ const s = signature.s;
9038
+ assert__default(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value');
9039
+ assert__default(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value');
9040
+ // A set LSB signifies that the y-coordinate is odd
9041
+ const isYOdd = !!(i & 1);
9042
+ // The more significant bit specifies whether we should use the
9043
+ // first or second candidate key.
9044
+ const isSecondKey = i >> 1;
9045
+ // 1.1 Let x = r + jn
9046
+ const x = isSecondKey ? r.add(n) : r;
9047
+ const R = curve.pointFromX(isYOdd, x);
9048
+ // 1.4 Check that nR is at infinity
9049
+ const nR = R.multiply(n);
9050
+ assert__default(curve.isInfinity(nR), 'nR is not a valid curve point');
9051
+ // Compute -e from e
9052
+ const eNeg = e.negate().mod(n);
9053
+ // 1.6.1 Compute Q = r^-1 (sR - eG)
9054
+ // Q = r^-1 (sR + -eG)
9055
+ const rInv = r.modInverse(n);
9056
+ const sR = R.multiply(s);
9057
+ const eGNeg = G.multiply(eNeg);
9058
+ const Q = sR.add(eGNeg).multiply(rInv);
9059
+ curve.validate(Q);
9060
+ return Q;
9061
+ }
9062
+ /**
9063
+ * Calculate pubkey extraction parameter.
9064
+ *
9065
+ * When extracting a pubkey from a signature, we have to
9066
+ * distinguish four different cases. Rather than putting this
9067
+ * burden on the verifier, Bitcoin includes a 2-bit value with the
9068
+ * signature.
9069
+ *
9070
+ * This function simply tries all four cases and returns the value
9071
+ * that resulted in a successful pubkey recovery.
9072
+ */
9073
+ function calcPubKeyRecoveryParam(curve, e, signature, Q) {
9074
+ for (let i = 0; i < 4; i++) {
9075
+ try {
9076
+ const Qprime = recoverPubKey(curve, e, signature, i);
9077
+ // 1.6.2 Verify Q = Q'
9078
+ if (Qprime.equals(Q)) {
9079
+ return i;
9080
+ }
9081
+ }
9082
+ catch (error) {
9083
+ // try next value
9084
+ }
9085
+ }
9086
+ throw new Error('Unable to find valid recovery factor');
9087
+ }
9088
+
8720
9089
  const secp256k1 = libExports$1.getCurveByName('secp256k1');
8721
9090
  class Signature {
8722
9091
  constructor(r, s, i) {
@@ -8756,28 +9125,27 @@ class Signature {
8756
9125
  throw new Error('private_key required');
8757
9126
  }
8758
9127
  const e = bigi.fromBuffer(buf_sha256);
8759
- const n = secp256k1.n;
8760
- const G = secp256k1.G;
8761
- const d = privKey.d;
8762
- let r, s;
9128
+ let ecsignature;
9129
+ let i = null;
8763
9130
  let nonce = 0;
9131
+ // Match old-steem-js behavior: find canonical signature (lenR === 32 && lenS === 32)
8764
9132
  while (true) {
8765
- const k = bigi.fromBuffer(sha256$1(Buffer.concat([buf_sha256, Buffer.from([nonce++])])));
8766
- const Q = G.multiply(k);
8767
- r = Q.affineX.mod(n);
8768
- if (r.signum() === 0)
8769
- continue;
8770
- s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
8771
- if (s.signum() === 0)
8772
- continue;
8773
- break;
8774
- }
8775
- const N_OVER_TWO = n.shiftRight(1);
8776
- if (s.compareTo(N_OVER_TWO) > 0) {
8777
- s = n.subtract(s);
9133
+ ecsignature = sign$3(secp256k1, buf_sha256, privKey.d, nonce++);
9134
+ const der = ecsignature.toDER();
9135
+ const lenR = der[3];
9136
+ const lenS = der[5 + lenR];
9137
+ if (lenR === 32 && lenS === 32) {
9138
+ // Calculate recovery parameter to match old-steem-js
9139
+ i = calcPubKeyRecoveryParam(secp256k1, e, ecsignature, privKey.toPublic().Q);
9140
+ i += 4; // compressed
9141
+ i += 27; // compact
9142
+ break;
9143
+ }
9144
+ if (nonce % 10 === 0) {
9145
+ debug.warn("WARN: " + nonce + " attempts to find canonical signature");
9146
+ }
8778
9147
  }
8779
- const i = 27 + 4; // compressed + compact
8780
- return new Signature(r, s, i);
9148
+ return new Signature(ecsignature.r, ecsignature.s, i);
8781
9149
  }
8782
9150
  static sign(string, private_key) {
8783
9151
  return Signature.signBuffer(Buffer.from(string), private_key);
@@ -9949,7 +10317,18 @@ class HttpTransport extends BaseTransport {
9949
10317
  timeout: timeoutMs,
9950
10318
  })
9951
10319
  .then((res) => res.json())
9952
- .then((result) => callback(null, result.result, currentAttempt), (error) => {
10320
+ .then((result) => {
10321
+ // Check for JSON-RPC errors
10322
+ if (result.error) {
10323
+ const error = new Error(result.error.message || 'JSON-RPC error');
10324
+ error.code = result.error.code;
10325
+ error.data = result.error.data;
10326
+ callback(error, undefined, currentAttempt);
10327
+ }
10328
+ else {
10329
+ callback(null, result.result, currentAttempt);
10330
+ }
10331
+ }, (error) => {
9953
10332
  if (operation.retry(error)) {
9954
10333
  return;
9955
10334
  }
@@ -9970,7 +10349,18 @@ class HttpTransport extends BaseTransport {
9970
10349
  timeout: timeoutMs,
9971
10350
  })
9972
10351
  .then((res) => res.json())
9973
- .then((result) => callback(null, result.result, 1), (error) => callback(error, undefined, 1));
10352
+ .then((result) => {
10353
+ // Check for JSON-RPC errors
10354
+ if (result.error) {
10355
+ const error = new Error(result.error.message || 'JSON-RPC error');
10356
+ error.code = result.error.code;
10357
+ error.data = result.error.data;
10358
+ callback(error, undefined, 1);
10359
+ }
10360
+ else {
10361
+ callback(null, result.result, 1);
10362
+ }
10363
+ }, (error) => callback(error, undefined, 1));
9974
10364
  }
9975
10365
  }
9976
10366
  }
@@ -21871,6 +22261,179 @@ if (typeof BigInt === "function") {
21871
22261
  };
21872
22262
  }
21873
22263
 
22264
+ /**
22265
+ * Serialize a transaction to binary format for Steem blockchain
22266
+ * This is a simplified implementation that handles the basic structure
22267
+ */
22268
+ function serializeTransaction$1(trx) {
22269
+ const bb = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
22270
+ // Write ref_block_num (uint16)
22271
+ bb.writeUint16(trx.ref_block_num || 0);
22272
+ // Write ref_block_prefix (uint32)
22273
+ bb.writeUint32(trx.ref_block_prefix || 0);
22274
+ // Write expiration (time_point_sec - uint32 seconds since epoch)
22275
+ // Match old-steem-js behavior: ensure UTC time and precision to seconds
22276
+ let expiration;
22277
+ if (typeof trx.expiration === 'string') {
22278
+ // If string doesn't end with 'Z', append it to ensure UTC time
22279
+ let expirationStr = trx.expiration;
22280
+ if (!expirationStr.endsWith('Z')) {
22281
+ expirationStr = expirationStr + 'Z';
22282
+ }
22283
+ const date = new Date(expirationStr);
22284
+ expiration = Math.floor(date.getTime() / 1000);
22285
+ }
22286
+ else if (typeof trx.expiration === 'number') {
22287
+ expiration = trx.expiration;
22288
+ }
22289
+ else {
22290
+ expiration = 0;
22291
+ }
22292
+ bb.writeUint32(expiration);
22293
+ // Write operations array
22294
+ const operations = trx.operations || [];
22295
+ bb.writeVarint32(operations.length);
22296
+ for (const op of operations) {
22297
+ serializeOperation$1(bb, op);
22298
+ }
22299
+ // Write extensions (set of future_extensions, which is void/empty)
22300
+ bb.writeVarint32(0); // Empty set
22301
+ bb.flip();
22302
+ return Buffer.from(bb.toBuffer());
22303
+ }
22304
+ /**
22305
+ * Serialize an operation to binary format
22306
+ */
22307
+ function serializeOperation$1(bb, op) {
22308
+ if (!Array.isArray(op) || op.length !== 2) {
22309
+ throw new Error('Operation must be an array of [operation_type, operation_data]');
22310
+ }
22311
+ const [opType, opData] = op;
22312
+ // Write operation type index (varint32)
22313
+ // For now, we'll use a simple mapping. In a full implementation,
22314
+ // this would use the static_variant index
22315
+ const opTypeIndex = getOperationTypeIndex(opType);
22316
+ bb.writeVarint32(opTypeIndex);
22317
+ // Serialize operation data based on type
22318
+ serializeOperationData(bb, opType, opData);
22319
+ }
22320
+ /**
22321
+ * Get operation type index based on Steem blockchain operation order
22322
+ * This matches the operation.st_operations array from the blockchain
22323
+ */
22324
+ function getOperationTypeIndex(opType) {
22325
+ // Operation type indices based on Steem blockchain operation.st_operations
22326
+ const opMap = {
22327
+ 'vote': 0,
22328
+ 'comment': 1,
22329
+ 'transfer': 2,
22330
+ 'transfer_to_vesting': 3,
22331
+ 'withdraw_vesting': 4,
22332
+ 'limit_order_create': 5,
22333
+ 'limit_order_cancel': 6,
22334
+ 'feed_publish': 7,
22335
+ 'convert': 8,
22336
+ 'account_create': 9,
22337
+ 'account_update': 10,
22338
+ 'witness_update': 11,
22339
+ 'account_witness_vote': 12,
22340
+ 'account_witness_proxy': 13,
22341
+ 'pow': 14,
22342
+ 'custom': 15,
22343
+ 'delete_comment': 17,
22344
+ 'custom_json': 18,
22345
+ 'comment_options': 19,
22346
+ };
22347
+ const index = opMap[opType];
22348
+ if (index === undefined) {
22349
+ throw new Error(`Unknown operation type: ${opType}. Please add it to the operation map.`);
22350
+ }
22351
+ return index;
22352
+ }
22353
+ /**
22354
+ * Serialize operation data based on operation type
22355
+ */
22356
+ function serializeOperationData(bb, opType, opData) {
22357
+ switch (opType) {
22358
+ case 'comment':
22359
+ serializeComment(bb, opData);
22360
+ break;
22361
+ case 'vote':
22362
+ serializeVote(bb, opData);
22363
+ break;
22364
+ case 'transfer':
22365
+ serializeTransfer(bb, opData);
22366
+ break;
22367
+ default:
22368
+ // For other operations, try to serialize common fields
22369
+ // This is a fallback and may not work for all operations
22370
+ throw new Error(`Operation type ${opType} serialization not fully implemented`);
22371
+ }
22372
+ }
22373
+ /**
22374
+ * Serialize comment operation
22375
+ */
22376
+ function serializeComment(bb, data) {
22377
+ writeString(bb, data.parent_author || '');
22378
+ writeString(bb, data.parent_permlink || '');
22379
+ writeString(bb, data.author || '');
22380
+ writeString(bb, data.permlink || '');
22381
+ writeString(bb, data.title || '');
22382
+ writeString(bb, data.body || '');
22383
+ writeString(bb, data.json_metadata || '{}');
22384
+ }
22385
+ /**
22386
+ * Serialize vote operation
22387
+ */
22388
+ function serializeVote(bb, data) {
22389
+ writeString(bb, data.voter || '');
22390
+ writeString(bb, data.author || '');
22391
+ writeString(bb, data.permlink || '');
22392
+ bb.writeInt16(data.weight || 0);
22393
+ }
22394
+ /**
22395
+ * Serialize transfer operation (simplified - asset serialization is complex)
22396
+ */
22397
+ function serializeTransfer(bb, data) {
22398
+ writeString(bb, data.from || '');
22399
+ writeString(bb, data.to || '');
22400
+ // Asset serialization is complex and requires parsing amount string
22401
+ // For now, this is a placeholder
22402
+ serializeAsset(bb, data.amount || '0.000 STEEM');
22403
+ writeString(bb, data.memo || '');
22404
+ }
22405
+ /**
22406
+ * Serialize asset (simplified - full implementation is complex)
22407
+ */
22408
+ function serializeAsset(bb, amount) {
22409
+ // Parse amount string like "1.000 STEEM"
22410
+ const parts = amount.split(' ');
22411
+ const valueStr = parts[0] || '0.000';
22412
+ const symbol = parts[1] || 'STEEM';
22413
+ // Parse decimal value
22414
+ const [intPart, decPart = ''] = valueStr.split('.');
22415
+ const precision = decPart.length;
22416
+ const amountValue = parseInt(intPart + decPart.padEnd(precision, '0'), 10);
22417
+ // Write amount as int64
22418
+ const amountLong = Long.fromNumber(amountValue, false);
22419
+ bb.writeInt64(amountLong);
22420
+ // Write precision and symbol (uint8 + 7 bytes)
22421
+ bb.writeUint8(precision);
22422
+ const symbolBytes = Buffer.from(symbol, 'utf8');
22423
+ bb.append(symbolBytes);
22424
+ // Pad to 7 bytes
22425
+ for (let i = symbolBytes.length; i < 7; i++) {
22426
+ bb.writeUint8(0);
22427
+ }
22428
+ }
22429
+ /**
22430
+ * Write a string using ByteBuffer's writeVString method
22431
+ * This matches the old implementation exactly
22432
+ */
22433
+ function writeString(bb, str) {
22434
+ bb.writeVString(str);
22435
+ }
22436
+
21874
22437
  class Serializer {
21875
22438
  static fromBuffer(buffer) {
21876
22439
  const bb = ByteBuffer.fromBinary(buffer.toString('binary'), ByteBuffer.LITTLE_ENDIAN);
@@ -21933,7 +22496,8 @@ class Serializer {
21933
22496
  }
21934
22497
  const transaction = {
21935
22498
  toBuffer(trx) {
21936
- return Buffer.from(JSON.stringify(trx));
22499
+ // Use binary serialization for proper signature generation
22500
+ return serializeTransaction$1(trx);
21937
22501
  }
21938
22502
  };
21939
22503
  const signed_transaction = {
@@ -21945,6 +22509,13 @@ const signed_transaction = {
21945
22509
  }
21946
22510
  };
21947
22511
 
22512
+ const serializer$1 = /*#__PURE__*/Object.freeze({
22513
+ __proto__: null,
22514
+ Serializer: Serializer,
22515
+ signed_transaction: signed_transaction,
22516
+ transaction: transaction
22517
+ });
22518
+
21948
22519
  const Auth = {
21949
22520
  verify(name, password, auths) {
21950
22521
  let hasKey = false;
@@ -22026,13 +22597,15 @@ const Auth = {
22026
22597
  }
22027
22598
  const signatures = [];
22028
22599
  if (trx.signatures) {
22029
- signatures.push(...trx.signatures.map((sig) => Buffer.from(sig)));
22600
+ signatures.push(...trx.signatures.map((sig) => Buffer.isBuffer(sig) ? sig.toString('hex') : sig));
22030
22601
  }
22031
22602
  const cid = Buffer.from(getConfig().get('chain_id') || '', 'hex');
22032
22603
  const buf = transaction.toBuffer(trx);
22033
22604
  for (const key of keys) {
22034
22605
  const sig = Signature.signBuffer(Buffer.concat([cid, buf]), key);
22035
- signatures.push(sig.toBuffer());
22606
+ // Use toBuffer() to match old-steem-js behavior
22607
+ // The serializer will convert Buffer to hex string when needed
22608
+ signatures.push(sig.toBuffer().toString('hex'));
22036
22609
  }
22037
22610
  return signed_transaction.toObject(Object.assign(trx, { signatures }));
22038
22611
  }
@@ -22369,6 +22942,21 @@ class Broadcast {
22369
22942
  try {
22370
22943
  // Prepare the transaction (fetch global props, block header, etc.)
22371
22944
  const transaction = await broadcastMethods._prepareTransaction.call(this, tx);
22945
+ // Debug: Print transaction, digest, and hex before signing (if debug enabled)
22946
+ const { debug } = await Promise.resolve().then(function () { return debug$1; });
22947
+ if (debug.isEnabled('transaction')) {
22948
+ const { transaction: transactionSerializer } = await Promise.resolve().then(function () { return serializer$1; });
22949
+ const { getConfig } = await Promise.resolve().then(function () { return config$1; });
22950
+ const { createHash } = await import('crypto');
22951
+ const buf = transactionSerializer.toBuffer(transaction);
22952
+ const chainId = Buffer.from(getConfig().get('chain_id') || '', 'hex');
22953
+ const digest = createHash('sha256').update(Buffer.concat([chainId, buf])).digest();
22954
+ debug.transaction('\n=== Transaction Debug Info (before signing) ===');
22955
+ debug.transaction('Transaction:', JSON.stringify(transaction, null, 2));
22956
+ debug.transaction('Transaction.toHex():', buf.toString('hex'));
22957
+ debug.transaction('Digest (sha256(chain_id + transaction)):', digest.toString('hex'));
22958
+ debug.transaction('===============================================\n');
22959
+ }
22372
22960
  // Ensure privKeys is always an array for signTransaction
22373
22961
  const keysArray = Array.isArray(privKeys)
22374
22962
  ? privKeys
@@ -25729,7 +26317,7 @@ const doubleSha256 = (data) => {
25729
26317
  return sha256(sha256(data));
25730
26318
  };
25731
26319
  const hmacSha256 = (key, data) => {
25732
- return createHmac$1('sha256', key).update(data).digest();
26320
+ return createHmac$2('sha256', key).update(data).digest();
25733
26321
  };
25734
26322
  /**
25735
26323
  * Generate a cryptographically secure key pair using ECC secp256k1