@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.cjs CHANGED
@@ -6085,6 +6085,98 @@ const setConfig = (newConfig) => {
6085
6085
  // Alias for setConfig to match the API's setOptions
6086
6086
  const setOptions$1 = setConfig;
6087
6087
 
6088
+ var config$1 = /*#__PURE__*/Object.freeze({
6089
+ __proto__: null,
6090
+ Config: Config,
6091
+ getConfig: getConfig,
6092
+ setConfig: setConfig,
6093
+ setOptions: setOptions$1
6094
+ });
6095
+
6096
+ /**
6097
+ * Debug utility for controlled debug output
6098
+ * Can be enabled via:
6099
+ * 1. Config: steem.config.set({ debug: true })
6100
+ * 2. Environment variable: DEBUG=steem-js or DEBUG=steem-js:*
6101
+ * 3. Specific debug flags: DEBUG=steem-js:transaction,steem-js:signature
6102
+ */
6103
+ // Check if debug is enabled via environment variable
6104
+ const DEBUG_ENV = process.env.DEBUG || '';
6105
+ const DEBUG_ENABLED = DEBUG_ENV.includes('steem-js');
6106
+ // Parse debug flags from environment
6107
+ const DEBUG_FLAGS = DEBUG_ENV.split(',').map(f => f.trim());
6108
+ function isDebugEnabled(flag) {
6109
+ // Check config first
6110
+ const configDebug = getConfig().get('debug');
6111
+ if (configDebug === true) {
6112
+ return true;
6113
+ }
6114
+ if (configDebug === false) {
6115
+ return false;
6116
+ }
6117
+ // Check environment variable
6118
+ if (!DEBUG_ENABLED) {
6119
+ return false;
6120
+ }
6121
+ // If no flag specified, check for general steem-js debug
6122
+ if (!flag) {
6123
+ return DEBUG_ENV.includes('steem-js') && !DEBUG_ENV.includes('steem-js:');
6124
+ }
6125
+ // Check for specific flag
6126
+ const flagPattern = `steem-js:${flag}`;
6127
+ return DEBUG_FLAGS.some(f => f === flagPattern || f === 'steem-js:*');
6128
+ }
6129
+ const debug = {
6130
+ /**
6131
+ * Log debug information
6132
+ * @param flag - Optional debug flag (e.g., 'transaction', 'signature')
6133
+ * @param args - Arguments to log
6134
+ */
6135
+ log(flag, ...args) {
6136
+ if (isDebugEnabled(flag)) {
6137
+ const prefix = flag ? `[steem-js:${flag}]` : '[steem-js]';
6138
+ console.log(prefix, ...args);
6139
+ }
6140
+ },
6141
+ /**
6142
+ * Log transaction debug info
6143
+ */
6144
+ transaction(...args) {
6145
+ this.log('transaction', ...args);
6146
+ },
6147
+ /**
6148
+ * Log signature debug info
6149
+ */
6150
+ signature(...args) {
6151
+ this.log('signature', ...args);
6152
+ },
6153
+ /**
6154
+ * Log warning (always shown, but can be controlled)
6155
+ */
6156
+ warn(...args) {
6157
+ if (isDebugEnabled() || getConfig().get('debug_warnings') !== false) {
6158
+ console.warn('[steem-js]', ...args);
6159
+ }
6160
+ },
6161
+ /**
6162
+ * Log error (always shown)
6163
+ */
6164
+ error(...args) {
6165
+ console.error('[steem-js]', ...args);
6166
+ },
6167
+ /**
6168
+ * Check if debug is enabled for a specific flag
6169
+ */
6170
+ isEnabled(flag) {
6171
+ return isDebugEnabled(flag);
6172
+ }
6173
+ };
6174
+
6175
+ var debug$1 = /*#__PURE__*/Object.freeze({
6176
+ __proto__: null,
6177
+ debug: debug
6178
+ });
6179
+
6088
6180
  const sleep = (ms) => {
6089
6181
  return new Promise(resolve => setTimeout(resolve, ms));
6090
6182
  };
@@ -6130,6 +6222,7 @@ var utils = /*#__PURE__*/Object.freeze({
6130
6222
  __proto__: null,
6131
6223
  camelCase: camelCase,
6132
6224
  chunk: chunk,
6225
+ debug: debug,
6133
6226
  flatten: flatten,
6134
6227
  isValidAddress: isValidAddress,
6135
6228
  isValidAmount: isValidAmount,
@@ -8310,17 +8403,18 @@ function requireCreateHash () {
8310
8403
  var createHashExports = requireCreateHash();
8311
8404
  var createHash = /*@__PURE__*/getDefaultExportFromCjs(createHashExports);
8312
8405
 
8313
- var createHmac;
8406
+ var createHmac$1;
8314
8407
  var hasRequiredCreateHmac;
8315
8408
 
8316
8409
  function requireCreateHmac () {
8317
- if (hasRequiredCreateHmac) return createHmac;
8410
+ if (hasRequiredCreateHmac) return createHmac$1;
8318
8411
  hasRequiredCreateHmac = 1;
8319
- createHmac = require$$3$1.createHmac;
8320
- return createHmac;
8412
+ createHmac$1 = require$$3$1.createHmac;
8413
+ return createHmac$1;
8321
8414
  }
8322
8415
 
8323
- requireCreateHmac();
8416
+ var createHmacExports = requireCreateHmac();
8417
+ var createHmac = /*@__PURE__*/getDefaultExportFromCjs(createHmacExports);
8324
8418
 
8325
8419
  /** @arg {string|Buffer} data
8326
8420
  @arg {string} [digest = null] - 'hex', 'binary' or 'base64'
@@ -8342,6 +8436,9 @@ function sha512(data, encoding) {
8342
8436
  }
8343
8437
  return createHash('sha512').update(data).digest();
8344
8438
  }
8439
+ function HmacSHA256(buffer, secret) {
8440
+ return createHmac('sha256', secret).update(buffer).digest();
8441
+ }
8345
8442
  function ripemd160$1(data) {
8346
8443
  return createHash('rmd160').update(data).digest();
8347
8444
  }
@@ -8627,7 +8724,7 @@ class PrivateKey {
8627
8724
  throw new Error("Expecting parameter to be a Buffer type");
8628
8725
  }
8629
8726
  if (32 !== buf.length) {
8630
- console.log(`WARN: Expecting 32 bytes, instead got ${buf.length}, stack trace:`, new Error().stack);
8727
+ debug.warn(`WARN: Expecting 32 bytes, instead got ${buf.length}, stack trace:`, new Error().stack);
8631
8728
  }
8632
8729
  if (buf.length === 0) {
8633
8730
  throw new Error("Empty buffer");
@@ -8746,6 +8843,278 @@ const toPublic = (data) => {
8746
8843
  return data;
8747
8844
  };
8748
8845
 
8846
+ function enforce(type, value) {
8847
+ switch (type) {
8848
+ case 'Array': {
8849
+ if (Array.isArray(value))
8850
+ return;
8851
+ break;
8852
+ }
8853
+ case 'Boolean': {
8854
+ if (typeof value === 'boolean')
8855
+ return;
8856
+ break;
8857
+ }
8858
+ case 'Buffer': {
8859
+ if (Buffer.isBuffer(value))
8860
+ return;
8861
+ break;
8862
+ }
8863
+ case 'Number': {
8864
+ if (typeof value === 'number')
8865
+ return;
8866
+ break;
8867
+ }
8868
+ case 'String': {
8869
+ if (typeof value === 'string')
8870
+ return;
8871
+ break;
8872
+ }
8873
+ default: {
8874
+ if (typeof type === 'function' && getName(value.constructor) === getName(type))
8875
+ return;
8876
+ }
8877
+ }
8878
+ throw new TypeError('Expected ' + (typeof type === 'function' ? getName(type) : type) + ', got ' + value);
8879
+ }
8880
+ function getName(fn) {
8881
+ const match = fn.toString().match(/function (.*?)\(/);
8882
+ return match ? match[1] : null;
8883
+ }
8884
+
8885
+ class ECSignature {
8886
+ constructor(r, s) {
8887
+ enforce(bigi, r);
8888
+ enforce(bigi, s);
8889
+ this.r = r;
8890
+ this.s = s;
8891
+ }
8892
+ static parseCompact(buffer) {
8893
+ if (buffer.length !== 65)
8894
+ throw new Error('Invalid signature length');
8895
+ let i = buffer.readUInt8(0) - 27;
8896
+ if ((i & 7) !== i)
8897
+ throw new Error('Invalid signature parameter');
8898
+ const compressed = !!(i & 4);
8899
+ i = i & 3;
8900
+ const r = bigi.fromBuffer(buffer.slice(1, 33));
8901
+ const s = bigi.fromBuffer(buffer.slice(33));
8902
+ return {
8903
+ compressed,
8904
+ i,
8905
+ signature: new ECSignature(r, s)
8906
+ };
8907
+ }
8908
+ static fromDER(buffer) {
8909
+ if (buffer.readUInt8(0) !== 0x30)
8910
+ throw new Error('Not a DER sequence');
8911
+ if (buffer.readUInt8(1) !== buffer.length - 2)
8912
+ throw new Error('Invalid sequence length');
8913
+ if (buffer.readUInt8(2) !== 0x02)
8914
+ throw new Error('Expected a DER integer');
8915
+ const rLen = buffer.readUInt8(3);
8916
+ if (rLen === 0)
8917
+ throw new Error('R length is zero');
8918
+ let offset = 4 + rLen;
8919
+ if (buffer.readUInt8(offset) !== 0x02)
8920
+ throw new Error('Expected a DER integer (2)');
8921
+ const sLen = buffer.readUInt8(offset + 1);
8922
+ if (sLen === 0)
8923
+ throw new Error('S length is zero');
8924
+ const rB = buffer.slice(4, offset);
8925
+ const sB = buffer.slice(offset + 2);
8926
+ offset += 2 + sLen;
8927
+ if (rLen > 1 && rB.readUInt8(0) === 0x00) {
8928
+ if (!(rB.readUInt8(1) & 0x80))
8929
+ throw new Error('R value excessively padded');
8930
+ }
8931
+ if (sLen > 1 && sB.readUInt8(0) === 0x00) {
8932
+ if (!(sB.readUInt8(1) & 0x80))
8933
+ throw new Error('S value excessively padded');
8934
+ }
8935
+ if (offset !== buffer.length)
8936
+ throw new Error('Invalid DER encoding');
8937
+ const r = bigi.fromBuffer(rB);
8938
+ const s = bigi.fromBuffer(sB);
8939
+ if (r.signum() < 0)
8940
+ throw new Error('R value is negative');
8941
+ if (s.signum() < 0)
8942
+ throw new Error('S value is negative');
8943
+ return new ECSignature(r, s);
8944
+ }
8945
+ static parseScriptSignature(buffer) {
8946
+ const hashType = buffer.readUInt8(buffer.length - 1);
8947
+ const hashTypeMod = hashType & -129;
8948
+ if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04)
8949
+ throw new Error('Invalid hashType');
8950
+ return {
8951
+ signature: ECSignature.fromDER(buffer.slice(0, -1)),
8952
+ hashType
8953
+ };
8954
+ }
8955
+ toCompact(i, compressed) {
8956
+ if (compressed)
8957
+ i += 4;
8958
+ i += 27;
8959
+ const buffer = Buffer.alloc(65);
8960
+ buffer.writeUInt8(i, 0);
8961
+ this.r.toBuffer(32).copy(buffer, 1);
8962
+ this.s.toBuffer(32).copy(buffer, 33);
8963
+ return buffer;
8964
+ }
8965
+ toDER() {
8966
+ const rBa = this.r.toBuffer();
8967
+ const sBa = this.s.toBuffer();
8968
+ const sequence = [];
8969
+ // INTEGER
8970
+ sequence.push(0x02, rBa.length);
8971
+ Array.from(rBa).forEach(b => sequence.push(b));
8972
+ // INTEGER
8973
+ sequence.push(0x02, sBa.length);
8974
+ Array.from(sBa).forEach(b => sequence.push(b));
8975
+ // SEQUENCE
8976
+ sequence.unshift(0x30, sequence.length);
8977
+ return Buffer.from(sequence);
8978
+ }
8979
+ toScriptSignature(hashType) {
8980
+ const hashTypeBuffer = Buffer.alloc(1);
8981
+ hashTypeBuffer.writeUInt8(hashType, 0);
8982
+ return Buffer.concat([this.toDER(), hashTypeBuffer]);
8983
+ }
8984
+ }
8985
+
8986
+ // https://tools.ietf.org/html/rfc6979#section-3.2
8987
+ function deterministicGenerateK(curve, hash, d, checkSig, nonce) {
8988
+ enforce('Buffer', hash);
8989
+ enforce(bigi, d);
8990
+ if (nonce) {
8991
+ hash = sha256$1(Buffer.concat([hash, Buffer.alloc(nonce)]));
8992
+ }
8993
+ // sanity check
8994
+ assert.equal(hash.length, 32, 'Hash must be 256 bit');
8995
+ const x = d.toBuffer(32);
8996
+ let k = Buffer.alloc(32);
8997
+ let v = Buffer.alloc(32);
8998
+ // Step B
8999
+ v.fill(1);
9000
+ // Step C
9001
+ k.fill(0);
9002
+ // Step D
9003
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([0]), x, hash]), k);
9004
+ // Step E
9005
+ v = HmacSHA256(v, k);
9006
+ // Step F
9007
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([1]), x, hash]), k);
9008
+ // Step G
9009
+ v = HmacSHA256(v, k);
9010
+ // Step H1/H2a, ignored as tlen === qlen (256 bit)
9011
+ // Step H2b
9012
+ v = HmacSHA256(v, k);
9013
+ let T = bigi.fromBuffer(v);
9014
+ // Step H3, repeat until T is within the interval [1, n - 1] and passes the supplied check
9015
+ while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0) || !checkSig(T)) {
9016
+ k = HmacSHA256(Buffer.concat([v, Buffer.from([0])]), k);
9017
+ v = HmacSHA256(v, k);
9018
+ // Step H1/H2a, again, ignored as tlen === qlen (256 bit)
9019
+ // Step H2b again
9020
+ v = HmacSHA256(v, k);
9021
+ T = bigi.fromBuffer(v);
9022
+ }
9023
+ return T;
9024
+ }
9025
+ function sign$3(curve, hash, d, nonce) {
9026
+ const e = bigi.fromBuffer(hash);
9027
+ const n = curve.n;
9028
+ const G = curve.G;
9029
+ let r;
9030
+ let s;
9031
+ deterministicGenerateK(curve, hash, d, function (k) {
9032
+ // find canonically valid signature
9033
+ const Q = G.multiply(k);
9034
+ if (curve.isInfinity(Q))
9035
+ return false;
9036
+ const tempR = Q.affineX.mod(n);
9037
+ if (tempR.signum() === 0)
9038
+ return false;
9039
+ const tempS = k.modInverse(n).multiply(e.add(d.multiply(tempR))).mod(n);
9040
+ if (tempS.signum() === 0)
9041
+ return false;
9042
+ r = tempR;
9043
+ s = tempS;
9044
+ return true;
9045
+ }, nonce);
9046
+ if (!r || !s)
9047
+ throw new Error('Unable to find valid signature');
9048
+ const N_OVER_TWO = n.shiftRight(1);
9049
+ // enforce low S values, see bip62: 'low s values in signatures'
9050
+ const finalS = s.compareTo(N_OVER_TWO) > 0 ? n.subtract(s) : s;
9051
+ return new ECSignature(r, finalS);
9052
+ }
9053
+ /**
9054
+ * Recover a public key from a signature.
9055
+ *
9056
+ * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
9057
+ * Key Recovery Operation".
9058
+ *
9059
+ * http://www.secg.org/download/aid-780/sec1-v2.pdf
9060
+ */
9061
+ function recoverPubKey(curve, e, signature, i) {
9062
+ assert.strictEqual(i & 3, i, 'Recovery param is more than two bits');
9063
+ const n = curve.n;
9064
+ const G = curve.G;
9065
+ const r = signature.r;
9066
+ const s = signature.s;
9067
+ assert(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value');
9068
+ assert(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value');
9069
+ // A set LSB signifies that the y-coordinate is odd
9070
+ const isYOdd = !!(i & 1);
9071
+ // The more significant bit specifies whether we should use the
9072
+ // first or second candidate key.
9073
+ const isSecondKey = i >> 1;
9074
+ // 1.1 Let x = r + jn
9075
+ const x = isSecondKey ? r.add(n) : r;
9076
+ const R = curve.pointFromX(isYOdd, x);
9077
+ // 1.4 Check that nR is at infinity
9078
+ const nR = R.multiply(n);
9079
+ assert(curve.isInfinity(nR), 'nR is not a valid curve point');
9080
+ // Compute -e from e
9081
+ const eNeg = e.negate().mod(n);
9082
+ // 1.6.1 Compute Q = r^-1 (sR - eG)
9083
+ // Q = r^-1 (sR + -eG)
9084
+ const rInv = r.modInverse(n);
9085
+ const sR = R.multiply(s);
9086
+ const eGNeg = G.multiply(eNeg);
9087
+ const Q = sR.add(eGNeg).multiply(rInv);
9088
+ curve.validate(Q);
9089
+ return Q;
9090
+ }
9091
+ /**
9092
+ * Calculate pubkey extraction parameter.
9093
+ *
9094
+ * When extracting a pubkey from a signature, we have to
9095
+ * distinguish four different cases. Rather than putting this
9096
+ * burden on the verifier, Bitcoin includes a 2-bit value with the
9097
+ * signature.
9098
+ *
9099
+ * This function simply tries all four cases and returns the value
9100
+ * that resulted in a successful pubkey recovery.
9101
+ */
9102
+ function calcPubKeyRecoveryParam(curve, e, signature, Q) {
9103
+ for (let i = 0; i < 4; i++) {
9104
+ try {
9105
+ const Qprime = recoverPubKey(curve, e, signature, i);
9106
+ // 1.6.2 Verify Q = Q'
9107
+ if (Qprime.equals(Q)) {
9108
+ return i;
9109
+ }
9110
+ }
9111
+ catch (error) {
9112
+ // try next value
9113
+ }
9114
+ }
9115
+ throw new Error('Unable to find valid recovery factor');
9116
+ }
9117
+
8749
9118
  const secp256k1 = libExports$1.getCurveByName('secp256k1');
8750
9119
  class Signature {
8751
9120
  constructor(r, s, i) {
@@ -8785,28 +9154,27 @@ class Signature {
8785
9154
  throw new Error('private_key required');
8786
9155
  }
8787
9156
  const e = bigi.fromBuffer(buf_sha256);
8788
- const n = secp256k1.n;
8789
- const G = secp256k1.G;
8790
- const d = privKey.d;
8791
- let r, s;
9157
+ let ecsignature;
9158
+ let i = null;
8792
9159
  let nonce = 0;
9160
+ // Match old-steem-js behavior: find canonical signature (lenR === 32 && lenS === 32)
8793
9161
  while (true) {
8794
- const k = bigi.fromBuffer(sha256$1(Buffer.concat([buf_sha256, Buffer.from([nonce++])])));
8795
- const Q = G.multiply(k);
8796
- r = Q.affineX.mod(n);
8797
- if (r.signum() === 0)
8798
- continue;
8799
- s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
8800
- if (s.signum() === 0)
8801
- continue;
8802
- break;
8803
- }
8804
- const N_OVER_TWO = n.shiftRight(1);
8805
- if (s.compareTo(N_OVER_TWO) > 0) {
8806
- s = n.subtract(s);
9162
+ ecsignature = sign$3(secp256k1, buf_sha256, privKey.d, nonce++);
9163
+ const der = ecsignature.toDER();
9164
+ const lenR = der[3];
9165
+ const lenS = der[5 + lenR];
9166
+ if (lenR === 32 && lenS === 32) {
9167
+ // Calculate recovery parameter to match old-steem-js
9168
+ i = calcPubKeyRecoveryParam(secp256k1, e, ecsignature, privKey.toPublic().Q);
9169
+ i += 4; // compressed
9170
+ i += 27; // compact
9171
+ break;
9172
+ }
9173
+ if (nonce % 10 === 0) {
9174
+ debug.warn("WARN: " + nonce + " attempts to find canonical signature");
9175
+ }
8807
9176
  }
8808
- const i = 27 + 4; // compressed + compact
8809
- return new Signature(r, s, i);
9177
+ return new Signature(ecsignature.r, ecsignature.s, i);
8810
9178
  }
8811
9179
  static sign(string, private_key) {
8812
9180
  return Signature.signBuffer(Buffer.from(string), private_key);
@@ -9978,7 +10346,18 @@ class HttpTransport extends BaseTransport {
9978
10346
  timeout: timeoutMs,
9979
10347
  })
9980
10348
  .then((res) => res.json())
9981
- .then((result) => callback(null, result.result, currentAttempt), (error) => {
10349
+ .then((result) => {
10350
+ // Check for JSON-RPC errors
10351
+ if (result.error) {
10352
+ const error = new Error(result.error.message || 'JSON-RPC error');
10353
+ error.code = result.error.code;
10354
+ error.data = result.error.data;
10355
+ callback(error, undefined, currentAttempt);
10356
+ }
10357
+ else {
10358
+ callback(null, result.result, currentAttempt);
10359
+ }
10360
+ }, (error) => {
9982
10361
  if (operation.retry(error)) {
9983
10362
  return;
9984
10363
  }
@@ -9999,7 +10378,18 @@ class HttpTransport extends BaseTransport {
9999
10378
  timeout: timeoutMs,
10000
10379
  })
10001
10380
  .then((res) => res.json())
10002
- .then((result) => callback(null, result.result, 1), (error) => callback(error, undefined, 1));
10381
+ .then((result) => {
10382
+ // Check for JSON-RPC errors
10383
+ if (result.error) {
10384
+ const error = new Error(result.error.message || 'JSON-RPC error');
10385
+ error.code = result.error.code;
10386
+ error.data = result.error.data;
10387
+ callback(error, undefined, 1);
10388
+ }
10389
+ else {
10390
+ callback(null, result.result, 1);
10391
+ }
10392
+ }, (error) => callback(error, undefined, 1));
10003
10393
  }
10004
10394
  }
10005
10395
  }
@@ -21900,6 +22290,179 @@ if (typeof BigInt === "function") {
21900
22290
  };
21901
22291
  }
21902
22292
 
22293
+ /**
22294
+ * Serialize a transaction to binary format for Steem blockchain
22295
+ * This is a simplified implementation that handles the basic structure
22296
+ */
22297
+ function serializeTransaction$1(trx) {
22298
+ const bb = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
22299
+ // Write ref_block_num (uint16)
22300
+ bb.writeUint16(trx.ref_block_num || 0);
22301
+ // Write ref_block_prefix (uint32)
22302
+ bb.writeUint32(trx.ref_block_prefix || 0);
22303
+ // Write expiration (time_point_sec - uint32 seconds since epoch)
22304
+ // Match old-steem-js behavior: ensure UTC time and precision to seconds
22305
+ let expiration;
22306
+ if (typeof trx.expiration === 'string') {
22307
+ // If string doesn't end with 'Z', append it to ensure UTC time
22308
+ let expirationStr = trx.expiration;
22309
+ if (!expirationStr.endsWith('Z')) {
22310
+ expirationStr = expirationStr + 'Z';
22311
+ }
22312
+ const date = new Date(expirationStr);
22313
+ expiration = Math.floor(date.getTime() / 1000);
22314
+ }
22315
+ else if (typeof trx.expiration === 'number') {
22316
+ expiration = trx.expiration;
22317
+ }
22318
+ else {
22319
+ expiration = 0;
22320
+ }
22321
+ bb.writeUint32(expiration);
22322
+ // Write operations array
22323
+ const operations = trx.operations || [];
22324
+ bb.writeVarint32(operations.length);
22325
+ for (const op of operations) {
22326
+ serializeOperation$1(bb, op);
22327
+ }
22328
+ // Write extensions (set of future_extensions, which is void/empty)
22329
+ bb.writeVarint32(0); // Empty set
22330
+ bb.flip();
22331
+ return Buffer.from(bb.toBuffer());
22332
+ }
22333
+ /**
22334
+ * Serialize an operation to binary format
22335
+ */
22336
+ function serializeOperation$1(bb, op) {
22337
+ if (!Array.isArray(op) || op.length !== 2) {
22338
+ throw new Error('Operation must be an array of [operation_type, operation_data]');
22339
+ }
22340
+ const [opType, opData] = op;
22341
+ // Write operation type index (varint32)
22342
+ // For now, we'll use a simple mapping. In a full implementation,
22343
+ // this would use the static_variant index
22344
+ const opTypeIndex = getOperationTypeIndex(opType);
22345
+ bb.writeVarint32(opTypeIndex);
22346
+ // Serialize operation data based on type
22347
+ serializeOperationData(bb, opType, opData);
22348
+ }
22349
+ /**
22350
+ * Get operation type index based on Steem blockchain operation order
22351
+ * This matches the operation.st_operations array from the blockchain
22352
+ */
22353
+ function getOperationTypeIndex(opType) {
22354
+ // Operation type indices based on Steem blockchain operation.st_operations
22355
+ const opMap = {
22356
+ 'vote': 0,
22357
+ 'comment': 1,
22358
+ 'transfer': 2,
22359
+ 'transfer_to_vesting': 3,
22360
+ 'withdraw_vesting': 4,
22361
+ 'limit_order_create': 5,
22362
+ 'limit_order_cancel': 6,
22363
+ 'feed_publish': 7,
22364
+ 'convert': 8,
22365
+ 'account_create': 9,
22366
+ 'account_update': 10,
22367
+ 'witness_update': 11,
22368
+ 'account_witness_vote': 12,
22369
+ 'account_witness_proxy': 13,
22370
+ 'pow': 14,
22371
+ 'custom': 15,
22372
+ 'delete_comment': 17,
22373
+ 'custom_json': 18,
22374
+ 'comment_options': 19,
22375
+ };
22376
+ const index = opMap[opType];
22377
+ if (index === undefined) {
22378
+ throw new Error(`Unknown operation type: ${opType}. Please add it to the operation map.`);
22379
+ }
22380
+ return index;
22381
+ }
22382
+ /**
22383
+ * Serialize operation data based on operation type
22384
+ */
22385
+ function serializeOperationData(bb, opType, opData) {
22386
+ switch (opType) {
22387
+ case 'comment':
22388
+ serializeComment(bb, opData);
22389
+ break;
22390
+ case 'vote':
22391
+ serializeVote(bb, opData);
22392
+ break;
22393
+ case 'transfer':
22394
+ serializeTransfer(bb, opData);
22395
+ break;
22396
+ default:
22397
+ // For other operations, try to serialize common fields
22398
+ // This is a fallback and may not work for all operations
22399
+ throw new Error(`Operation type ${opType} serialization not fully implemented`);
22400
+ }
22401
+ }
22402
+ /**
22403
+ * Serialize comment operation
22404
+ */
22405
+ function serializeComment(bb, data) {
22406
+ writeString(bb, data.parent_author || '');
22407
+ writeString(bb, data.parent_permlink || '');
22408
+ writeString(bb, data.author || '');
22409
+ writeString(bb, data.permlink || '');
22410
+ writeString(bb, data.title || '');
22411
+ writeString(bb, data.body || '');
22412
+ writeString(bb, data.json_metadata || '{}');
22413
+ }
22414
+ /**
22415
+ * Serialize vote operation
22416
+ */
22417
+ function serializeVote(bb, data) {
22418
+ writeString(bb, data.voter || '');
22419
+ writeString(bb, data.author || '');
22420
+ writeString(bb, data.permlink || '');
22421
+ bb.writeInt16(data.weight || 0);
22422
+ }
22423
+ /**
22424
+ * Serialize transfer operation (simplified - asset serialization is complex)
22425
+ */
22426
+ function serializeTransfer(bb, data) {
22427
+ writeString(bb, data.from || '');
22428
+ writeString(bb, data.to || '');
22429
+ // Asset serialization is complex and requires parsing amount string
22430
+ // For now, this is a placeholder
22431
+ serializeAsset(bb, data.amount || '0.000 STEEM');
22432
+ writeString(bb, data.memo || '');
22433
+ }
22434
+ /**
22435
+ * Serialize asset (simplified - full implementation is complex)
22436
+ */
22437
+ function serializeAsset(bb, amount) {
22438
+ // Parse amount string like "1.000 STEEM"
22439
+ const parts = amount.split(' ');
22440
+ const valueStr = parts[0] || '0.000';
22441
+ const symbol = parts[1] || 'STEEM';
22442
+ // Parse decimal value
22443
+ const [intPart, decPart = ''] = valueStr.split('.');
22444
+ const precision = decPart.length;
22445
+ const amountValue = parseInt(intPart + decPart.padEnd(precision, '0'), 10);
22446
+ // Write amount as int64
22447
+ const amountLong = Long.fromNumber(amountValue, false);
22448
+ bb.writeInt64(amountLong);
22449
+ // Write precision and symbol (uint8 + 7 bytes)
22450
+ bb.writeUint8(precision);
22451
+ const symbolBytes = Buffer.from(symbol, 'utf8');
22452
+ bb.append(symbolBytes);
22453
+ // Pad to 7 bytes
22454
+ for (let i = symbolBytes.length; i < 7; i++) {
22455
+ bb.writeUint8(0);
22456
+ }
22457
+ }
22458
+ /**
22459
+ * Write a string using ByteBuffer's writeVString method
22460
+ * This matches the old implementation exactly
22461
+ */
22462
+ function writeString(bb, str) {
22463
+ bb.writeVString(str);
22464
+ }
22465
+
21903
22466
  class Serializer {
21904
22467
  static fromBuffer(buffer) {
21905
22468
  const bb = ByteBuffer.fromBinary(buffer.toString('binary'), ByteBuffer.LITTLE_ENDIAN);
@@ -21962,7 +22525,8 @@ class Serializer {
21962
22525
  }
21963
22526
  const transaction = {
21964
22527
  toBuffer(trx) {
21965
- return Buffer.from(JSON.stringify(trx));
22528
+ // Use binary serialization for proper signature generation
22529
+ return serializeTransaction$1(trx);
21966
22530
  }
21967
22531
  };
21968
22532
  const signed_transaction = {
@@ -21974,6 +22538,13 @@ const signed_transaction = {
21974
22538
  }
21975
22539
  };
21976
22540
 
22541
+ var serializer$1 = /*#__PURE__*/Object.freeze({
22542
+ __proto__: null,
22543
+ Serializer: Serializer,
22544
+ signed_transaction: signed_transaction,
22545
+ transaction: transaction
22546
+ });
22547
+
21977
22548
  const Auth = {
21978
22549
  verify(name, password, auths) {
21979
22550
  let hasKey = false;
@@ -22055,13 +22626,15 @@ const Auth = {
22055
22626
  }
22056
22627
  const signatures = [];
22057
22628
  if (trx.signatures) {
22058
- signatures.push(...trx.signatures.map((sig) => Buffer.from(sig)));
22629
+ signatures.push(...trx.signatures.map((sig) => Buffer.isBuffer(sig) ? sig.toString('hex') : sig));
22059
22630
  }
22060
22631
  const cid = Buffer.from(getConfig().get('chain_id') || '', 'hex');
22061
22632
  const buf = transaction.toBuffer(trx);
22062
22633
  for (const key of keys) {
22063
22634
  const sig = Signature.signBuffer(Buffer.concat([cid, buf]), key);
22064
- signatures.push(sig.toBuffer());
22635
+ // Use toBuffer() to match old-steem-js behavior
22636
+ // The serializer will convert Buffer to hex string when needed
22637
+ signatures.push(sig.toBuffer().toString('hex'));
22065
22638
  }
22066
22639
  return signed_transaction.toObject(Object.assign(trx, { signatures }));
22067
22640
  }
@@ -22398,6 +22971,21 @@ class Broadcast {
22398
22971
  try {
22399
22972
  // Prepare the transaction (fetch global props, block header, etc.)
22400
22973
  const transaction = await broadcastMethods._prepareTransaction.call(this, tx);
22974
+ // Debug: Print transaction, digest, and hex before signing (if debug enabled)
22975
+ const { debug } = await Promise.resolve().then(function () { return debug$1; });
22976
+ if (debug.isEnabled('transaction')) {
22977
+ const { transaction: transactionSerializer } = await Promise.resolve().then(function () { return serializer$1; });
22978
+ const { getConfig } = await Promise.resolve().then(function () { return config$1; });
22979
+ const { createHash } = await import('crypto');
22980
+ const buf = transactionSerializer.toBuffer(transaction);
22981
+ const chainId = Buffer.from(getConfig().get('chain_id') || '', 'hex');
22982
+ const digest = createHash('sha256').update(Buffer.concat([chainId, buf])).digest();
22983
+ debug.transaction('\n=== Transaction Debug Info (before signing) ===');
22984
+ debug.transaction('Transaction:', JSON.stringify(transaction, null, 2));
22985
+ debug.transaction('Transaction.toHex():', buf.toString('hex'));
22986
+ debug.transaction('Digest (sha256(chain_id + transaction)):', digest.toString('hex'));
22987
+ debug.transaction('===============================================\n');
22988
+ }
22401
22989
  // Ensure privKeys is always an array for signTransaction
22402
22990
  const keysArray = Array.isArray(privKeys)
22403
22991
  ? privKeys