Socket
Socket
Sign inDemoInstall

@ethersproject/transactions

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ethersproject/transactions - npm Package Compare versions

Comparing version 5.0.11 to 5.1.0

2

lib.esm/_version.d.ts

@@ -1,2 +0,2 @@

export declare const version = "transactions/5.0.11";
export declare const version = "transactions/5.1.0";
//# sourceMappingURL=_version.d.ts.map

@@ -1,2 +0,2 @@

export const version = "transactions/5.0.11";
export const version = "transactions/5.1.0";
//# sourceMappingURL=_version.js.map
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { BytesLike, SignatureLike } from "@ethersproject/bytes";
export declare type AccessList = Array<{
address: string;
storageKeys: Array<string>;
}>;
export declare type AccessListish = AccessList | Array<[string, Array<string>]> | Record<string, Array<string>>;
export declare type UnsignedTransaction = {

@@ -11,2 +16,4 @@ to?: string;

chainId?: number;
type?: number | null;
accessList?: AccessListish;
};

@@ -26,7 +33,10 @@ export interface Transaction {

v?: number;
type?: number | null;
accessList?: AccessList;
}
export declare function computeAddress(key: BytesLike | string): string;
export declare function recoverAddress(digest: BytesLike, signature: SignatureLike): string;
export declare function accessListify(value: AccessListish): AccessList;
export declare function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string;
export declare function parse(rawTransaction: BytesLike): Transaction;
//# sourceMappingURL=index.d.ts.map
"use strict";
import { getAddress } from "@ethersproject/address";
import { BigNumber } from "@ethersproject/bignumber";
import { arrayify, hexDataSlice, hexlify, hexZeroPad, isBytesLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { arrayify, hexConcat, hexDataLength, hexDataSlice, hexlify, hexZeroPad, isBytesLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { Zero } from "@ethersproject/constants";

@@ -26,2 +26,3 @@ import { keccak256 } from "@ethersproject/keccak256";

}
// Legacy Transaction Fields
const transactionFields = [

@@ -45,3 +46,66 @@ { name: "nonce", maxLength: 32, numeric: true },

}
export function serialize(transaction, signature) {
function formatNumber(value, name) {
const result = stripZeros(BigNumber.from(value).toHexString());
if (result.length > 32) {
logger.throwArgumentError("invalid length for " + name, ("transaction:" + name), value);
}
return result;
}
function accessSetify(addr, storageKeys) {
return {
address: getAddress(addr),
storageKeys: (storageKeys || []).map((storageKey, index) => {
if (hexDataLength(storageKey) !== 32) {
logger.throwArgumentError("invalid access list storageKey", `accessList[${addr}:${index}]`, storageKey);
}
return storageKey.toLowerCase();
})
};
}
export function accessListify(value) {
if (Array.isArray(value)) {
return value.map((set, index) => {
if (Array.isArray(set)) {
if (set.length > 2) {
logger.throwArgumentError("access list expected to be [ address, storageKeys[] ]", `value[${index}]`, set);
}
return accessSetify(set[0], set[1]);
}
return accessSetify(set.address, set.storageKeys);
});
}
const result = Object.keys(value).map((addr) => {
const storageKeys = value[addr].reduce((accum, storageKey) => {
accum[storageKey] = true;
return accum;
}, {});
return accessSetify(addr, Object.keys(storageKeys).sort());
});
result.sort((a, b) => (a.address.localeCompare(b.address)));
return result;
}
function formatAccessList(value) {
return accessListify(value).map((set) => [set.address, set.storageKeys]);
}
function _serializeEip2930(transaction, signature) {
const fields = [
formatNumber(transaction.chainId || 0, "chainId"),
formatNumber(transaction.nonce || 0, "nonce"),
formatNumber(transaction.gasPrice || 0, "gasPrice"),
formatNumber(transaction.gasLimit || 0, "gasLimit"),
((transaction.to != null) ? getAddress(transaction.to) : "0x"),
formatNumber(transaction.value || 0, "value"),
(transaction.data || "0x"),
(formatAccessList(transaction.accessList || []))
];
if (signature) {
const sig = splitSignature(signature);
fields.push(formatNumber(sig.recoveryParam, "recoveryParam"));
fields.push(stripZeros(sig.r));
fields.push(stripZeros(sig.s));
}
return hexConcat(["0x01", RLP.encode(fields)]);
}
// Legacy Transactions and EIP-155
function _serialize(transaction, signature) {
checkProperties(transaction, allowedTransactionKeys);

@@ -114,3 +178,63 @@ const raw = [];

}
export function parse(rawTransaction) {
export function serialize(transaction, signature) {
// Legacy and EIP-155 Transactions
if (transaction.type == null) {
return _serialize(transaction, signature);
}
// Typed Transactions (EIP-2718)
switch (transaction.type) {
case 1:
return _serializeEip2930(transaction, signature);
default:
break;
}
return logger.throwError(`unsupported transaction type: ${transaction.type}`, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "serializeTransaction",
transactionType: transaction.type
});
}
function _parseEip2930(payload) {
const transaction = RLP.decode(payload.slice(1));
if (transaction.length !== 8 && transaction.length !== 11) {
logger.throwArgumentError("invalid component count for transaction type: 1", "payload", hexlify(payload));
}
const tx = {
type: 1,
chainId: handleNumber(transaction[0]).toNumber(),
nonce: handleNumber(transaction[1]).toNumber(),
gasPrice: handleNumber(transaction[2]),
gasLimit: handleNumber(transaction[3]),
to: handleAddress(transaction[4]),
value: handleNumber(transaction[5]),
data: transaction[6],
accessList: accessListify(transaction[7]),
};
// Unsigned EIP-2930 Transaction
if (transaction.length === 8) {
return tx;
}
try {
const recid = handleNumber(transaction[8]).toNumber();
if (recid !== 0 && recid !== 1) {
throw new Error("bad recid");
}
tx.v = recid;
}
catch (error) {
logger.throwArgumentError("invalid v for transaction type: 1", "v", transaction[8]);
}
tx.r = hexZeroPad(transaction[9], 32);
tx.s = hexZeroPad(transaction[10], 32);
try {
const digest = keccak256(_serializeEip2930(tx));
tx.from = recoverAddress(digest, { r: tx.r, s: tx.s, recoveryParam: tx.v });
}
catch (error) {
console.log(error);
}
tx.hash = keccak256(payload);
return tx;
}
// Legacy Transactions and EIP-155
function _parse(rawTransaction) {
const transaction = RLP.decode(rawTransaction);

@@ -170,4 +294,23 @@ if (transaction.length !== 9 && transaction.length !== 6) {

}
tx.type = null;
return tx;
}
export function parse(rawTransaction) {
const payload = arrayify(rawTransaction);
// Legacy and EIP-155 Transactions
if (payload[0] > 0x7f) {
return _parse(payload);
}
// Typed Transaction (EIP-2718)
switch (payload[0]) {
case 1:
return _parseEip2930(payload);
default:
break;
}
return logger.throwError(`unsupported transaction type: ${payload[0]}`, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "parseTransaction",
transactionType: payload[0]
});
}
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

export declare const version = "transactions/5.0.11";
export declare const version = "transactions/5.1.0";
//# sourceMappingURL=_version.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = void 0;
exports.version = "transactions/5.0.11";
exports.version = "transactions/5.1.0";
//# sourceMappingURL=_version.js.map
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { BytesLike, SignatureLike } from "@ethersproject/bytes";
export declare type AccessList = Array<{
address: string;
storageKeys: Array<string>;
}>;
export declare type AccessListish = AccessList | Array<[string, Array<string>]> | Record<string, Array<string>>;
export declare type UnsignedTransaction = {

@@ -11,2 +16,4 @@ to?: string;

chainId?: number;
type?: number | null;
accessList?: AccessListish;
};

@@ -26,7 +33,10 @@ export interface Transaction {

v?: number;
type?: number | null;
accessList?: AccessList;
}
export declare function computeAddress(key: BytesLike | string): string;
export declare function recoverAddress(digest: BytesLike, signature: SignatureLike): string;
export declare function accessListify(value: AccessListish): AccessList;
export declare function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string;
export declare function parse(rawTransaction: BytesLike): Transaction;
//# sourceMappingURL=index.d.ts.map

@@ -22,3 +22,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = exports.serialize = exports.recoverAddress = exports.computeAddress = void 0;
exports.parse = exports.serialize = exports.accessListify = exports.recoverAddress = exports.computeAddress = void 0;
var address_1 = require("@ethersproject/address");

@@ -48,2 +48,3 @@ var bignumber_1 = require("@ethersproject/bignumber");

}
// Legacy Transaction Fields
var transactionFields = [

@@ -69,3 +70,67 @@ { name: "nonce", maxLength: 32, numeric: true },

exports.recoverAddress = recoverAddress;
function serialize(transaction, signature) {
function formatNumber(value, name) {
var result = bytes_1.stripZeros(bignumber_1.BigNumber.from(value).toHexString());
if (result.length > 32) {
logger.throwArgumentError("invalid length for " + name, ("transaction:" + name), value);
}
return result;
}
function accessSetify(addr, storageKeys) {
return {
address: address_1.getAddress(addr),
storageKeys: (storageKeys || []).map(function (storageKey, index) {
if (bytes_1.hexDataLength(storageKey) !== 32) {
logger.throwArgumentError("invalid access list storageKey", "accessList[" + addr + ":" + index + "]", storageKey);
}
return storageKey.toLowerCase();
})
};
}
function accessListify(value) {
if (Array.isArray(value)) {
return value.map(function (set, index) {
if (Array.isArray(set)) {
if (set.length > 2) {
logger.throwArgumentError("access list expected to be [ address, storageKeys[] ]", "value[" + index + "]", set);
}
return accessSetify(set[0], set[1]);
}
return accessSetify(set.address, set.storageKeys);
});
}
var result = Object.keys(value).map(function (addr) {
var storageKeys = value[addr].reduce(function (accum, storageKey) {
accum[storageKey] = true;
return accum;
}, {});
return accessSetify(addr, Object.keys(storageKeys).sort());
});
result.sort(function (a, b) { return (a.address.localeCompare(b.address)); });
return result;
}
exports.accessListify = accessListify;
function formatAccessList(value) {
return accessListify(value).map(function (set) { return [set.address, set.storageKeys]; });
}
function _serializeEip2930(transaction, signature) {
var fields = [
formatNumber(transaction.chainId || 0, "chainId"),
formatNumber(transaction.nonce || 0, "nonce"),
formatNumber(transaction.gasPrice || 0, "gasPrice"),
formatNumber(transaction.gasLimit || 0, "gasLimit"),
((transaction.to != null) ? address_1.getAddress(transaction.to) : "0x"),
formatNumber(transaction.value || 0, "value"),
(transaction.data || "0x"),
(formatAccessList(transaction.accessList || []))
];
if (signature) {
var sig = bytes_1.splitSignature(signature);
fields.push(formatNumber(sig.recoveryParam, "recoveryParam"));
fields.push(bytes_1.stripZeros(sig.r));
fields.push(bytes_1.stripZeros(sig.s));
}
return bytes_1.hexConcat(["0x01", RLP.encode(fields)]);
}
// Legacy Transactions and EIP-155
function _serialize(transaction, signature) {
properties_1.checkProperties(transaction, allowedTransactionKeys);

@@ -138,4 +203,64 @@ var raw = [];

}
function serialize(transaction, signature) {
// Legacy and EIP-155 Transactions
if (transaction.type == null) {
return _serialize(transaction, signature);
}
// Typed Transactions (EIP-2718)
switch (transaction.type) {
case 1:
return _serializeEip2930(transaction, signature);
default:
break;
}
return logger.throwError("unsupported transaction type: " + transaction.type, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
operation: "serializeTransaction",
transactionType: transaction.type
});
}
exports.serialize = serialize;
function parse(rawTransaction) {
function _parseEip2930(payload) {
var transaction = RLP.decode(payload.slice(1));
if (transaction.length !== 8 && transaction.length !== 11) {
logger.throwArgumentError("invalid component count for transaction type: 1", "payload", bytes_1.hexlify(payload));
}
var tx = {
type: 1,
chainId: handleNumber(transaction[0]).toNumber(),
nonce: handleNumber(transaction[1]).toNumber(),
gasPrice: handleNumber(transaction[2]),
gasLimit: handleNumber(transaction[3]),
to: handleAddress(transaction[4]),
value: handleNumber(transaction[5]),
data: transaction[6],
accessList: accessListify(transaction[7]),
};
// Unsigned EIP-2930 Transaction
if (transaction.length === 8) {
return tx;
}
try {
var recid = handleNumber(transaction[8]).toNumber();
if (recid !== 0 && recid !== 1) {
throw new Error("bad recid");
}
tx.v = recid;
}
catch (error) {
logger.throwArgumentError("invalid v for transaction type: 1", "v", transaction[8]);
}
tx.r = bytes_1.hexZeroPad(transaction[9], 32);
tx.s = bytes_1.hexZeroPad(transaction[10], 32);
try {
var digest = keccak256_1.keccak256(_serializeEip2930(tx));
tx.from = recoverAddress(digest, { r: tx.r, s: tx.s, recoveryParam: tx.v });
}
catch (error) {
console.log(error);
}
tx.hash = keccak256_1.keccak256(payload);
return tx;
}
// Legacy Transactions and EIP-155
function _parse(rawTransaction) {
var transaction = RLP.decode(rawTransaction);

@@ -195,5 +320,24 @@ if (transaction.length !== 9 && transaction.length !== 6) {

}
tx.type = null;
return tx;
}
function parse(rawTransaction) {
var payload = bytes_1.arrayify(rawTransaction);
// Legacy and EIP-155 Transactions
if (payload[0] > 0x7f) {
return _parse(payload);
}
// Typed Transaction (EIP-2718)
switch (payload[0]) {
case 1:
return _parseEip2930(payload);
default:
break;
}
return logger.throwError("unsupported transaction type: " + payload[0], logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
operation: "parseTransaction",
transactionType: payload[0]
});
}
exports.parse = parse;
//# sourceMappingURL=index.js.map
{
"author": "Richard Moore <me@ricmoo.com>",
"dependencies": {
"@ethersproject/address": "^5.0.9",
"@ethersproject/bignumber": "^5.0.13",
"@ethersproject/bytes": "^5.0.9",
"@ethersproject/constants": "^5.0.8",
"@ethersproject/keccak256": "^5.0.7",
"@ethersproject/logger": "^5.0.8",
"@ethersproject/properties": "^5.0.7",
"@ethersproject/rlp": "^5.0.7",
"@ethersproject/signing-key": "^5.0.8"
"@ethersproject/address": "^5.1.0",
"@ethersproject/bignumber": "^5.1.0",
"@ethersproject/bytes": "^5.1.0",
"@ethersproject/constants": "^5.1.0",
"@ethersproject/keccak256": "^5.1.0",
"@ethersproject/logger": "^5.1.0",
"@ethersproject/properties": "^5.1.0",
"@ethersproject/rlp": "^5.1.0",
"@ethersproject/signing-key": "^5.1.0"
},

@@ -26,3 +26,3 @@ "description": "Utilities for decoding and encoding Ethereum transaction for ethers.",

],
"gitHead": "6c43e20e7a68f3f5a141c74527ec63d9fe8458be",
"gitHead": "3b1d3fcee6bfb5178861e26ff1a1e9daa0663ec9",
"keywords": [

@@ -48,5 +48,5 @@ "Ethereum",

"sideEffects": false,
"tarballHash": "0x826a4b29d124329797ed54f00e1b48c246c2c148ed88ef449e16d30df72574fd",
"tarballHash": "0xfcc7bf02b3381db31f124dd3b0cfcfa12e70b371e86b45238bc125e8d8e41d87",
"types": "./lib/index.d.ts",
"version": "5.0.11"
"version": "5.1.0"
}

@@ -1,1 +0,1 @@

export const version = "transactions/5.0.11";
export const version = "transactions/5.1.0";

@@ -5,3 +5,3 @@ "use strict";

import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { arrayify, BytesLike, DataOptions, hexDataSlice, hexlify, hexZeroPad, isBytesLike, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { arrayify, BytesLike, DataOptions, hexConcat, hexDataLength, hexDataSlice, hexlify, hexZeroPad, isBytesLike, SignatureLike, splitSignature, stripZeros, } from "@ethersproject/bytes";
import { Zero } from "@ethersproject/constants";

@@ -20,2 +20,9 @@ import { keccak256 } from "@ethersproject/keccak256";

export type AccessList = Array<{ address: string, storageKeys: Array<string> }>;
// Input allows flexibility in describing an access list
export type AccessListish = AccessList |
Array<[ string, Array<string> ]> |
Record<string, Array<string>>;
export type UnsignedTransaction = {

@@ -31,2 +38,6 @@ to?: string;

chainId?: number;
// Typed-Transaction features
type?: number | null;
accessList?: AccessListish;
}

@@ -51,2 +62,8 @@

v?: number;
// Typed-Transaction features
type?: number | null;
// EIP-2930; Type 1
accessList?: AccessList;
}

@@ -66,2 +83,3 @@

// Legacy Transaction Fields
const transactionFields = [

@@ -89,4 +107,74 @@ { name: "nonce", maxLength: 32, numeric: true },

function formatNumber(value: BigNumberish, name: string): Uint8Array {
const result = stripZeros(BigNumber.from(value).toHexString());
if (result.length > 32) {
logger.throwArgumentError("invalid length for " + name, ("transaction:" + name), value);
}
return result;
}
export function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
function accessSetify(addr: string, storageKeys: Array<string>): { address: string,storageKeys: Array<string> } {
return {
address: getAddress(addr),
storageKeys: (storageKeys || []).map((storageKey, index) => {
if (hexDataLength(storageKey) !== 32) {
logger.throwArgumentError("invalid access list storageKey", `accessList[${ addr }:${ index }]`, storageKey)
}
return storageKey.toLowerCase();
})
};
}
export function accessListify(value: AccessListish): AccessList {
if (Array.isArray(value)) {
return (<Array<[ string, Array<string>] | { address: string, storageKeys: Array<string>}>>value).map((set, index) => {
if (Array.isArray(set)) {
if (set.length > 2) {
logger.throwArgumentError("access list expected to be [ address, storageKeys[] ]", `value[${ index }]`, set);
}
return accessSetify(set[0], set[1])
}
return accessSetify(set.address, set.storageKeys);
});
}
const result: Array<{ address: string, storageKeys: Array<string> }> = Object.keys(value).map((addr) => {
const storageKeys: Record<string, true> = value[addr].reduce((accum, storageKey) => {
accum[storageKey] = true;
return accum;
}, <Record<string, true>>{ });
return accessSetify(addr, Object.keys(storageKeys).sort())
});
result.sort((a, b) => (a.address.localeCompare(b.address)));
return result;
}
function formatAccessList(value: AccessListish): Array<[ string, Array<string> ]> {
return accessListify(value).map((set) => [ set.address, set.storageKeys ]);
}
function _serializeEip2930(transaction: UnsignedTransaction, signature?: SignatureLike): string {
const fields: any = [
formatNumber(transaction.chainId || 0, "chainId"),
formatNumber(transaction.nonce || 0, "nonce"),
formatNumber(transaction.gasPrice || 0, "gasPrice"),
formatNumber(transaction.gasLimit || 0, "gasLimit"),
((transaction.to != null) ? getAddress(transaction.to): "0x"),
formatNumber(transaction.value || 0, "value"),
(transaction.data || "0x"),
(formatAccessList(transaction.accessList || []))
];
if (signature) {
const sig = splitSignature(signature);
fields.push(formatNumber(sig.recoveryParam, "recoveryParam"));
fields.push(stripZeros(sig.r));
fields.push(stripZeros(sig.s));
}
return hexConcat([ "0x01", RLP.encode(fields)]);
}
// Legacy Transactions and EIP-155
function _serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
checkProperties(transaction, allowedTransactionKeys);

@@ -171,3 +259,66 @@

export function parse(rawTransaction: BytesLike): Transaction {
export function serialize(transaction: UnsignedTransaction, signature?: SignatureLike): string {
// Legacy and EIP-155 Transactions
if (transaction.type == null) { return _serialize(transaction, signature); }
// Typed Transactions (EIP-2718)
switch (transaction.type) {
case 1:
return _serializeEip2930(transaction, signature);
default:
break;
}
return logger.throwError(`unsupported transaction type: ${ transaction.type }`, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "serializeTransaction",
transactionType: transaction.type
});
}
function _parseEip2930(payload: Uint8Array): Transaction {
const transaction = RLP.decode(payload.slice(1));
if (transaction.length !== 8 && transaction.length !== 11) {
logger.throwArgumentError("invalid component count for transaction type: 1", "payload", hexlify(payload));
}
const tx: Transaction = {
type: 1,
chainId: handleNumber(transaction[0]).toNumber(),
nonce: handleNumber(transaction[1]).toNumber(),
gasPrice: handleNumber(transaction[2]),
gasLimit: handleNumber(transaction[3]),
to: handleAddress(transaction[4]),
value: handleNumber(transaction[5]),
data: transaction[6],
accessList: accessListify(transaction[7]),
};
// Unsigned EIP-2930 Transaction
if (transaction.length === 8) { return tx; }
try {
const recid = handleNumber(transaction[8]).toNumber();
if (recid !== 0 && recid !== 1) { throw new Error("bad recid"); }
tx.v = recid;
} catch (error) {
logger.throwArgumentError("invalid v for transaction type: 1", "v", transaction[8]);
}
tx.r = hexZeroPad(transaction[9], 32);
tx.s = hexZeroPad(transaction[10], 32);
try {
const digest = keccak256(_serializeEip2930(tx));
tx.from = recoverAddress(digest, { r: tx.r, s: tx.s, recoveryParam: tx.v });
} catch (error) {
console.log(error);
}
tx.hash = keccak256(payload);
return tx;
}
// Legacy Transactions and EIP-155
function _parse(rawTransaction: Uint8Array): Transaction {
const transaction = RLP.decode(rawTransaction);

@@ -235,4 +386,27 @@

tx.type = null;
return tx;
}
export function parse(rawTransaction: BytesLike): Transaction {
const payload = arrayify(rawTransaction);
// Legacy and EIP-155 Transactions
if (payload[0] > 0x7f) { return _parse(payload); }
// Typed Transaction (EIP-2718)
switch (payload[0]) {
case 1:
return _parseEip2930(payload);
default:
break;
}
return logger.throwError(`unsupported transaction type: ${ payload[0] }`, Logger.errors.UNSUPPORTED_OPERATION, {
operation: "parseTransaction",
transactionType: payload[0]
});
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc