@altiuslabs/tx-sdk 0.1.21 → 0.1.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@altiuslabs/tx-sdk",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "SDK for signing and sending Altius USD multi-token transactions",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -23,7 +23,7 @@ export class TxBuilder {
23
23
  this._data = '0x';
24
24
  this._max_priority_fee_per_gas = 0;
25
25
  this._max_fee_per_gas = 0;
26
- this._max_fee_per_gas_usd_attodollars = 0;
26
+ this._max_fee_per_gas_usd_attodollars = 40000000000n; // $0.04/gas default
27
27
  this._fee_token = null;
28
28
  this._fee_payer = '0x0000000000000000000000000000000000000000';
29
29
  this._fee_payer_signature = '0x';
@@ -227,9 +227,14 @@ export class TxBuilder {
227
227
  const rBuffer = Buffer.from(sig.r.slice(2), 'hex');
228
228
  const sBuffer = Buffer.from(sig.s.slice(2), 'hex');
229
229
 
230
+ // Note: y_parity is used directly as a number in signature_bytes below
231
+
230
232
  // Build signed transaction list (for EIP-2718 encoding)
231
233
  // Format matches node's rlp_encode_fields: [chainId, nonce, ..., feePayerSignature, signature]
232
234
  // IMPORTANT: Use Buffer for addresses and data to match Rust alloy-rlp encoding
235
+ //
236
+ // NOTE: For signature encoding, we use RLP encoding to match Rust alloy's behavior.
237
+ // The signature (y_parity, r, s) is added to the RLP list and encoded together.
233
238
  const signed_fields = [
234
239
  BigInt(tx.chain_id),
235
240
  BigInt(tx.nonce),
@@ -244,14 +249,15 @@ export class TxBuilder {
244
249
  Buffer.from(feePayer.slice(2), 'hex'), // fee_payer as buffer
245
250
  BigInt(tx.max_fee_per_gas_usd_attodollars),
246
251
  Buffer.from(tx.fee_payer_signature?.slice(2) || '', 'hex') || Buffer.alloc(0),
247
- // Signature: y_parity (1 byte), r (32 bytes), s (32 bytes)
248
- y_parity,
249
- rBuffer,
250
- sBuffer,
252
+ // Signature: y_parity, r, s - RLP encoded as part of the list
253
+ BigInt(y_parity),
254
+ Buffer.from(sig.r.slice(2), 'hex'), // r as 32-byte buffer
255
+ Buffer.from(sig.s.slice(2), 'hex'), // s as 32-byte buffer
251
256
  ];
252
257
 
253
258
  // EIP-2718: first byte is type (0x7a), then RLP encoded fields
254
259
  const rlp_fields_buf = RLP.encode(signed_fields);
260
+
255
261
  const raw_transaction = '0x7a' + rlp_fields_buf.toString('hex');
256
262
 
257
263
  const transaction_hash = keccak256(raw_transaction);
package/src/wallet.js CHANGED
@@ -23,9 +23,12 @@ export function generate_private_key() {
23
23
  */
24
24
  export function private_key_to_address(private_key) {
25
25
  const pk = private_key.slice(2);
26
- const publicKey = secp256k1.getPublicKey(pk, true);
27
- // Remove first byte (prefix) and take last 64 bytes (x, y)
28
- const hash = keccak256(publicKey.slice(1));
26
+ // false = uncompressed key (65 bytes starting with 0x04)
27
+ const publicKey = secp256k1.getPublicKey(pk, false);
28
+ // Convert hex string to Buffer
29
+ const publicKeyBuffer = Buffer.from(publicKey, 'hex');
30
+ // Remove first byte (prefix 0x04 for uncompressed key) and hash
31
+ const hash = keccak256(publicKeyBuffer.slice(1));
29
32
  // Take last 20 bytes
30
33
  return '0x' + hash.slice(-40);
31
34
  }
@@ -56,7 +59,13 @@ function parse_der(der) {
56
59
  offset += 2;
57
60
 
58
61
  // Get r (may need padding for leading zeros)
59
- const rHex = der.slice(offset, offset + rLen * 2);
62
+ // DER uses signed integers, so if MSB >= 0x80, a 0x00 prefix is added
63
+ // We need to strip that prefix if present, then pad to 32 bytes
64
+ let rHex = der.slice(offset, offset + rLen * 2);
65
+ if (rHex.startsWith('00') && rLen === 33) {
66
+ // Strip the leading 0x00 added by DER encoding
67
+ rHex = rHex.slice(2);
68
+ }
60
69
  const r = '0x' + rHex.padStart(64, '0');
61
70
  offset += rLen * 2;
62
71
 
@@ -68,8 +77,12 @@ function parse_der(der) {
68
77
  const sLen = parseInt(der.slice(offset, offset + 2), 16);
69
78
  offset += 2;
70
79
 
71
- // Get s
72
- const sHex = der.slice(offset, offset + sLen * 2);
80
+ // Get s (may need to strip leading 0x00 added by DER encoding)
81
+ let sHex = der.slice(offset, offset + sLen * 2);
82
+ if (sHex.startsWith('00') && sLen === 33) {
83
+ // Strip the leading 0x00 added by DER encoding
84
+ sHex = sHex.slice(2);
85
+ }
73
86
  const s = '0x' + sHex.padStart(64, '0');
74
87
 
75
88
  return { r, s };