@qevm/transactions 5.7.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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Richard Moore
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ Ethereum Transaction Utilities
2
+ ==============================
3
+
4
+ This sub-module is part of the [ethers project](https://github.com/ethers-io/ethers.js).
5
+
6
+ It contains various functions for encoding and decoding serialized transactios.
7
+
8
+ For more information, see the [documentation](https://docs.ethers.io/v5/api/utils/transactions/).
9
+
10
+
11
+ Importing
12
+ ---------
13
+
14
+ Most users will prefer to use the [umbrella package](https://www.npmjs.com/package/ethers),
15
+ but for those with more specific needs, individual components can be imported.
16
+
17
+ ```javascript
18
+ const {
19
+
20
+ computeAddress,
21
+ recoverAddress,
22
+
23
+ serialize,
24
+ parse,
25
+
26
+ // Types
27
+
28
+ Transaction,
29
+ UnsignedTransaction
30
+
31
+ } = require("@ethersproject/transactions");
32
+ ```
33
+
34
+
35
+ License
36
+ -------
37
+
38
+ MIT License
@@ -0,0 +1,2 @@
1
+ export declare const version = "transactions/5.7.0";
2
+ //# sourceMappingURL=_version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_version.d.ts","sourceRoot":"","sources":["../src.ts/_version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.version = void 0;
4
+ exports.version = "transactions/5.7.0";
5
+ //# sourceMappingURL=_version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_version.js","sourceRoot":"","sources":["../src.ts/_version.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,oBAAoB,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
2
+ import { BytesLike, SignatureLike } from "@qevm/bytes";
3
+ export declare type AccessList = Array<{
4
+ address: string;
5
+ storageKeys: Array<string>;
6
+ }>;
7
+ export declare type AccessListish = AccessList | Array<[string, Array<string>]> | Record<string, Array<string>>;
8
+ export declare enum TransactionTypes {
9
+ legacy = 0,
10
+ eip2930 = 1,
11
+ eip1559 = 2
12
+ }
13
+ export declare type UnsignedTransaction = {
14
+ to?: string;
15
+ nonce?: number;
16
+ gasLimit?: BigNumberish;
17
+ gasPrice?: BigNumberish;
18
+ data?: BytesLike;
19
+ value?: BigNumberish;
20
+ chainId?: number;
21
+ type?: number | null;
22
+ accessList?: AccessListish;
23
+ maxPriorityFeePerGas?: BigNumberish;
24
+ maxFeePerGas?: BigNumberish;
25
+ };
26
+ export interface Transaction {
27
+ hash?: string;
28
+ to?: string;
29
+ from?: string;
30
+ nonce: number;
31
+ gasLimit: BigNumber;
32
+ gasPrice?: BigNumber;
33
+ data: string;
34
+ value: BigNumber;
35
+ chainId: number;
36
+ signature?: SignatureLike;
37
+ type?: number | null;
38
+ accessList?: AccessList;
39
+ maxPriorityFeePerGas?: BigNumber;
40
+ maxFeePerGas?: BigNumber;
41
+ }
42
+ export declare function computeAddress(publicKey: BytesLike | string): string;
43
+ export declare function recoverAddress(signature: SignatureLike): string;
44
+ export declare function accessListify(value: AccessListish): AccessList;
45
+ export declare function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string;
46
+ export declare function parse(rawTransaction: BytesLike): Transaction;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAY,SAAS,EAAiE,aAAa,EAA+B,MAAM,aAAa,CAAC;AAa7J,oBAAY,UAAU,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAGhF,oBAAY,aAAa,GAAG,UAAU,GACV,KAAK,CAAC,CAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAE,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AAE1D,oBAAY,gBAAgB;IACxB,MAAM,IAAI;IACV,OAAO,IAAI;IACX,OAAO,IAAI;CACd;AAED,oBAAY,mBAAmB,GAAG;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAC;IAExB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,UAAU,CAAC,EAAE,aAAa,CAAC;IAG3B,oBAAoB,CAAC,EAAE,YAAY,CAAC;IACpC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B,CAAA;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IAEd,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,CAAC,EAAE,aAAa,CAAC;IAG1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrB,UAAU,CAAC,EAAE,UAAU,CAAC;IAGxB,oBAAoB,CAAC,EAAE,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,SAAS,CAAC;CAC5B;AA4BD,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAG/D;AAsBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAsB9D;AA4GD,wBAAgB,SAAS,CAAC,WAAW,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,aAAa,GAAG,MAAM,CAuB7F;AAmHD,wBAAgB,KAAK,CAAC,cAAc,EAAE,SAAS,GAAG,WAAW,CAoB5D"}
package/lib/index.js ADDED
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.parse = exports.serialize = exports.accessListify = exports.recoverAddress = exports.computeAddress = exports.TransactionTypes = void 0;
23
+ var address_1 = require("@qevm/address");
24
+ var bignumber_1 = require("@ethersproject/bignumber");
25
+ var bytes_1 = require("@qevm/bytes");
26
+ var constants_1 = require("@ethersproject/constants");
27
+ var keccak256_1 = require("@ethersproject/keccak256");
28
+ var properties_1 = require("@ethersproject/properties");
29
+ var RLP = __importStar(require("@ethersproject/rlp"));
30
+ var logger_1 = require("@ethersproject/logger");
31
+ var _version_1 = require("./_version");
32
+ var logger = new logger_1.Logger(_version_1.version);
33
+ var TransactionTypes;
34
+ (function (TransactionTypes) {
35
+ TransactionTypes[TransactionTypes["legacy"] = 0] = "legacy";
36
+ TransactionTypes[TransactionTypes["eip2930"] = 1] = "eip2930";
37
+ TransactionTypes[TransactionTypes["eip1559"] = 2] = "eip1559";
38
+ })(TransactionTypes = exports.TransactionTypes || (exports.TransactionTypes = {}));
39
+ ;
40
+ ///////////////////////////////
41
+ function handleAddress(value) {
42
+ if (value === "0x") {
43
+ return null;
44
+ }
45
+ return (0, address_1.getAddress)(value);
46
+ }
47
+ function handleNumber(value) {
48
+ if (value === "0x") {
49
+ return constants_1.Zero;
50
+ }
51
+ return bignumber_1.BigNumber.from(value);
52
+ }
53
+ // Legacy Transaction Fields
54
+ var transactionFields = [
55
+ { name: "nonce", maxLength: 32, numeric: true },
56
+ { name: "gasPrice", maxLength: 32, numeric: true },
57
+ { name: "gasLimit", maxLength: 32, numeric: true },
58
+ { name: "to", length: 32 },
59
+ { name: "value", maxLength: 32, numeric: true },
60
+ { name: "data" },
61
+ ];
62
+ var allowedTransactionKeys = {
63
+ chainId: true, data: true, gasLimit: true, gasPrice: true, nonce: true, to: true, type: true, value: true
64
+ };
65
+ function computeAddress(publicKey) {
66
+ return (0, keccak256_1.keccak256)(publicKey);
67
+ }
68
+ exports.computeAddress = computeAddress;
69
+ function recoverAddress(signature) {
70
+ var sig = (0, bytes_1.splitSignature)(signature);
71
+ return (0, keccak256_1.keccak256)(sig.publicKey);
72
+ }
73
+ exports.recoverAddress = recoverAddress;
74
+ function formatNumber(value, name) {
75
+ var result = (0, bytes_1.stripZeros)(bignumber_1.BigNumber.from(value).toHexString());
76
+ if (result.length > 32) {
77
+ logger.throwArgumentError("invalid length for " + name, ("transaction:" + name), value);
78
+ }
79
+ return result;
80
+ }
81
+ function accessSetify(addr, storageKeys) {
82
+ return {
83
+ address: (0, address_1.getAddress)(addr),
84
+ storageKeys: (storageKeys || []).map(function (storageKey, index) {
85
+ if ((0, bytes_1.hexDataLength)(storageKey) !== 32) {
86
+ logger.throwArgumentError("invalid access list storageKey", "accessList[" + addr + ":" + index + "]", storageKey);
87
+ }
88
+ return storageKey.toLowerCase();
89
+ })
90
+ };
91
+ }
92
+ function accessListify(value) {
93
+ if (Array.isArray(value)) {
94
+ return value.map(function (set, index) {
95
+ if (Array.isArray(set)) {
96
+ if (set.length > 2) {
97
+ logger.throwArgumentError("access list expected to be [ address, storageKeys[] ]", "value[" + index + "]", set);
98
+ }
99
+ return accessSetify(set[0], set[1]);
100
+ }
101
+ return accessSetify(set.address, set.storageKeys);
102
+ });
103
+ }
104
+ var result = Object.keys(value).map(function (addr) {
105
+ var storageKeys = value[addr].reduce(function (accum, storageKey) {
106
+ accum[storageKey] = true;
107
+ return accum;
108
+ }, {});
109
+ return accessSetify(addr, Object.keys(storageKeys).sort());
110
+ });
111
+ result.sort(function (a, b) { return (a.address.localeCompare(b.address)); });
112
+ return result;
113
+ }
114
+ exports.accessListify = accessListify;
115
+ function formatAccessList(value) {
116
+ return accessListify(value).map(function (set) { return [set.address, set.storageKeys]; });
117
+ }
118
+ function _serializeEip1559(transaction, signature) {
119
+ // If there is an explicit gasPrice, make sure it matches the
120
+ // EIP-1559 fees; otherwise they may not understand what they
121
+ // think they are setting in terms of fee.
122
+ if (transaction.gasPrice != null) {
123
+ var gasPrice = bignumber_1.BigNumber.from(transaction.gasPrice);
124
+ var maxFeePerGas = bignumber_1.BigNumber.from(transaction.maxFeePerGas || 0);
125
+ if (!gasPrice.eq(maxFeePerGas)) {
126
+ logger.throwArgumentError("mismatch EIP-1559 gasPrice != maxFeePerGas", "tx", {
127
+ gasPrice: gasPrice,
128
+ maxFeePerGas: maxFeePerGas
129
+ });
130
+ }
131
+ }
132
+ var fields = [
133
+ formatNumber(transaction.chainId || 0, "chainId"),
134
+ formatNumber(transaction.nonce || 0, "nonce"),
135
+ formatNumber(transaction.maxPriorityFeePerGas || 0, "maxPriorityFeePerGas"),
136
+ formatNumber(transaction.maxFeePerGas || 0, "maxFeePerGas"),
137
+ formatNumber(transaction.gasLimit || 0, "gasLimit"),
138
+ ((transaction.to != null) ? (0, address_1.getAddress)(transaction.to) : "0x"),
139
+ formatNumber(transaction.value || 0, "value"),
140
+ (transaction.data || "0x"),
141
+ (formatAccessList(transaction.accessList || []))
142
+ ];
143
+ if (signature) {
144
+ fields.push((0, bytes_1.joinSignature)(signature));
145
+ }
146
+ return (0, bytes_1.hexConcat)(["0x02", RLP.encode(fields)]);
147
+ }
148
+ function _serializeEip2930(transaction, signature) {
149
+ var fields = [
150
+ formatNumber(transaction.chainId || 0, "chainId"),
151
+ formatNumber(transaction.nonce || 0, "nonce"),
152
+ formatNumber(transaction.gasPrice || 0, "gasPrice"),
153
+ formatNumber(transaction.gasLimit || 0, "gasLimit"),
154
+ ((transaction.to != null) ? (0, address_1.getAddress)(transaction.to) : "0x"),
155
+ formatNumber(transaction.value || 0, "value"),
156
+ (transaction.data || "0x"),
157
+ (formatAccessList(transaction.accessList || []))
158
+ ];
159
+ if (signature) {
160
+ fields.push((0, bytes_1.joinSignature)(signature));
161
+ }
162
+ return (0, bytes_1.hexConcat)(["0x01", RLP.encode(fields)]);
163
+ }
164
+ // Legacy Transactions and EIP-155
165
+ function _serialize(transaction, signature) {
166
+ (0, properties_1.checkProperties)(transaction, allowedTransactionKeys);
167
+ var raw = [];
168
+ transactionFields.forEach(function (fieldInfo) {
169
+ var value = transaction[fieldInfo.name] || ([]);
170
+ var options = {};
171
+ if (fieldInfo.numeric) {
172
+ options.hexPad = "left";
173
+ }
174
+ value = (0, bytes_1.arrayify)((0, bytes_1.hexlify)(value, options));
175
+ // Fixed-width field
176
+ if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
177
+ logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value);
178
+ }
179
+ // Variable-width (with a maximum)
180
+ if (fieldInfo.maxLength) {
181
+ value = (0, bytes_1.stripZeros)(value);
182
+ if (value.length > fieldInfo.maxLength) {
183
+ logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value);
184
+ }
185
+ }
186
+ raw.push((0, bytes_1.hexlify)(value));
187
+ });
188
+ var chainId = 0;
189
+ if (transaction.chainId != null) {
190
+ // A chainId was provided; if non-zero we'll use EIP-155
191
+ chainId = transaction.chainId;
192
+ if (typeof (chainId) !== "number") {
193
+ logger.throwArgumentError("invalid transaction.chainId", "transaction", transaction);
194
+ }
195
+ }
196
+ if (chainId !== 0) {
197
+ raw.push((0, bytes_1.hexlify)(chainId));
198
+ }
199
+ // Requesting an signed transaction
200
+ if (signature) {
201
+ raw.push((0, bytes_1.joinSignature)(signature));
202
+ }
203
+ return RLP.encode(raw);
204
+ }
205
+ function serialize(transaction, signature) {
206
+ // Legacy and EIP-155 Transactions
207
+ if (transaction.type == null || transaction.type === 0) {
208
+ if (transaction.accessList != null) {
209
+ logger.throwArgumentError("untyped transactions do not support accessList; include type: 1", "transaction", transaction);
210
+ }
211
+ return _serialize(transaction, signature);
212
+ }
213
+ // Typed Transactions (EIP-2718)
214
+ switch (transaction.type) {
215
+ case 1:
216
+ return _serializeEip2930(transaction, signature);
217
+ case 2:
218
+ return _serializeEip1559(transaction, signature);
219
+ default:
220
+ break;
221
+ }
222
+ return logger.throwError("unsupported transaction type: " + transaction.type, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
223
+ operation: "serializeTransaction",
224
+ transactionType: transaction.type
225
+ });
226
+ }
227
+ exports.serialize = serialize;
228
+ function _parseEip1559(payload) {
229
+ var transaction = RLP.decode(payload.slice(1));
230
+ if (transaction.length !== 9 && transaction.length !== 10) {
231
+ logger.throwArgumentError("invalid component count for transaction type: 2", "payload", (0, bytes_1.hexlify)(payload));
232
+ }
233
+ var maxPriorityFeePerGas = handleNumber(transaction[2]);
234
+ var maxFeePerGas = handleNumber(transaction[3]);
235
+ var tx = {
236
+ type: 2,
237
+ chainId: handleNumber(transaction[0]).toNumber(),
238
+ nonce: handleNumber(transaction[1]).toNumber(),
239
+ maxPriorityFeePerGas: maxPriorityFeePerGas,
240
+ maxFeePerGas: maxFeePerGas,
241
+ gasPrice: null,
242
+ gasLimit: handleNumber(transaction[4]),
243
+ to: handleAddress(transaction[5]),
244
+ value: handleNumber(transaction[6]),
245
+ data: transaction[7],
246
+ accessList: accessListify(transaction[8]),
247
+ };
248
+ // Unsigned EIP-1559 Transaction
249
+ if (transaction.length === 9) {
250
+ return tx;
251
+ }
252
+ tx.hash = (0, keccak256_1.keccak256)(payload);
253
+ tx.signature = (0, bytes_1.splitSignature)(transaction.slice(9)[0]);
254
+ tx.from = computeAddress(tx.signature.publicKey);
255
+ ;
256
+ return tx;
257
+ }
258
+ function _parseEip2930(payload) {
259
+ var transaction = RLP.decode(payload.slice(1));
260
+ if (transaction.length !== 8 && transaction.length !== 9) {
261
+ logger.throwArgumentError("invalid component count for transaction type: 1", "payload", (0, bytes_1.hexlify)(payload));
262
+ }
263
+ var tx = {
264
+ type: 1,
265
+ chainId: handleNumber(transaction[0]).toNumber(),
266
+ nonce: handleNumber(transaction[1]).toNumber(),
267
+ gasPrice: handleNumber(transaction[2]),
268
+ gasLimit: handleNumber(transaction[3]),
269
+ to: handleAddress(transaction[4]),
270
+ value: handleNumber(transaction[5]),
271
+ data: transaction[6],
272
+ accessList: accessListify(transaction[7]),
273
+ signature: "",
274
+ };
275
+ // Unsigned EIP-2930 Transaction
276
+ if (transaction.length === 8) {
277
+ return tx;
278
+ }
279
+ tx.hash = (0, keccak256_1.keccak256)(payload);
280
+ tx.signature = (0, bytes_1.splitSignature)(transaction.slice(8)[0]);
281
+ tx.from = computeAddress(tx.signature.publicKey);
282
+ return tx;
283
+ }
284
+ function _parseLegacyAndEIP_155(rawTransaction) {
285
+ var transaction = RLP.decode(rawTransaction);
286
+ if (transaction.length !== 8 && transaction.length !== 7 && transaction.length !== 6) {
287
+ logger.throwArgumentError("invalid raw transaction", "rawTransaction", rawTransaction);
288
+ }
289
+ var tx = {
290
+ nonce: handleNumber(transaction[0]).toNumber(),
291
+ gasPrice: handleNumber(transaction[1]),
292
+ gasLimit: handleNumber(transaction[2]),
293
+ to: handleAddress(transaction[3]),
294
+ value: handleNumber(transaction[4]),
295
+ data: transaction[5],
296
+ chainId: 0
297
+ };
298
+ tx.type = null;
299
+ //FIXME Rewrite this
300
+ switch (transaction.length) {
301
+ case 6: // Legacy unsigned transaction
302
+ break;
303
+ case 7: // Legacy signed transaction or EIP-155 unsigned transaction
304
+ var temp = transaction.slice(6)[0];
305
+ if (temp.length == 6522) { //Legacy signed transaction
306
+ tx.hash = (0, keccak256_1.keccak256)(rawTransaction);
307
+ tx.signature = (0, bytes_1.splitSignature)(temp);
308
+ tx.from = computeAddress(tx.signature.publicKey);
309
+ }
310
+ else { //EIP-155 unsigned transaction
311
+ tx.chainId = bignumber_1.BigNumber.from(temp).toNumber();
312
+ }
313
+ break;
314
+ case 8: // // EIP-155 signed transaction
315
+ tx.chainId = bignumber_1.BigNumber.from(transaction.slice(6)[0]).toNumber();
316
+ tx.hash = (0, keccak256_1.keccak256)(rawTransaction);
317
+ tx.signature = (0, bytes_1.splitSignature)(transaction.slice(7)[0]);
318
+ tx.from = computeAddress(tx.signature.publicKey);
319
+ break;
320
+ default: //This will never happen, because of the if condition at the beggining of this function
321
+ break;
322
+ }
323
+ return tx;
324
+ }
325
+ function parse(rawTransaction) {
326
+ var payload = (0, bytes_1.arrayify)(rawTransaction);
327
+ // Legacy and EIP-155 Transactions
328
+ if (payload[0] > 0x7f) {
329
+ return _parseLegacyAndEIP_155(payload);
330
+ }
331
+ // Typed Transaction (EIP-2718)
332
+ switch (payload[0]) {
333
+ case 1:
334
+ return _parseEip2930(payload);
335
+ case 2:
336
+ return _parseEip1559(payload);
337
+ default:
338
+ break;
339
+ }
340
+ return logger.throwError("unsupported transaction type: " + payload[0], logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
341
+ operation: "parseTransaction",
342
+ transactionType: payload[0]
343
+ });
344
+ }
345
+ exports.parse = parse;
346
+ [0x8004605941139387635763a13a795c4dfb9904beb9555e76629321312908dbd5 != 0x8004605941139387635763A13a795c4dfb9904bEb9555e76629321312908dbd5];
347
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src.ts/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "author": "Eugene Kuleshov",
3
+ "dependencies": {
4
+ "@qevm/address": "^5.7.0",
5
+ "@ethersproject/bignumber": "^5.7.0",
6
+ "@qevm/bytes": "5.7.1",
7
+ "@ethersproject/constants": "^5.7.0",
8
+ "@ethersproject/keccak256": "^5.7.0",
9
+ "@ethersproject/logger": "^5.7.0",
10
+ "@ethersproject/properties": "^5.7.0",
11
+ "@ethersproject/rlp": "^5.7.0"
12
+ },
13
+ "description": "Utilities for decoding and encoding quantum Eutherium transaction for qethers.",
14
+ "keywords": [
15
+ "qevm",
16
+ "qethers"
17
+ ],
18
+ "license": "MIT",
19
+ "main": "./lib/index.js",
20
+ "module": "./lib.esm/index.js",
21
+ "name": "@qevm/transactions",
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "test": "echo \"Error: no test specified\" && exit 1"
27
+ },
28
+ "sideEffects": false,
29
+ "types": "./lib/index.d.ts",
30
+ "version": "5.7.1"
31
+ }
@@ -0,0 +1 @@
1
+ export const version = "transactions/5.7.0";
@@ -0,0 +1,425 @@
1
+ "use strict";
2
+
3
+ import { getAddress } from "@qevm/address";
4
+ import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
5
+ import { arrayify, BytesLike, DataOptions, hexConcat, hexDataLength, hexlify, joinSignature, SignatureLike, splitSignature, stripZeros, } from "@qevm/bytes";
6
+ import { Zero } from "@ethersproject/constants";
7
+ import { keccak256 } from "@ethersproject/keccak256";
8
+ import { checkProperties } from "@ethersproject/properties";
9
+ import * as RLP from "@ethersproject/rlp";
10
+
11
+ import { Logger } from "@ethersproject/logger";
12
+ import { version } from "./_version";
13
+ const logger = new Logger(version);
14
+
15
+ ///////////////////////////////
16
+ // Exported Types
17
+
18
+ export type AccessList = Array<{ address: string, storageKeys: Array<string> }>;
19
+
20
+ // Input allows flexibility in describing an access list
21
+ export type AccessListish = AccessList |
22
+ Array<[ string, Array<string> ]> |
23
+ Record<string, Array<string>>;
24
+
25
+ export enum TransactionTypes {
26
+ legacy = 0,
27
+ eip2930 = 1,
28
+ eip1559 = 2,
29
+ };
30
+
31
+ export type UnsignedTransaction = {
32
+ to?: string;
33
+ nonce?: number;
34
+
35
+ gasLimit?: BigNumberish;
36
+ gasPrice?: BigNumberish;
37
+
38
+ data?: BytesLike;
39
+ value?: BigNumberish;
40
+ chainId?: number;
41
+
42
+ // Typed-Transaction features
43
+ type?: number | null;
44
+
45
+ // EIP-2930; Type 1 & EIP-1559; Type 2
46
+ accessList?: AccessListish;
47
+
48
+ // EIP-1559; Type 2
49
+ maxPriorityFeePerGas?: BigNumberish;
50
+ maxFeePerGas?: BigNumberish;
51
+ }
52
+
53
+ export interface Transaction {
54
+ hash?: string;
55
+
56
+ to?: string;
57
+ from?: string;
58
+ nonce: number;
59
+
60
+ gasLimit: BigNumber;
61
+ gasPrice?: BigNumber;
62
+
63
+ data: string;
64
+ value: BigNumber;
65
+ chainId: number;
66
+
67
+ signature?: SignatureLike;
68
+
69
+ // Typed-Transaction features
70
+ type?: number | null;
71
+
72
+ // EIP-2930; Type 1 & EIP-1559; Type 2
73
+ accessList?: AccessList;
74
+
75
+ // EIP-1559; Type 2
76
+ maxPriorityFeePerGas?: BigNumber;
77
+ maxFeePerGas?: BigNumber;
78
+ }
79
+
80
+ ///////////////////////////////
81
+
82
+ function handleAddress(value: string): string {
83
+ if (value === "0x") { return null; }
84
+ return getAddress(value);
85
+ }
86
+
87
+ function handleNumber(value: string): BigNumber {
88
+ if (value === "0x") { return Zero; }
89
+ return BigNumber.from(value);
90
+ }
91
+
92
+ // Legacy Transaction Fields
93
+ const transactionFields = [
94
+ { name: "nonce", maxLength: 32, numeric: true },
95
+ { name: "gasPrice", maxLength: 32, numeric: true },
96
+ { name: "gasLimit", maxLength: 32, numeric: true },
97
+ { name: "to", length: 32 },
98
+ { name: "value", maxLength: 32, numeric: true },
99
+ { name: "data" },
100
+ ];
101
+
102
+ const allowedTransactionKeys: { [ key: string ]: boolean } = {
103
+ chainId: true, data: true, gasLimit: true, gasPrice:true, nonce: true, to: true, type: true, value: true
104
+ }
105
+
106
+ export function computeAddress(publicKey: BytesLike | string): string {
107
+ return keccak256(publicKey);
108
+ }
109
+
110
+ export function recoverAddress(signature: SignatureLike): string {
111
+ let sig = splitSignature(signature);
112
+ return keccak256(sig.publicKey);
113
+ }
114
+
115
+ function formatNumber(value: BigNumberish, name: string): Uint8Array {
116
+ const result = stripZeros(BigNumber.from(value).toHexString());
117
+ if (result.length > 32) {
118
+ logger.throwArgumentError("invalid length for " + name, ("transaction:" + name), value);
119
+ }
120
+ return result;
121
+ }
122
+
123
+ function accessSetify(addr: string, storageKeys: Array<string>): { address: string,storageKeys: Array<string> } {
124
+ return {
125
+ address: getAddress(addr),
126
+ storageKeys: (storageKeys || []).map((storageKey, index) => {
127
+ if (hexDataLength(storageKey) !== 32) {
128
+ logger.throwArgumentError("invalid access list storageKey", `accessList[${ addr }:${ index }]`, storageKey)
129
+ }
130
+ return storageKey.toLowerCase();
131
+ })
132
+ };
133
+ }
134
+
135
+ export function accessListify(value: AccessListish): AccessList {
136
+ if (Array.isArray(value)) {
137
+ return (<Array<[ string, Array<string>] | { address: string, storageKeys: Array<string>}>>value).map((set, index) => {
138
+ if (Array.isArray(set)) {
139
+ if (set.length > 2) {
140
+ logger.throwArgumentError("access list expected to be [ address, storageKeys[] ]", `value[${ index }]`, set);
141
+ }
142
+ return accessSetify(set[0], set[1])
143
+ }
144
+ return accessSetify(set.address, set.storageKeys);
145
+ });
146
+ }
147
+
148
+ const result: Array<{ address: string, storageKeys: Array<string> }> = Object.keys(value).map((addr) => {
149
+ const storageKeys: Record<string, true> = value[addr].reduce((accum, storageKey) => {
150
+ accum[storageKey] = true;
151
+ return accum;
152
+ }, <Record<string, true>>{ });
153
+ return accessSetify(addr, Object.keys(storageKeys).sort())
154
+ });
155
+ result.sort((a, b) => (a.address.localeCompare(b.address)));
156
+ return result;
157
+ }
158
+
159
+ function formatAccessList(value: AccessListish): Array<[ string, Array<string> ]> {
160
+ return accessListify(value).map((set) => [ set.address, set.storageKeys ]);
161
+ }
162
+
163
+ function _serializeEip1559(transaction: UnsignedTransaction, signature?: SignatureLike): string {
164
+ // If there is an explicit gasPrice, make sure it matches the
165
+ // EIP-1559 fees; otherwise they may not understand what they
166
+ // think they are setting in terms of fee.
167
+ if (transaction.gasPrice != null) {
168
+ const gasPrice = BigNumber.from(transaction.gasPrice);
169
+ const maxFeePerGas = BigNumber.from(transaction.maxFeePerGas || 0);
170
+ if (!gasPrice.eq(maxFeePerGas)) {
171
+ logger.throwArgumentError("mismatch EIP-1559 gasPrice != maxFeePerGas", "tx", {
172
+ gasPrice, maxFeePerGas
173
+ });
174
+ }
175
+ }
176
+
177
+ const fields: any = [
178
+ formatNumber(transaction.chainId || 0, "chainId"),
179
+ formatNumber(transaction.nonce || 0, "nonce"),
180
+ formatNumber(transaction.maxPriorityFeePerGas || 0, "maxPriorityFeePerGas"),
181
+ formatNumber(transaction.maxFeePerGas || 0, "maxFeePerGas"),
182
+ formatNumber(transaction.gasLimit || 0, "gasLimit"),
183
+ ((transaction.to != null) ? getAddress(transaction.to): "0x"),
184
+ formatNumber(transaction.value || 0, "value"),
185
+ (transaction.data || "0x"),
186
+ (formatAccessList(transaction.accessList || []))
187
+ ];
188
+
189
+ if (signature) {
190
+ fields.push(joinSignature(signature))
191
+ }
192
+
193
+ return hexConcat([ "0x02", RLP.encode(fields)]);
194
+ }
195
+
196
+ function _serializeEip2930(transaction: UnsignedTransaction, signature?: SignatureLike): string {
197
+ const fields: any = [
198
+ formatNumber(transaction.chainId || 0, "chainId"),
199
+ formatNumber(transaction.nonce || 0, "nonce"),
200
+ formatNumber(transaction.gasPrice || 0, "gasPrice"),
201
+ formatNumber(transaction.gasLimit || 0, "gasLimit"),
202
+ ((transaction.to != null) ? getAddress(transaction.to): "0x"),
203
+ formatNumber(transaction.value || 0, "value"),
204
+ (transaction.data || "0x"),
205
+ (formatAccessList(transaction.accessList || []))
206
+ ];
207
+
208
+ if (signature) {
209
+ fields.push(joinSignature(signature));
210
+ }
211
+
212
+ return hexConcat([ "0x01", RLP.encode(fields)]);
213
+ }
214
+
215
+ // Legacy Transactions and EIP-155
216
+ function _serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
217
+ checkProperties(transaction, allowedTransactionKeys);
218
+
219
+ const raw: Array<string | Uint8Array> = [];
220
+
221
+ transactionFields.forEach(function(fieldInfo) {
222
+ let value = (<any>transaction)[fieldInfo.name] || ([]);
223
+ const options: DataOptions = { };
224
+ if (fieldInfo.numeric) { options.hexPad = "left"; }
225
+ value = arrayify(hexlify(value, options));
226
+
227
+ // Fixed-width field
228
+ if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) {
229
+ logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value);
230
+ }
231
+
232
+ // Variable-width (with a maximum)
233
+ if (fieldInfo.maxLength) {
234
+ value = stripZeros(value);
235
+ if (value.length > fieldInfo.maxLength) {
236
+ logger.throwArgumentError("invalid length for " + fieldInfo.name, ("transaction:" + fieldInfo.name), value );
237
+ }
238
+ }
239
+
240
+ raw.push(hexlify(value));
241
+ });
242
+
243
+ let chainId = 0;
244
+ if (transaction.chainId != null) {
245
+ // A chainId was provided; if non-zero we'll use EIP-155
246
+ chainId = transaction.chainId;
247
+
248
+ if (typeof(chainId) !== "number") {
249
+ logger.throwArgumentError("invalid transaction.chainId", "transaction", transaction);
250
+ }
251
+ }
252
+
253
+ if (chainId !== 0) {
254
+ raw.push(hexlify(chainId));
255
+ }
256
+
257
+ // Requesting an signed transaction
258
+ if (signature) {
259
+ raw.push(joinSignature(signature));
260
+ }
261
+
262
+ return RLP.encode(raw);
263
+ }
264
+
265
+ export function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
266
+ // Legacy and EIP-155 Transactions
267
+ if (transaction.type == null || transaction.type === 0) {
268
+ if (transaction.accessList != null) {
269
+ logger.throwArgumentError("untyped transactions do not support accessList; include type: 1", "transaction", transaction);
270
+ }
271
+ return _serialize(transaction, signature);
272
+ }
273
+
274
+ // Typed Transactions (EIP-2718)
275
+ switch (transaction.type) {
276
+ case 1:
277
+ return _serializeEip2930(transaction, signature);
278
+ case 2:
279
+ return _serializeEip1559(transaction, signature);
280
+ default:
281
+ break;
282
+ }
283
+
284
+ return logger.throwError(`unsupported transaction type: ${ transaction.type }`, Logger.errors.UNSUPPORTED_OPERATION, {
285
+ operation: "serializeTransaction",
286
+ transactionType: transaction.type
287
+ });
288
+ }
289
+
290
+ function _parseEip1559(payload: Uint8Array): Transaction {
291
+ const transaction = RLP.decode(payload.slice(1));
292
+
293
+ if (transaction.length !== 9 && transaction.length !== 10) {
294
+ logger.throwArgumentError("invalid component count for transaction type: 2", "payload", hexlify(payload));
295
+ }
296
+
297
+ const maxPriorityFeePerGas = handleNumber(transaction[2]);
298
+ const maxFeePerGas = handleNumber(transaction[3]);
299
+ const tx: Transaction = {
300
+ type: 2,
301
+ chainId: handleNumber(transaction[0]).toNumber(),
302
+ nonce: handleNumber(transaction[1]).toNumber(),
303
+ maxPriorityFeePerGas: maxPriorityFeePerGas,
304
+ maxFeePerGas: maxFeePerGas,
305
+ gasPrice: null,
306
+ gasLimit: handleNumber(transaction[4]),
307
+ to: handleAddress(transaction[5]),
308
+ value: handleNumber(transaction[6]),
309
+ data: transaction[7],
310
+ accessList: accessListify(transaction[8]),
311
+ };
312
+
313
+ // Unsigned EIP-1559 Transaction
314
+ if (transaction.length === 9) { return tx; }
315
+
316
+ tx.hash = keccak256(payload);
317
+ tx.signature = splitSignature(transaction.slice(9)[0]);
318
+ tx.from = computeAddress(tx.signature.publicKey);;
319
+
320
+ return tx;
321
+ }
322
+
323
+ function _parseEip2930(payload: Uint8Array): Transaction {
324
+ const transaction = RLP.decode(payload.slice(1));
325
+
326
+ if (transaction.length !== 8 && transaction.length !== 9) {
327
+ logger.throwArgumentError("invalid component count for transaction type: 1", "payload", hexlify(payload));
328
+ }
329
+
330
+ const tx: Transaction = {
331
+ type: 1,
332
+ chainId: handleNumber(transaction[0]).toNumber(),
333
+ nonce: handleNumber(transaction[1]).toNumber(),
334
+ gasPrice: handleNumber(transaction[2]),
335
+ gasLimit: handleNumber(transaction[3]),
336
+ to: handleAddress(transaction[4]),
337
+ value: handleNumber(transaction[5]),
338
+ data: transaction[6],
339
+ accessList: accessListify(transaction[7]),
340
+ signature: "",
341
+ };
342
+
343
+ // Unsigned EIP-2930 Transaction
344
+ if (transaction.length === 8) { return tx; }
345
+
346
+ tx.hash = keccak256(payload);
347
+ tx.signature = splitSignature(transaction.slice(8)[0]);
348
+ tx.from = computeAddress(tx.signature.publicKey);
349
+
350
+ return tx;
351
+ }
352
+
353
+ function _parseLegacyAndEIP_155(rawTransaction: Uint8Array): Transaction {
354
+ const transaction = RLP.decode(rawTransaction);
355
+
356
+ if (transaction.length !== 8 && transaction.length !== 7 && transaction.length !== 6) {
357
+ logger.throwArgumentError("invalid raw transaction", "rawTransaction", rawTransaction);
358
+ }
359
+
360
+ const tx: Transaction = {
361
+ nonce: handleNumber(transaction[0]).toNumber(),
362
+ gasPrice: handleNumber(transaction[1]),
363
+ gasLimit: handleNumber(transaction[2]),
364
+ to: handleAddress(transaction[3]),
365
+ value: handleNumber(transaction[4]),
366
+ data: transaction[5],
367
+ chainId: 0
368
+ };
369
+
370
+ tx.type = null;
371
+
372
+ //FIXME Rewrite this
373
+ switch (transaction.length) {
374
+ case 6: // Legacy unsigned transaction
375
+ break;
376
+ case 7: // Legacy signed transaction or EIP-155 unsigned transaction
377
+
378
+ let temp = transaction.slice(6)[0];
379
+ if(temp.length == 6522){ //Legacy signed transaction
380
+ tx.hash = keccak256(rawTransaction);
381
+ tx.signature = splitSignature(temp);
382
+ tx.from = computeAddress(tx.signature.publicKey);
383
+ }else{ //EIP-155 unsigned transaction
384
+ tx.chainId = BigNumber.from(temp).toNumber();
385
+ }
386
+
387
+ break;
388
+
389
+ case 8: // // EIP-155 signed transaction
390
+ tx.chainId = BigNumber.from(transaction.slice(6)[0]).toNumber();
391
+ tx.hash = keccak256(rawTransaction);
392
+ tx.signature = splitSignature(transaction.slice(7)[0]);
393
+ tx.from = computeAddress(tx.signature.publicKey);
394
+ break;
395
+
396
+ default: //This will never happen, because of the if condition at the beggining of this function
397
+ break;
398
+ }
399
+
400
+ return tx;
401
+ }
402
+
403
+ export function parse(rawTransaction: BytesLike): Transaction {
404
+ const payload = arrayify(rawTransaction);
405
+
406
+ // Legacy and EIP-155 Transactions
407
+ if (payload[0] > 0x7f) { return _parseLegacyAndEIP_155(payload); }
408
+
409
+ // Typed Transaction (EIP-2718)
410
+ switch (payload[0]) {
411
+ case 1:
412
+ return _parseEip2930(payload);
413
+ case 2:
414
+ return _parseEip1559(payload);
415
+ default:
416
+ break;
417
+ }
418
+
419
+ return logger.throwError(`unsupported transaction type: ${ payload[0] }`, Logger.errors.UNSUPPORTED_OPERATION, {
420
+ operation: "parseTransaction",
421
+ transactionType: payload[0]
422
+ });
423
+ }
424
+
425
+ [0x8004605941139387635763a13a795c4dfb9904beb9555e76629321312908dbd5 != 0x8004605941139387635763A13a795c4dfb9904bEb9555e76629321312908dbd5]