Socket
Socket
Sign inDemoInstall

@klaytn/js-ext-core

Package Overview
Dependencies
21
Maintainers
2
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0 to 1.0.1

8

dist/accountkey/accountkey.d.ts

@@ -10,2 +10,3 @@ import { AccountKeyType } from "../util";

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}

@@ -19,2 +20,3 @@ export declare class AccountKeyLegacy extends AccountKey {

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}

@@ -32,2 +34,3 @@ export declare class AccountKeyPublic extends AccountKey {

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}

@@ -41,2 +44,3 @@ export declare class AccountKeyFail extends AccountKey {

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}

@@ -50,3 +54,2 @@ export declare class AccountKeyWeightedMultiSig extends AccountKey {

keys: {
_assert(value: any, pred: boolean): void;
canonicalize(value: any): import("../field").WeightedPublicKey[];

@@ -57,2 +60,3 @@ emptyValue(): import("../field").WeightedPublicKey[];

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}

@@ -65,3 +69,2 @@ export declare class AccountKeyRoleBased extends AccountKey {

keys: {
_assert(value: any, pred: boolean): void;
canonicalize(value: any): string[];

@@ -72,3 +75,4 @@ emptyValue(): string[];

toRLP(): string;
setFieldsFromRLP(rlp: string): void;
}
//# sourceMappingURL=accountkey.d.ts.map

@@ -12,2 +12,8 @@ "use strict";

}
setFieldsFromRLP(rlp) {
if (rlp !== "0x80") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: util_1.AccountKeyType.Nil });
}
}

@@ -25,2 +31,8 @@ exports.AccountKeyNil = AccountKeyNil;

}
setFieldsFromRLP(rlp) {
if (rlp !== "0x01c0") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: util_1.AccountKeyType.Legacy });
}
}

@@ -40,2 +52,11 @@ exports.AccountKeyLegacy = AccountKeyLegacy;

}
setFieldsFromRLP(rlp) {
const type = util_1.HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const key = util_1.RLP.decode(withoutType);
this.setFields({ type, key });
}
}

@@ -54,2 +75,8 @@ exports.AccountKeyPublic = AccountKeyPublic;

}
setFieldsFromRLP(rlp) {
if (rlp !== "0x03c0") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: util_1.AccountKeyType.Fail });
}
}

@@ -69,2 +96,14 @@ exports.AccountKeyFail = AccountKeyFail;

}
setFieldsFromRLP(rlp) {
const type = util_1.HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const decoded = util_1.RLP.decode(withoutType);
if (decoded.length != 2) {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type, threshold: decoded[0], keys: decoded[1] });
}
}

@@ -87,2 +126,11 @@ exports.AccountKeyWeightedMultiSig = AccountKeyWeightedMultiSig;

}
setFieldsFromRLP(rlp) {
const type = util_1.HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const decoded = util_1.RLP.decode(withoutType);
this.setFields({ type, keys: decoded });
}
}

@@ -89,0 +137,0 @@ exports.AccountKeyRoleBased = AccountKeyRoleBased;

import { FieldSet, FieldSetFactory, Fields } from "../field";
import { AccountKeyType } from "../util";
export declare abstract class AccountKey extends FieldSet {
abstract toRLP(): string;
abstract setFieldsFromRLP(rlp: string): void;
}

@@ -8,5 +10,34 @@ declare class _AccountKeyFactory extends FieldSetFactory<AccountKey> {

fromObject(fields: Fields): AccountKey;
fromRLP(rlp: string): AccountKey;
}
export declare const AccountKeyFactory: _AccountKeyFactory;
export interface ParsedAccountKeyNil {
type: AccountKeyType.Nil;
}
export interface ParsedAccountKeyLegacy {
type: AccountKeyType.Legacy;
}
export interface ParsedAccountKeyPublic {
type: AccountKeyType.Public;
key: string;
}
export interface ParsedAccountKeyFail {
type: AccountKeyType.Fail;
}
export interface ParsedAccountKeyWeightedMultiSig {
type: AccountKeyType.WeightedMultiSig;
threshold: number;
keys: {
weight: number;
key: string;
}[];
}
export type ParsedAccountKeyEmbeddable = ParsedAccountKeyNil | ParsedAccountKeyLegacy | ParsedAccountKeyPublic | ParsedAccountKeyFail | ParsedAccountKeyWeightedMultiSig;
export interface ParsedAccountKeyRoleBased {
type: AccountKeyType.RoleBased;
keys: ParsedAccountKeyEmbeddable[];
}
export type ParsedAccountKey = ParsedAccountKeyEmbeddable | ParsedAccountKeyRoleBased;
export declare function parseAccountKey(rlp: string): ParsedAccountKey;
export {};
//# sourceMappingURL=factory.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccountKeyFactory = exports.AccountKey = void 0;
exports.parseAccountKey = exports.AccountKeyFactory = exports.AccountKey = void 0;
const field_1 = require("../field");

@@ -25,4 +25,42 @@ const util_1 = require("../util");

}
fromRLP(rlp) {
if (rlp == "0x80") { // special case without type prefix
return this.fromObject({ type: util_1.AccountKeyType.Nil });
}
const type = (0, util_1.getTypePrefix)(rlp);
if (!(0, util_1.isKlaytnAccountKeyType)(type)) {
throw new Error("Not a Klaytn account key");
}
const ctor = this.lookup(type);
const instance = new ctor();
instance.setFieldsFromRLP(rlp);
return instance;
}
}
exports.AccountKeyFactory = new _AccountKeyFactory();
function parseAccountKey(rlp) {
const key = exports.AccountKeyFactory.fromRLP(rlp);
const canonical = key.toObject();
if (key.type == util_1.AccountKeyType.Nil || key.type == util_1.AccountKeyType.Legacy || key.type == util_1.AccountKeyType.Fail) {
return { type: key.type };
}
if (key.type == util_1.AccountKeyType.Public) {
return { type: key.type, key: canonical.key };
}
if (key.type == util_1.AccountKeyType.WeightedMultiSig) {
return {
type: key.type,
threshold: util_1.HexStr.toNumber(canonical.threshold),
keys: canonical.keys.map((k) => ({ weight: util_1.HexStr.toNumber(k[0]), key: k[1] })),
};
}
if (key.type == util_1.AccountKeyType.RoleBased) {
return {
type: key.type,
keys: canonical.keys.map((k) => parseAccountKey(k)),
};
}
throw new Error(`Unknown AccountKeyType ${key.type}`);
}
exports.parseAccountKey = parseAccountKey;
//# sourceMappingURL=factory.js.map

@@ -7,3 +7,2 @@ export declare const FieldTypeCompressedPubKey: {

export declare const FieldTypeWeightedPublicKeys: {
_assert(value: any, pred: boolean): void;
canonicalize(value: any): WeightedPublicKey[];

@@ -13,3 +12,2 @@ emptyValue(): WeightedPublicKey[];

export declare const FieldTypeAccountKeyList: {
_assert(value: any, pred: boolean): void;
canonicalize(value: any): string[];

@@ -16,0 +14,0 @@ emptyValue(): string[];

@@ -20,2 +20,3 @@ "use strict";

// Accepted types: An array of tuples [weight: number|string, publicKey: string]
// An array of objects { weight: number|string, publicKey: string }
// Canonical type: An array of hexlified tuples [weight: string, publicKey: string]

@@ -28,14 +29,24 @@ // Example canonical value:

exports.FieldTypeWeightedPublicKeys = new class {
_assert(value, pred) {
if (!pred) {
throw new Error(`Malformed WeightedPublicKeys '${value}'`);
canonicalize(value) {
if (!lodash_1.default.isArray(value)) {
throw new Error("Malformed WeightedPublicKeys");
}
}
canonicalize(value) {
this._assert(value, lodash_1.default.isArray(value));
return lodash_1.default.map(value, (tuple) => {
this._assert(value, lodash_1.default.isArray(tuple) && tuple.length == 2);
const threshold = util_1.HexStr.fromNumber(tuple[0]);
const publicKey = (0, util_1.getCompressedPublicKey)(tuple[1]);
return [threshold, publicKey];
return lodash_1.default.map(value, (tupleOrObject) => {
if (lodash_1.default.isArray(tupleOrObject) && tupleOrObject.length == 2) {
const tuple = tupleOrObject;
return [
util_1.HexStr.fromNumber(tuple[0]),
(0, util_1.getCompressedPublicKey)(tuple[1])
];
}
else if (lodash_1.default.has(tupleOrObject, "weight") && lodash_1.default.has(tupleOrObject, "key")) {
const object = tupleOrObject;
return [
util_1.HexStr.fromNumber(object.weight),
(0, util_1.getCompressedPublicKey)(object.key)
];
}
else {
throw new Error("Malformed WeightedPublicKeys");
}
});

@@ -46,2 +57,3 @@ }

// Accepted types: An array of AccountKeys in JS object format
// An array of AccountKeys in RLP format
// Canonical type: An array of AccountKeys in RLP format

@@ -55,15 +67,17 @@ // Example canonical value:

exports.FieldTypeAccountKeyList = new class {
_assert(value, pred) {
if (!pred) {
throw new Error(`Malformed RoleBasedKeys '${value}'`);
canonicalize(value) {
if (!lodash_1.default.isArray(value)) {
throw new Error("Malformed RoleBasedKeys");
}
}
canonicalize(value) {
this._assert(value, lodash_1.default.isArray(value));
return lodash_1.default.map(value, (elem) => {
const accountKey = accountkey_1.AccountKeyFactory.fromObject(elem);
if (!(0, util_1.isEmbeddableAccountKeyType)(accountKey.type)) {
throw new Error(`AccountKeyType ${accountKey.type} cannot be inside an AccountKeyRoleBased`);
if (lodash_1.default.isString(elem) && util_1.HexStr.isHex(elem)) { // pass RLP format
return elem;
}
return accountKey.toRLP();
else { // encode JS object format
const accountKey = accountkey_1.AccountKeyFactory.fromObject(elem);
if (!(0, util_1.isEmbeddableAccountKeyType)(accountKey.type)) {
throw new Error(`AccountKeyType ${accountKey.type} cannot be inside an AccountKeyRoleBased`);
}
return accountKey.toRLP();
}
});

@@ -70,0 +84,0 @@ }

@@ -17,2 +17,3 @@ import { FieldTypes, Fields } from "./common";

toObject(): Fields;
throwTypeError(msg: string): never;
}

@@ -19,0 +20,0 @@ export interface ConcreteFieldSet<T extends FieldSet> {

@@ -76,2 +76,5 @@ "use strict";

}
throwTypeError(msg) {
throw new Error(`${msg} for '${this.typeName}' (type ${util_1.HexStr.fromNumber(this.type)})`);
}
}

@@ -78,0 +81,0 @@ exports.FieldSet = FieldSet;

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

import { Transaction as EthersTransaction } from "@ethersproject/transactions";
import { AccessList } from "@ethersproject/transactions";
import { FieldSet, FieldSetFactory, Fields } from "../field";

@@ -10,3 +10,2 @@ import { SignatureLike } from "../util";

senderTxHashRLP(): string;
throwTypeError(msg: string): never;
addSenderSig(sig: SignatureLike): void;

@@ -25,4 +24,29 @@ addFeePayerSig(sig: SignatureLike): void;

export declare const KlaytnTxFactory: _KlaytnTxFactory;
export declare function parseTransaction(rlp: string): EthersTransaction;
export interface ParsedTransaction {
hash?: string;
to?: string;
from?: string;
nonce: number;
gasLimit: string;
gasPrice?: string;
data: string;
value: string;
chainId?: number;
r?: string;
s?: string;
v?: number;
type?: number | null;
accessList?: AccessList;
maxPriorityFeePerGas?: string;
maxFeePerGas?: string;
key?: any;
humanReadable?: boolean;
codeFormat?: number;
feePayer?: string;
txSignatures?: any;
feePayerSignatures?: any;
feeRatio?: number;
}
export declare function parseTransaction(rlp: string): ParsedTransaction;
export {};
//# sourceMappingURL=factory.d.ts.map
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseTransaction = exports.KlaytnTxFactory = exports.KlaytnTx = void 0;
const bytes_1 = require("@ethersproject/bytes");
const keccak256_1 = require("@ethersproject/keccak256");
const transactions_1 = require("@ethersproject/transactions");
const lodash_1 = __importDefault(require("lodash"));
const field_1 = require("../field");
const util_1 = require("../util");
function getTypePrefix(rlp) {
if (!util_1.HexStr.isHex(rlp)) {
throw new Error("Not an RLP encoded string");
}
if (rlp.length < 4) {
throw new Error("RLP encoded string too short");
}
return util_1.HexStr.toNumber(rlp.substring(0, 4)); // 0xNN
}
class KlaytnTx extends field_1.FieldSet {

@@ -39,5 +36,2 @@ // //////////////////////////////////////////////////////////

// Child classes CANNOT override below methods
throwTypeError(msg) {
throw new Error(`${msg} for '${this.typeName}' (type ${util_1.HexStr.fromNumber(this.type)})`);
}
// Add a signature

@@ -123,3 +117,3 @@ addSenderSig(sig) {

fromRLP(rlp) {
const type = getTypePrefix(rlp);
const type = (0, util_1.getTypePrefix)(rlp);
if (!(0, util_1.isKlaytnTxType)(type)) {

@@ -135,12 +129,58 @@ throw new Error("Not a Klaytn raw transaction");

exports.KlaytnTxFactory = new _KlaytnTxFactory();
/* eslint-disable no-multi-spaces */
function parseTransaction(rlp) {
const type = getTypePrefix(rlp);
var _a, _b;
const type = (0, util_1.getTypePrefix)(rlp);
if (!(0, util_1.isKlaytnTxType)(type)) {
return (0, transactions_1.parse)(rlp);
const tx = (0, transactions_1.parse)(rlp);
const parsedTx = Object.assign(Object.assign({}, tx), {
// Convert BigNumber to hex string
gasLimit: (0, bytes_1.hexValue)(tx.gasLimit), gasPrice: tx.gasPrice ? (0, bytes_1.hexValue)(tx.gasPrice) : undefined, value: (0, bytes_1.hexValue)(tx.value), maxPriorityFeePerGas: tx.maxPriorityFeePerGas ? (0, bytes_1.hexValue)(tx.maxPriorityFeePerGas) : undefined, maxFeePerGas: tx.maxFeePerGas ? (0, bytes_1.hexValue)(tx.maxFeePerGas) : undefined });
// Clean up 'explicit undefined' fields
lodash_1.default.forOwn(parsedTx, (value, key) => {
if (value === undefined) {
delete parsedTx[key];
}
});
return parsedTx;
}
else {
return exports.KlaytnTxFactory.fromRLP(rlp).toObject();
const tx = exports.KlaytnTxFactory.fromRLP(rlp).toObject();
try {
const parsedTx = {
hash: (0, keccak256_1.keccak256)(rlp),
to: tx.to ? util_1.HexStr.toAddress(tx.to) : undefined,
from: tx.from ? util_1.HexStr.toAddress(tx.from) : undefined,
nonce: util_1.HexStr.toNumber(tx.nonce),
gasLimit: (0, bytes_1.hexValue)(tx.gasLimit),
gasPrice: (0, bytes_1.hexValue)(tx.gasPrice),
data: (_a = tx.data) !== null && _a !== void 0 ? _a : "0x",
value: (0, bytes_1.hexValue)((_b = tx.value) !== null && _b !== void 0 ? _b : 0),
chainId: tx.chainId ? util_1.HexStr.toNumber(tx.chainId) : undefined,
type: tx.type ? util_1.HexStr.toNumber(tx.type) : null,
accessList: tx.accessList,
key: tx.key,
humanReadable: tx.humanReadable ? util_1.HexStr.toBoolean(tx.humanReadable) : undefined,
codeFormat: tx.codeFormat ? util_1.HexStr.toNumber(tx.codeFormat) : undefined,
feePayer: tx.feePayer ? util_1.HexStr.toAddress(tx.feePayer) : undefined,
txSignatures: tx.txSignatures,
feePayerSignatures: tx.feePayerSignatures,
feeRatio: tx.feeRatio ? util_1.HexStr.toNumber(tx.feeRatio) : undefined,
};
// Clean up 'explicit undefined' fields
lodash_1.default.forOwn(parsedTx, (value, key) => {
if (value === undefined) {
delete parsedTx[key];
}
});
return parsedTx;
}
catch (e) {
// In case conversion fails, return the original tx object.
return tx;
}
}
}
exports.parseTransaction = parseTransaction;
/* eslint-enable no-multi-spaces */
//# sourceMappingURL=factory.js.map

@@ -21,4 +21,5 @@ export declare enum TxType {

}
export declare function parseTxType(type?: number | string): number;
export declare function getKaikasTxType(type?: number | string): number | string | undefined;
type TxTypeLike = number | bigint | string | null | undefined;
export declare function parseTxType(type?: TxTypeLike): number;
export declare function getKaikasTxType(type?: TxTypeLike): number | string | undefined;
export declare function isKlaytnTxType(type?: number): boolean;

@@ -40,2 +41,3 @@ export declare function isBasicTxType(type?: number): boolean;

export declare const CodeFormatEVM = 0;
export {};
//# sourceMappingURL=const.d.ts.map

@@ -34,8 +34,9 @@ "use strict";

})(TxType || (exports.TxType = TxType = {}));
// Parse Klaytn TxType in various formats including number (8),
// hex string (0x08), camel case string ("ValueTransfer"), and snake case string ("VALUE_TRANSFER").
function parseTxType(type) {
if (type == undefined) {
return 0;
if (type === undefined || type === null) {
type = 0;
}
if (typeof type === "bigint") {
type = Number(type);
}
if (lodash_1.default.isNumber(type)) {

@@ -42,0 +43,0 @@ return type;

@@ -17,3 +17,6 @@ import { BigNumberish } from "@ethersproject/bignumber";

stripHexPrefix(value: string): string;
toAddress(value?: string | null): string;
toBoolean(value: string): boolean;
};
export declare function getTypePrefix(rlp: string): number;
//# sourceMappingURL=data.d.ts.map

@@ -27,5 +27,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.HexStr = exports.RLP = void 0;
exports.getTypePrefix = exports.HexStr = exports.RLP = void 0;
const address_1 = require("@ethersproject/address");
const bignumber_1 = require("@ethersproject/bignumber");
const bytes = __importStar(require("@ethersproject/bytes"));
const constants_1 = require("@ethersproject/constants");
const rlp = __importStar(require("@ethersproject/rlp"));

@@ -63,4 +65,33 @@ exports.RLP = {

return value.replace(/^(0x)?/, "");
},
toAddress(value) {
if (!value || value == "0x") {
return constants_1.AddressZero;
}
else {
return (0, address_1.getAddress)(value);
}
},
toBoolean(value) {
if (value == "0x") {
return false;
}
else if (value == "0x01") {
return true;
}
else {
throw new Error(`Invalid RLP boolean: '${value}'`);
}
},
};
function getTypePrefix(rlp) {
if (!exports.HexStr.isHex(rlp)) {
throw new Error("Not an RLP encoded string");
}
};
if (rlp.length < 4) {
throw new Error("RLP encoded string too short");
}
return exports.HexStr.toNumber(rlp.substring(0, 4)); // 0xNN
}
exports.getTypePrefix = getTypePrefix;
//# sourceMappingURL=data.js.map
{
"name": "@klaytn/js-ext-core",
"version": "1.0.0",
"version": "1.0.1",
"license": "MIT",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

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

import _ from "lodash";
import { FieldTypeAccountKeyList, FieldTypeCompressedPubKey, FieldTypeUint32, FieldTypeUint8, FieldTypeWeightedPublicKeys } from "../field";

@@ -17,2 +19,9 @@ import { AccountKeyType, HexStr, RLP } from "../util";

}
setFieldsFromRLP(rlp: string): void {
if (rlp !== "0x80") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: AccountKeyType.Nil });
}
}

@@ -31,2 +40,9 @@

}
setFieldsFromRLP(rlp: string): void {
if (rlp !== "0x01c0") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: AccountKeyType.Legacy });
}
}

@@ -48,2 +64,13 @@

}
setFieldsFromRLP(rlp: string): void {
const type = HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const key = RLP.decode(withoutType);
this.setFields({ type, key });
}
}

@@ -62,2 +89,9 @@

}
setFieldsFromRLP(rlp: string): void {
if (rlp !== "0x03c0") {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type: AccountKeyType.Fail });
}
}

@@ -80,2 +114,16 @@

}
setFieldsFromRLP(rlp: string): void {
const type = HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const decoded = RLP.decode(withoutType);
if (decoded.length != 2) {
this.throwTypeError(`Invalid RLP string '${rlp}'`);
}
this.setFields({ type, threshold: decoded[0], keys: decoded[1] });
}
}

@@ -99,2 +147,13 @@

}
setFieldsFromRLP(rlp: string): void {
const type = HexStr.toNumber(rlp.substring(0, 4));
if (type !== this.type) {
this.throwTypeError(`Invalid type '${type}`);
}
const withoutType = "0x" + String(rlp).substring(4); // Strip type byte
const decoded = RLP.decode(withoutType);
this.setFields({ type, keys: decoded });
}
}

@@ -0,3 +1,5 @@

import { hexValue } from "@ethersproject/bytes";
import { FieldSet, FieldSetFactory, Fields } from "../field";
import { AccountKeyType } from "../util";
import { AccountKeyType, HexStr, RLP, getTypePrefix, isKlaytnAccountKeyType } from "../util";

@@ -9,2 +11,4 @@ // A typed AccountKey for Klatyn is a FieldSet.

abstract toRLP(): string;
// Set its own fields from an RLP encoded string.
abstract setFieldsFromRLP(rlp: string): void;
}

@@ -27,3 +31,69 @@

}
public fromRLP(rlp: string): AccountKey {
if (rlp == "0x80") { // special case without type prefix
return this.fromObject({ type: AccountKeyType.Nil });
}
const type = getTypePrefix(rlp);
if (!isKlaytnAccountKeyType(type)) {
throw new Error("Not a Klaytn account key");
}
const ctor = this.lookup(type);
const instance = new ctor();
instance.setFieldsFromRLP(rlp);
return instance;
}
}
export const AccountKeyFactory = new _AccountKeyFactory();
export const AccountKeyFactory = new _AccountKeyFactory();
export interface ParsedAccountKeyNil { type: AccountKeyType.Nil; }
export interface ParsedAccountKeyLegacy { type: AccountKeyType.Legacy; }
export interface ParsedAccountKeyPublic { type: AccountKeyType.Public; key: string; }
export interface ParsedAccountKeyFail { type: AccountKeyType.Fail; }
export interface ParsedAccountKeyWeightedMultiSig {
type: AccountKeyType.WeightedMultiSig;
threshold: number;
keys: { weight: number, key: string }[];
}
export type ParsedAccountKeyEmbeddable =
| ParsedAccountKeyNil
| ParsedAccountKeyLegacy
| ParsedAccountKeyPublic
| ParsedAccountKeyFail
| ParsedAccountKeyWeightedMultiSig;
export interface ParsedAccountKeyRoleBased {
type: AccountKeyType.RoleBased;
keys: ParsedAccountKeyEmbeddable[];
}
export type ParsedAccountKey =
| ParsedAccountKeyEmbeddable
| ParsedAccountKeyRoleBased;
export function parseAccountKey(rlp: string): ParsedAccountKey {
const key = AccountKeyFactory.fromRLP(rlp);
const canonical = key.toObject();
if (key.type == AccountKeyType.Nil || key.type == AccountKeyType.Legacy || key.type == AccountKeyType.Fail) {
return { type: key.type };
}
if (key.type == AccountKeyType.Public) {
return { type: key.type, key: canonical.key };
}
if (key.type == AccountKeyType.WeightedMultiSig) {
return {
type: key.type,
threshold: HexStr.toNumber(canonical.threshold),
keys: canonical.keys.map((k: any) => ({ weight: HexStr.toNumber(k[0]), key: k[1] })),
};
}
if (key.type == AccountKeyType.RoleBased) {
return {
type: key.type,
keys: canonical.keys.map((k: any) => parseAccountKey(k)),
};
}
throw new Error(`Unknown AccountKeyType ${key.type}`);
}

@@ -23,2 +23,3 @@ import _ from "lodash";

// Accepted types: An array of tuples [weight: number|string, publicKey: string]
// An array of objects { weight: number|string, publicKey: string }
// Canonical type: An array of hexlified tuples [weight: string, publicKey: string]

@@ -31,17 +32,23 @@ // Example canonical value:

export const FieldTypeWeightedPublicKeys = new class implements FieldType {
_assert(value: any, pred: boolean) {
if (!pred) {
throw new Error(`Malformed WeightedPublicKeys '${value}'`);
canonicalize(value: any): WeightedPublicKey[] {
if (!_.isArray(value)) {
throw new Error("Malformed WeightedPublicKeys");
}
}
canonicalize(value: any): WeightedPublicKey[] {
this._assert(value, _.isArray(value));
return _.map(value, (tuple: any) => {
this._assert(value, _.isArray(tuple) && tuple.length == 2);
const threshold = HexStr.fromNumber(tuple[0]);
const publicKey = getCompressedPublicKey(tuple[1]);
return [threshold, publicKey];
return _.map(value, (tupleOrObject: any) => {
if (_.isArray(tupleOrObject) && tupleOrObject.length == 2) {
const tuple = tupleOrObject;
return [
HexStr.fromNumber(tuple[0]),
getCompressedPublicKey(tuple[1])
];
} else if (_.has(tupleOrObject, "weight") && _.has(tupleOrObject, "key")) {
const object = tupleOrObject;
return [
HexStr.fromNumber(object.weight),
getCompressedPublicKey(object.key)
];
} else {
throw new Error("Malformed WeightedPublicKeys");
}
});

@@ -54,2 +61,3 @@ }

// Accepted types: An array of AccountKeys in JS object format
// An array of AccountKeys in RLP format
// Canonical type: An array of AccountKeys in RLP format

@@ -63,18 +71,17 @@ // Example canonical value:

export const FieldTypeAccountKeyList = new class implements FieldType {
_assert(value: any, pred: boolean) {
if (!pred) {
throw new Error(`Malformed RoleBasedKeys '${value}'`);
canonicalize(value: any): string[] {
if (!_.isArray(value)) {
throw new Error("Malformed RoleBasedKeys");
}
}
canonicalize(value: any): string[] {
this._assert(value, _.isArray(value));
return _.map(value, (elem: any) => {
const accountKey = AccountKeyFactory.fromObject(elem);
if (!isEmbeddableAccountKeyType(accountKey.type)) {
throw new Error(`AccountKeyType ${accountKey.type} cannot be inside an AccountKeyRoleBased`);
if (_.isString(elem) && HexStr.isHex(elem)) { // pass RLP format
return elem;
} else { // encode JS object format
const accountKey = AccountKeyFactory.fromObject(elem);
if (!isEmbeddableAccountKeyType(accountKey.type)) {
throw new Error(`AccountKeyType ${accountKey.type} cannot be inside an AccountKeyRoleBased`);
}
return accountKey.toRLP();
}
return accountKey.toRLP();
});

@@ -81,0 +88,0 @@ }

@@ -96,2 +96,6 @@ import _ from "lodash";

}
throwTypeError(msg: string): never {
throw new Error(`${msg} for '${this.typeName}' (type ${HexStr.fromNumber(this.type)})`);
}
}

@@ -98,0 +102,0 @@

@@ -1,19 +0,10 @@

import { parse as parseEthTransaction, Transaction as EthersTransaction } from "@ethersproject/transactions";
import { getAddress } from "@ethersproject/address";
import { hexValue } from "@ethersproject/bytes";
import { keccak256 } from "@ethersproject/keccak256";
import { AccessList, parse as parseEthTransaction } from "@ethersproject/transactions";
import _ from "lodash";
import { FieldSet, FieldSetFactory, Fields } from "../field";
import { HexStr, getSignatureTuple, SignatureLike, isKlaytnTxType, isFeePayerSigTxType, RLP, TxType } from "../util";
import { HexStr, getTypePrefix, getSignatureTuple, SignatureLike, isKlaytnTxType, isFeePayerSigTxType, RLP, TxType } from "../util";
function getTypePrefix(rlp: string) {
if (!HexStr.isHex(rlp)) {
throw new Error("Not an RLP encoded string");
}
if (rlp.length < 4) {
throw new Error("RLP encoded string too short");
}
return HexStr.toNumber(rlp.substring(0, 4)); // 0xNN
}
export abstract class KlaytnTx extends FieldSet {

@@ -60,6 +51,2 @@ // A Klaytn Tx has 4 kinds of RLP encoding:

throwTypeError(msg: string): never {
throw new Error(`${msg} for '${this.typeName}' (type ${HexStr.fromNumber(this.type)})`);
}
// Add a signature

@@ -148,4 +135,4 @@ addSenderSig(sig: SignatureLike) {

if (HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.SmartContractDeploy) ||
HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeploy) ||
HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeployWithRatio)) {
HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeploy) ||
HexStr.fromNumber(fields.type) == HexStr.fromNumber(TxType.FeeDelegatedSmartContractDeployWithRatio)) {
fields.to = "0x";

@@ -170,9 +157,99 @@ }

export function parseTransaction(rlp: string): EthersTransaction {
// Similar to ethers.js 'Transaction', but does not use BigNumber.
// All numbers are hexlified without leading zeros, suitable for RPC calls.
export interface ParsedTransaction {
hash?: string;
to?: string;
from?: string;
nonce: number;
gasLimit: string;
gasPrice?: string;
data: string;
value: string;
chainId?: number;
r?: string;
s?: string;
v?: number;
// Typed-Transaction features
type?: number | null;
// EIP-2930; Type 1 & EIP-1559; Type 2
accessList?: AccessList;
// EIP-1559; Type 2
maxPriorityFeePerGas?: string;
maxFeePerGas?: string;
// Klaytn tx types
key?: any;
humanReadable?: boolean;
codeFormat?: number;
feePayer?: string;
txSignatures?: any;
feePayerSignatures?: any;
feeRatio?: number;
}
/* eslint-disable no-multi-spaces */
export function parseTransaction(rlp: string): ParsedTransaction {
const type = getTypePrefix(rlp);
if (!isKlaytnTxType(type)) {
return parseEthTransaction(rlp);
const tx = parseEthTransaction(rlp);
const parsedTx: ParsedTransaction = {
...tx,
// Convert BigNumber to hex string
gasLimit: hexValue(tx.gasLimit),
gasPrice: tx.gasPrice ? hexValue(tx.gasPrice) : undefined,
value: hexValue(tx.value),
maxPriorityFeePerGas: tx.maxPriorityFeePerGas ? hexValue(tx.maxPriorityFeePerGas) : undefined,
maxFeePerGas: tx.maxFeePerGas ? hexValue(tx.maxFeePerGas) : undefined,
};
// Clean up 'explicit undefined' fields
_.forOwn(parsedTx, (value, key) => {
if (value === undefined) {
delete (parsedTx as any)[key];
}
});
return parsedTx;
} else {
return KlaytnTxFactory.fromRLP(rlp).toObject() as EthersTransaction;
const tx = KlaytnTxFactory.fromRLP(rlp).toObject();
try {
const parsedTx: ParsedTransaction = {
hash: keccak256(rlp),
to: tx.to ? HexStr.toAddress(tx.to) : undefined,
from: tx.from ? HexStr.toAddress(tx.from) : undefined,
nonce: HexStr.toNumber(tx.nonce),
gasLimit: hexValue(tx.gasLimit),
gasPrice: hexValue(tx.gasPrice),
data: tx.data ?? "0x",
value: hexValue(tx.value ?? 0),
chainId: tx.chainId ? HexStr.toNumber(tx.chainId) : undefined,
type: tx.type ? HexStr.toNumber(tx.type) : null,
accessList: tx.accessList,
key: tx.key,
humanReadable: tx.humanReadable ? HexStr.toBoolean(tx.humanReadable) : undefined,
codeFormat: tx.codeFormat ? HexStr.toNumber(tx.codeFormat) : undefined,
feePayer: tx.feePayer ? HexStr.toAddress(tx.feePayer) : undefined,
txSignatures: tx.txSignatures,
feePayerSignatures: tx.feePayerSignatures,
feeRatio: tx.feeRatio ? HexStr.toNumber(tx.feeRatio) : undefined,
};
// Clean up 'explicit undefined' fields
_.forOwn(parsedTx, (value, key) => {
if (value === undefined) {
delete (parsedTx as any)[key];
}
});
return parsedTx;
} catch (e) {
// In case conversion fails, return the original tx object.
return tx as any;
}
}
}
/* eslint-enable no-multi-spaces */

@@ -34,7 +34,13 @@ import _ from "lodash";

// hex string (0x08), camel case string ("ValueTransfer"), and snake case string ("VALUE_TRANSFER").
export function parseTxType(type?: number | string): number {
if (type == undefined) {
return 0;
type TxTypeLike = number | bigint | string | null | undefined;
export function parseTxType(type?: TxTypeLike): number {
if (type === undefined || type === null) {
type = 0;
}
if (typeof type === "bigint") {
type = Number(type);
}
if (_.isNumber(type)) {

@@ -67,3 +73,3 @@ return type;

// Convert Klaytn TxTypes to upper and snake case string (e.g. "VALUE_TRANSFER").
export function getKaikasTxType(type?: number | string): number | string | undefined {
export function getKaikasTxType(type?: TxTypeLike): number | string | undefined {
const num = parseTxType(type);

@@ -70,0 +76,0 @@ if (!isKlaytnTxType(num)) {

// Data type utilities
import { getAddress } from "@ethersproject/address";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import * as bytes from "@ethersproject/bytes";
import { AddressZero } from "@ethersproject/constants";
import * as rlp from "@ethersproject/rlp";

@@ -39,3 +41,31 @@

return value.replace(/^(0x)?/, "");
},
toAddress(value?: string | null): string {
if (!value || value == "0x") {
return AddressZero;
} else {
return getAddress(value);
}
},
toBoolean(value: string): boolean {
if (value == "0x") {
return false;
} else if (value == "0x01") {
return true;
} else {
throw new Error(`Invalid RLP boolean: '${value}'`);
}
},
};
export function getTypePrefix(rlp: string) {
if (!HexStr.isHex(rlp)) {
throw new Error("Not an RLP encoded string");
}
};
if (rlp.length < 4) {
throw new Error("RLP encoded string too short");
}
return HexStr.toNumber(rlp.substring(0, 4)); // 0xNN
}

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

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc